# Breaking changes in v5, part two: core components

This is a reference guide to the breaking changes introduced in Material UI v5, and how to migrating from v4. This part covers changes to components.

## Material UI v5 migration 1. [Getting started](/material-ui/migration/migration-v4/) 2. [Breaking changes part one: style and theme](/material-ui/migration/v5-style-changes/) 3. Breaking changes part two: components 👈 _you are here_ 4. [Migrating from JSS](/material-ui/migration/migrating-from-jss/) 5. [Troubleshooting](/material-ui/migration/troubleshooting/) ## Breaking changes, part two Material UI v5 introduces a number of breaking changes from v4. Many of these changes can be resolved automatically using [the codemods](/material-ui/migration/migration-v4/#run-codemods) described in the [main migration guide](/material-ui/migration/migration-v4/). The following document lists all breaking changes related to components in v5 and how to address them. If you haven't already, please be sure to review [Breaking changes in v5 part one: styles and themes](/material-ui/migration/v5-style-changes/) to continue the migration process. :::warning Breaking changes that are handled by the codemods are denoted by a ✅ emoji in the table of contents on the right side of the screen. If you have already followed the instructions in the main migration guide and run the codemods, then you should not need to take any further action on these items. All other changes must be handled manually. ::: As the core components use Emotion as their style engine, the props used by Emotion are not intercepted. The prop `as` in the following code snippet will not be propagated to `SomeOtherComponent`. ```jsx ``` ## AccordionSummary ### Rename `expandIcon` to `expandIconWrapper` This change was made to make it clearer that the element is a wrapper around the icon, not the icon itself. Update the CSS class name and the theme overrides accordingly. ```diff -'.MuiAccordionSummary-expandIcon': { +'.MuiAccordionSummary-expandIconWrapper': { ``` ```diff createTheme({ components: { MuiAccordionSummary: { styleOverrides: { - expandIcon: { + expandIconWrapper: { // ... }, }, }, }, }); ``` ## AppBar ### Fix z-index issues Remove z-index when position static and relative. This avoids the creation of a stacking context and rendering issues. ### Replace color prop for dark mode The `color` prop has no longer any effect in dark mode. The app bar uses the background color required by the elevation to follow the [Material Design guidelines](https://m2.material.io/design/color/dark-theme.html). Use `enableColorOnDark` to restore the behavior of v4. ```jsx ``` ## Alert ### ✅ Update import Move the component from the lab to the core. The component is now stable. ```diff -import Alert from '@mui/lab/Alert'; -import AlertTitle from '@mui/lab/AlertTitle'; +import Alert from '@mui/material/Alert'; +import AlertTitle from '@mui/material/AlertTitle'; ``` ## Autocomplete ### ✅ Update import Move the component from the lab to the core. The component is now stable. ```diff -import Autocomplete from '@mui/lab/Autocomplete'; -import useAutocomplete from '@mui/lab/useAutocomplete'; +import Autocomplete from '@mui/material/Autocomplete'; +import useAutocomplete from '@mui/material/useAutocomplete'; ``` ### Remove debug prop Remove `debug` prop. There are a couple of simpler alternatives: `open={true}`, Chrome devtools ["Emulate focused"](https://x.com/sulco/status/1305841873945272321), or React devtools prop setter. ### Update `renderOption` `renderOption` should now return the full DOM structure of the option. It makes customizations easier. You can recover from the change with: ```diff ( - + renderOption={(props, option, { selected }) => ( +
  • {option.title} - +
  • )} /> ``` ### ✅ Rename `closeIcon` to `clearIcon` Rename `closeIcon` prop to `clearIcon` to avoid confusion. ```diff - + ``` ### Rename reason arguments The following values of the reason argument in `onChange` and `onClose` were renamed for consistency: 1. `create-option` to `createOption` 2. `select-option` to `selectOption` 3. `remove-option` to `removeOption` Change the CSS rules that use `[data-focus="true"]` to use `.Mui-focused`. The `data-focus` attribute is not set on the focused option anymore; instead, global class names are used. ```diff -'.MuiAutocomplete-option[data-focus="true"]': { +'.MuiAutocomplete-option.Mui-focused': { ``` ### ✅ Rename getOptionSelected Rename `getOptionSelected` to `isOptionEqualToValue` to better describe its purpose. ```diff option.title === value.title} + isOptionEqualToValue={(option, value) => option.title === value.title} ``` ## Avatar ### ✅ Rename circle Rename `circle` to `circular` for consistency: ```diff - - + + ``` Since `circular` is the default value, the variant prop can be deleted: ```diff - + ``` ### ✅ Update AvatarGroup import Move the AvatarGroup from the lab to the core. ```diff -import AvatarGroup from '@mui/lab/AvatarGroup'; +import AvatarGroup from '@mui/material/AvatarGroup'; ``` ## Badge ### ✅ Rename circle and rectangle Rename `circle` to `circular` and `rectangle` to `rectangular` for consistency. ```diff - - + + ``` ```diff ``` ## BottomNavigation ### Update event type (TypeScript) The `event` in `onChange` is now typed as a `React.SyntheticEvent` instead of a `React.ChangeEvent`. ```diff -) => {}} /> + {}} /> ``` ## BottomNavigationAction ### Remove span and wrapper Remove the `span` element that wraps the children. Remove the `wrapper` classKey too. You can find out more details about this change in [this GitHub pull request](https://github.com/mui/material-ui/pull/26923). ```diff ``` ## Box ### ✅ Update borderRadius prop value The `borderRadius` system prop value transformation has been changed. If it receives a number, it multiplies this value with the `theme.shape.borderRadius` value. Use a string to provide an explicit px value. ```diff - + ``` ```diff - + ``` ### ✅ Apply sx API The Box system props have an optional alternative API in v5, using the `sx` prop. Check out MUI System docs to learn more about [the tradeoffs of this API](/system/getting-started/usage/#api-tradeoff). ```jsx ``` ### ✅ Rename CSS properties The following properties have been renamed because they are considered deprecated CSS properties by the CSS specification: 1. `gridGap` to `gap` 2. `gridColumnGap` to `columnGap` 3. `gridRowGap` to `rowGap` ```diff - - - + + + ``` :::info The system grid function was not documented in v4. ::: ### Remove clone prop The `clone` prop was removed because its behavior can be obtained by applying the `sx` prop directly to the child if it is a Material UI component. ```diff - - - + ``` ### Replace render prop with `sx` The ability to pass a render prop was removed because its behavior can be obtained by applying the `sx` prop directly to the child if it is a Material UI component. ```diff - - {(props) => } - + ``` For non-Material UI components, use the `component` prop. ```diff - - {(props) => } - +Save ``` ## Button ### ✅ Remove default color prop The button `color` prop is now "primary" by default, and "default" has been removed. This makes the button closer to the Material Design guidelines and simplifies the API. ```diff - ``` ## Chip ### ✅ Rename default to filled Rename `default` variant to `filled` for consistency. Since `filled` is the default value, the variant prop can be deleted: ```diff - + ``` ## Checkbox ### Set to "primary" by default The checkbox color prop is now "primary" by default. To continue using the "secondary" color, you must explicitly indicate `secondary`. This brings the checkbox closer to the Material Design guidelines. ```diff - + ``` ### Update CSS class names The component doesn't have `.MuiIconButton-root` and `.MuiIconButton-label` class names anymore. Target `.MuiButtonBase-root` instead. ```diff - - - + + ``` ## CircularProgress ### ✅ Rename static to determinate The `static` variant has been renamed to `determinate`, and the previous appearance of `determinate` has been replaced by that of `static`. This was an exception to Material Design, and was removed from the specification. ```diff - + ``` :::error If you had previously customized `determinate`, then your customizations are most likely no longer valid. Please remove them. ::: ## Collapse ### ✅ Rename collapsedHeight prop The `collapsedHeight` prop was renamed `collapsedSize` to support the horizontal direction. ```diff - + ``` The `classes.container` key was changed to match the convention of the other components. ```diff - + ``` ## CssBaseline ### Update styled-engine The component was migrated to use the `@mui/styled-engine` (`emotion` or `styled-components`) instead of `jss`. You should remove the `@global` key when defining the style overrides for it. You could also start using the CSS template syntax over the JavaScript object syntax. ```diff const theme = createTheme({ components: { MuiCssBaseline: { - styleOverrides: { - '@global': { - html: { - WebkitFontSmoothing: 'auto', - }, - }, - }, + styleOverrides: ` + html { + -webkit-font-smoothing: auto; + } + ` }, }, }); ``` ### Update body font size The `body` font size has changed from `theme.typography.body2` (`0.875rem`) to `theme.typography.body1` (`1rem`). To return to the previous size, you can override it in the theme: ```js const theme = createMuiTheme({ components: { MuiCssBaseline: { styleOverrides: { body: { fontSize: '0.875rem', lineHeight: 1.43, letterSpacing: '0.01071em', }, }, }, }, }); ``` ## Dialog ### ✅ Update transition props The `on*` transition props were removed. Use `TransitionProps` instead. ```diff ``` ### ✅ Remove disableBackdropClick prop Remove the `disableBackdropClick` prop because it is redundant. Ignore close events from `onClose` when `reason === 'backdropClick'` instead. ```diff { + if (reason !== 'backdropClick') { + handleClose(event, reason); + } + }} /> ``` ### Remove withMobileDialog component Remove the `withMobileDialog` higher-order component. :::warning This is handled in the [preset-safe codemod](#preset-safe) by applying hard-coded function to prevent application crash, but further fixes are required. ::: The hook API allows a simpler and more flexible solution: ```diff -import withMobileDialog from '@mui/material/withMobileDialog'; +import { useTheme, useMediaQuery } from '@mui/material'; function ResponsiveDialog(props) { - const { fullScreen } = props; + const theme = useTheme(); + const fullScreen = useMediaQuery(theme.breakpoints.down('sm')); const [open, setOpen] = React.useState(false); // ... -export default withMobileDialog()(ResponsiveDialog); +export default ResponsiveDialog; ``` ### ✅ Remove disableTypography prop Flatten DialogTitle DOM structure and remove the `disableTypography` prop. ```diff - - + + My header ``` ## Divider ### Replace background-color with border-color Use `border-color` instead of `background-color`. This prevents inconsistent height on scaled screens. If you have customized the color of the border, you will need to update the CSS property override: ```diff .MuiDivider-root { - background-color: #f00; + border-color: #f00; } ``` ### Support "middle" variant with "vertical" orientation In v4, using `orientation="vertical"` and `variant="middle"` was adding a left and right margins of `16px` in the component. In the v5, to avoid fixed spacing on the component, this margin was removed. :::info If you want to use the previous margin values, this change can be made in your theme with the following code. See the example on [CodeSandbox demo](https://codesandbox.io/p/sandbox/v5-migration-vertical-alignment-middle-divider-45vepj?file=/src/index.tsx). ::: ```diff const theme = createTheme({ components: { MuiDivider: { + styleOverrides: { + root: ({ ownerState, theme }) => ({ + ...(ownerState.orientation === 'vertical' && ownerState.variant === 'middle' && { + marginLeft: theme.spacing(2), + marginRight: theme.spacing(2), + }), + }) + } }, }, }); ``` ## ExpansionPanel ### ✅ Rename components Rename the `ExpansionPanel` components to `Accordion` to use a more common naming convention: ```diff -import ExpansionPanel from '@mui/material/ExpansionPanel'; -import ExpansionPanelSummary from '@mui/material/ExpansionPanelSummary'; -import ExpansionPanelDetails from '@mui/material/ExpansionPanelDetails'; -import ExpansionPanelActions from '@mui/material/ExpansionPanelActions'; +import Accordion from '@mui/material/Accordion'; +import AccordionSummary from '@mui/material/AccordionSummary'; +import AccordionDetails from '@mui/material/AccordionDetails'; +import AccordionActions from '@mui/material/AccordionActions'; - + - + Location Select trip destination - + - + {}} /> Select your destination of choice - + - + - + - + ``` ### Update event type (TypeScript) The `event` in `onChange` is now typed as a `React.SyntheticEvent` instead of a `React.ChangeEvent`. ```diff -, expanded: boolean) => {}} /> + {}} /> ``` ## ExpansionPanelDetails ### Remove display: flex Remove `display: flex` from `AccordionDetails` (formerly `ExpansionPanelDetails`) as it was too opinionated—most developers expect `display: block`. ## ExpansionPanelSummary ### Rename focused to focusVisible Rename `focused` to `focusVisible` for consistency: ```diff ``` ### Remove IconButtonProps prop Remove `IconButtonProps` prop from `AccordionSummary` (formerly `ExpansionPanelSummary`). The component renders a `
    ` element instead of an `IconButton`, so the prop is no longer necessary. ## Fab ### ✅ Rename round to circular ```diff - + ``` ### Remove span and label The `span` element that wraps children has been removed. The `label` classKey is also removed. You can find out more details about this change in [this GitHub pull request](https://github.com/mui/material-ui/pull/27112), it used to be necessary for iOS. ```diff ``` ## FormControl ### ✅ Update default variant Change the default variant from `standard` to `outlined`. `standard` has been removed from the Material Design guidelines. :::success This is handled in [variant-prop codemod](#variant-prop)—read the details before running this codemod. ::: ```diff - - + + ``` ## FormControlLabel ### Add required label prop The `label` prop is now required. If you were using a `FormControlLabel` without a `label`, you can replace it with just the value of the `control` prop. ```diff -} /> + ``` ## Grid ### ✅ Rename justify prop Rename the `justify` prop to `justifyContent` to align with the CSS property name. ```diff - + ``` ### ✅ Remove align and justify props and classes The props `alignItems`, `alignContent`, and `justifyContent`—along with their classes and style overrides keys—have been removed: "align-items-xs-center", "align-items-xs-flex-start", "align-items-xs-flex-end", "align-items-xs-baseline", "align-content-xs-center", "align-content-xs-flex-start", "align-content-xs-flex-end", "align-content-xs-space-between", "align-content-xs-space-around", "justify-content-xs-center", "justify-content-xs-flex-end", "justify-content-xs-space-between", "justify-content-xs-space-around" and "justify-content-xs-space-evenly". These props are now considered part of MUI System, not the `Grid` component itself. If you still wish to add overrides for them, you can use the [callback as a value in `styleOverrides`](https://v5.mui.com/material-ui/customization/theme-components/#overrides-based-on-props). ```diff const theme = createTheme({ components: { MuiGrid: { - styleOverrides: { - 'align-items-xs-flex-end': { - marginTop: 20, - }, - }, + styleOverrides: ({ ownerState }) => ({ + ...ownerState.alignItems === 'flex-end' && { + marginTop: 20, + }, + }), }, }, }); ``` ### Change negative margins The negative margins apply only to the top and left sides of the grid container. If you need negative margins on all sides, we recommend using the new Grid v2 instead: ```diff - import Grid from '@mui/material/Grid'; + import Grid from '@mui/material/Grid2'; ``` To learn more about Grid2, check out the [Grid2 component doc](/material-ui/react-grid/) and the [upgrade guide](/material-ui/migration/upgrade-to-grid-v2/). :::info Grid2 was introduced in Material UI v5.9.1 and features negative margins on all sides by default. ::: ## GridList ### ✅ Rename GridList component Rename the `GridList` components to `ImageList` to align with the current Material Design naming. ### Rename GridList props - Rename the GridList `spacing` prop to `gap` to align with the CSS attribute. - Rename the GridList `cellHeight` prop to `rowHeight`. - Add the `variant` prop to GridList. - Rename the GridListItemBar `actionPosition` prop to `position`. (Note also the related classname changes.) ### Use CSS object-fit Use CSS `object-fit`. For IE 11 support either use a polyfill such as [this npm package](https://www.npmjs.com/package/object-fit-images), or else continue to use the v4 component. ```diff -import GridList from '@mui/material/GridList'; -import GridListTile from '@mui/material/GridListTile'; -import GridListTileBar from '@mui/material/GridListTileBar'; +import ImageList from '@mui/material/ImageList'; +import ImageListItem from '@mui/material/ImageListItem'; +import ImageListItemBar from '@mui/material/ImageListItemBar'; - - + + Image title - - - + + ``` ## Hidden ### Replace deprecated component This component is deprecated because its functionality can be created with the [`sx`](/system/getting-started/the-sx-prop/) prop or the [`useMediaQuery`](/material-ui/react-use-media-query/) hook. :::success This is handled in the [preset-safe codemod](#preset-safe) by applying fake `Hidden` component to prevent application crash, but further fixes are required. ::: Use the `sx` prop to replace `implementation="css"`: ```diff - - ``` ## Link ### ✅ Update default underline prop The default `underline` prop is changed from `"hover"` to `"always"`. To recreate the behavior from v4, apply `defaultProps` in the theme. :::success This is handled in [link-underline-hover codemod](#link-underline-hover)—read the details before running this codemod. ::: ```js createTheme({ components: { MuiLink: { defaultProps: { underline: 'hover', }, }, }, }); ``` ## Menu ### ✅ Update transition props The `on*` transition props were removed. Use `TransitionProps` instead. ```diff ``` :::info The `selectedMenu` variant will no longer vertically align the selected item with the anchor. ::: ### Change default anchorOrigin.vertical value Change the default value of `anchorOrigin.vertical` to follow the Material Design guidelines. The menu is now displayed below the anchor instead of on top of it. You can restore the previous behavior with: ```diff +
  • ``` ### Replace listItemClasses prop prop `listItemClasses` is removed, use `classes` instead. ```diff - + ``` Read more about the [MenuItem CSS API](/material-ui/api/menu-item/#classes). ## Modal ### ✅ Remove disableBackdropClick prop Remove the `disableBackdropClick` prop because it is redundant. Use `onClose` with `reason === 'backdropClick'` instead. ```diff { + if (reason !== 'backdropClick') { + handleClose(event, reason); + } + }} /> ``` ### ✅ Remove `onEscapeKeyDown` prop Remove the `onEscapeKeyDown` prop because it is redundant. Use `onClose` with `reason === "escapeKeyDown"` instead. ```diff { + if (reason === 'escapeKeyDown') { + handleEscapeKeyDown(event); + } + }} /> ``` ### Remove `onRendered` prop Remove the `onRendered` prop. Depending on your use case, you can either use a [callback ref](https://react.dev/learn/manipulating-the-dom-with-refs#how-to-manage-a-list-of-refs-using-a-ref-callback) on the child element, or an effect hook in the child component. ## NativeSelect ### Remove selectMenu slot Merge the `selectMenu` slot into `select`. The `selectMenu` slot was redundant. The `root` slot is no longer applied to the select, but to the root. ```diff - + ``` ## OutlinedInput ### Replace labelWidth prop Remove the `labelWidth` prop. The `label` prop now fulfills the same purpose, using CSS layout instead of JavaScript measurement to render the gap in the outlined. ```diff - + ``` ## Paper ### Change dark mode background opacity Change the background opacity based on the elevation in dark mode. This change was made to better conform to the Material Design guidelines. You can revert it in the theme: ```diff const theme = createTheme({ components: { MuiPaper: { + styleOverrides: { root: { backgroundImage: 'unset' } }, }, }, }); ``` ## Pagination ### ✅ Update import Move the component from the lab to the core. The component is now stable. ```diff -import Pagination from '@mui/lab/Pagination'; -import PaginationItem from '@mui/lab/PaginationItem'; -import { usePagination } from '@mui/lab/Pagination'; +import Pagination from '@mui/material/Pagination'; +import PaginationItem from '@mui/material/PaginationItem'; +import usePagination from '@mui/material/usePagination'; ``` ### ✅ Rename round to circular ```diff - - + + ``` ## Popover ### ✅ Update transition props The `on*` transition props were removed. Use `TransitionProps` instead. ```diff ``` ### Remove getContentAnchorEl prop The `getContentAnchorEl` prop was removed to simplify the positioning logic. ## Popper ### Upgrade from v1 to v2 Upgrade [Popper.js](https://popper.js.org/) from v1 to v2. The CSS prefixes have changed: ```diff popper: { zIndex: 1, - '&[x-placement*="bottom"] .arrow': { + '&[data-popper-placement*="bottom"] .arrow': { ``` Method names have changed: ```diff -popperRef.current.scheduleUpdate() +popperRef.current.update() ``` ```diff -popperRef.current.update() +popperRef.current.forceUpdate() ``` The Modifiers API has been changed too significantly to fully cover here. Read the [Popper.js migration guide](https://popper.js.org/docs/v2/migration-guide/) for complete details. ## Portal ### Remove onRendered prop Remove the `onRendered` prop. Depending on your use case, you can either use a [callback ref](https://react.dev/learn/manipulating-the-dom-with-refs#how-to-manage-a-list-of-refs-using-a-ref-callback) on the child element, or an effect hook in the child component. ## Radio ### Update default color prop The radio color prop is now "primary" by default. To continue using the "secondary" color, you must explicitly indicate `secondary`. This brings the radio closer to the Material Design guidelines. ```diff - + ``` ### Update CSS classes This component no longer has the class names `.MuiIconButton-root` or `.MuiIconButton-label`. Instead, target `.MuiButtonBase-root`. ```diff - - - + + ``` ## Rating ### ✅ Update imports Move the component from the lab to the core. The component is now stable. ```diff -import Rating from '@mui/lab/Rating'; +import Rating from '@mui/material/Rating'; ``` ### Change default empty icon Change the default empty icon to improve accessibility. If you have a custom `icon` prop but no `emptyIcon` prop, you can restore the previous behavior with: ```diff ``` ### Rename visuallyhidden Rename `visuallyhidden` to `visuallyHidden` for consistency: ```diff ``` ## RootRef ### Remove component This component has been removed. You can get a reference to the underlying DOM node of our components via `ref` prop. The component relied on [`ReactDOM.findDOMNode`](https://legacy.reactjs.org/docs/react-dom.html#finddomnode) which is [deprecated in `React.StrictMode`](https://react.dev/reference/react/StrictMode#warning-about-deprecated-finddomnode-usage). :::success This is handled in the [preset-safe codemod](#preset-safe) by applying fake `RootRef` component to prevent application crash, but further fixes are required. ::: ```diff - -