docs/data/material/migration/upgrade-to-v9/upgrade-to-v9.md
Material UI v9 continues improving the accessibility and semantics of core components. This release includes updates to keyboard navigation, focus management, and DOM structure so components align more closely with web platform, accessibility expectations and modern assistive technology behavior.
Material UI v9 also includes a number of quality-of-life improvements, including:
slot and slotProps APIsIf you're using any of these packages, you should also update them to compatible v9 versions:
@mui/icons-material to 9.0.0@mui/system to 9.0.0@mui/lab to the latest v9 beta release@mui/material-nextjs to 9.0.0@mui/styled-engine to 9.0.0@mui/styled-engine-sc to 9.0.0@mui/utils to 9.0.0The default bundle targets have changed in v9.
<!-- #stable-snapshot -->stable entry)Since v9 is a new major release, it contains some changes that affect the public API. The steps you need to take to migrate from Material UI v7 to v9 are described below.
The listbox does not toggle anymore when using right click on the input. The left click toggle behavior remains unchanged.
When freeSolo is true:
getOptionLabel prop accepts string for its option argumentisOptionEqualToValue prop accepts string for its value argument- isOptionEqualToValue?: (option: Value, value: Value) => boolean;
+ isOptionEqualToValue?: (
+ option: Value,
+ value: AutocompleteValueOrFreeSoloValueMapping<Value, FreeSolo>,
+ ) => boolean;
- getOptionLabel?: (option: Value | AutocompleteFreeSoloValueMapping<FreeSolo>) => string;
+ getOptionLabel?: (option: AutocompleteValueOrFreeSoloValueMapping<Value, FreeSolo>) => string;
For reference:
type AutocompleteFreeSoloValueMapping<FreeSolo> = FreeSolo extends true
? string
: never;
type AutocompleteValueOrFreeSoloValueMapping<Value, FreeSolo> = FreeSolo extends true
? Value | string
: Value;
The Backdrop component no longer adds the aria-hidden="true" attribute to the Root slot by default.
When sending Enter and Spacebar keys on the ButtonBase or components that are composed from ButtonBase, the click event now bubbles to their ancestors.
Also, the event passed to the onClick prop is a MouseEvent instead of the KeyboardEvent captured
in the ButtonBase keyboard handlers. This matches the expected behavior.
When ButtonBase renders a non-native element like a <span>, keyboard and click event handlers will no longer run when the component is disabled.
The nativeButton prop is available on <ButtonBase> and all button-like components to ensure that they are rendered with the correct HTML attributes before hydration, for example during server-side rendering.
This should be specified when passing a React component to the component prop of a button-like component that either replaces the default rendered element:
<button> to a non-interactive element like a <div>, or<div> to a native <button>const CustomButton = React.forwardRef(function CustomButton(props, ref) {
return <div ref={ref} {...props} />;
})
<Button component={CustomButton} nativeButton={false}>
OK
</Button>
A warning will be shown in development mode if the nativeButton prop is incorrectly omitted, or if the resolved element
does not match the value of the prop.
The prop can be used for: <ButtonBase>, <Button>, <Fab>, <IconButton>, <ListItemButton>, <MenuItem>, <StepButton>, <Tab>, <ToggleButton>, <AccordionSummary>, <BottomNavigationAction>, <CardActionArea>, <TableSortLabel> and <PaginationItem>.
The disableEscapeKeyDown prop has been removed. The same behavior could be achieved
by checking the value of the reason argument in onClose:
const [open, setOpen] = React.useState(true);
- const handleClose = () => {
- setOpen(false);
- };
+ const handleClose = (_event: React.SyntheticEvent<unknown>, reason: string) => {
+ if (reason !== 'escapeKeyDown') {
+ setOpen(false);
+ }
+ };
return (
- <Dialog open={open} disableEscapeKeyDown onClose={handleClose}>
+ <Dialog open={open} onClose={handleClose}>
</Dialog>
);
The same applies to Modal.
The GridLegacy component is removed, use the Grid component instead.
The main API differences are:
item prop is no longer needed.xs, sm, md, lg, xl props are replaced by the size prop.-import Grid from '@mui/material/GridLegacy';
+import Grid from '@mui/material/Grid';
<Grid container spacing={2}>
- <Grid item xs={12} sm={6}>
+ <Grid size={{ xs: 12, sm: 6 }}>
...
</Grid>
</Grid>
See the Grid v2 migration guide for more details.
MuiGridLegacy has also been removed from the theme components types (ComponentsProps, ComponentsOverrides, and ComponentsVariants).
The ListItemIcon default min-width has changed to 36px (previously 56px) to be consistent with the menu item, and now uses theme.spacing instead of a hardcoded number.
23 legacy icon exports that ended with Outline (without the "d") have been removed.
These were exact duplicates of their Outlined counterparts (for example, InfoOutline had the same SVG as InfoOutlined).
To migrate, rename the import to use the Outlined suffix:
-import InfoOutlineIcon from '@mui/icons-material/InfoOutline';
+import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';
The full list of removed exports: AddCircleOutline, ChatBubbleOutline, CheckCircleOutline, DeleteOutline, DoneOutline, DriveFileMoveOutline, ErrorOutline, HelpOutline, InfoOutline, LabelImportantOutline, LightbulbOutline, LockOutline, MailOutline, ModeEditOutline, PauseCircleOutline, PeopleOutline, PersonOutline, PieChartOutline, PlayCircleOutline, RemoveCircleOutline, StarOutline, WorkOutline, WorkspacesOutline.
Theme variants of these icons (for example, InfoOutlineRounded, DeleteOutlineSharp) are not affected and remain available.
When using variant="selectedMenu", the tabindex attribute for each menu item will change on Arrow Key, Home / End or Character Key navigation. Previously, keyboard navigation moved DOM focus without updating tabindex on focused items. Now, we move DOM focus and also add tabindex="0" to the focused element. The previously focused element will have its tabindex updated to -1 in order to keep only one focusable MenuItem at a time.
This change also applies to both Menu and MenuList with variant="selectedMenu".
The autoFocus prop in MenuList does not set tabindex="0" on the List component anymore. It will always stay as -1.
MenuItems will throw an error when rendered outside of Menu or MenuList.
Keyboard navigation now supports MenuItems inside React.Fragment.
Custom non-interactive menu content such as ListSubheader or Divider no longer need to set muiSkipListHighlight to opt-out of the menu's focus management.
Custom children that set role="menuitem" but do not wrap the MenuItem component are no longer supported inside Menu or MenuList.
The Slider component uses pointer events instead of mouse events. Previously, onMouseDown={(event) => event.preventDefault()} would cancel a drag from starting. Now, onPointerDown must be used instead.
The Stepper and Step markups have changed to improve their semantics:
Stepper returns a <ol> element instead of <div>.Step returns a <li> element instead of <div>.The Stepper component now supports keyboard navigation when used with StepButton descendants. The navigation is implemented as a roving tabindex, supporting Arrow Keys as well as Home and End. Only one StepButton is focusable at a time, by having tabindex="0", while the rest all have tabindex="-1". Once selection is changed by Arrow Keys or Home / End, the tabindex value is also updated.
The markup for a Stepper with StepButton descendants has changed further to reflect this behavior. These changes apply on top of the tag changes described above.
The Stepper has:
role of tablist.aria-orientation added. The value is either horizontal or vertical depending on the orientation prop.The StepButton has:
role of tab.aria-current changed to aria-selected. The value is true when step is selected, and false otherwise.aria-setsize added. The value is the total number of steps.aria-posinset added. The value is the index of the step inside the list, 1-based.Pagination numbers in TablePagination are now formatted using Intl.NumberFormat according to the locale.
For example, 103177 is displayed as 103,177 in en-US or 103.177 in de-DE.
To opt out of number formatting, provide a custom labelDisplayedRows function:
<TablePagination
labelDisplayedRows={({ from, to, count }) =>
`${from}–${to} of ${count !== -1 ? count : `more than ${to}`}`
}
/>
Or when using a locale:
import { enUS } from '@mui/material/locale';
const theme = createTheme(
{
palette: {
primary: { main: '#1976d2' },
},
},
enUS,
{
components: {
MuiTablePagination: {
defaultProps: {
labelDisplayedRows: ({ from, to, count }) =>
`${from}–${to} of ${count !== -1 ? count : `more than ${to}`}`,
},
},
},
},
);
The tabindex attribute for each tab will be changed on Arrow Key or Home / End navigation. Previously, keyboard navigation moved DOM focus without updating tabindex on the focused Tab. Now, we move DOM focus and also add the tabindex="0" to the focused Tab. Other tabs will have tabindex="-1" to keep only one focusable Tab at a time.
Selecting a Tab will update the focus and tabindex as before.
Tabs not placed inside Tabs will now throw an error.
When specifying <TextField select /> to render a <Select>, the underlying <InputLabel> renders a <div> instead of a native <label> element. This does not affect <InputLabel> on its own.
MuiTouchRipple has been removed from the theme components types (ComponentsProps, ComponentsOverrides, and ComponentsVariants).
TouchRipple has been an internal component since v5 and never consumed theme overrides or default props, so the types were misleading.
If you were using MuiTouchRipple in your theme, remove it and use global CSS with the MuiTouchRipple-* class names instead:
const theme = createTheme({
components: {
- MuiTouchRipple: {
- styleOverrides: {
- root: { color: 'red' },
- },
- },
+ MuiButtonBase: {
+ styleOverrides: {
+ root: {
+ '& .MuiTouchRipple-root': { color: 'red' },
+ },
+ },
+ },
},
});
The behavior of the components in test environments has been improved to be more reliable.
The use of process.env.NODE_ENV === 'test' has been replaced with feature detection or user-agent sniffing wherever it more accurately reflects the intention of the code.
This change shouldn't impact most users, but it might lead to unintended CI changes.
For example, the code has been updated to auto-detect DOM environments that don't support layout, such as jsdom and happy-dom, with user-agent sniffing.
APIs that were deprecated earlier have been removed in v9.
Use the accordion-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/accordion-props <path>
The following deprecated props have been removed from the Accordion component:
TransitionComponent → use slots.transitionTransitionProps → use slotProps.transition <Accordion
- TransitionComponent={CustomTransition}
- TransitionProps={{ unmountOnExit: true }}
+ slots={{ transition: CustomTransition }}
+ slotProps={{ transition: { unmountOnExit: true } }}
>
Use the accordion-summary-classes codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/accordion-summary-classes <path>
The deprecated AccordionSummary CSS class contentGutters has been removed.
Use the combination of .MuiAccordionSummary-gutters and .MuiAccordionSummary-content classes instead:
-.MuiAccordionSummary-contentGutters {
+.MuiAccordionSummary-gutters .MuiAccordionSummary-content {
margin: 20px 0;
}
Use the alert-classes codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/alert-classes <path>
The following deprecated Alert CSS classes have been removed:
standardSuccess → use .MuiAlert-standard.MuiAlert-colorSuccessstandardInfo → use .MuiAlert-standard.MuiAlert-colorInfostandardWarning → use .MuiAlert-standard.MuiAlert-colorWarningstandardError → use .MuiAlert-standard.MuiAlert-colorErroroutlinedSuccess → use .MuiAlert-outlined.MuiAlert-colorSuccessoutlinedInfo → use .MuiAlert-outlined.MuiAlert-colorInfooutlinedWarning → use .MuiAlert-outlined.MuiAlert-colorWarningoutlinedError → use .MuiAlert-outlined.MuiAlert-colorErrorfilledSuccess → use .MuiAlert-filled.MuiAlert-colorSuccessfilledInfo → use .MuiAlert-filled.MuiAlert-colorInfofilledWarning → use .MuiAlert-filled.MuiAlert-colorWarningfilledError → use .MuiAlert-filled.MuiAlert-colorErrorIf you were using these deprecated class names as styleOverrides keys in your theme, use the variants array in the root override instead:
const theme = createTheme({
components: {
MuiAlert: {
styleOverrides: {
- standardSuccess: { color: 'green' },
- standardInfo: { color: 'blue' },
- standardWarning: { color: 'orange' },
- standardError: { color: 'red' },
- outlinedSuccess: { borderColor: 'green' },
- outlinedInfo: { borderColor: 'blue' },
- outlinedWarning: { borderColor: 'orange' },
- outlinedError: { borderColor: 'red' },
- filledSuccess: { backgroundColor: 'green' },
- filledInfo: { backgroundColor: 'blue' },
- filledWarning: { backgroundColor: 'orange' },
- filledError: { backgroundColor: 'red' },
+ root: {
+ variants: [
+ { props: { variant: 'standard', color: 'success' }, style: { color: 'green' } },
+ { props: { variant: 'standard', color: 'info' }, style: { color: 'blue' } },
+ { props: { variant: 'standard', color: 'warning' }, style: { color: 'orange' } },
+ { props: { variant: 'standard', color: 'error' }, style: { color: 'red' } },
+ { props: { variant: 'outlined', color: 'success' }, style: { borderColor: 'green' } },
+ { props: { variant: 'outlined', color: 'info' }, style: { borderColor: 'blue' } },
+ { props: { variant: 'outlined', color: 'warning' }, style: { borderColor: 'orange' } },
+ { props: { variant: 'outlined', color: 'error' }, style: { borderColor: 'red' } },
+ { props: { variant: 'filled', color: 'success' }, style: { backgroundColor: 'green' } },
+ { props: { variant: 'filled', color: 'info' }, style: { backgroundColor: 'blue' } },
+ { props: { variant: 'filled', color: 'warning' }, style: { backgroundColor: 'orange' } },
+ { props: { variant: 'filled', color: 'error' }, style: { backgroundColor: 'red' } },
+ ],
+ },
},
},
},
});
Use the alert-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/alert-props <path>
The following deprecated props have been removed from the Alert component:
components → use slotscomponentsProps → use slotProps <Alert
onClose={handleClose}
- components={{ CloseIcon: MyCloseIcon, CloseButton: MyCloseButton }}
- componentsProps={{ closeButton: { size: 'large' }, closeIcon: { fontSize: 'small' } }}
+ slots={{ closeIcon: MyCloseIcon, closeButton: MyCloseButton }}
+ slotProps={{ closeButton: { size: 'large' }, closeIcon: { fontSize: 'small' } }}
/>
Use the avatar-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/avatar-props <path>
The following deprecated props have been removed from the Avatar component:
imgProps → use slotProps.img-<Avatar imgProps={{ crossOrigin: 'anonymous', referrerPolicy: 'no-referrer' }} />
+<Avatar slotProps={{ img: { crossOrigin: 'anonymous', referrerPolicy: 'no-referrer' } }} />
Use the avatar-group-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/avatar-group-props <path>
The following deprecated props have been removed from the AvatarGroup component:
componentsProps → use slotProps (the additionalAvatar key has been renamed to surplus)-<AvatarGroup componentsProps={{ additionalAvatar: { className: 'my-class' } }}>
+<AvatarGroup slotProps={{ surplus: { className: 'my-class' } }}>
If you were already using the surplus key via componentsProps, move it to slotProps:
-<AvatarGroup componentsProps={{ surplus: { className: 'my-class' } }}>
+<AvatarGroup slotProps={{ surplus: { className: 'my-class' } }}>
Use the autocomplete-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/autocomplete-props <path>
The following deprecated props have been removed from the Autocomplete component:
ChipProps → use slotProps.chipcomponentsProps → use slotPropsListboxComponent → use slots.listboxListboxProps → use slotProps.listboxPaperComponent → use slots.paperPopperComponent → use slots.popperrenderTags → use renderValue <Autocomplete
multiple
options={options}
renderInput={(params) => <TextField {...params} />}
- ChipProps={{ size: 'small' }}
- componentsProps={{
- clearIndicator: { size: 'large' },
- paper: { elevation: 2 },
- popper: { placement: 'bottom-end' },
- popupIndicator: { size: 'large' },
- }}
- ListboxComponent={CustomListbox}
- ListboxProps={{ style: { maxHeight: 200 }, ref }}
- PaperComponent={CustomPaper}
- PopperComponent={(props) => {
- const { disablePortal, anchorEl, open, ...other } = props;
- return <Box {...other} />;
- }}
- renderTags={(value, getTagProps, ownerState) =>
- value.map((option, index) => (
- <Chip label={option.label} {...getTagProps({ index })} />
- ))
- }
+ slots={{
+ listbox: CustomListbox,
+ paper: CustomPaper,
+ popper: (props) => {
+ const { disablePortal, anchorEl, open, ...other } = props;
+ return <Box {...other} />;
+ },
+ }}
+ slotProps={{
+ chip: { size: 'small' },
+ clearIndicator: { size: 'large' },
+ listbox: { style: { maxHeight: 200 }, ref },
+ paper: { elevation: 2 },
+ popper: { placement: 'bottom-end' },
+ popupIndicator: { size: 'large' },
+ }}
+ renderValue={(value, getItemProps, ownerState) =>
+ value.map((option, index) => (
+ <Chip label={option.label} {...getItemProps({ index })} />
+ ))
+ }
/>
Use the autocomplete-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/autocomplete-props <path>
The following deprecated members have been removed from the useAutocomplete hook return value:
getTagProps → use getItemPropsfocusedTag → use focusedItem const {
- getTagProps,
+ getItemProps,
} = useAutocomplete(props);
// ...
-<Chip {...getTagProps({ index })} />
+<Chip {...getItemProps({ index })} />
const {
- focusedTag,
+ focusedItem,
} = useAutocomplete(props);
Use the backdrop-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/backdrop-props <path>
The following deprecated Backdrop props have been removed:
components — use slots insteadcomponentsProps — use slotProps insteadTransitionComponent — use slots.transition instead <Backdrop
- components={{ Root: CustomRoot }}
- componentsProps={{ root: { className: 'my-class' } }}
- TransitionComponent={CustomTransition}
+ slots={{ root: CustomRoot, transition: CustomTransition }}
+ slotProps={{ root: { className: 'my-class' } }}
Use the badge-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/badge-props <path>
The following deprecated props have been removed from the Badge component:
components → use slotscomponentsProps → use slotProps <Badge
- components={{ Root: CustomRoot, Badge: CustomBadge }}
- componentsProps={{ root: { className: 'my-root' }, badge: { className: 'my-badge' } }}
+ slots={{ root: CustomRoot, badge: CustomBadge }}
+ slotProps={{ root: { className: 'my-root' }, badge: { className: 'my-badge' } }}
/>
Use the button-classes codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/button-classes <path>
The following deprecated Button CSS classes have been removed:
textInherit → use .MuiButton-text.MuiButton-colorInherittextPrimary → use .MuiButton-text.MuiButton-colorPrimarytextSecondary → use .MuiButton-text.MuiButton-colorSecondarytextSuccess → use .MuiButton-text.MuiButton-colorSuccesstextError → use .MuiButton-text.MuiButton-colorErrortextInfo → use .MuiButton-text.MuiButton-colorInfotextWarning → use .MuiButton-text.MuiButton-colorWarningoutlinedInherit → use .MuiButton-outlined.MuiButton-colorInheritoutlinedPrimary → use .MuiButton-outlined.MuiButton-colorPrimaryoutlinedSecondary → use .MuiButton-outlined.MuiButton-colorSecondaryoutlinedSuccess → use .MuiButton-outlined.MuiButton-colorSuccessoutlinedError → use .MuiButton-outlined.MuiButton-colorErroroutlinedInfo → use .MuiButton-outlined.MuiButton-colorInfooutlinedWarning → use .MuiButton-outlined.MuiButton-colorWarningcontainedInherit → use .MuiButton-contained.MuiButton-colorInheritcontainedPrimary → use .MuiButton-contained.MuiButton-colorPrimarycontainedSecondary → use .MuiButton-contained.MuiButton-colorSecondarycontainedSuccess → use .MuiButton-contained.MuiButton-colorSuccesscontainedError → use .MuiButton-contained.MuiButton-colorErrorcontainedInfo → use .MuiButton-contained.MuiButton-colorInfocontainedWarning → use .MuiButton-contained.MuiButton-colorWarningtextSizeSmall → use .MuiButton-text.MuiButton-sizeSmalltextSizeMedium → use .MuiButton-text.MuiButton-sizeMediumtextSizeLarge → use .MuiButton-text.MuiButton-sizeLargeoutlinedSizeSmall → use .MuiButton-outlined.MuiButton-sizeSmalloutlinedSizeMedium → use .MuiButton-outlined.MuiButton-sizeMediumoutlinedSizeLarge → use .MuiButton-outlined.MuiButton-sizeLargecontainedSizeSmall → use .MuiButton-contained.MuiButton-sizeSmallcontainedSizeMedium → use .MuiButton-contained.MuiButton-sizeMediumcontainedSizeLarge → use .MuiButton-contained.MuiButton-sizeLargeiconSizeSmall → use .MuiButton-root.MuiButton-sizeSmall > .MuiButton-iconiconSizeMedium → use .MuiButton-root.MuiButton-sizeMedium > .MuiButton-iconiconSizeLarge → use .MuiButton-root.MuiButton-sizeLarge > .MuiButton-iconIf you were using these deprecated class names as styleOverrides keys in your theme, use the variants array in the root override instead:
const theme = createTheme({
components: {
MuiButton: {
styleOverrides: {
- textInherit: { color: 'inherit' },
- textPrimary: { color: 'blue' },
- textSecondary: { color: 'purple' },
- textSuccess: { color: 'green' },
- textError: { color: 'red' },
- textInfo: { color: 'cyan' },
- textWarning: { color: 'orange' },
- outlinedInherit: { borderColor: 'inherit' },
- outlinedPrimary: { borderColor: 'blue' },
- outlinedSecondary: { borderColor: 'purple' },
- outlinedSuccess: { borderColor: 'green' },
- outlinedError: { borderColor: 'red' },
- outlinedInfo: { borderColor: 'cyan' },
- outlinedWarning: { borderColor: 'orange' },
- containedInherit: { backgroundColor: 'inherit' },
- containedPrimary: { backgroundColor: 'blue' },
- containedSecondary: { backgroundColor: 'purple' },
- containedSuccess: { backgroundColor: 'green' },
- containedError: { backgroundColor: 'red' },
- containedInfo: { backgroundColor: 'cyan' },
- containedWarning: { backgroundColor: 'orange' },
- textSizeSmall: { fontSize: '0.75rem' },
- textSizeMedium: { fontSize: '0.875rem' },
- textSizeLarge: { fontSize: '1rem' },
- outlinedSizeSmall: { fontSize: '0.75rem' },
- outlinedSizeMedium: { fontSize: '0.875rem' },
- outlinedSizeLarge: { fontSize: '1rem' },
- containedSizeSmall: { fontSize: '0.75rem' },
- containedSizeMedium: { fontSize: '0.875rem' },
- containedSizeLarge: { fontSize: '1rem' },
- iconSizeSmall: { fontSize: '18px' },
- iconSizeMedium: { fontSize: '20px' },
- iconSizeLarge: { fontSize: '22px' },
+ root: {
+ variants: [
+ { props: { variant: 'text', color: 'inherit' }, style: { color: 'inherit' } },
+ { props: { variant: 'text', color: 'primary' }, style: { color: 'blue' } },
+ { props: { variant: 'text', color: 'secondary' }, style: { color: 'purple' } },
+ { props: { variant: 'text', color: 'success' }, style: { color: 'green' } },
+ { props: { variant: 'text', color: 'error' }, style: { color: 'red' } },
+ { props: { variant: 'text', color: 'info' }, style: { color: 'cyan' } },
+ { props: { variant: 'text', color: 'warning' }, style: { color: 'orange' } },
+ { props: { variant: 'outlined', color: 'inherit' }, style: { borderColor: 'inherit' } },
+ { props: { variant: 'outlined', color: 'primary' }, style: { borderColor: 'blue' } },
+ { props: { variant: 'outlined', color: 'secondary' }, style: { borderColor: 'purple' } },
+ { props: { variant: 'outlined', color: 'success' }, style: { borderColor: 'green' } },
+ { props: { variant: 'outlined', color: 'error' }, style: { borderColor: 'red' } },
+ { props: { variant: 'outlined', color: 'info' }, style: { borderColor: 'cyan' } },
+ { props: { variant: 'outlined', color: 'warning' }, style: { borderColor: 'orange' } },
+ { props: { variant: 'contained', color: 'inherit' }, style: { backgroundColor: 'inherit' } },
+ { props: { variant: 'contained', color: 'primary' }, style: { backgroundColor: 'blue' } },
+ { props: { variant: 'contained', color: 'secondary' }, style: { backgroundColor: 'purple' } },
+ { props: { variant: 'contained', color: 'success' }, style: { backgroundColor: 'green' } },
+ { props: { variant: 'contained', color: 'error' }, style: { backgroundColor: 'red' } },
+ { props: { variant: 'contained', color: 'info' }, style: { backgroundColor: 'cyan' } },
+ { props: { variant: 'contained', color: 'warning' }, style: { backgroundColor: 'orange' } },
+ { props: { variant: 'text', size: 'small' }, style: { fontSize: '0.75rem' } },
+ { props: { variant: 'text', size: 'medium' }, style: { fontSize: '0.875rem' } },
+ { props: { variant: 'text', size: 'large' }, style: { fontSize: '1rem' } },
+ { props: { variant: 'outlined', size: 'small' }, style: { fontSize: '0.75rem' } },
+ { props: { variant: 'outlined', size: 'medium' }, style: { fontSize: '0.875rem' } },
+ { props: { variant: 'outlined', size: 'large' }, style: { fontSize: '1rem' } },
+ { props: { variant: 'contained', size: 'small' }, style: { fontSize: '0.75rem' } },
+ { props: { variant: 'contained', size: 'medium' }, style: { fontSize: '0.875rem' } },
+ { props: { variant: 'contained', size: 'large' }, style: { fontSize: '1rem' } },
+ { props: { size: 'small' }, style: { '& .MuiButton-icon': { fontSize: '18px' } } },
+ { props: { size: 'medium' }, style: { '& .MuiButton-icon': { fontSize: '20px' } } },
+ { props: { size: 'large' }, style: { '& .MuiButton-icon': { fontSize: '22px' } } },
+ ],
+ },
},
},
},
});
Use the button-group-classes codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/button-group-classes <path>
The following deprecated ButtonGroup CSS classes have been removed:
groupedHorizontal → use .MuiButtonGroup-horizontal > .MuiButtonGroup-groupedgroupedVertical → use .MuiButtonGroup-vertical > .MuiButtonGroup-groupedgroupedText → use .MuiButtonGroup-text > .MuiButtonGroup-groupedgroupedTextHorizontal → use .MuiButtonGroup-text.MuiButtonGroup-horizontal > .MuiButtonGroup-groupedgroupedTextVertical → use .MuiButtonGroup-text.MuiButtonGroup-vertical > .MuiButtonGroup-groupedgroupedTextPrimary → use .MuiButtonGroup-text.MuiButtonGroup-colorPrimary > .MuiButtonGroup-groupedgroupedTextSecondary → use .MuiButtonGroup-text.MuiButtonGroup-colorSecondary > .MuiButtonGroup-groupedgroupedOutlined → use .MuiButtonGroup-outlined > .MuiButtonGroup-groupedgroupedOutlinedHorizontal → use .MuiButtonGroup-outlined.MuiButtonGroup-horizontal > .MuiButtonGroup-groupedgroupedOutlinedVertical → use .MuiButtonGroup-outlined.MuiButtonGroup-vertical > .MuiButtonGroup-groupedgroupedOutlinedPrimary → use .MuiButtonGroup-outlined.MuiButtonGroup-colorPrimary > .MuiButtonGroup-groupedgroupedOutlinedSecondary → use .MuiButtonGroup-outlined.MuiButtonGroup-colorSecondary > .MuiButtonGroup-groupedgroupedContained → use .MuiButtonGroup-contained > .MuiButtonGroup-groupedgroupedContainedHorizontal → use .MuiButtonGroup-contained.MuiButtonGroup-horizontal > .MuiButtonGroup-groupedgroupedContainedVertical → use .MuiButtonGroup-contained.MuiButtonGroup-vertical > .MuiButtonGroup-groupedgroupedContainedPrimary → use .MuiButtonGroup-contained.MuiButtonGroup-colorPrimary > .MuiButtonGroup-groupedgroupedContainedSecondary → use .MuiButtonGroup-contained.MuiButtonGroup-colorSecondary > .MuiButtonGroup-groupedIf you were using these deprecated class names as styleOverrides keys in your theme, use the variants array in the root override instead:
const theme = createTheme({
components: {
MuiButtonGroup: {
styleOverrides: {
- groupedContainedPrimary: { borderColor: 'red' },
+ root: {
+ variants: [
+ {
+ props: { variant: 'contained', color: 'primary' },
+ style: {
+ '& > .MuiButtonGroup-grouped': { borderColor: 'red' },
+ },
+ },
+ ],
+ },
},
},
},
});
Use the card-header-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/card-header-props <path>
The following deprecated props have been removed from the CardHeader component:
titleTypographyProps → use slotProps.titlesubheaderTypographyProps → use slotProps.subheader <CardHeader
- titleTypographyProps={{ className: 'my-title' }}
- subheaderTypographyProps={{ className: 'my-subheader' }}
+ slotProps={{ title: { className: 'my-title' }, subheader: { className: 'my-subheader' } }}
/>
Use the checkbox-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/checkbox-props <path>
The following deprecated Checkbox props have been removed:
inputProps — use slotProps.input insteadinputRef — use slotProps.input.ref instead <Checkbox
- inputProps={{ 'aria-label': 'Checkbox' }}
- inputRef={ref}
+ slotProps={{ input: { 'aria-label': 'Checkbox', ref } }}
/>
Use the chip-classes codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/chip-classes <path>
The following deprecated Chip CSS classes have been removed:
clickableColorPrimary → use .MuiChip-clickable.MuiChip-colorPrimaryclickableColorSecondary → use .MuiChip-clickable.MuiChip-colorSecondarydeletableColorPrimary → use .MuiChip-deletable.MuiChip-colorPrimarydeletableColorSecondary → use .MuiChip-deletable.MuiChip-colorSecondaryoutlinedPrimary → use .MuiChip-outlined.MuiChip-colorPrimaryoutlinedSecondary → use .MuiChip-outlined.MuiChip-colorSecondaryfilledPrimary → use .MuiChip-filled.MuiChip-colorPrimaryfilledSecondary → use .MuiChip-filled.MuiChip-colorSecondaryavatarSmall → use .MuiChip-sizeSmall > .MuiChip-avataravatarMedium → use .MuiChip-sizeMedium > .MuiChip-avataravatarColorPrimary → use .MuiChip-colorPrimary > .MuiChip-avataravatarColorSecondary → use .MuiChip-colorSecondary > .MuiChip-avatariconSmall → use .MuiChip-sizeSmall > .MuiChip-iconiconMedium → use .MuiChip-sizeMedium > .MuiChip-iconiconColorPrimary → use .MuiChip-colorPrimary > .MuiChip-iconiconColorSecondary → use .MuiChip-colorSecondary > .MuiChip-iconlabelSmall → use .MuiChip-sizeSmall > .MuiChip-labellabelMedium → use .MuiChip-sizeMedium > .MuiChip-labeldeleteIconSmall → use .MuiChip-sizeSmall > .MuiChip-deleteIcondeleteIconMedium → use .MuiChip-sizeMedium > .MuiChip-deleteIcondeleteIconColorPrimary → use .MuiChip-colorPrimary > .MuiChip-deleteIcondeleteIconColorSecondary → use .MuiChip-colorSecondary > .MuiChip-deleteIcondeleteIconOutlinedColorPrimary → use .MuiChip-outlined.MuiChip-colorPrimary > .MuiChip-deleteIcondeleteIconOutlinedColorSecondary → use .MuiChip-outlined.MuiChip-colorSecondary > .MuiChip-deleteIcondeleteIconFilledColorPrimary → use .MuiChip-filled.MuiChip-colorPrimary > .MuiChip-deleteIcondeleteIconFilledColorSecondary → use .MuiChip-filled.MuiChip-colorSecondary > .MuiChip-deleteIconIf you were using these deprecated class names as styleOverrides keys in your theme, use the variants array in the root override instead.
For classes that targeted child elements (avatar, icon, deleteIcon), use CSS child selectors inside the root variants since those are not standalone styled slots.
The label slot is a proper styled component and can use variants directly in styleOverrides.label:
const theme = createTheme({
components: {
MuiChip: {
styleOverrides: {
- clickableColorPrimary: { boxShadow: 'none' },
- outlinedPrimary: { borderWidth: 2 },
- filledSecondary: { opacity: 0.9 },
- avatarColorPrimary: { color: 'white' },
- iconSmall: { fontSize: 14 },
- deleteIconColorPrimary: { color: 'red' },
- labelSmall: { padding: '0 6px' },
+ root: {
+ variants: [
+ { props: { clickable: true, color: 'primary' }, style: { boxShadow: 'none' } },
+ { props: { variant: 'outlined', color: 'primary' }, style: { borderWidth: 2 } },
+ { props: { variant: 'filled', color: 'secondary' }, style: { opacity: 0.9 } },
+ { props: { color: 'primary' }, style: { '& .MuiChip-avatar': { color: 'white' } } },
+ { props: { size: 'small' }, style: { '& .MuiChip-icon': { fontSize: 14 } } },
+ { props: { color: 'primary' }, style: { '& .MuiChip-deleteIcon': { color: 'red' } } },
+ ],
+ },
+ label: {
+ variants: [
+ { props: { size: 'small' }, style: { padding: '0 6px' } },
+ ],
+ },
},
},
},
});
Use the circular-progress-classes codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/circular-progress-classes <path>
The following deprecated CircularProgress CSS classes have been removed:
circleDeterminate → use .MuiCircularProgress-determinate .MuiCircularProgress-circlecircleIndeterminate → use .MuiCircularProgress-indeterminate .MuiCircularProgress-circleIf you were using these deprecated class names as styleOverrides keys in your theme, use the variants array in the circle override instead:
const theme = createTheme({
components: {
MuiCircularProgress: {
styleOverrides: {
- circleDeterminate: { strokeDashoffset: '10px' },
- circleIndeterminate: { animationDuration: '1.4s' },
+ circle: {
+ variants: [
+ {
+ props: { variant: 'determinate' },
+ style: { strokeDashoffset: '10px' },
+ },
+ {
+ props: { variant: 'indeterminate' },
+ style: { animationDuration: '1.4s' },
+ },
+ ],
+ },
},
},
},
});
Use the dialog-classes codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/dialog-classes <path>
The following deprecated Dialog CSS classes have been removed:
paperScrollPaper → use .MuiDialog-scrollPaper > .MuiDialog-paperpaperScrollBody → use .MuiDialog-scrollBody > .MuiDialog-paperIf you were using these classes in styleOverrides, use the variants array in the paper slot instead:
const theme = createTheme({
components: {
MuiDialog: {
styleOverrides: {
- paperScrollPaper: {
- maxHeight: '80vh',
- },
- paperScrollBody: {
- verticalAlign: 'bottom',
- },
+ paper: {
+ variants: [
+ {
+ props: { scroll: 'paper' },
+ style: {
+ maxHeight: '80vh',
+ },
+ },
+ {
+ props: { scroll: 'body' },
+ style: {
+ verticalAlign: 'bottom',
+ },
+ },
+ ],
+ },
},
},
},
});
Use the dialog-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/dialog-props <path>
The following deprecated props have been removed from the Dialog component:
BackdropComponent → use slots.backdropBackdropProps → use slotProps.backdropPaperProps → use slotProps.paperTransitionComponent → use slots.transitionTransitionProps → use slotProps.transition <Dialog
- BackdropComponent={CustomBackdrop}
- BackdropProps={{ invisible: true }}
- PaperProps={{ elevation: 3 }}
- TransitionComponent={CustomTransition}
- TransitionProps={{ timeout: 500 }}
+ slots={{ backdrop: CustomBackdrop, transition: CustomTransition }}
+ slotProps={{ backdrop: { invisible: true }, paper: { elevation: 3 }, transition: { timeout: 500 } }}
/>
Use the drawer-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/drawer-props <path>
The following deprecated props have been removed from the Drawer component:
BackdropComponent → use slots.backdropBackdropProps → use slotProps.backdropPaperProps → use slotProps.paperSlideProps → use slotProps.transitionTransitionComponent → use slots.transition <Drawer
- BackdropComponent={CustomBackdrop}
- BackdropProps={{ invisible: true }}
- PaperProps={{ elevation: 2 }}
- SlideProps={{ timeout: 500 }}
- TransitionComponent={CustomTransition}
+ slots={{ backdrop: CustomBackdrop, transition: CustomTransition }}
+ slotProps={{ backdrop: { invisible: true }, paper: { elevation: 2 }, transition: { timeout: 500 } }}
/>
Use the drawer-classes codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/drawer-classes <path>
The following deprecated classes have been removed:
paperAnchorLeft — combine .MuiDrawer-anchorLeft and .MuiDrawer-paper insteadpaperAnchorRight — combine .MuiDrawer-anchorRight and .MuiDrawer-paper insteadpaperAnchorTop — combine .MuiDrawer-anchorTop and .MuiDrawer-paper insteadpaperAnchorBottom — combine .MuiDrawer-anchorBottom and .MuiDrawer-paper insteadpaperAnchorDockedLeft — combine .MuiDrawer-anchorLeft, .MuiDrawer-docked, and .MuiDrawer-paper insteadpaperAnchorDockedRight — combine .MuiDrawer-anchorRight, .MuiDrawer-docked, and .MuiDrawer-paper insteadpaperAnchorDockedTop — combine .MuiDrawer-anchorTop, .MuiDrawer-docked, and .MuiDrawer-paper insteadpaperAnchorDockedBottom — combine .MuiDrawer-anchorBottom, .MuiDrawer-docked, and .MuiDrawer-paper instead-.MuiDrawer-paperAnchorLeft
+.MuiDrawer-anchorLeft > .MuiDrawer-paper
-.MuiDrawer-paperAnchorDockedLeft
+.MuiDrawer-anchorLeft.MuiDrawer-docked > .MuiDrawer-paper
Use the codemod below to migrate the code as described in the following sections:
npx @mui/codemod@latest deprecations/divider-props <path>
The deprecated Divider prop has been removed.
Use sx={{ opacity: 0.6 }} (or any opacity):
<Divider
- light
+ sx={{ opacity: 0.6 }}
/>
The following deprecated class has been removed:
withChildrenVertical — combine the .MuiDivider-withChildren and .MuiDivider-vertical classes instead-.MuiDivider-withChildrenVertical
+.MuiDivider-withChildren.MuiDivider-vertical
Use the form-control-label-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/form-control-label-props <path>
The following deprecated prop has been removed:
componentsProps — use slotProps instead <FormControlLabel
- componentsProps={{ typography: { fontWeight: 'bold' } }}
+ slotProps={{ typography: { fontWeight: 'bold' } }}
/>
Use the filled-input-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/filled-input-props <path>
The following deprecated FilledInput props have been removed:
components → use slots insteadcomponentsProps → use slotProps instead <FilledInput
- components={{ Root: CustomRoot, Input: CustomInput }}
- componentsProps={{ root: { id: 'root' }, input: { id: 'input' } }}
+ slots={{ root: CustomRoot, input: CustomInput }}
+ slotProps={{ root: { id: 'root' }, input: { id: 'input' } }}
/>
Use the image-list-item-bar-classes codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/image-list-item-bar-classes <path>
The following deprecated ImageListItemBar CSS classes have been removed:
titleWrapBelow → use .MuiImageListItemBar-titleWrap with .MuiImageListItemBar-positionBelow on the roottitleWrapActionPosLeft → use .MuiImageListItemBar-titleWrap with .MuiImageListItemBar-actionPositionLeft on the roottitleWrapActionPosRight → use .MuiImageListItemBar-titleWrap with .MuiImageListItemBar-actionPositionRight on the rootactionIconActionPosLeft → use .MuiImageListItemBar-actionIcon with .MuiImageListItemBar-actionPositionLeft on the rootUse the input-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/input-props <path>
The following deprecated Input props have been removed:
components → use slots insteadcomponentsProps → use slotProps instead <Input
- components={{ Root: CustomRoot, Input: CustomInput }}
- componentsProps={{ root: { id: 'root' }, input: { id: 'input' } }}
+ slots={{ root: CustomRoot, input: CustomInput }}
+ slotProps={{ root: { id: 'root' }, input: { id: 'input' } }}
/>
Use the input-base-classes codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/input-base-classes <path>
The following deprecated InputBase CSS classes have been removed:
inputSizeSmall → use .MuiInputBase-sizeSmall > .MuiInputBase-inputinputMultiline → use .MuiInputBase-multiline > .MuiInputBase-inputinputAdornedStart → use .MuiInputBase-adornedStart > .MuiInputBase-inputinputAdornedEnd → use .MuiInputBase-adornedEnd > .MuiInputBase-inputinputHiddenLabel → use .MuiInputBase-hiddenLabel > .MuiInputBase-inputIf you were using these deprecated class names as styleOverrides keys in your theme, use the root slot with combined class selectors instead:
import { inputBaseClasses } from '@mui/material/InputBase';
const theme = createTheme({
components: {
MuiInputBase: {
styleOverrides: {
- inputSizeSmall: { padding: 1 },
- inputMultiline: { resize: 'none' },
- inputAdornedStart: { paddingLeft: 0 },
- inputAdornedEnd: { paddingRight: 0 },
- inputHiddenLabel: { paddingTop: 8 },
+ root: {
+ [`&.${inputBaseClasses.sizeSmall} > .${inputBaseClasses.input}`]: { padding: 1 },
+ [`&.${inputBaseClasses.multiline} > .${inputBaseClasses.input}`]: { resize: 'none' },
+ [`&.${inputBaseClasses.adornedStart} > .${inputBaseClasses.input}`]: { paddingLeft: 0 },
+ [`&.${inputBaseClasses.adornedEnd} > .${inputBaseClasses.input}`]: { paddingRight: 0 },
+ [`&.${inputBaseClasses.hiddenLabel} > .${inputBaseClasses.input}`]: { paddingTop: 8 },
+ },
},
},
},
});
Use the input-base-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/input-base-props <path>
The following deprecated InputBase props have been removed:
components → use slots insteadcomponentsProps → use slotProps instead <InputBase
- components={{ Root: CustomRoot, Input: CustomInput }}
- componentsProps={{ root: { id: 'root' }, input: { id: 'input' } }}
+ slots={{ root: CustomRoot, input: CustomInput }}
+ slotProps={{ root: { id: 'root' }, input: { id: 'input' } }}
/>
Use the linear-progress-classes codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/linear-progress-classes <path>
The following deprecated LinearProgress CSS classes have been removed:
bar1Buffer → use .MuiLinearProgress-buffer > .MuiLinearProgress-bar1bar1Determinate → use .MuiLinearProgress-determinate > .MuiLinearProgress-bar1bar1Indeterminate → use .MuiLinearProgress-indeterminate > .MuiLinearProgress-bar1bar2Buffer → use .MuiLinearProgress-buffer > .MuiLinearProgress-bar2bar2Indeterminate → use .MuiLinearProgress-indeterminate > .MuiLinearProgress-bar2barColorPrimary → use .MuiLinearProgress-colorPrimary > .MuiLinearProgress-barbarColorSecondary → use .MuiLinearProgress-colorSecondary > .MuiLinearProgress-bardashedColorPrimary → use .MuiLinearProgress-colorPrimary > .MuiLinearProgress-dasheddashedColorSecondary → use .MuiLinearProgress-colorSecondary > .MuiLinearProgress-dashedIf you were using these deprecated class names as styleOverrides keys in your theme, use the variants array in the appropriate slot override instead:
const theme = createTheme({
components: {
MuiLinearProgress: {
styleOverrides: {
- bar1Determinate: { transition: 'none' },
- bar1Indeterminate: { width: 'auto' },
- bar1Buffer: { zIndex: 1 },
- barColorPrimary: { backgroundColor: 'red' },
- dashedColorPrimary: { backgroundSize: '10px 10px' },
+ bar1: {
+ variants: [
+ { props: { variant: 'determinate' }, style: { transition: 'none' } },
+ { props: { variant: 'indeterminate' }, style: { width: 'auto' } },
+ { props: { variant: 'buffer' }, style: { zIndex: 1 } },
+ ],
+ },
+ bar: {
+ variants: [
+ { props: { color: 'primary' }, style: { backgroundColor: 'red' } },
+ ],
+ },
+ dashed: {
+ variants: [
+ { props: { color: 'primary' }, style: { backgroundSize: '10px 10px' } },
+ ],
+ },
},
},
},
});
Use the list-item-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/list-item-props <path>
The following deprecated props have been removed:
components — use slots insteadcomponentsProps — use slotProps insteadContainerComponent — use component or slots.root insteadContainerProps — use slotProps.root instead <ListItem
- components={{ Root: CustomRoot }}
- componentsProps={{ root: { className: 'custom' } }}
+ slots={{ root: CustomRoot }}
+ slotProps={{ root: { className: 'custom' } }}
/>
The theming styleOverrides key secondaryAction now targets the secondaryAction slot instead of the root slot.
const theme = createTheme({
components: {
MuiListItem: {
styleOverrides: {
- secondaryAction: {
- [`& .${listItemClasses.secondaryAction}`]: {
- // styles
- },
- },
+ secondaryAction: {
+ // styles applied directly to the secondaryAction slot
+ },
},
},
},
});
Use the list-item-text-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/list-item-text-props <path>
The following deprecated props have been removed:
primaryTypographyProps — use slotProps.primary insteadsecondaryTypographyProps — use slotProps.secondary instead <ListItemText
- primaryTypographyProps={{ variant: 'h6' }}
- secondaryTypographyProps={{ color: 'textSecondary' }}
+ slotProps={{
+ primary: { variant: 'h6' },
+ secondary: { color: 'textSecondary' },
+ }}
/>
Use the menu-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/menu-props <path>
The following deprecated props have been removed:
MenuListProps — use slotProps.list insteadPaperProps — use slotProps.paper insteadTransitionProps — use slotProps.transition instead <Menu
- MenuListProps={{ disablePadding: true }}
- PaperProps={{ elevation: 12 }}
- TransitionProps={{ timeout: 500 }}
+ slotProps={{
+ list: { disablePadding: true },
+ paper: { elevation: 12 },
+ transition: { timeout: 500 },
+ }}
/>
If you pass these props via Select's MenuProps, update them the same way:
<Select
MenuProps={{
- PaperProps: { style: { maxHeight: 200 } },
- MenuListProps: { disablePadding: true },
- TransitionProps: { timeout: 500 },
+ slotProps: {
+ paper: { style: { maxHeight: 200 } },
+ list: { disablePadding: true },
+ transition: { timeout: 500 },
+ },
}}
/>
Use the mobile-stepper-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/mobile-stepper-props <path>
The following deprecated props have been removed:
LinearProgressProps — use slotProps.progress instead <MobileStepper
- LinearProgressProps={{ className: 'progress' }}
+ slotProps={{ progress: { className: 'progress' } }}
/>
Use the modal-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/modal-props <path>
The following deprecated props have been removed from the Modal component:
BackdropComponent → use slots.backdropBackdropProps → use slotProps.backdropcomponents → use slotscomponentsProps → use slotProps <Modal
- BackdropComponent={CustomBackdrop}
- BackdropProps={{ invisible: true }}
- components={{ Root: CustomRoot }}
- componentsProps={{ root: { className: 'custom' } }}
+ slots={{ backdrop: CustomBackdrop, root: CustomRoot }}
+ slotProps={{ backdrop: { invisible: true }, root: { className: 'custom' } }}
/>
Use the outlined-input-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/outlined-input-props <path>
The following deprecated OutlinedInput props have been removed:
components → use slots insteadcomponentsProps → use slotProps instead <OutlinedInput
- components={{ Root: CustomRoot, Input: CustomInput }}
- componentsProps={{ root: { id: 'root' }, input: { id: 'input' } }}
+ slots={{ root: CustomRoot, input: CustomInput }}
+ slotProps={{ root: { id: 'root' }, input: { id: 'input' } }}
/>
Use the pagination-item-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/pagination-item-props <path>
The following deprecated props have been removed:
components — use slots instead <PaginationItem
- components={{
- first: MyFirstIcon,
- last: MyLastIcon,
- previous: MyPreviousIcon,
- next: MyNextIcon,
- }}
+ slots={{
+ first: MyFirstIcon,
+ last: MyLastIcon,
+ previous: MyPreviousIcon,
+ next: MyNextIcon,
+ }}
/>
Use the pagination-item-classes codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/pagination-item-classes <path>
The following deprecated classes have been removed:
textPrimary — combine the .MuiPaginationItem-text and .MuiPaginationItem-colorPrimary classes insteadtextSecondary — combine the .MuiPaginationItem-text and .MuiPaginationItem-colorSecondary classes insteadoutlinedPrimary — combine the .MuiPaginationItem-outlined and .MuiPaginationItem-colorPrimary classes insteadoutlinedSecondary — combine the .MuiPaginationItem-outlined and .MuiPaginationItem-colorSecondary classes instead-.MuiPaginationItem-textPrimary
+.MuiPaginationItem-text.MuiPaginationItem-colorPrimary
-.MuiPaginationItem-outlinedPrimary
+.MuiPaginationItem-outlined.MuiPaginationItem-colorPrimary
Use the popper-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/popper-props <path>
The following deprecated props have been removed:
components — use slots insteadcomponentsProps — use slotProps instead <Popper
- components={{ Root: CustomRoot }}
- componentsProps={{ root: { className: 'custom' } }}
+ slots={{ root: CustomRoot }}
+ slotProps={{ root: { className: 'custom' } }}
/>
Use the popover-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/popover-props <path>
The following deprecated props have been removed:
BackdropComponent — use slots.backdrop insteadBackdropProps — use slotProps.backdrop insteadPaperProps — use slotProps.paper insteadTransitionComponent — use slots.transition insteadTransitionProps — use slotProps.transition instead <Popover
- BackdropComponent={CustomBackdrop}
- BackdropProps={{ invisible: true }}
- PaperProps={{ elevation: 12 }}
- TransitionComponent={CustomTransition}
- TransitionProps={{ timeout: 500 }}
+ slots={{ backdrop: CustomBackdrop, transition: CustomTransition }}
+ slotProps={{
+ backdrop: { invisible: true },
+ paper: { elevation: 12 },
+ transition: { timeout: 500 },
+ }}
/>
Use the radio-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/radio-props <path>
The following deprecated Radio props have been removed:
inputProps — use slotProps.input insteadinputRef — use slotProps.input.ref instead <Radio
- inputProps={{ 'aria-label': 'Radio' }}
- inputRef={ref}
+ slotProps={{ input: { 'aria-label': 'Radio', ref } }}
/>
Use the rating-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/rating-props <path>
The following deprecated prop has been removed:
IconContainerComponent — use slotProps.icon.component instead <Rating
- IconContainerComponent={CustomIconContainer}
+ slotProps={{ icon: { component: CustomIconContainer } }}
/>
Use the select-classes codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/select-classes <path>
The following deprecated Select CSS classes have been removed:
iconFilled → use .MuiSelect-filled ~ .MuiSelect-iconiconOutlined → use .MuiSelect-outlined ~ .MuiSelect-iconiconStandard → use .MuiSelect-standard ~ .MuiSelect-iconIf you were using these deprecated class names as styleOverrides in your theme, use sibling selectors in the root override instead:
import { selectClasses } from '@mui/material/Select';
const theme = createTheme({
components: {
MuiSelect: {
styleOverrides: {
root: {
- [`& .${selectClasses.iconFilled}`]: {
+ [`& .${selectClasses.filled} ~ .${selectClasses.icon}`]: {
color: 'red',
},
- [`& .${selectClasses.iconOutlined}`]: {
+ [`& .${selectClasses.outlined} ~ .${selectClasses.icon}`]: {
color: 'red',
},
- [`& .${selectClasses.iconStandard}`]: {
+ [`& .${selectClasses.standard} ~ .${selectClasses.icon}`]: {
color: 'red',
},
},
},
},
},
});
Use the slider-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/slider-props <path>
The following deprecated props have been removed from the Slider component:
components — use slots insteadcomponentsProps — use slotProps instead <Slider
- components={{ Track: CustomTrack }}
- componentsProps={{ track: { testid: 'test-id' } }}
+ slots={{ track: CustomTrack }}
+ slotProps={{ track: { testid: 'test-id' } }}
/>
Use the slider-classes codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/slider-classes <path>
The following deprecated classes have been removed:
thumbColorPrimary — use .MuiSlider-colorPrimary > .MuiSlider-thumb insteadthumbColorSecondary — use .MuiSlider-colorSecondary > .MuiSlider-thumb insteadthumbColorError — use .MuiSlider-colorError > .MuiSlider-thumb insteadthumbColorInfo — use .MuiSlider-colorInfo > .MuiSlider-thumb insteadthumbColorSuccess — use .MuiSlider-colorSuccess > .MuiSlider-thumb insteadthumbColorWarning — use .MuiSlider-colorWarning > .MuiSlider-thumb insteadthumbSizeSmall — use .MuiSlider-sizeSmall > .MuiSlider-thumb instead-.MuiSlider-thumbColorPrimary
+.MuiSlider-colorPrimary > .MuiSlider-thumb
-.MuiSlider-thumbColorSecondary
+.MuiSlider-colorSecondary > .MuiSlider-thumb
-.MuiSlider-thumbSizeSmall
+.MuiSlider-sizeSmall > .MuiSlider-thumb
Use the snackbar-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/snackbar-props <path>
The following deprecated Snackbar props have been removed:
ClickAwayListenerProps — use slotProps.clickAwayListener insteadContentProps — use slotProps.content insteadTransitionComponent — use slots.transition insteadTransitionProps — use slotProps.transition instead <Snackbar
- ClickAwayListenerProps={CustomClickAwayListenerProps}
- ContentProps={CustomContentProps}
- TransitionComponent={CustomTransition}
- TransitionProps={CustomTransitionProps}
+ slots={{ transition: CustomTransition }}
+ slotProps={{
+ clickAwayListener: CustomClickAwayListenerProps,
+ content: CustomContentProps,
+ transition: CustomTransitionProps,
+ }}
/>
Use the step-connector-classes codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/step-connector-classes <path>
The following deprecated StepConnector CSS classes have been removed:
lineHorizontal → use .MuiStepConnector-horizontal .MuiStepConnector-linelineVertical → use .MuiStepConnector-vertical .MuiStepConnector-lineIf you were using these deprecated class names as styleOverrides keys in your theme, use the variants array in the line override instead:
const theme = createTheme({
components: {
MuiStepConnector: {
styleOverrides: {
- lineHorizontal: { borderTopWidth: 3 },
- lineVertical: { borderLeftWidth: 3 },
+ line: {
+ variants: [
+ { props: { orientation: 'horizontal' }, style: { borderTopWidth: 3 } },
+ { props: { orientation: 'vertical' }, style: { borderLeftWidth: 3 } },
+ ],
+ },
},
},
},
});
Use the step-content-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/step-content-props <path>
The following deprecated StepContent props have been removed:
TransitionComponent → use slots.transition insteadTransitionProps → use slotProps.transition instead <StepContent
- TransitionComponent={CustomTransition}
- TransitionProps={{ unmountOnExit: true }}
+ slots={{ transition: CustomTransition }}
+ slotProps={{ transition: { unmountOnExit: true } }}
/>
Use the step-label-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/step-label-props <path>
The following deprecated StepLabel props have been removed:
componentsProps → use slotProps insteadStepIconComponent → use slots.stepIcon insteadStepIconProps → use slotProps.stepIcon instead <StepLabel
- StepIconComponent={CustomIcon}
- StepIconProps={{ error: true }}
- componentsProps={{ label: { className: 'my-label' } }}
+ slots={{ stepIcon: CustomIcon }}
+ slotProps={{ stepIcon: { error: true }, label: { className: 'my-label' } }}
/>
Use the speed-dial-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/speed-dial-props <path>
The deprecated SpeedDial props have been removed.
Use the slots and slotProps props instead:
<SpeedDial
- TransitionComponent={CustomTransition}
- TransitionProps={{ timeout: 500 }}
+ slots={{ transition: CustomTransition }}
+ slotProps={{ transition: { timeout: 500 } }}
>
Use the speed-dial-action-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/speed-dial-action-props <path>
The deprecated SpeedDialAction props have been removed.
Use the slotProps prop instead:
<SpeedDialAction
- FabProps={{ size: 'large' }}
- tooltipTitle="Add"
- tooltipPlacement="right"
- tooltipOpen
- TooltipClasses={{ tooltip: 'custom' }}
+ slotProps={{
+ fab: { size: 'large' },
+ tooltip: {
+ title: 'Add',
+ placement: 'right',
+ open: true,
+ classes: { tooltip: 'custom' },
+ },
Use the switch-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/switch-props <path>
The following deprecated Switch props have been removed:
inputProps — use slotProps.input insteadinputRef — use slotProps.input.ref instead <Switch
- inputProps={{ 'aria-label': 'Switch' }}
- inputRef={ref}
+ slotProps={{ input: { 'aria-label': 'Switch', ref } }}
/>
Use the drawer-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/drawer-props <path>
The following deprecated props have been removed from the SwipeableDrawer component:
BackdropComponent → use slots.backdropBackdropProps → use slotProps.backdropSwipeAreaProps → use slotProps.swipeArea <SwipeableDrawer
- BackdropComponent={CustomBackdrop}
- BackdropProps={{ invisible: true }}
- SwipeAreaProps={{ className: 'custom' }}
+ slots={{ backdrop: CustomBackdrop }}
+ slotProps={{ backdrop: { invisible: true }, swipeArea: { className: 'custom' } }}
/>
Use the table-pagination-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/table-pagination-props <path>
The following deprecated props have been removed:
backIconButtonProps — use slotProps.actions.previousButton insteadnextIconButtonProps — use slotProps.actions.nextButton insteadSelectProps — use slotProps.select instead <TablePagination
- backIconButtonProps={{ disabled: true }}
- nextIconButtonProps={{ disabled: true }}
- SelectProps={{ variant: 'outlined' }}
+ slotProps={{
+ actions: {
+ previousButton: { disabled: true },
+ nextButton: { disabled: true },
+ },
+ select: { variant: 'outlined' },
+ }}
/>
Use the table-sort-label-classes codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/table-sort-label-classes <path>
The following deprecated classes have been removed:
iconDirectionDesc — combine the .MuiTableSortLabel-directionDesc and .MuiTableSortLabel-icon classes insteadiconDirectionAsc — combine the .MuiTableSortLabel-directionAsc and .MuiTableSortLabel-icon classes instead-.MuiTableSortLabel-iconDirectionDesc
+.MuiTableSortLabel-directionDesc > .MuiTableSortLabel-icon
-.MuiTableSortLabel-iconDirectionAsc
+.MuiTableSortLabel-directionAsc > .MuiTableSortLabel-icon
If you were using these deprecated class names as styleOverrides keys in your theme, use the variants array in the icon override instead:
const theme = createTheme({
components: {
MuiTableSortLabel: {
styleOverrides: {
- iconDirectionDesc: { opacity: 1 },
- iconDirectionAsc: { opacity: 1 },
+ icon: {
+ variants: [
+ { props: { direction: 'desc' }, style: { opacity: 1 } },
+ { props: { direction: 'asc' }, style: { opacity: 1 } },
+ ],
+ },
},
},
},
});
Use the tabs-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/tabs-props <path>
The following deprecated props have been removed:
ScrollButtonComponent — use slots.scrollButtons insteadTabIndicatorProps — use slotProps.indicator insteadTabScrollButtonProps — use slotProps.scrollButtons insteadslots.StartScrollButtonIcon — use slots.startScrollButtonIcon insteadslots.EndScrollButtonIcon — use slots.endScrollButtonIcon instead <Tabs
- ScrollButtonComponent={CustomScrollButton}
- TabIndicatorProps={{ style: { backgroundColor: 'green' } }}
- TabScrollButtonProps={{ disableRipple: true }}
+ slots={{ scrollButtons: CustomScrollButton }}
+ slotProps={{
+ indicator: { style: { backgroundColor: 'green' } },
+ scrollButtons: { disableRipple: true },
+ }}
/>
<Tabs
- slots={{ StartScrollButtonIcon: CustomIcon, EndScrollButtonIcon: CustomIcon2 }}
+ slots={{ startScrollButtonIcon: CustomIcon, endScrollButtonIcon: CustomIcon2 }}
/>
Use the tab-classes codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/tab-classes <path>
The following deprecated class has been removed:
iconWrapper — use the icon class instead-.MuiTab-iconWrapper
+.MuiTab-icon
The following deprecated classes have been removed:
flexContainer — use the list class insteadflexContainerVertical — combine the list and vertical classes instead-.MuiTabs-flexContainer
+.MuiTabs-list
-.MuiTabs-flexContainerVertical
+.MuiTabs-list.MuiTabs-vertical
Use the toggle-button-group-classes codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/toggle-button-group-classes <path>
The following deprecated ToggleButtonGroup CSS classes have been removed:
groupedHorizontal → use .MuiToggleButtonGroup-horizontal > .MuiToggleButtonGroup-groupedgroupedVertical → use .MuiToggleButtonGroup-vertical > .MuiToggleButtonGroup-groupedIf you were using these deprecated class names as styleOverrides keys in your theme, use the variants array in the grouped override instead:
const theme = createTheme({
components: {
MuiToggleButtonGroup: {
styleOverrides: {
- groupedHorizontal: { borderRadius: 0 },
- groupedVertical: { borderRadius: 0 },
+ grouped: {
+ variants: [
+ { props: { orientation: 'horizontal' }, style: { borderRadius: 0 } },
+ { props: { orientation: 'vertical' }, style: { borderRadius: 0 } },
+ ],
+ },
},
},
},
});
Use the text-field-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/text-field-props <path>
The following deprecated props have been removed from the TextField component:
InputProps → use slotProps.inputinputProps → use slotProps.htmlInputSelectProps → use slotProps.selectInputLabelProps → use slotProps.inputLabelFormHelperTextProps → use slotProps.formHelperText <TextField
- InputProps={CustomInputProps}
- inputProps={CustomHtmlInputProps}
- SelectProps={CustomSelectProps}
- InputLabelProps={CustomInputLabelProps}
- FormHelperTextProps={CustomFormHelperTextProps}
+ slotProps={{
+ input: CustomInputProps,
+ htmlInput: CustomHtmlInputProps,
+ select: CustomSelectProps,
+ inputLabel: CustomInputLabelProps,
+ formHelperText: CustomFormHelperTextProps,
+ }}
/>
Use the autocomplete-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/autocomplete-props <path>
If you render a TextField from Autocomplete, the params shape also changed to match the new TextField API:
<Autocomplete
renderInput={(params) => (
<TextField
{...params}
- inputProps={{
- ...params.inputProps,
- autoComplete: 'new-password',
+ slotProps={{
+ ...params.slotProps,
+ htmlInput: {
+ ...params.slotProps.htmlInput,
+ autoComplete: 'new-password',
+ },
}}
/>
)}
Use the tooltip-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/tooltip-props <path>
The following deprecated props have been removed from the Tooltip component:
components → use slotscomponentsProps → use slotPropsPopperComponent → use slots.popperPopperProps → use slotProps.popperTransitionComponent → use slots.transitionTransitionProps → use slotProps.transition <Tooltip
title="Hello World"
- components={{ Popper: CustomPopper, Tooltip: CustomTooltip, Transition: CustomTransition, Arrow: CustomArrow }}
- componentsProps={{ popper: { placement: 'top' }, tooltip: { className: 'custom' }, arrow: { className: 'arrow' } }}
- PopperComponent={CustomPopper}
- PopperProps={{ disablePortal: true }}
- TransitionComponent={CustomTransition}
- TransitionProps={{ timeout: 500 }}
+ slots={{ popper: CustomPopper, tooltip: CustomTooltip, transition: CustomTransition, arrow: CustomArrow }}
+ slotProps={{
+ popper: { placement: 'top', disablePortal: true },
+ tooltip: { className: 'custom' },
+ transition: { timeout: 500 },
+ arrow: { className: 'arrow' },
+ }}
/>
The deprecated paragraph CSS class has been removed.
Use CSS .MuiTypography-root:where(p) to apply custom styles for the paragraph element instead:
-.MuiTypography-paragraph {
- margin-bottom: 16px;
-}
+.MuiTypography-root:where(p) {
+ margin-bottom: 16px;
+}
Use the typography-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest deprecations/typography-props <path>
The following deprecated props have been removed from the Typography component:
paragraph → use the sx prop to add a margin bottom instead-<Typography paragraph />
+<Typography sx={{ marginBottom: '16px' }} />
Use the system-props codemod below to migrate the code as described in the following section:
npx @mui/codemod@latest v9.0.0/system-props <path/to/folder>
Use --jsx to specify extra JSX tags to migrate, bypassing import detection:
npx @mui/codemod@latest v9.0.0/system-props <path/to/folder> -- --jsx=Box,Typography,Stack,Link,Grid,DialogContentText
This is useful if your project uses auto-import plugins (for example unplugin-auto-import) where Material UI components are available without explicit import statements.
The deprecated system props have been removed from the following components:
BoxDialogContentTextGridLinkStackTypographyTimelineContentTimelineOppositeContent-<Box mt={2} color="primary.main" />
+<Box sx={{ mt: 2, color: 'primary.main' }} />
-<DialogContentText mt={2} color="text.secondary" />
+<DialogContentText sx={{ mt: 2, color: 'text.secondary' }} />
-<Grid mt={2} mr={1} />
+<Grid sx={{ mt: 2, mr: 1 }} />
-<Link mt={2} color="text.secondary" />
+<Link sx={{ mt: 2, color: 'text.secondary' }} />
-<Stack mt={2} alignItems="center" />
+<Stack sx={{ mt: 2, alignItems: 'center' }} />
-<Typography mt={2} fontWeight="bold" />
+<Typography sx={{ mt: 2, fontWeight: 'bold' }} />
-<TimelineContent mt={2} color="text.secondary" />
+<TimelineContent sx={{ mt: 2, color: 'text.secondary' }} />
-<TimelineOppositeContent mt={2} color="text.secondary" />
+<TimelineOppositeContent sx={{ mt: 2, color: 'text.secondary' }} />
This also fixes an issue where props like color were consumed by the component instead of being forwarded to the element rendered via the component prop:
// `color` is now correctly forwarded to Button
<Grid component={Button} color="secondary" variant="contained">
hello
</Grid>