From 2efb7a17c4eeaec80ecb57274f035dfc0133b842 Mon Sep 17 00:00:00 2001 From: "Yenuga, Thathva Sri Sai Reddy" Date: Tue, 19 Mar 2024 21:26:19 -0400 Subject: [PATCH 01/24] Removing deprecated props from material-ui ListItem --- .../integrations/routing/ListRouter.js | 6 +- .../integrations/routing/ListRouter.tsx | 6 +- docs/pages/material-ui/api/list-item.json | 48 -------- .../api-docs/list-item/list-item.json | 28 ----- .../mui-material/src/ListItem/ListItem.d.ts | 50 +------- .../mui-material/src/ListItem/ListItem.js | 109 ------------------ .../src/ListItem/ListItem.spec.tsx | 23 +--- .../src/ListItem/ListItem.test.js | 75 +----------- .../src/ListItem/listItemClasses.ts | 12 -- .../material-ui/components.spec.tsx | 27 +++-- 10 files changed, 24 insertions(+), 360 deletions(-) diff --git a/docs/data/material/integrations/routing/ListRouter.js b/docs/data/material/integrations/routing/ListRouter.js index f503a9f39cf918..b0c92f1522ae32 100644 --- a/docs/data/material/integrations/routing/ListRouter.js +++ b/docs/data/material/integrations/routing/ListRouter.js @@ -2,7 +2,6 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import List from '@mui/material/List'; import Box from '@mui/material/Box'; -import ListItem from '@mui/material/ListItem'; import Paper from '@mui/material/Paper'; import ListItemIcon from '@mui/material/ListItemIcon'; import ListItemText from '@mui/material/ListItemText'; @@ -18,6 +17,7 @@ import { useLocation, } from 'react-router-dom'; import { StaticRouter } from 'react-router-dom/server'; +import { ListItemButton } from '@mui/material'; function Router(props) { const { children } = props; @@ -45,10 +45,10 @@ function ListItemLink(props) { return (
  • - + {icon ? {icon} : null} - +
  • ); } diff --git a/docs/data/material/integrations/routing/ListRouter.tsx b/docs/data/material/integrations/routing/ListRouter.tsx index 1900b67cf2d582..39d567108e176b 100644 --- a/docs/data/material/integrations/routing/ListRouter.tsx +++ b/docs/data/material/integrations/routing/ListRouter.tsx @@ -1,7 +1,6 @@ import * as React from 'react'; import List from '@mui/material/List'; import Box from '@mui/material/Box'; -import ListItem from '@mui/material/ListItem'; import Paper from '@mui/material/Paper'; import ListItemIcon from '@mui/material/ListItemIcon'; import ListItemText from '@mui/material/ListItemText'; @@ -18,6 +17,7 @@ import { useLocation, } from 'react-router-dom'; import { StaticRouter } from 'react-router-dom/server'; +import { ListItemButton } from '@mui/material'; function Router(props: { children?: React.ReactNode }) { const { children } = props; @@ -49,10 +49,10 @@ function ListItemLink(props: ListItemLinkProps) { return (
  • - + {icon ? {icon} : null} - +
  • ); } diff --git a/docs/pages/material-ui/api/list-item.json b/docs/pages/material-ui/api/list-item.json index d9de1313fd03c9..70be860de93410 100644 --- a/docs/pages/material-ui/api/list-item.json +++ b/docs/pages/material-ui/api/list-item.json @@ -4,18 +4,6 @@ "type": { "name": "enum", "description": "'center'
    | 'flex-start'" }, "default": "'center'" }, - "autoFocus": { - "type": { "name": "bool" }, - "default": "false", - "deprecated": true, - "deprecationInfo": "checkout ListItemButton instead" - }, - "button": { - "type": { "name": "bool" }, - "default": "false", - "deprecated": true, - "deprecationInfo": "checkout ListItemButton instead" - }, "children": { "type": { "name": "custom", "description": "node" } }, "classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } }, "component": { "type": { "name": "elementType" } }, @@ -34,22 +22,10 @@ }, "ContainerProps": { "type": { "name": "object" }, "default": "{}", "deprecated": true }, "dense": { "type": { "name": "bool" }, "default": "false" }, - "disabled": { - "type": { "name": "bool" }, - "default": "false", - "deprecated": true, - "deprecationInfo": "checkout ListItemButton instead" - }, "disableGutters": { "type": { "name": "bool" }, "default": "false" }, "disablePadding": { "type": { "name": "bool" }, "default": "false" }, "divider": { "type": { "name": "bool" }, "default": "false" }, "secondaryAction": { "type": { "name": "node" } }, - "selected": { - "type": { "name": "bool" }, - "default": "false", - "deprecated": true, - "deprecationInfo": "checkout ListItemButton instead" - }, "slotProps": { "type": { "name": "shape", "description": "{ root?: object }" }, "default": "{}" @@ -78,12 +54,6 @@ "description": "Styles applied to the component element if `alignItems=\"flex-start\"`.", "isGlobal": false }, - { - "key": "button", - "className": "MuiListItem-button", - "description": "Styles applied to the inner `component` element if `button={true}`.", - "isGlobal": false - }, { "key": "container", "className": "MuiListItem-container", @@ -96,24 +66,12 @@ "description": "Styles applied to the component element if dense.", "isGlobal": false }, - { - "key": "disabled", - "className": "Mui-disabled", - "description": "State class applied to the inner `component` element if `disabled={true}`.", - "isGlobal": true - }, { "key": "divider", "className": "MuiListItem-divider", "description": "Styles applied to the inner `component` element if `divider={true}`.", "isGlobal": false }, - { - "key": "focusVisible", - "className": "Mui-focusVisible", - "description": "State class applied to the `component`'s `focusVisibleClassName` prop if `button={true}`.", - "isGlobal": true - }, { "key": "gutters", "className": "MuiListItem-gutters", @@ -137,12 +95,6 @@ "className": "MuiListItem-secondaryAction", "description": "Styles applied to the component element if `children` includes `ListItemSecondaryAction`.", "isGlobal": false - }, - { - "key": "selected", - "className": "Mui-selected", - "description": "State class applied to the root element if `selected={true}`.", - "isGlobal": true } ], "spread": true, diff --git a/docs/translations/api-docs/list-item/list-item.json b/docs/translations/api-docs/list-item/list-item.json index e2e49cb15c36ab..75befddb9e4a4c 100644 --- a/docs/translations/api-docs/list-item/list-item.json +++ b/docs/translations/api-docs/list-item/list-item.json @@ -2,12 +2,6 @@ "componentDescription": "Uses an additional container component if `ListItemSecondaryAction` is the last child.", "propDescriptions": { "alignItems": { "description": "Defines the align-items style property." }, - "autoFocus": { - "description": "If true, the list item is focused during the first mount. Focus will also be triggered if the value changes from false to true." - }, - "button": { - "description": "If true, the list item is a button (using ButtonBase). Props intended for ButtonBase can then be applied to ListItem." - }, "children": { "description": "The content of the component if a ListItemSecondaryAction is used it must be the last child." }, @@ -29,7 +23,6 @@ "dense": { "description": "If true, compact vertical padding designed for keyboard and mouse input is used. The prop defaults to the value inherited from the parent List component." }, - "disabled": { "description": "If true, the component is disabled." }, "disableGutters": { "description": "If true, the left and right padding is removed." }, @@ -38,7 +31,6 @@ "description": "If true, a 1px light border is added to the bottom of the list item." }, "secondaryAction": { "description": "The element to display at the end of ListItem." }, - "selected": { "description": "Use to apply selected styling." }, "slotProps": { "description": "The extra props for the slot components. You can override the existing props or add new ones.
    This prop is an alias for the componentsProps prop, which will be deprecated in the future." }, @@ -55,11 +47,6 @@ "nodeName": "the component element", "conditions": "alignItems=\"flex-start\"" }, - "button": { - "description": "Styles applied to {{nodeName}} if {{conditions}}.", - "nodeName": "the inner component element", - "conditions": "button={true}" - }, "container": { "description": "Styles applied to {{nodeName}} if {{conditions}}.", "nodeName": "the container element", @@ -70,21 +57,11 @@ "nodeName": "the component element", "conditions": "dense" }, - "disabled": { - "description": "State class applied to {{nodeName}} if {{conditions}}.", - "nodeName": "the inner component element", - "conditions": "disabled={true}" - }, "divider": { "description": "Styles applied to {{nodeName}} if {{conditions}}.", "nodeName": "the inner component element", "conditions": "divider={true}" }, - "focusVisible": { - "description": "State class applied to {{nodeName}} if {{conditions}}.", - "nodeName": "the component's focusVisibleClassName prop", - "conditions": "button={true}" - }, "gutters": { "description": "Styles applied to {{nodeName}} unless {{conditions}}.", "nodeName": "the inner component element", @@ -103,11 +80,6 @@ "description": "Styles applied to {{nodeName}} if {{conditions}}.", "nodeName": "the component element", "conditions": "children includes ListItemSecondaryAction" - }, - "selected": { - "description": "State class applied to {{nodeName}} if {{conditions}}.", - "nodeName": "the root element", - "conditions": "selected={true}" } } } diff --git a/packages/mui-material/src/ListItem/ListItem.d.ts b/packages/mui-material/src/ListItem/ListItem.d.ts index b4e22ee6ba1c8f..9bf456c65390b7 100644 --- a/packages/mui-material/src/ListItem/ListItem.d.ts +++ b/packages/mui-material/src/ListItem/ListItem.d.ts @@ -16,13 +16,6 @@ export interface ListItemBaseProps { * @default 'center' */ alignItems?: 'flex-start' | 'center'; - /** - * If `true`, the list item is focused during the first mount. - * Focus will also be triggered if the value changes from false to true. - * @default false - * @deprecated checkout [ListItemButton](/material-ui/api/list-item-button/) instead - */ - autoFocus?: boolean; /** * The content of the component if a `ListItemSecondaryAction` is used it must * be the last child. @@ -50,12 +43,6 @@ export interface ListItemBaseProps { * @default false */ dense?: boolean; - /** - * If `true`, the component is disabled. - * @default false - * @deprecated checkout [ListItemButton](/material-ui/api/list-item-button/) instead - */ - disabled?: boolean; /** * If `true`, the left and right padding is removed. * @default false @@ -75,12 +62,6 @@ export interface ListItemBaseProps { * The element to display at the end of ListItem. */ secondaryAction?: React.ReactNode; - /** - * Use to apply selected styling. - * @default false - * @deprecated checkout [ListItemButton](/material-ui/api/list-item-button/) instead - */ - selected?: boolean; /** * The system prop that allows defining system overrides as well as additional CSS styles. */ @@ -151,35 +132,8 @@ export interface ListItemTypeMap -> & - OverridableComponent< - ListItemTypeMap< - { - /** - * If `true`, the list item is a button (using `ButtonBase`). Props intended - * for `ButtonBase` can then be applied to `ListItem`. - * @default false - * @deprecated checkout [ListItemButton](/material-ui/api/list-item-button/) instead - */ - button?: false; - }, - 'li' - > - >; +declare const ListItem: ExtendButtonBase> & + OverridableComponent>; export type ListItemProps< RootComponent extends React.ElementType = 'li', diff --git a/packages/mui-material/src/ListItem/ListItem.js b/packages/mui-material/src/ListItem/ListItem.js index d60ee0e4892a8c..8e2d4f8ac48b97 100644 --- a/packages/mui-material/src/ListItem/ListItem.js +++ b/packages/mui-material/src/ListItem/ListItem.js @@ -6,12 +6,9 @@ import { isHostComponent } from '@mui/base/utils'; import composeClasses from '@mui/utils/composeClasses'; import elementTypeAcceptingRef from '@mui/utils/elementTypeAcceptingRef'; import chainPropTypes from '@mui/utils/chainPropTypes'; -import { alpha } from '@mui/system/colorManipulator'; import styled from '../styles/styled'; import useThemeProps from '../styles/useThemeProps'; -import ButtonBase from '../ButtonBase'; import isMuiElement from '../utils/isMuiElement'; -import useEnhancedEffect from '../utils/useEnhancedEffect'; import useForkRef from '../utils/useForkRef'; import ListContext from '../List/ListContext'; import listItemClasses, { getListItemUtilityClass } from './listItemClasses'; @@ -28,7 +25,6 @@ export const overridesResolver = (props, styles) => { ownerState.divider && styles.divider, !ownerState.disableGutters && styles.gutters, !ownerState.disablePadding && styles.padding, - ownerState.button && styles.button, ownerState.hasSecondaryAction && styles.secondaryAction, ]; }; @@ -36,15 +32,12 @@ export const overridesResolver = (props, styles) => { const useUtilityClasses = (ownerState) => { const { alignItems, - button, classes, dense, - disabled, disableGutters, disablePadding, divider, hasSecondaryAction, - selected, } = ownerState; const slots = { @@ -54,11 +47,8 @@ const useUtilityClasses = (ownerState) => { !disableGutters && 'gutters', !disablePadding && 'padding', divider && 'divider', - disabled && 'disabled', - button && 'button', alignItems === 'flex-start' && 'alignItemsFlexStart', hasSecondaryAction && 'secondaryAction', - selected && 'selected', ], container: ['container'], }; @@ -104,22 +94,6 @@ export const ListItemRoot = styled('div', { [`&.${listItemClasses.focusVisible}`]: { backgroundColor: (theme.vars || theme).palette.action.focus, }, - [`&.${listItemClasses.selected}`]: { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` - : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity), - [`&.${listItemClasses.focusVisible}`]: { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.focusOpacity}))` - : alpha( - theme.palette.primary.main, - theme.palette.action.selectedOpacity + theme.palette.action.focusOpacity, - ), - }, - }, - [`&.${listItemClasses.disabled}`]: { - opacity: (theme.vars || theme).palette.action.disabledOpacity, - }, ...(ownerState.alignItems === 'flex-start' && { alignItems: 'flex-start', }), @@ -127,33 +101,6 @@ export const ListItemRoot = styled('div', { borderBottom: `1px solid ${(theme.vars || theme).palette.divider}`, backgroundClip: 'padding-box', }), - ...(ownerState.button && { - transition: theme.transitions.create('background-color', { - duration: theme.transitions.duration.shortest, - }), - '&:hover': { - textDecoration: 'none', - backgroundColor: (theme.vars || theme).palette.action.hover, - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - backgroundColor: 'transparent', - }, - }, - [`&.${listItemClasses.selected}:hover`]: { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` - : alpha( - theme.palette.primary.main, - theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity, - ), - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` - : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity), - }, - }, - }), ...(ownerState.hasSecondaryAction && { // Add some space to avoid collision as `ListItemSecondaryAction` // is absolutely positioned. @@ -176,8 +123,6 @@ const ListItem = React.forwardRef(function ListItem(inProps, ref) { const props = useThemeProps({ props: inProps, name: 'MuiListItem' }); const { alignItems = 'center', - autoFocus = false, - button = false, children: childrenProp, className, component: componentProp, @@ -186,13 +131,11 @@ const ListItem = React.forwardRef(function ListItem(inProps, ref) { ContainerComponent = 'li', ContainerProps: { className: ContainerClassName, ...ContainerProps } = {}, dense = false, - disabled = false, disableGutters = false, disablePadding = false, divider = false, focusVisibleClassName, secondaryAction, - selected = false, slotProps = {}, slots = {}, ...other @@ -209,17 +152,6 @@ const ListItem = React.forwardRef(function ListItem(inProps, ref) { ); const listItemRef = React.useRef(null); - useEnhancedEffect(() => { - if (autoFocus) { - if (listItemRef.current) { - listItemRef.current.focus(); - } else if (process.env.NODE_ENV !== 'production') { - console.error( - 'MUI: Unable to set focus to a ListItem whose component has not been rendered.', - ); - } - } - }, [autoFocus]); const children = React.Children.toArray(childrenProp); @@ -230,15 +162,11 @@ const ListItem = React.forwardRef(function ListItem(inProps, ref) { const ownerState = { ...props, alignItems, - autoFocus, - button, dense: childContext.dense, - disabled, disableGutters, disablePadding, divider, hasSecondaryAction, - selected, }; const classes = useUtilityClasses(ownerState); @@ -250,22 +178,11 @@ const ListItem = React.forwardRef(function ListItem(inProps, ref) { const componentProps = { className: clsx(classes.root, rootProps.className, className), - disabled, ...other, }; let Component = componentProp || 'li'; - if (button) { - componentProps.component = componentProp || 'div'; - componentProps.focusVisibleClassName = clsx( - listItemClasses.focusVisible, - focusVisibleClassName, - ); - - Component = ButtonBase; - } - // v4 implementation, deprecated in v5, will be removed in v6 if (hasSecondaryAction) { // Use div by default. @@ -333,20 +250,6 @@ ListItem.propTypes /* remove-proptypes */ = { * @default 'center' */ alignItems: PropTypes.oneOf(['center', 'flex-start']), - /** - * If `true`, the list item is focused during the first mount. - * Focus will also be triggered if the value changes from false to true. - * @default false - * @deprecated checkout [ListItemButton](/material-ui/api/list-item-button/) instead - */ - autoFocus: PropTypes.bool, - /** - * If `true`, the list item is a button (using `ButtonBase`). Props intended - * for `ButtonBase` can then be applied to `ListItem`. - * @default false - * @deprecated checkout [ListItemButton](/material-ui/api/list-item-button/) instead - */ - button: PropTypes.bool, /** * The content of the component if a `ListItemSecondaryAction` is used it must * be the last child. @@ -429,12 +332,6 @@ ListItem.propTypes /* remove-proptypes */ = { * @default false */ dense: PropTypes.bool, - /** - * If `true`, the component is disabled. - * @default false - * @deprecated checkout [ListItemButton](/material-ui/api/list-item-button/) instead - */ - disabled: PropTypes.bool, /** * If `true`, the left and right padding is removed. * @default false @@ -458,12 +355,6 @@ ListItem.propTypes /* remove-proptypes */ = { * The element to display at the end of ListItem. */ secondaryAction: PropTypes.node, - /** - * Use to apply selected styling. - * @default false - * @deprecated checkout [ListItemButton](/material-ui/api/list-item-button/) instead - */ - selected: PropTypes.bool, /** * The extra props for the slot components. * You can override the existing props or add new ones. diff --git a/packages/mui-material/src/ListItem/ListItem.spec.tsx b/packages/mui-material/src/ListItem/ListItem.spec.tsx index 2814e8736ee60f..d395f323166fb7 100644 --- a/packages/mui-material/src/ListItem/ListItem.spec.tsx +++ b/packages/mui-material/src/ListItem/ListItem.spec.tsx @@ -1,25 +1,7 @@ import * as React from 'react'; import ListItem from '@mui/material/ListItem'; import { styled } from '@mui/material/styles'; - -// button: boolean -function BooleanButtonTest() { - // https://github.com/mui/material-ui/issues/14971 - - function EditableItemFail(props: { editable: boolean }) { - const { editable } = props; - // @ts-expect-error 'boolean' is not assignable to type 'true' - return Editable? {editable}; - } - - function EditableItemValid(props: { editable: boolean }) { - const { editable } = props; - if (editable) { - Editable? Yes; - } - return Editable? No; - } -} +import ListItemButton from '@mui/material/ListItemButton'; // verify that https://github.com/mui/material-ui/issues/19756 already worked. function MouseEnterTest() { @@ -27,9 +9,8 @@ function MouseEnterTest() { ; function handleMouseEnterButton(event: React.MouseEvent) {} - // @ts-expect-error ; // desired: missing property button - ; + ; } // https://github.com/mui/material-ui/issues/26469 diff --git a/packages/mui-material/src/ListItem/ListItem.test.js b/packages/mui-material/src/ListItem/ListItem.test.js index aaf0e4bffd7ef8..a27a281fc67355 100644 --- a/packages/mui-material/src/ListItem/ListItem.test.js +++ b/packages/mui-material/src/ListItem/ListItem.test.js @@ -1,7 +1,7 @@ import * as React from 'react'; import { expect } from 'chai'; import PropTypes from 'prop-types'; -import { act, createRenderer, fireEvent, queries } from '@mui-internal/test-utils'; +import { createRenderer } from '@mui-internal/test-utils'; import { ThemeProvider, createTheme } from '@mui/material/styles'; import ListItemText from '@mui/material/ListItemText'; import ListItemSecondaryAction from '@mui/material/ListItemSecondaryAction'; @@ -9,10 +9,6 @@ import ListItem, { listItemClasses as classes } from '@mui/material/ListItem'; import ListContext from '../List/ListContext'; import describeConformance from '../../test/describeConformance'; -const NoContent = React.forwardRef(() => { - return null; -}); - describe('', () => { const { render } = createRenderer(); @@ -38,23 +34,11 @@ describe('', () => { expect(getByRole('listitem')).to.have.class(classes.gutters); }); - it('should render with the selected class', () => { - const { getByRole } = render(); - expect(getByRole('listitem')).to.have.class(classes.selected); - }); - it('should disable the gutters', () => { const { getByRole } = render(); expect(getByRole('listitem')).not.to.have.class(classes.gutters); }); - describe('prop: button', () => { - it('renders a div', () => { - const { container } = render(); - expect(container.firstChild).to.have.property('nodeName', 'DIV'); - }); - }); - describe('context: dense', () => { it('should forward the context', () => { let context = null; @@ -108,19 +92,6 @@ describe('', () => { expect(listItem.querySelector(`span.${classes.root}`)).not.to.equal(null); }); - it('should accept a button property', () => { - const { getByRole } = render( - - - - , - ); - const listItem = getByRole('listitem'); - - expect(listItem).to.have.class(classes.container); - expect(queries.getByRole(listItem, 'button')).not.to.equal(null); - }); - it('should accept a ContainerComponent property', () => { const { getByRole } = render( @@ -135,21 +106,6 @@ describe('', () => { expect(listItem.querySelector(`div.${classes.root}`)).not.to.equal(null); }); - it('can autofocus a custom ContainerComponent', () => { - const { getByRole } = render( - - - - , - ); - - expect(getByRole('listitem')).toHaveFocus(); - }); - it('should allow customization of the wrapper', () => { const { getByRole } = render( @@ -184,35 +140,6 @@ describe('', () => { ); }).toErrorDev('Warning: Failed prop type: MUI: You used an element'); }); - - it('should warn (but not error) with autoFocus with a function component with no content', () => { - expect(() => { - render(); - }).toErrorDev([ - 'MUI: Unable to set focus to a ListItem whose component has not been rendered.', - // React 18 Strict Effects run mount effects twice - React.version.startsWith('18') && - 'MUI: Unable to set focus to a ListItem whose component has not been rendered.', - ]); - }); - }); - }); - - // TODO remove in v6 in favor of ListItemButton - describe('prop: focusVisibleClassName', () => { - it('should merge the class names', () => { - const { getByRole } = render( - , - ); - const button = getByRole('button'); - - act(() => { - fireEvent.keyDown(document.activeElement || document.body, { key: 'Tab' }); - button.focus(); - }); - - expect(button).to.have.class('focusVisibleClassName'); - expect(button).to.have.class(classes.focusVisible); }); }); diff --git a/packages/mui-material/src/ListItem/listItemClasses.ts b/packages/mui-material/src/ListItem/listItemClasses.ts index 98a317a8fe4d69..d56735452c5f5c 100644 --- a/packages/mui-material/src/ListItem/listItemClasses.ts +++ b/packages/mui-material/src/ListItem/listItemClasses.ts @@ -6,26 +6,18 @@ export interface ListItemClasses { root: string; /** Styles applied to the container element if `children` includes `ListItemSecondaryAction`. */ container: string; - /** State class applied to the `component`'s `focusVisibleClassName` prop if `button={true}`. */ - focusVisible: string; /** Styles applied to the component element if dense. */ dense: string; /** Styles applied to the component element if `alignItems="flex-start"`. */ alignItemsFlexStart: string; - /** State class applied to the inner `component` element if `disabled={true}`. */ - disabled: string; /** Styles applied to the inner `component` element if `divider={true}`. */ divider: string; /** Styles applied to the inner `component` element unless `disableGutters={true}`. */ gutters: string; /** Styles applied to the root element unless `disablePadding={true}`. */ padding: string; - /** Styles applied to the inner `component` element if `button={true}`. */ - button: string; /** Styles applied to the component element if `children` includes `ListItemSecondaryAction`. */ secondaryAction: string; - /** State class applied to the root element if `selected={true}`. */ - selected: string; } export type ListItemClassKey = keyof ListItemClasses; @@ -37,16 +29,12 @@ export function getListItemUtilityClass(slot: string): string { const listItemClasses: ListItemClasses = generateUtilityClasses('MuiListItem', [ 'root', 'container', - 'focusVisible', 'dense', 'alignItemsFlexStart', - 'disabled', 'divider', 'gutters', 'padding', - 'button', 'secondaryAction', - 'selected', ]); export default listItemClasses; diff --git a/test/integration/material-ui/components.spec.tsx b/test/integration/material-ui/components.spec.tsx index 0a4575b210c06d..e9dfa3b55f6882 100644 --- a/test/integration/material-ui/components.spec.tsx +++ b/test/integration/material-ui/components.spec.tsx @@ -73,6 +73,7 @@ import { Toolbar, Tooltip, Typography, + ListItemButton, } from '@mui/material'; import { Theme } from '@mui/material/styles'; import { ButtonBaseActions } from '@mui/material/ButtonBase'; @@ -322,21 +323,21 @@ function DialogTest() {
    {emails.map((email) => ( - log(e)} key={email}> + log(e)} key={email}> - + ))} { - expectType(elem); + expectType(elem); }} onClick={(e) => { - expectType, typeof e>(e); + expectType, typeof e>(e); log(e); }} > @@ -345,8 +346,7 @@ function DialogTest() { - { expectType(elem); }} @@ -361,8 +361,8 @@ function DialogTest() { - - + + component="a" ref={(elem) => { expectType(elem); @@ -371,19 +371,18 @@ function DialogTest() { expectType, typeof e>(e); log(e); }} - button > - - + + - +
    @@ -563,7 +562,7 @@ function ListTest() { return ( {[0, 1, 2, 3].map((value) => ( - log(e)}> + log(e)}> @@ -571,7 +570,7 @@ function ListTest() { - +
    ))} an item From 6a09a81b373a509bd86c47513a420f649c4ad236 Mon Sep 17 00:00:00 2001 From: "Yenuga, Thathva Sri Sai Reddy" Date: Wed, 20 Mar 2024 19:48:51 -0400 Subject: [PATCH 02/24] Removed ListItem's dependency on ExtendButtonBase --- packages/mui-material/src/ListItem/ListItem.d.ts | 4 +--- packages/mui-material/src/ListItem/ListItem.js | 10 +--------- packages/mui-material/src/ListItem/ListItem.spec.tsx | 1 + test/integration/material-ui/components.spec.tsx | 4 ++-- 4 files changed, 5 insertions(+), 14 deletions(-) diff --git a/packages/mui-material/src/ListItem/ListItem.d.ts b/packages/mui-material/src/ListItem/ListItem.d.ts index 9bf456c65390b7..ec9b6660cfa531 100644 --- a/packages/mui-material/src/ListItem/ListItem.d.ts +++ b/packages/mui-material/src/ListItem/ListItem.d.ts @@ -1,7 +1,6 @@ import * as React from 'react'; import { SxProps } from '@mui/system'; import { Theme } from '../styles'; -import { ExtendButtonBase } from '../ButtonBase'; import { OverridableComponent, OverrideProps } from '../OverridableComponent'; import { ListItemClasses } from './listItemClasses'; @@ -132,8 +131,7 @@ export interface ListItemTypeMap> & - OverridableComponent>; +declare const ListItem: OverridableComponent>; export type ListItemProps< RootComponent extends React.ElementType = 'li', diff --git a/packages/mui-material/src/ListItem/ListItem.js b/packages/mui-material/src/ListItem/ListItem.js index 8e2d4f8ac48b97..e01f0b6e4e7707 100644 --- a/packages/mui-material/src/ListItem/ListItem.js +++ b/packages/mui-material/src/ListItem/ListItem.js @@ -11,7 +11,7 @@ import useThemeProps from '../styles/useThemeProps'; import isMuiElement from '../utils/isMuiElement'; import useForkRef from '../utils/useForkRef'; import ListContext from '../List/ListContext'; -import listItemClasses, { getListItemUtilityClass } from './listItemClasses'; +import { getListItemUtilityClass } from './listItemClasses'; import { listItemButtonClasses } from '../ListItemButton'; import ListItemSecondaryAction from '../ListItemSecondaryAction'; @@ -91,9 +91,6 @@ export const ListItemRoot = styled('div', { paddingRight: 48, }, }), - [`&.${listItemClasses.focusVisible}`]: { - backgroundColor: (theme.vars || theme).palette.action.focus, - }, ...(ownerState.alignItems === 'flex-start' && { alignItems: 'flex-start', }), @@ -134,7 +131,6 @@ const ListItem = React.forwardRef(function ListItem(inProps, ref) { disableGutters = false, disablePadding = false, divider = false, - focusVisibleClassName, secondaryAction, slotProps = {}, slots = {}, @@ -347,10 +343,6 @@ ListItem.propTypes /* remove-proptypes */ = { * @default false */ divider: PropTypes.bool, - /** - * @ignore - */ - focusVisibleClassName: PropTypes.string, /** * The element to display at the end of ListItem. */ diff --git a/packages/mui-material/src/ListItem/ListItem.spec.tsx b/packages/mui-material/src/ListItem/ListItem.spec.tsx index d395f323166fb7..aa3d9ff870d40f 100644 --- a/packages/mui-material/src/ListItem/ListItem.spec.tsx +++ b/packages/mui-material/src/ListItem/ListItem.spec.tsx @@ -9,6 +9,7 @@ function MouseEnterTest() { ; function handleMouseEnterButton(event: React.MouseEvent) {} + // @ts-expect-error ; // desired: missing property button ; } diff --git a/test/integration/material-ui/components.spec.tsx b/test/integration/material-ui/components.spec.tsx index e9dfa3b55f6882..89efc56d9914ea 100644 --- a/test/integration/material-ui/components.spec.tsx +++ b/test/integration/material-ui/components.spec.tsx @@ -334,10 +334,10 @@ function DialogTest() { ))} { - expectType(elem); + expectType(elem); }} onClick={(e) => { - expectType, typeof e>(e); + expectType, typeof e>(e); log(e); }} > From 5a84d0579f7c54333493a5d54f22886ecb717071 Mon Sep 17 00:00:00 2001 From: "Yenuga, Thathva Sri Sai Reddy" Date: Fri, 22 Mar 2024 19:27:17 -0400 Subject: [PATCH 03/24] Updated migration document --- docs/data/material/migration/migration-v5/migration-v5.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/data/material/migration/migration-v5/migration-v5.md b/docs/data/material/migration/migration-v5/migration-v5.md index 4042fa86648dc2..761eaa24caffd8 100644 --- a/docs/data/material/migration/migration-v5/migration-v5.md +++ b/docs/data/material/migration/migration-v5/migration-v5.md @@ -23,3 +23,6 @@ The steps you need to take to migrate from MaterialĀ UIĀ v5 to v6 are described This list is a work in progress. Expect updates as new breaking changes are introduced. ::: + +### Removal of deprecated ListItem props +`ListItem` props `autoFocus`, `button`, `disabled`, and `selected` have been removed as they are deprecated. `ListItemButton` is used as an alternative to `button`. \ No newline at end of file From 418bf7afc2411af6657e6d7ce3966190947ad6d3 Mon Sep 17 00:00:00 2001 From: "Yenuga, Thathva Sri Sai Reddy" Date: Fri, 22 Mar 2024 19:39:25 -0400 Subject: [PATCH 04/24] Adding space between headings in markdown --- docs/data/material/migration/migration-v5/migration-v5.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/data/material/migration/migration-v5/migration-v5.md b/docs/data/material/migration/migration-v5/migration-v5.md index 761eaa24caffd8..07635221ee0144 100644 --- a/docs/data/material/migration/migration-v5/migration-v5.md +++ b/docs/data/material/migration/migration-v5/migration-v5.md @@ -25,4 +25,5 @@ Expect updates as new breaking changes are introduced. ::: ### Removal of deprecated ListItem props -`ListItem` props `autoFocus`, `button`, `disabled`, and `selected` have been removed as they are deprecated. `ListItemButton` is used as an alternative to `button`. \ No newline at end of file + +`ListItem` props `autoFocus`, `button`, `disabled`, and `selected` have been removed as they are deprecated. `ListItemButton` is used as an alternative to `button`. From 8f8db62b84511a713e897123539d1aa630cf0332 Mon Sep 17 00:00:00 2001 From: "Yenuga, Thathva Sri Sai Reddy" Date: Mon, 25 Mar 2024 14:01:15 -0400 Subject: [PATCH 05/24] Rephrasing breaking changes section in migration doc --- .../material/migration/migration-v5/migration-v5.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/data/material/migration/migration-v5/migration-v5.md b/docs/data/material/migration/migration-v5/migration-v5.md index 07635221ee0144..a9ef64d1157d3c 100644 --- a/docs/data/material/migration/migration-v5/migration-v5.md +++ b/docs/data/material/migration/migration-v5/migration-v5.md @@ -26,4 +26,13 @@ Expect updates as new breaking changes are introduced. ### Removal of deprecated ListItem props -`ListItem` props `autoFocus`, `button`, `disabled`, and `selected` have been removed as they are deprecated. `ListItemButton` is used as an alternative to `button`. +## ListItem + +### Removed deprecated props + +`ListItem`'s props `autoFocus`, `button`, `disabled`, and `selected`, deprecated in v5, have been removed. To replace the `button` prop, use `ListItemButton` instead. The other removed props are available in the `ListItemButton` component as well. + +```diff +- ++ +``` From 6e1462171d0d9c7f76262755c865eb5ad5d8879c Mon Sep 17 00:00:00 2001 From: "Yenuga, Thathva Sri Sai Reddy" Date: Tue, 9 Apr 2024 21:14:15 -0400 Subject: [PATCH 06/24] Codemod changes for converting ListItem to ListItemButton --- .../src/v6.0.0/all/deprecations-all.js | 11 ++++ packages/mui-codemod/src/v6.0.0/all/v6-all.js | 4 -- .../src/v6.0.0/list-item-button-prop/index.js | 1 + .../list-item-button-prop.js | 58 +++++++++++++++++ .../list-item-button-prop.test.js | 65 +++++++++++++++++++ .../test-cases/actual.js | 6 ++ .../test-cases/expected.js | 6 ++ .../test-cases/theme.actual.js | 8 +++ .../test-cases/theme.expected.js | 4 ++ 9 files changed, 159 insertions(+), 4 deletions(-) create mode 100644 packages/mui-codemod/src/v6.0.0/all/deprecations-all.js create mode 100644 packages/mui-codemod/src/v6.0.0/list-item-button-prop/index.js create mode 100644 packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js create mode 100644 packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.test.js create mode 100644 packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/actual.js create mode 100644 packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/expected.js create mode 100644 packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.actual.js create mode 100644 packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.expected.js diff --git a/packages/mui-codemod/src/v6.0.0/all/deprecations-all.js b/packages/mui-codemod/src/v6.0.0/all/deprecations-all.js new file mode 100644 index 00000000000000..9290e60d665d24 --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/all/deprecations-all.js @@ -0,0 +1,11 @@ +import transformerListItemButtonProps from '../list-item-button-prop/list-item-button-prop'; + +/** + * @param {import('jscodeshift').FileInfo} file + * @param {import('jscodeshift').API} api + */ +export default function deprecationsAll(file, api, options) { + file.source = transformerListItemButtonProps(file, api, options); + + return file.source; +} diff --git a/packages/mui-codemod/src/v6.0.0/all/v6-all.js b/packages/mui-codemod/src/v6.0.0/all/v6-all.js index 77c8e343a4b08a..b1eb5c51b43113 100644 --- a/packages/mui-codemod/src/v6.0.0/all/v6-all.js +++ b/packages/mui-codemod/src/v6.0.0/all/v6-all.js @@ -3,9 +3,5 @@ * @param {import('jscodeshift').API} api */ export default function v6All(file) { - // Currently empty, when adding the first codemod: - // - Read mui-codemod/CONTRIBUTING.md - // - Follow mui-codemod/src/deprecations/all/deprecations-all.js as a guide - // - Remove this comment return file.source; } diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/index.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/index.js new file mode 100644 index 00000000000000..b88071f5fe050e --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/index.js @@ -0,0 +1 @@ +export { default } from './list-item-button-prop' \ No newline at end of file diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js new file mode 100644 index 00000000000000..f5e748d1213e7d --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js @@ -0,0 +1,58 @@ +import findComponentJSX from '../../util/findComponentJSX'; + +/** + * @param {import('jscodeshift').FileInfo} file + * @param {import('jscodeshift').API} api + */ +export default function transformer(file, api, options) { + const j = api.jscodeshift; + const root = j(file.source); + const printOptions = options.printOptions; + + //Rename components that have ListItem button to ListItemButton + findComponentJSX(j, { root, componentName: 'ListItem' }, (elementPath) => { + const index = elementPath.node.openingElement.attributes.findIndex( + (attr) => attr.type === 'JSXAttribute' && attr.name.name === 'button', + ); + if (index !== -1) { + elementPath.node.openingElement.name.name = 'ListItemButton'; + elementPath.node.openingElement.attributes.splice(index, 1); + } + }); + + //Find if there are ListItem imports/named imports. + let containsListItemImport = root.find(j.ImportDeclaration).filter(path => path.node.source.value === '@mui/material'); + let containsListItemNamedImport = containsListItemImport.find(j.ImportSpecifier).filter(path => path.node.imported.name === 'ListItem'); + let containsListItem = false; + + //Find components that use ListItem. If they do, we shouldn't remove it + findComponentJSX(j, { root, componentName: 'ListItem' }, (elementPath) => { + if(elementPath.node.openingElement.name.name === 'ListItem') { + containsListItem = true; + } + }); + + //Remove ListItem import if there is no usage + if(containsListItemNamedImport.length === 0 || !containsListItem) { + // root.find(j.ImportDeclaration).filter(path => path.node.source.value === '@mui/material').find(j.ImportSpecifier) + // .filter(path => path.node.imported.name === 'ListItem').remove(); + root.find(j.ImportDeclaration).filter(path => path.node.source.value === '@mui/material/ListItem').remove(); + } + + //If ListItemButton does not already exist, add it at the end + let imports = root.find(j.ImportDeclaration).filter(path => path.node.source.value === '@mui/material/ListItemButton'); + + if(imports.length === 0) { + let lastImport = root.find(j.ImportDeclaration).at(-1); + + // Insert the import for 'ListItemButton' after the last import declaration + lastImport.insertAfter( + j.importDeclaration( + [j.importDefaultSpecifier(j.identifier('ListItemButton'))], + j.stringLiteral('@mui/material/ListItemButton') + ) + ); + } + + return root.toSource(printOptions); +} diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.test.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.test.js new file mode 100644 index 00000000000000..4dc4aa6cc86c49 --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.test.js @@ -0,0 +1,65 @@ +import path from 'path'; +import { expect } from 'chai'; +import { jscodeshift } from '../../../testUtils'; +import transform from './list-item-button-prop'; +import readFile from '../../util/readFile'; + +function read(fileName) { + return readFile(path.join(__dirname, fileName)); +} + +describe('@mui/codemod', () => { + describe('deprecations', () => { + describe('list-item-button-prop', () => { + it('transforms props as needed', () => { + const actual = transform({ source: read('./test-cases/actual.js') }, { jscodeshift }, {}); + + const expected = read('./test-cases/expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + + it('should be idempotent', () => { + const actual = transform({ source: read('./test-cases/expected.js') }, { jscodeshift }, {}); + + const expected = read('./test-cases/expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + + it('actual.js should not be equal to expected.js', () => { + const actual = read('./test-cases/actual.js'); + const expected = read('./test-cases/expected.js'); + expect(actual).to.not.equal(expected); + }); + }); + + describe('[theme] divider-props', () => { + it('transforms props as needed', () => { + const actual = transform( + { source: read('./test-cases/theme.actual.js') }, + { jscodeshift }, + {}, + ); + + const expected = read('./test-cases/theme.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + + it('should be idempotent', () => { + const actual = transform( + { source: read('./test-cases/theme.expected.js') }, + { jscodeshift }, + {}, + ); + + const expected = read('./test-cases/theme.expected.js'); + expect(actual).to.equal(expected, 'The transformed version should be correct'); + }); + + it('theme.actual.js should not be equal to theme.expected.js', () => { + const actual = read('./test-cases/theme.actual.js'); + const expected = read('./test-cases/theme.expected.js'); + expect(actual).to.not.equal(expected); + }); + }); + }); +}); diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/actual.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/actual.js new file mode 100644 index 00000000000000..2615c6f9b50e87 --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/actual.js @@ -0,0 +1,6 @@ +import ListItem from '@mui/material/ListItem'; +import {ListItem as MyListItem} from '@mui/material'; + +; + +; \ No newline at end of file diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/expected.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/expected.js new file mode 100644 index 00000000000000..3fe7eda0db8a42 --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/expected.js @@ -0,0 +1,6 @@ +import ListItemButton from '@mui/material/ListItemButton'; +import {ListItemButton as MyListItemButton} from '@mui/material'; + +; + +; \ No newline at end of file diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.actual.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.actual.js new file mode 100644 index 00000000000000..52cf172b2f3f2e --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.actual.js @@ -0,0 +1,8 @@ +fn({ + MuiListItem: { + defaultProps: { + button + }, + }, + }); + \ No newline at end of file diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.expected.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.expected.js new file mode 100644 index 00000000000000..3c91a2cf065c4e --- /dev/null +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.expected.js @@ -0,0 +1,4 @@ +fn({ + MuiListItemButton + }); + \ No newline at end of file From 86242b484b53eeb87797f13560df9198c6b68794 Mon Sep 17 00:00:00 2001 From: "Yenuga, Thathva Sri Sai Reddy" Date: Thu, 11 Apr 2024 19:49:45 -0400 Subject: [PATCH 07/24] Fixing failed test case related to component --- .../src/v6.0.0/all/deprecations-all.js | 11 ----- packages/mui-codemod/src/v6.0.0/all/v6-all.js | 3 ++ .../list-item-button-prop.js | 42 ++++++++++++++----- .../test-cases/actual.js | 4 +- .../test-cases/expected.js | 6 +-- 5 files changed, 40 insertions(+), 26 deletions(-) delete mode 100644 packages/mui-codemod/src/v6.0.0/all/deprecations-all.js diff --git a/packages/mui-codemod/src/v6.0.0/all/deprecations-all.js b/packages/mui-codemod/src/v6.0.0/all/deprecations-all.js deleted file mode 100644 index 9290e60d665d24..00000000000000 --- a/packages/mui-codemod/src/v6.0.0/all/deprecations-all.js +++ /dev/null @@ -1,11 +0,0 @@ -import transformerListItemButtonProps from '../list-item-button-prop/list-item-button-prop'; - -/** - * @param {import('jscodeshift').FileInfo} file - * @param {import('jscodeshift').API} api - */ -export default function deprecationsAll(file, api, options) { - file.source = transformerListItemButtonProps(file, api, options); - - return file.source; -} diff --git a/packages/mui-codemod/src/v6.0.0/all/v6-all.js b/packages/mui-codemod/src/v6.0.0/all/v6-all.js index b1eb5c51b43113..747471a67f1cf9 100644 --- a/packages/mui-codemod/src/v6.0.0/all/v6-all.js +++ b/packages/mui-codemod/src/v6.0.0/all/v6-all.js @@ -1,7 +1,10 @@ +import transformerListItemButtonProps from '../list-item-button-prop/list-item-button-prop'; /** * @param {import('jscodeshift').FileInfo} file * @param {import('jscodeshift').API} api */ export default function v6All(file) { + file.source = transformerListItemButtonProps(file, api, options); + return file.source; } diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js index f5e748d1213e7d..2b468f21f6936d 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js @@ -15,30 +15,52 @@ export default function transformer(file, api, options) { (attr) => attr.type === 'JSXAttribute' && attr.name.name === 'button', ); if (index !== -1) { - elementPath.node.openingElement.name.name = 'ListItemButton'; + if(elementPath.node.openingElement.name.name === 'ListItem') { + elementPath.node.openingElement.name.name = 'ListItemButton'; + } elementPath.node.openingElement.attributes.splice(index, 1); } }); - //Find if there are ListItem imports/named imports. - let containsListItemImport = root.find(j.ImportDeclaration).filter(path => path.node.source.value === '@mui/material'); - let containsListItemNamedImport = containsListItemImport.find(j.ImportSpecifier).filter(path => path.node.imported.name === 'ListItem'); + let containsListItem = false; - //Find components that use ListItem. If they do, we shouldn't remove it findComponentJSX(j, { root, componentName: 'ListItem' }, (elementPath) => { if(elementPath.node.openingElement.name.name === 'ListItem') { containsListItem = true; } }); - - //Remove ListItem import if there is no usage - if(containsListItemNamedImport.length === 0 || !containsListItem) { - // root.find(j.ImportDeclaration).filter(path => path.node.source.value === '@mui/material').find(j.ImportSpecifier) - // .filter(path => path.node.imported.name === 'ListItem').remove(); + + //Find if there are ListItem named imports. + let containsListItemNamedImport = root.find(j.ImportSpecifier).filter(path => path.node.imported.name === 'ListItem'); + + // Remove ListItem imports if there is no usage + if(!containsListItem) { + // Remove default imports root.find(j.ImportDeclaration).filter(path => path.node.source.value === '@mui/material/ListItem').remove(); } + // If there is no usage of alias imports, remove it. Or else rename the imported component to ListItemButton + if(!containsListItemNamedImport) { + root.find(j.ImportDeclaration).filter(path => path.node.source.value === '@mui/material').find(j.ImportSpecifier).filter(path => path.node.imported.name === 'ListItem').remove(); + } + else { + root + .find(j.ImportDeclaration) + .filter(path => path.node.source.value === '@mui/material') + .find(j.ImportSpecifier) + .filter(path => path.node.imported.name === 'ListItem') + .forEach(path => { + const originalLocalName = path.node.local.name; + const newImport = j.importSpecifier( + j.identifier('ListItemButton'), + j.identifier(originalLocalName) + ); + path.replace(newImport); + }); + } + + //If ListItemButton does not already exist, add it at the end let imports = root.find(j.ImportDeclaration).filter(path => path.node.source.value === '@mui/material/ListItemButton'); diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/actual.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/actual.js index 2615c6f9b50e87..f041bd28f61e1b 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/actual.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/actual.js @@ -1,5 +1,5 @@ -import ListItem from '@mui/material/ListItem'; -import {ListItem as MyListItem} from '@mui/material'; +import ListItem from "@mui/material/ListItem"; +import {ListItem as MyListItem} from "@mui/material"; ; diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/expected.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/expected.js index 3fe7eda0db8a42..956e3e9612b26a 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/expected.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/expected.js @@ -1,6 +1,6 @@ -import ListItemButton from '@mui/material/ListItemButton'; -import {ListItemButton as MyListItemButton} from '@mui/material'; +import {ListItemButton as MyListItem} from "@mui/material"; +import ListItemButton from "@mui/material/ListItemButton"; ; -; \ No newline at end of file +; \ No newline at end of file From 9b310198e19a0c08c8c0e9deb816c1524fd2d9f0 Mon Sep 17 00:00:00 2001 From: "Yenuga, Thathva Sri Sai Reddy" Date: Fri, 12 Apr 2024 15:46:42 -0400 Subject: [PATCH 08/24] Fixing failing theme related test case --- .../list-item-button-prop.js | 15 +++++++++++++++ .../test-cases/theme.actual.js | 4 ++-- .../test-cases/theme.expected.js | 4 +++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js index 2b468f21f6936d..2daa9154cecb70 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js @@ -21,6 +21,21 @@ export default function transformer(file, api, options) { elementPath.node.openingElement.attributes.splice(index, 1); } }); + + root.find(j.ObjectProperty).forEach((path) => { + if (path.parent?.parent?.parent?.parent?.node.key?.name === 'MuiListItem') { + // Replace MuiListItem with MuiListItemButton + path.parent.parent.parent.parent.node.key = j.identifier('MuiListItemButton'); + + // Remove the 'button' property inside defaultProps + const defaultPropsNode = path.parent.parent.parent.parent.node.value.properties.find(prop => prop.key.name === 'defaultProps'); + if (defaultPropsNode && defaultPropsNode.value.type === 'ObjectExpression') { + defaultPropsNode.value.properties = defaultPropsNode.value.properties.filter(prop => prop.key.name !== 'button'); + } + } + }); + + let containsListItem = false; diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.actual.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.actual.js index 52cf172b2f3f2e..bc8b84e57929d8 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.actual.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.actual.js @@ -2,7 +2,7 @@ fn({ MuiListItem: { defaultProps: { button - }, - }, + } + } }); \ No newline at end of file diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.expected.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.expected.js index 3c91a2cf065c4e..60778c3297366b 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.expected.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.expected.js @@ -1,4 +1,6 @@ fn({ - MuiListItemButton + MuiListItemButton: { + defaultProps: {} + } }); \ No newline at end of file From 0947ef8873c58065f8063d2d9a73505f7c72b4d3 Mon Sep 17 00:00:00 2001 From: "Yenuga, Thathva Sri Sai Reddy" Date: Tue, 16 Apr 2024 20:54:23 -0400 Subject: [PATCH 09/24] Updated test cases for codemod --- .../list-item-button-prop.js | 34 +++++++++++++++---- .../test-cases/actual.js | 5 ++- .../test-cases/expected.js | 5 ++- .../test-cases/theme.actual.js | 12 +++---- .../test-cases/theme.expected.js | 15 +++++--- 5 files changed, 52 insertions(+), 19 deletions(-) diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js index 2daa9154cecb70..652a0b6be9af1d 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js @@ -21,21 +21,41 @@ export default function transformer(file, api, options) { elementPath.node.openingElement.attributes.splice(index, 1); } }); - + + let hasButton = false; root.find(j.ObjectProperty).forEach((path) => { if (path.parent?.parent?.parent?.parent?.node.key?.name === 'MuiListItem') { - // Replace MuiListItem with MuiListItemButton - path.parent.parent.parent.parent.node.key = j.identifier('MuiListItemButton'); - + const muiListItemNode = path.parent.parent.parent.parent.node; + // Remove the 'button' property inside defaultProps - const defaultPropsNode = path.parent.parent.parent.parent.node.value.properties.find(prop => prop.key.name === 'defaultProps'); + const defaultPropsNode = muiListItemNode.value.properties.find(prop => prop.key.name === 'defaultProps'); + hasButton = defaultPropsNode && defaultPropsNode.value.properties.some(prop => prop.key.name === 'button') if (defaultPropsNode && defaultPropsNode.value.type === 'ObjectExpression') { defaultPropsNode.value.properties = defaultPropsNode.value.properties.filter(prop => prop.key.name !== 'button'); } - } - }); + // Check if the 'button' property was present and add a new entry for MuiListItemButton + if (hasButton) { + // Copy properties from MuiListItem's defaultProps except 'button' + const newButtonProps = defaultPropsNode.value.properties.filter(prop => prop.key.name !== 'button'); + // Add autoFocus:true to newButtonProps + newButtonProps.push(j.property('init', j.identifier('autoFocus'), j.literal(true))); + + // Create a new ObjectProperty for MuiListItemButton + const muiListItemButtonNode = j.objectProperty( + j.identifier('MuiListItemButton'), + j.objectExpression([ + j.property('init', j.identifier('defaultProps'), j.objectExpression(newButtonProps)), + ]) + ); + + // Add MuiListItemButton entry to the parent object + const parentObject = path.parent.parent.parent.node; + parentObject.properties.push(muiListItemButtonNode); + } + } + }); let containsListItem = false; diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/actual.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/actual.js index f041bd28f61e1b..dd4606b1bf7f7d 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/actual.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/actual.js @@ -1,6 +1,9 @@ import ListItem from "@mui/material/ListItem"; import {ListItem as MyListItem} from "@mui/material"; +import AnotherComponent from "ui"; ; -; \ No newline at end of file +; + +; \ No newline at end of file diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/expected.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/expected.js index 956e3e9612b26a..95d9a660dded7f 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/expected.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/expected.js @@ -1,6 +1,9 @@ import {ListItemButton as MyListItem} from "@mui/material"; +import AnotherComponent from "ui"; import ListItemButton from "@mui/material/ListItemButton"; ; -; \ No newline at end of file +; + +; \ No newline at end of file diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.actual.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.actual.js index bc8b84e57929d8..8b4e0409ff8af7 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.actual.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.actual.js @@ -1,8 +1,8 @@ fn({ - MuiListItem: { - defaultProps: { - button - } + MuiListItem: { + defaultProps: { + anotherProp: 'value', + button, } - }); - \ No newline at end of file + } +}); \ No newline at end of file diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.expected.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.expected.js index 60778c3297366b..859229c5108335 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.expected.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.expected.js @@ -1,6 +1,13 @@ fn({ - MuiListItemButton: { - defaultProps: {} + MuiListItem: { + defaultProps: { + anotherProp: 'value' } - }); - \ No newline at end of file + }, + MuiListItemButton: { + defaultProps: { + anotherProp: 'value', + autoFocus: true + } + } +}); \ No newline at end of file From 463ced86e477966277d25bd81a79cfeec4a5bd48 Mon Sep 17 00:00:00 2001 From: mnajdova Date: Wed, 31 Jul 2024 09:10:06 +0200 Subject: [PATCH 10/24] Update the migration guide --- .../migration/migrating-to-v6/migrating-to-v6.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/data/material/migration/migrating-to-v6/migrating-to-v6.md b/docs/data/material/migration/migrating-to-v6/migrating-to-v6.md index d5e82f71a3a54c..39e176a649b985 100644 --- a/docs/data/material/migration/migrating-to-v6/migrating-to-v6.md +++ b/docs/data/material/migration/migrating-to-v6/migrating-to-v6.md @@ -198,6 +198,15 @@ The `Grid2` was updated and stabilized: This brings some breaking changes described in the following sections. +### ListItem + +`ListItem`'s props `autoFocus`, `button`, `disabled`, and `selected`, deprecated in v5, have been removed. To replace the `button` prop, use `ListItemButton` instead. The other removed props are available in the `ListItemButton` component as well. + +```diff +- ++ +``` + #### Stabilized API The `Grid2` component API was stabilized, so its import no longer contains the `Unstable_` prefix: From 1e1630c96c646b746297e0a83a241282c083ffb4 Mon Sep 17 00:00:00 2001 From: mnajdova Date: Wed, 31 Jul 2024 09:58:39 +0200 Subject: [PATCH 11/24] wrong import --- packages/mui-material/src/ListItem/ListItem.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mui-material/src/ListItem/ListItem.test.js b/packages/mui-material/src/ListItem/ListItem.test.js index a27a281fc67355..524f0e0416923c 100644 --- a/packages/mui-material/src/ListItem/ListItem.test.js +++ b/packages/mui-material/src/ListItem/ListItem.test.js @@ -1,7 +1,7 @@ import * as React from 'react'; import { expect } from 'chai'; import PropTypes from 'prop-types'; -import { createRenderer } from '@mui-internal/test-utils'; +import { createRenderer } from '@mui/internal-test-utils'; import { ThemeProvider, createTheme } from '@mui/material/styles'; import ListItemText from '@mui/material/ListItemText'; import ListItemSecondaryAction from '@mui/material/ListItemSecondaryAction'; From fdb20e98a798e9126877ea27431f13662ac91925 Mon Sep 17 00:00:00 2001 From: mnajdova Date: Wed, 31 Jul 2024 10:17:00 +0200 Subject: [PATCH 12/24] improve codemod --- .../src/v6.0.0/list-item-button-prop/index.js | 2 +- .../list-item-button-prop.js | 120 ++++++++++-------- .../list-item-button-prop.test.js | 2 +- .../test-cases/theme.actual.js | 10 +- .../test-cases/theme.expected.js | 12 +- 5 files changed, 86 insertions(+), 60 deletions(-) diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/index.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/index.js index b88071f5fe050e..add9efbd02c949 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/index.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/index.js @@ -1 +1 @@ -export { default } from './list-item-button-prop' \ No newline at end of file +export { default } from './list-item-button-prop'; diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js index 652a0b6be9af1d..a481d1c29e9925 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js @@ -1,4 +1,5 @@ import findComponentJSX from '../../util/findComponentJSX'; +import findComponentDefaultProps from '../../util/findComponentDefaultProps'; /** * @param {import('jscodeshift').FileInfo} file @@ -15,99 +16,108 @@ export default function transformer(file, api, options) { (attr) => attr.type === 'JSXAttribute' && attr.name.name === 'button', ); if (index !== -1) { - if(elementPath.node.openingElement.name.name === 'ListItem') { + if (elementPath.node.openingElement.name.name === 'ListItem') { elementPath.node.openingElement.name.name = 'ListItemButton'; } elementPath.node.openingElement.attributes.splice(index, 1); } }); - let hasButton = false; - root.find(j.ObjectProperty).forEach((path) => { - if (path.parent?.parent?.parent?.parent?.node.key?.name === 'MuiListItem') { - const muiListItemNode = path.parent.parent.parent.parent.node; - - // Remove the 'button' property inside defaultProps - const defaultPropsNode = muiListItemNode.value.properties.find(prop => prop.key.name === 'defaultProps'); - hasButton = defaultPropsNode && defaultPropsNode.value.properties.some(prop => prop.key.name === 'button') - if (defaultPropsNode && defaultPropsNode.value.type === 'ObjectExpression') { - defaultPropsNode.value.properties = defaultPropsNode.value.properties.filter(prop => prop.key.name !== 'button'); - } - - // Check if the 'button' property was present and add a new entry for MuiListItemButton - if (hasButton) { - // Copy properties from MuiListItem's defaultProps except 'button' - const newButtonProps = defaultPropsNode.value.properties.filter(prop => prop.key.name !== 'button'); - - // Add autoFocus:true to newButtonProps - newButtonProps.push(j.property('init', j.identifier('autoFocus'), j.literal(true))); - - // Create a new ObjectProperty for MuiListItemButton + let defaultPropsPathCollection = findComponentDefaultProps(j, { + root, + componentName: 'ListItem', + }); + + defaultPropsPathCollection.find(j.ObjectProperty, { key: { name: 'button' } }).forEach((path) => { + const defaultProps = path.parent.value; + + let hasButton = false; + defaultProps.properties.forEach((property) => { + if (property.key?.name === 'button') { + hasButton = true; + const newListButtonProps = defaultProps.properties.filter( + (prop) => prop.key.name !== 'button', + ); + const muiListItemButtonNode = j.objectProperty( j.identifier('MuiListItemButton'), j.objectExpression([ - j.property('init', j.identifier('defaultProps'), j.objectExpression(newButtonProps)), - ]) + j.property( + 'init', + j.identifier('defaultProps'), + j.objectExpression(newListButtonProps), + ), + ]), ); - + // Add MuiListItemButton entry to the parent object - const parentObject = path.parent.parent.parent.node; + const parentObject = path.parent.parent.parent.parent.parent.node; parentObject.properties.push(muiListItemButtonNode); } - } + }); + path.prune(); }); - let containsListItem = false; //Find components that use ListItem. If they do, we shouldn't remove it findComponentJSX(j, { root, componentName: 'ListItem' }, (elementPath) => { - if(elementPath.node.openingElement.name.name === 'ListItem') { + if (elementPath.node.openingElement.name.name === 'ListItem') { containsListItem = true; } }); - + //Find if there are ListItem named imports. - let containsListItemNamedImport = root.find(j.ImportSpecifier).filter(path => path.node.imported.name === 'ListItem'); - + let containsListItemNamedImport = root + .find(j.ImportSpecifier) + .filter((path) => path.node.imported.name === 'ListItem'); + // Remove ListItem imports if there is no usage - if(!containsListItem) { + if (!containsListItem) { // Remove default imports - root.find(j.ImportDeclaration).filter(path => path.node.source.value === '@mui/material/ListItem').remove(); + root + .find(j.ImportDeclaration) + .filter((path) => path.node.source.value === '@mui/material/ListItem') + .remove(); } // If there is no usage of alias imports, remove it. Or else rename the imported component to ListItemButton - if(!containsListItemNamedImport) { - root.find(j.ImportDeclaration).filter(path => path.node.source.value === '@mui/material').find(j.ImportSpecifier).filter(path => path.node.imported.name === 'ListItem').remove(); - } - else { + if (!containsListItemNamedImport) { root - .find(j.ImportDeclaration) - .filter(path => path.node.source.value === '@mui/material') - .find(j.ImportSpecifier) - .filter(path => path.node.imported.name === 'ListItem') - .forEach(path => { - const originalLocalName = path.node.local.name; - const newImport = j.importSpecifier( - j.identifier('ListItemButton'), - j.identifier(originalLocalName) - ); - path.replace(newImport); - }); + .find(j.ImportDeclaration) + .filter((path) => path.node.source.value === '@mui/material') + .find(j.ImportSpecifier) + .filter((path) => path.node.imported.name === 'ListItem') + .remove(); + } else { + root + .find(j.ImportDeclaration) + .filter((path) => path.node.source.value === '@mui/material') + .find(j.ImportSpecifier) + .filter((path) => path.node.imported.name === 'ListItem') + .forEach((path) => { + const originalLocalName = path.node.local.name; + const newImport = j.importSpecifier( + j.identifier('ListItemButton'), + j.identifier(originalLocalName), + ); + path.replace(newImport); + }); } - //If ListItemButton does not already exist, add it at the end - let imports = root.find(j.ImportDeclaration).filter(path => path.node.source.value === '@mui/material/ListItemButton'); + let imports = root + .find(j.ImportDeclaration) + .filter((path) => path.node.source.value === '@mui/material/ListItemButton'); - if(imports.length === 0) { + if (imports.length === 0) { let lastImport = root.find(j.ImportDeclaration).at(-1); // Insert the import for 'ListItemButton' after the last import declaration lastImport.insertAfter( j.importDeclaration( [j.importDefaultSpecifier(j.identifier('ListItemButton'))], - j.stringLiteral('@mui/material/ListItemButton') - ) + j.stringLiteral('@mui/material/ListItemButton'), + ), ); } diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.test.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.test.js index 4dc4aa6cc86c49..723ae584e04f5d 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.test.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.test.js @@ -32,7 +32,7 @@ describe('@mui/codemod', () => { }); }); - describe('[theme] divider-props', () => { + describe('[theme] button-props', () => { it('transforms props as needed', () => { const actual = transform( { source: read('./test-cases/theme.actual.js') }, diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.actual.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.actual.js index 8b4e0409ff8af7..dca992dee2bda5 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.actual.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.actual.js @@ -2,7 +2,15 @@ fn({ MuiListItem: { defaultProps: { anotherProp: 'value', - button, + button: true, + } + } +}); + +fn({ + MuiListItem: { + defaultProps: { + anotherProp: 'value' } } }); \ No newline at end of file diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.expected.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.expected.js index 859229c5108335..a8d567deaf4906 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.expected.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.expected.js @@ -4,10 +4,18 @@ fn({ anotherProp: 'value' } }, + MuiListItemButton: { defaultProps: { - anotherProp: 'value', - autoFocus: true + anotherProp: 'value' + } + } +}); + +fn({ + MuiListItem: { + defaultProps: { + anotherProp: 'value' } } }); \ No newline at end of file From 2e38c0925bdba112f5e7368795b8d0b6a3cc76d6 Mon Sep 17 00:00:00 2001 From: mnajdova Date: Wed, 31 Jul 2024 10:36:14 +0200 Subject: [PATCH 13/24] lint issues --- .../list-item-button-prop.js | 19 +++++++++---------- .../mui-material/src/ListItem/ListItem.js | 1 - 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js index a481d1c29e9925..cd0c8b52f2569f 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js @@ -10,7 +10,7 @@ export default function transformer(file, api, options) { const root = j(file.source); const printOptions = options.printOptions; - //Rename components that have ListItem button to ListItemButton + // Rename components that have ListItem button to ListItemButton findComponentJSX(j, { root, componentName: 'ListItem' }, (elementPath) => { const index = elementPath.node.openingElement.attributes.findIndex( (attr) => attr.type === 'JSXAttribute' && attr.name.name === 'button', @@ -23,7 +23,7 @@ export default function transformer(file, api, options) { } }); - let defaultPropsPathCollection = findComponentDefaultProps(j, { + const defaultPropsPathCollection = findComponentDefaultProps(j, { root, componentName: 'ListItem', }); @@ -31,10 +31,9 @@ export default function transformer(file, api, options) { defaultPropsPathCollection.find(j.ObjectProperty, { key: { name: 'button' } }).forEach((path) => { const defaultProps = path.parent.value; - let hasButton = false; defaultProps.properties.forEach((property) => { if (property.key?.name === 'button') { - hasButton = true; + // Remove the button property from the defaultProps object const newListButtonProps = defaultProps.properties.filter( (prop) => prop.key.name !== 'button', ); @@ -59,15 +58,15 @@ export default function transformer(file, api, options) { }); let containsListItem = false; - //Find components that use ListItem. If they do, we shouldn't remove it + // Find components that use ListItem. If they do, we shouldn't remove it findComponentJSX(j, { root, componentName: 'ListItem' }, (elementPath) => { if (elementPath.node.openingElement.name.name === 'ListItem') { containsListItem = true; } }); - //Find if there are ListItem named imports. - let containsListItemNamedImport = root + // Find if there are ListItem named imports. + const containsListItemNamedImport = root .find(j.ImportSpecifier) .filter((path) => path.node.imported.name === 'ListItem'); @@ -104,13 +103,13 @@ export default function transformer(file, api, options) { }); } - //If ListItemButton does not already exist, add it at the end - let imports = root + // If ListItemButton does not already exist, add it at the end + const imports = root .find(j.ImportDeclaration) .filter((path) => path.node.source.value === '@mui/material/ListItemButton'); if (imports.length === 0) { - let lastImport = root.find(j.ImportDeclaration).at(-1); + const lastImport = root.find(j.ImportDeclaration).at(-1); // Insert the import for 'ListItemButton' after the last import declaration lastImport.insertAfter( diff --git a/packages/mui-material/src/ListItem/ListItem.js b/packages/mui-material/src/ListItem/ListItem.js index 8ad5c78bc68d64..12fc6552d8a68d 100644 --- a/packages/mui-material/src/ListItem/ListItem.js +++ b/packages/mui-material/src/ListItem/ListItem.js @@ -9,7 +9,6 @@ import { alpha } from '@mui/system/colorManipulator'; import isHostComponent from '../utils/isHostComponent'; import { styled } from '../zero-styled'; import { useDefaultProps } from '../DefaultPropsProvider'; -import ButtonBase from '../ButtonBase'; import isMuiElement from '../utils/isMuiElement'; import useForkRef from '../utils/useForkRef'; import ListContext from '../List/ListContext'; From 60dfaf5da7c9addb39f3b8f36a349674c2c5809e Mon Sep 17 00:00:00 2001 From: mnajdova Date: Wed, 31 Jul 2024 13:04:56 +0200 Subject: [PATCH 14/24] improve codemod --- .../list-item-button-prop.js | 70 ++++--------------- .../test-cases/actual.js | 8 ++- .../test-cases/expected.js | 6 +- 3 files changed, 25 insertions(+), 59 deletions(-) diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js index cd0c8b52f2569f..a40a94cfe2e4a7 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js @@ -10,19 +10,6 @@ export default function transformer(file, api, options) { const root = j(file.source); const printOptions = options.printOptions; - // Rename components that have ListItem button to ListItemButton - findComponentJSX(j, { root, componentName: 'ListItem' }, (elementPath) => { - const index = elementPath.node.openingElement.attributes.findIndex( - (attr) => attr.type === 'JSXAttribute' && attr.name.name === 'button', - ); - if (index !== -1) { - if (elementPath.node.openingElement.name.name === 'ListItem') { - elementPath.node.openingElement.name.name = 'ListItemButton'; - } - elementPath.node.openingElement.attributes.splice(index, 1); - } - }); - const defaultPropsPathCollection = findComponentDefaultProps(j, { root, componentName: 'ListItem', @@ -57,52 +44,25 @@ export default function transformer(file, api, options) { path.prune(); }); - let containsListItem = false; - // Find components that use ListItem. If they do, we shouldn't remove it + const openTaggedNotHavingButtonProp = new Set(); + // Rename components that have ListItem button to ListItemButton findComponentJSX(j, { root, componentName: 'ListItem' }, (elementPath) => { - if (elementPath.node.openingElement.name.name === 'ListItem') { - containsListItem = true; + const index = elementPath.node.openingElement.attributes.findIndex( + (attr) => attr.type === 'JSXAttribute' && attr.name.name === 'button', + ); + // The ListItem has a button prop + if (index !== -1) { + if (elementPath.node.openingElement.name.name === 'ListItem') { + elementPath.node.openingElement.name.name = 'ListItemButton'; + } else { + elementPath.node.openingElement.name.name = `ListItemButton`; + } + elementPath.node.openingElement.attributes.splice(index, 1); + } else { + openTaggedNotHavingButtonProp.add(elementPath.node.openingElement.name.name); } }); - // Find if there are ListItem named imports. - const containsListItemNamedImport = root - .find(j.ImportSpecifier) - .filter((path) => path.node.imported.name === 'ListItem'); - - // Remove ListItem imports if there is no usage - if (!containsListItem) { - // Remove default imports - root - .find(j.ImportDeclaration) - .filter((path) => path.node.source.value === '@mui/material/ListItem') - .remove(); - } - - // If there is no usage of alias imports, remove it. Or else rename the imported component to ListItemButton - if (!containsListItemNamedImport) { - root - .find(j.ImportDeclaration) - .filter((path) => path.node.source.value === '@mui/material') - .find(j.ImportSpecifier) - .filter((path) => path.node.imported.name === 'ListItem') - .remove(); - } else { - root - .find(j.ImportDeclaration) - .filter((path) => path.node.source.value === '@mui/material') - .find(j.ImportSpecifier) - .filter((path) => path.node.imported.name === 'ListItem') - .forEach((path) => { - const originalLocalName = path.node.local.name; - const newImport = j.importSpecifier( - j.identifier('ListItemButton'), - j.identifier(originalLocalName), - ); - path.replace(newImport); - }); - } - // If ListItemButton does not already exist, add it at the end const imports = root .find(j.ImportDeclaration) diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/actual.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/actual.js index dd4606b1bf7f7d..982aa4e6287c62 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/actual.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/actual.js @@ -1,9 +1,11 @@ import ListItem from "@mui/material/ListItem"; -import {ListItem as MyListItem} from "@mui/material"; +import { ListItem as MyListItem } from "@mui/material"; import AnotherComponent from "ui"; -; +; +; -; +; +; ; \ No newline at end of file diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/expected.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/expected.js index 95d9a660dded7f..652d1bf53fe19e 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/expected.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/expected.js @@ -1,9 +1,13 @@ -import {ListItemButton as MyListItem} from "@mui/material"; +import ListItem from "@mui/material/ListItem"; +import { ListItem as MyListItem } from "@mui/material"; import AnotherComponent from "ui"; + import ListItemButton from "@mui/material/ListItemButton"; ; +; ; +; ; \ No newline at end of file From a9861fe3397f98f78cff135e8254031c504869da Mon Sep 17 00:00:00 2001 From: mnajdova Date: Wed, 31 Jul 2024 13:47:02 +0200 Subject: [PATCH 15/24] finish codemod --- .../list-item-button-prop.js | 47 +++++++++++++++++-- .../test-cases/actual.js | 13 +++++ .../test-cases/expected.js | 11 +++++ 3 files changed, 66 insertions(+), 5 deletions(-) diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js index a40a94cfe2e4a7..db364068d94095 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js @@ -45,6 +45,7 @@ export default function transformer(file, api, options) { }); const openTaggedNotHavingButtonProp = new Set(); + const openTaggedHavingButtonProp = new Set(); // Rename components that have ListItem button to ListItemButton findComponentJSX(j, { root, componentName: 'ListItem' }, (elementPath) => { const index = elementPath.node.openingElement.attributes.findIndex( @@ -52,17 +53,53 @@ export default function transformer(file, api, options) { ); // The ListItem has a button prop if (index !== -1) { - if (elementPath.node.openingElement.name.name === 'ListItem') { - elementPath.node.openingElement.name.name = 'ListItemButton'; - } else { - elementPath.node.openingElement.name.name = `ListItemButton`; - } + openTaggedHavingButtonProp.add(elementPath.node.openingElement.name.name); + elementPath.node.openingElement.name.name = `ListItemButton`; elementPath.node.openingElement.attributes.splice(index, 1); } else { openTaggedNotHavingButtonProp.add(elementPath.node.openingElement.name.name); } }); + const importsToRemove = [...openTaggedHavingButtonProp].filter( + (item) => !openTaggedNotHavingButtonProp.has(item), + ); + + root + .find(j.ImportDeclaration) + .filter((path) => path.node.source.value === '@mui/material/ListItem') + .filter((path) => { + path.node.specifiers.forEach((specifier) => { + if (specifier.type === 'ImportDefaultSpecifier') { + if (importsToRemove.indexOf(specifier.local.name) >= 0) { + path.node.specifiers = path.node.specifiers.filter((spec) => spec != specifier); + } + } + }); + if (path.node.specifiers.length === 0) { + return true; + } + }) + .remove(); + + root + .find(j.ImportDeclaration) + .filter((path) => path.node.source.value === '@mui/material') + .filter((path) => { + path.node.specifiers.forEach((specifier) => { + if ( + specifier.type === 'ImportSpecifier' && + specifier.imported.name === 'ListItem' && + importsToRemove.indexOf(specifier.local.name) >= 0 + ) { + path.node.specifiers = path.node.specifiers.filter((spec) => spec != specifier); + } + }); + if (path.node.specifiers.length === 0) { + return true; + } + }) + .remove(); // If ListItemButton does not already exist, add it at the end const imports = root .find(j.ImportDeclaration) diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/actual.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/actual.js index 982aa4e6287c62..b58cbe361031a6 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/actual.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/actual.js @@ -1,5 +1,9 @@ import ListItem from "@mui/material/ListItem"; +import MuiListItem from "@mui/material/ListItem"; import { ListItem as MyListItem } from "@mui/material"; +import { ListItem as MyListItem1 } from "@mui/material"; +import { ListItem as MyListItem2, Button } from "@mui/material"; +import { ListItem as MyListItem3, List } from "@mui/material"; import AnotherComponent from "ui"; ; @@ -8,4 +12,13 @@ import AnotherComponent from "ui"; ; ; +; + +; + +; + +; +; + ; \ No newline at end of file diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/expected.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/expected.js index 652d1bf53fe19e..01e7933e147757 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/expected.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/expected.js @@ -1,5 +1,7 @@ import ListItem from "@mui/material/ListItem"; import { ListItem as MyListItem } from "@mui/material"; +import { Button } from "@mui/material"; +import { ListItem as MyListItem3, List } from "@mui/material"; import AnotherComponent from "ui"; import ListItemButton from "@mui/material/ListItemButton"; @@ -10,4 +12,13 @@ import ListItemButton from "@mui/material/ListItemButton"; ; ; +; + +; + +; + +; +; + ; \ No newline at end of file From 5e78016af4e21d290bbcf8178bb1f6621d33a045 Mon Sep 17 00:00:00 2001 From: mnajdova Date: Wed, 31 Jul 2024 14:39:50 +0200 Subject: [PATCH 16/24] fixed some issues --- .../templates/dashboard/theme/customizations/menus.tsx | 8 ++++---- packages/mui-codemod/src/v6.0.0/all/v6-all.js | 2 +- .../v6.0.0/list-item-button-prop/list-item-button-prop.js | 6 ++++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/data/material/getting-started/templates/dashboard/theme/customizations/menus.tsx b/docs/data/material/getting-started/templates/dashboard/theme/customizations/menus.tsx index 09bfbacb5a2e6f..6725ea5d17a2c2 100644 --- a/docs/data/material/getting-started/templates/dashboard/theme/customizations/menus.tsx +++ b/docs/data/material/getting-started/templates/dashboard/theme/customizations/menus.tsx @@ -5,7 +5,7 @@ import { svgIconClasses } from '@mui/material/SvgIcon'; import { typographyClasses } from '@mui/material/Typography'; import { buttonBaseClasses } from '@mui/material/ButtonBase'; import { dividerClasses } from '@mui/material/Divider'; -import { listItemClasses } from '@mui/material/ListItem'; +import { listItemButtonClasses } from '@mui/material/ListItemButton'; import { menuItemClasses } from '@mui/material/MenuItem'; import { selectClasses } from '@mui/material/Select'; import UnfoldMoreRoundedIcon from '@mui/icons-material/UnfoldMoreRounded'; @@ -40,20 +40,20 @@ export const menuComponentsCustomizations: Components = { padding: '2px 8px', borderRadius: theme.shape.borderRadius, opacity: 0.7, - [`&.${listItemClasses.selected}`]: { + [`&.${listItemButtonClasses.selected}`]: { opacity: 1, backgroundColor: alpha(theme.palette.action.selected, 0.3), [`& .${svgIconClasses.root}`]: { color: theme.palette.text.primary, }, - [`&.${listItemClasses.focusVisible}`]: { + [`&.${listItemButtonClasses.focusVisible}`]: { backgroundColor: alpha(theme.palette.action.selected, 0.3), }, '&:hover': { backgroundColor: alpha(theme.palette.action.selected, 0.5), }, }, - [`&.${listItemClasses.focusVisible}`]: { + [`&.${listItemButtonClasses.focusVisible}`]: { backgroundColor: 'transparent', }, }, diff --git a/packages/mui-codemod/src/v6.0.0/all/v6-all.js b/packages/mui-codemod/src/v6.0.0/all/v6-all.js index 747471a67f1cf9..416fc9cbea8793 100644 --- a/packages/mui-codemod/src/v6.0.0/all/v6-all.js +++ b/packages/mui-codemod/src/v6.0.0/all/v6-all.js @@ -3,7 +3,7 @@ import transformerListItemButtonProps from '../list-item-button-prop/list-item-b * @param {import('jscodeshift').FileInfo} file * @param {import('jscodeshift').API} api */ -export default function v6All(file) { +export default function v6All(file, api, options) { file.source = transformerListItemButtonProps(file, api, options); return file.source; diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js index db364068d94095..03b77357e39200 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js @@ -72,13 +72,14 @@ export default function transformer(file, api, options) { path.node.specifiers.forEach((specifier) => { if (specifier.type === 'ImportDefaultSpecifier') { if (importsToRemove.indexOf(specifier.local.name) >= 0) { - path.node.specifiers = path.node.specifiers.filter((spec) => spec != specifier); + path.node.specifiers = path.node.specifiers.filter((spec) => spec !== specifier); } } }); if (path.node.specifiers.length === 0) { return true; } + return false; }) .remove(); @@ -92,12 +93,13 @@ export default function transformer(file, api, options) { specifier.imported.name === 'ListItem' && importsToRemove.indexOf(specifier.local.name) >= 0 ) { - path.node.specifiers = path.node.specifiers.filter((spec) => spec != specifier); + path.node.specifiers = path.node.specifiers.filter((spec) => spec !== specifier); } }); if (path.node.specifiers.length === 0) { return true; } + return false; }) .remove(); // If ListItemButton does not already exist, add it at the end From 0e23f10d84ad3ffe90d50f5156537311c1878655 Mon Sep 17 00:00:00 2001 From: mnajdova Date: Wed, 31 Jul 2024 14:44:45 +0200 Subject: [PATCH 17/24] docs:typescript:formatted --- .../templates/dashboard/theme/customizations/menus.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/data/material/getting-started/templates/dashboard/theme/customizations/menus.js b/docs/data/material/getting-started/templates/dashboard/theme/customizations/menus.js index b41437644f63ad..3fb9562666631e 100644 --- a/docs/data/material/getting-started/templates/dashboard/theme/customizations/menus.js +++ b/docs/data/material/getting-started/templates/dashboard/theme/customizations/menus.js @@ -5,7 +5,7 @@ import { svgIconClasses } from '@mui/material/SvgIcon'; import { typographyClasses } from '@mui/material/Typography'; import { buttonBaseClasses } from '@mui/material/ButtonBase'; import { dividerClasses } from '@mui/material/Divider'; -import { listItemClasses } from '@mui/material/ListItem'; +import { listItemButtonClasses } from '@mui/material/ListItemButton'; import { menuItemClasses } from '@mui/material/MenuItem'; import { selectClasses } from '@mui/material/Select'; import UnfoldMoreRoundedIcon from '@mui/icons-material/UnfoldMoreRounded'; @@ -40,20 +40,20 @@ export const menuComponentsCustomizations = { padding: '2px 8px', borderRadius: theme.shape.borderRadius, opacity: 0.7, - [`&.${listItemClasses.selected}`]: { + [`&.${listItemButtonClasses.selected}`]: { opacity: 1, backgroundColor: alpha(theme.palette.action.selected, 0.3), [`& .${svgIconClasses.root}`]: { color: theme.palette.text.primary, }, - [`&.${listItemClasses.focusVisible}`]: { + [`&.${listItemButtonClasses.focusVisible}`]: { backgroundColor: alpha(theme.palette.action.selected, 0.3), }, '&:hover': { backgroundColor: alpha(theme.palette.action.selected, 0.5), }, }, - [`&.${listItemClasses.focusVisible}`]: { + [`&.${listItemButtonClasses.focusVisible}`]: { backgroundColor: 'transparent', }, }, From c312da315fcdbb28c6b0dbd795147b04650740f0 Mon Sep 17 00:00:00 2001 From: mnajdova Date: Wed, 31 Jul 2024 14:46:34 +0200 Subject: [PATCH 18/24] remove style assosiated with some of the removed classes --- .../mui-material/src/ListItem/ListItem.js | 35 +------------------ 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/packages/mui-material/src/ListItem/ListItem.js b/packages/mui-material/src/ListItem/ListItem.js index 12fc6552d8a68d..ac29608cf10188 100644 --- a/packages/mui-material/src/ListItem/ListItem.js +++ b/packages/mui-material/src/ListItem/ListItem.js @@ -12,7 +12,7 @@ import { useDefaultProps } from '../DefaultPropsProvider'; import isMuiElement from '../utils/isMuiElement'; import useForkRef from '../utils/useForkRef'; import ListContext from '../List/ListContext'; -import listItemClasses, { getListItemUtilityClass } from './listItemClasses'; +import { getListItemUtilityClass } from './listItemClasses'; import { listItemButtonClasses } from '../ListItemButton'; import ListItemSecondaryAction from '../ListItemSecondaryAction'; @@ -70,25 +70,6 @@ export const ListItemRoot = styled('div', { width: '100%', boxSizing: 'border-box', textAlign: 'left', - [`&.${listItemClasses.focusVisible}`]: { - backgroundColor: (theme.vars || theme).palette.action.focus, - }, - [`&.${listItemClasses.selected}`]: { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` - : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity), - [`&.${listItemClasses.focusVisible}`]: { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.focusOpacity}))` - : alpha( - theme.palette.primary.main, - theme.palette.action.selectedOpacity + theme.palette.action.focusOpacity, - ), - }, - }, - [`&.${listItemClasses.disabled}`]: { - opacity: (theme.vars || theme).palette.action.disabledOpacity, - }, variants: [ { props: ({ ownerState }) => !ownerState.disablePadding, @@ -156,20 +137,6 @@ export const ListItemRoot = styled('div', { backgroundColor: 'transparent', }, }, - [`&.${listItemClasses.selected}:hover`]: { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` - : alpha( - theme.palette.primary.main, - theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity, - ), - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` - : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity), - }, - }, }, }, { From 842d1f627acdf07ac0eede8a4d906874e9a57495 Mon Sep 17 00:00:00 2001 From: mnajdova Date: Wed, 31 Jul 2024 14:55:51 +0200 Subject: [PATCH 19/24] remove unused import --- packages/mui-material/src/ListItem/ListItem.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/mui-material/src/ListItem/ListItem.js b/packages/mui-material/src/ListItem/ListItem.js index ac29608cf10188..e435033a1f11c7 100644 --- a/packages/mui-material/src/ListItem/ListItem.js +++ b/packages/mui-material/src/ListItem/ListItem.js @@ -5,7 +5,6 @@ import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import elementTypeAcceptingRef from '@mui/utils/elementTypeAcceptingRef'; import chainPropTypes from '@mui/utils/chainPropTypes'; -import { alpha } from '@mui/system/colorManipulator'; import isHostComponent from '../utils/isHostComponent'; import { styled } from '../zero-styled'; import { useDefaultProps } from '../DefaultPropsProvider'; From 21bc5f4c04fdc685df7bc9e81cf7b2793561306e Mon Sep 17 00:00:00 2001 From: mnajdova Date: Fri, 2 Aug 2024 10:35:10 +0200 Subject: [PATCH 20/24] add codemod instructions, fix theme codemod --- .../migration/migrating-to-v6/migrating-to-v6.md | 13 +++++++++++++ .../list-item-button-prop/list-item-button-prop.js | 8 ++++++++ .../test-cases/theme.actual.js | 3 +++ .../test-cases/theme.expected.js | 5 ++++- 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/docs/data/material/migration/migrating-to-v6/migrating-to-v6.md b/docs/data/material/migration/migrating-to-v6/migrating-to-v6.md index 39e176a649b985..5b830158a959c6 100644 --- a/docs/data/material/migration/migrating-to-v6/migrating-to-v6.md +++ b/docs/data/material/migration/migrating-to-v6/migrating-to-v6.md @@ -207,6 +207,19 @@ This brings some breaking changes described in the following sections. + ``` +Use this codemod to migrate your project to the` ListItemButton` component: + +```bash +npx @mui/codemod@next v6.0.0/list-item-button-prop +``` + +As the `ListItem` no longer supports these props, the class names related to these props were removed. You should use the `listItemButtonClasses` object instead. + +```diff +-import { listItemClasses } from '@mui/material/ListItem'; ++import { listItemButtonClasses } from '@mui/material/ListItemButton'; +``` + #### Stabilized API The `Grid2` component API was stabilized, so its import no longer contains the `Unstable_` prefix: diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js index 03b77357e39200..0fb4f0cc53fa73 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js @@ -41,6 +41,14 @@ export default function transformer(file, api, options) { parentObject.properties.push(muiListItemButtonNode); } }); + + defaultProps.properties = defaultProps.properties.filter( + (prop) => + prop.key.name !== 'button' && + prop.key.name !== 'autoFocus' && + prop.key.name !== 'disabled' && + prop.key.name !== 'selected', + ); path.prune(); }); diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.actual.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.actual.js index dca992dee2bda5..b9013d5a5e45f8 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.actual.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.actual.js @@ -2,6 +2,9 @@ fn({ MuiListItem: { defaultProps: { anotherProp: 'value', + autoFocus: true, + disabled: false, + selected: true, button: true, } } diff --git a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.expected.js b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.expected.js index a8d567deaf4906..fccbe337fea630 100644 --- a/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.expected.js +++ b/packages/mui-codemod/src/v6.0.0/list-item-button-prop/test-cases/theme.expected.js @@ -7,7 +7,10 @@ fn({ MuiListItemButton: { defaultProps: { - anotherProp: 'value' + anotherProp: 'value', + autoFocus: true, + disabled: false, + selected: true } } }); From 5bde93a8488262385cda02ff0f83a976014a02fe Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Mon, 5 Aug 2024 10:05:44 +0200 Subject: [PATCH 21/24] Update docs/data/material/migration/migrating-to-v6/migrating-to-v6.md Signed-off-by: Marija Najdova --- docs/data/material/migration/migrating-to-v6/migrating-to-v6.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/data/material/migration/migrating-to-v6/migrating-to-v6.md b/docs/data/material/migration/migrating-to-v6/migrating-to-v6.md index 5b830158a959c6..bf4b40a8029594 100644 --- a/docs/data/material/migration/migrating-to-v6/migrating-to-v6.md +++ b/docs/data/material/migration/migrating-to-v6/migrating-to-v6.md @@ -207,7 +207,7 @@ This brings some breaking changes described in the following sections. + ``` -Use this codemod to migrate your project to the` ListItemButton` component: +Use this codemod to migrate your project to the `ListItemButton` component: ```bash npx @mui/codemod@next v6.0.0/list-item-button-prop From ffa33dad49f418d870045526d94faffae8d2a671 Mon Sep 17 00:00:00 2001 From: mnajdova Date: Thu, 8 Aug 2024 08:37:44 +0200 Subject: [PATCH 22/24] Fix usage of wrong class names --- .../templates/blog/theme/customizations/menus.js | 8 ++++---- .../templates/blog/theme/customizations/menus.tsx | 8 ++++---- packages/mui-material/src/ListItem/ListItem.test.js | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/data/material/getting-started/templates/blog/theme/customizations/menus.js b/docs/data/material/getting-started/templates/blog/theme/customizations/menus.js index 167af530c54596..ffd022a1ae476c 100644 --- a/docs/data/material/getting-started/templates/blog/theme/customizations/menus.js +++ b/docs/data/material/getting-started/templates/blog/theme/customizations/menus.js @@ -4,7 +4,7 @@ import { svgIconClasses } from '@mui/material/SvgIcon'; import { typographyClasses } from '@mui/material/Typography'; import { buttonBaseClasses } from '@mui/material/ButtonBase'; import { dividerClasses } from '@mui/material/Divider'; -import { listItemClasses } from '@mui/material/ListItem'; +import { listItemButtonClasses } from '@mui/material/ListItemButton'; import { menuItemClasses } from '@mui/material/MenuItem'; import { selectClasses } from '@mui/material/Select'; import UnfoldMoreRoundedIcon from '@mui/icons-material/UnfoldMoreRounded'; @@ -39,20 +39,20 @@ export const menuComponentsCustomizations = { padding: '2px 8px', borderRadius: theme.shape.borderRadius, opacity: 0.7, - [`&.${listItemClasses.selected}`]: { + [`&.${listItemButtonClasses.selected}`]: { opacity: 1, backgroundColor: alpha(theme.palette.action.selected, 0.3), [`& .${svgIconClasses.root}`]: { color: theme.palette.text.primary, }, - [`&.${listItemClasses.focusVisible}`]: { + [`&.${listItemButtonClasses.focusVisible}`]: { backgroundColor: alpha(theme.palette.action.selected, 0.3), }, '&:hover': { backgroundColor: alpha(theme.palette.action.selected, 0.5), }, }, - [`&.${listItemClasses.focusVisible}`]: { + [`&.${listItemButtonClasses.focusVisible}`]: { backgroundColor: 'transparent', }, }, diff --git a/docs/data/material/getting-started/templates/blog/theme/customizations/menus.tsx b/docs/data/material/getting-started/templates/blog/theme/customizations/menus.tsx index 7125260edd8583..391c849ff6e644 100644 --- a/docs/data/material/getting-started/templates/blog/theme/customizations/menus.tsx +++ b/docs/data/material/getting-started/templates/blog/theme/customizations/menus.tsx @@ -4,7 +4,7 @@ import { svgIconClasses, SvgIconProps } from '@mui/material/SvgIcon'; import { typographyClasses } from '@mui/material/Typography'; import { buttonBaseClasses } from '@mui/material/ButtonBase'; import { dividerClasses } from '@mui/material/Divider'; -import { listItemClasses } from '@mui/material/ListItem'; +import { listItemButtonClasses } from '@mui/material/ListItemButton'; import { menuItemClasses } from '@mui/material/MenuItem'; import { selectClasses } from '@mui/material/Select'; import UnfoldMoreRoundedIcon from '@mui/icons-material/UnfoldMoreRounded'; @@ -39,20 +39,20 @@ export const menuComponentsCustomizations: Components = { padding: '2px 8px', borderRadius: theme.shape.borderRadius, opacity: 0.7, - [`&.${listItemClasses.selected}`]: { + [`&.${listItemButtonClasses.selected}`]: { opacity: 1, backgroundColor: alpha(theme.palette.action.selected, 0.3), [`& .${svgIconClasses.root}`]: { color: theme.palette.text.primary, }, - [`&.${listItemClasses.focusVisible}`]: { + [`&.${listItemButtonClasses.focusVisible}`]: { backgroundColor: alpha(theme.palette.action.selected, 0.3), }, '&:hover': { backgroundColor: alpha(theme.palette.action.selected, 0.5), }, }, - [`&.${listItemClasses.focusVisible}`]: { + [`&.${listItemButtonClasses.focusVisible}`]: { backgroundColor: 'transparent', }, }, diff --git a/packages/mui-material/src/ListItem/ListItem.test.js b/packages/mui-material/src/ListItem/ListItem.test.js index edffd8aae61e12..8df90d7167c584 100644 --- a/packages/mui-material/src/ListItem/ListItem.test.js +++ b/packages/mui-material/src/ListItem/ListItem.test.js @@ -1,7 +1,7 @@ import * as React from 'react'; import { expect } from 'chai'; import PropTypes from 'prop-types'; -import { act, createRenderer, reactMajor } from '@mui/internal-test-utils'; +import { createRenderer, reactMajor } from '@mui/internal-test-utils'; import { ThemeProvider, createTheme } from '@mui/material/styles'; import ListItemText from '@mui/material/ListItemText'; import ListItemSecondaryAction from '@mui/material/ListItemSecondaryAction'; From 30aa518bc4fe929240e0093b57a6615a21d75047 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 8 Aug 2024 08:46:49 +0200 Subject: [PATCH 23/24] Update docs/data/material/migration/migrating-to-v6/migrating-to-v6.md Co-authored-by: Siriwat K Signed-off-by: Marija Najdova --- .../migration/migrating-to-v6/migrating-to-v6.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/data/material/migration/migrating-to-v6/migrating-to-v6.md b/docs/data/material/migration/migrating-to-v6/migrating-to-v6.md index 71f380318802ba..1974710e8c47d9 100644 --- a/docs/data/material/migration/migrating-to-v6/migrating-to-v6.md +++ b/docs/data/material/migration/migrating-to-v6/migrating-to-v6.md @@ -219,6 +219,18 @@ As the `ListItem` no longer supports these props, the class names related to the ```diff -import { listItemClasses } from '@mui/material/ListItem'; +import { listItemButtonClasses } from '@mui/material/ListItemButton'; + +- listItemClasses.button ++ listItemButtonClasses.root + +- listItemClasses.focusVisible +- listItemButtonClasses.focusVisible + +- listItemClasses.disabled ++ listItemButtonClasses.disabled + +- listItemClasses.selected ++ listItemButtonClasses.selected ``` #### Stabilized API From ac75cc689a583ad1422230ad2a3684b52f24541a Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Thu, 8 Aug 2024 08:47:54 +0200 Subject: [PATCH 24/24] Update docs/data/material/migration/migrating-to-v6/migrating-to-v6.md Signed-off-by: Marija Najdova --- docs/data/material/migration/migrating-to-v6/migrating-to-v6.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/data/material/migration/migrating-to-v6/migrating-to-v6.md b/docs/data/material/migration/migrating-to-v6/migrating-to-v6.md index 1974710e8c47d9..e297a98a04ed3a 100644 --- a/docs/data/material/migration/migrating-to-v6/migrating-to-v6.md +++ b/docs/data/material/migration/migrating-to-v6/migrating-to-v6.md @@ -224,7 +224,7 @@ As the `ListItem` no longer supports these props, the class names related to the + listItemButtonClasses.root - listItemClasses.focusVisible -- listItemButtonClasses.focusVisible ++ listItemButtonClasses.focusVisible - listItemClasses.disabled + listItemButtonClasses.disabled