v9로 업그레이드하기

v9로 업그레이드하기 (Upgrade to v9)

이 가이드는 Material UI v7에서 v9로 업그레이드하는 방법을 설명합니다.

출처: 문서

본문

이 가이드에서는 Material UI v7에서 v9로 업그레이드하는 방법을 설명할게요.

왜 Material UI v9로 업그레이드해야 하나요

개선된 접근성과 플랫폼 정렬 (Improved accessibility and platform alignment)

Material UI v9는 핵심 컴포넌트의 접근성과 시맨틱을 계속 개선합니다. 이번 릴리스에는 키보드 내비게이션, 포커스 관리, DOM 구조에 대한 업데이트가 포함되어, 컴포넌트가 웹 플랫폼, 접근성 기대치, 현대 보조 기술 동작에 더 가깝게 정렬됩니다.

삶의 질 개선 (Quality-of-life improvements)

Material UI v9에는 다음과 같은 여러 삶의 질 개선 사항도 포함됩니다.

  • API 표면을 줄이고 문서 탐색을 쉽게 하기 위한 deprecated API 제거
  • slot과 slotProps API 전반의 일관성 개선
  • 현대 브라우저 환경을 위한 더 나은 기본값과 동작

이 패키지들 중 하나라도 사용 중이라면 호환되는 v9 버전으로 함께 업데이트해야 합니다.

  • @mui/icons-material을 9.0.0으로
  • @mui/system을 9.0.0으로
  • @mui/lab을 최신 v9 베타 릴리스로
  • @mui/material-nextjs를 9.0.0으로
  • @mui/styled-engine을 9.0.0으로
  • @mui/styled-engine-sc를 9.0.0으로
  • @mui/utils를 9.0.0으로

지원 브라우저와 버전 (Supported browsers and versions)

기본 번들 타깃이 v9에서 변경되었습니다.

  • Chrome 117 (109에서 상향)
  • Edge 121
  • Firefox 121 (115에서 상향)
  • macOS와 iOS 모두에서 Safari 17.0 (15.4에서 상향)
  • 그 외 더 있음 (.browserslistrc stable 항목 참고)

Breaking changes

v9는 새로운 메이저 릴리스이므로 공개 API에 영향을 주는 변경이 몇 가지 포함되어 있습니다. Material UI v7에서 v9로 마이그레이션할 때 취해야 할 단계는 아래에 설명되어 있어요.

Autocomplete

오른쪽 클릭 시 Listbox 토글 (Listbox toggle on right click)

입력 필드에서 오른쪽 클릭을 사용할 때 더 이상 listbox가 토글되지 않습니다. 왼쪽 클릭 토글 동작은 그대로입니다.

freeSolo 타입 관련 변경 (freeSolo type related changes)

freeSolo가 true일 때:

  • getOptionLabel prop은 option 인자로 string을 받습니다.
  • isOptionEqualToValue prop은 value 인자로 string을 받습니다.
- 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;

참고로:

type AutocompleteFreeSoloValueMapping<FreeSolo> = FreeSolo extends true
  ? string
  : never;

type AutocompleteValueOrFreeSoloValueMapping<Value, FreeSolo> = FreeSolo extends true
  ? Value | string
  : Value;

Backdrop

Backdrop 컴포넌트는 더 이상 기본적으로 Root 슬롯에 aria-hidden="true" 속성을 추가하지 않습니다.

ButtonBase

Enter와 Spacebar에서의 클릭 이벤트 전파 (Click event propagation from Enter and Spacebar)

ButtonBase 또는 ButtonBase로 구성된 컴포넌트에서 Enter와 Spacebar 키를 보내면 클릭 이벤트가 이제 상위(ancestor) 요소로 버블링됩니다.

또한 onClick prop에 전달되는 event는 ButtonBase의 키보드 핸들러에서 캡처된 KeyboardEvent 대신 MouseEvent입니다. 이는 기대되는 동작과 일치합니다.

비활성 비-네이티브 버튼에서의 이벤트 핸들러 (Event handlers on disabled non-native buttons)

ButtonBase가 <span> 같은 비-네이티브 요소를 렌더링할 때, 컴포넌트가 비활성 상태이면 키보드와 클릭 이벤트 핸들러가 더 이상 실행되지 않습니다.

네이티브 버튼 요소를 비-상호작용 요소로 대체 (Replacing native button elements with non-interactive elements)

nativeButton prop은 <ButtonBase>와 모든 버튼형 컴포넌트에서 사용할 수 있습니다. 서버 사이드 렌더링 시점처럼 hydration 전에 올바른 HTML 속성으로 렌더링되도록 보장하기 위해서예요.

이 prop은 버튼형 컴포넌트의 component prop에 기본 렌더 요소를 대체하는 React 컴포넌트를 전달할 때 지정해야 합니다:

  • 네이티브 <button>에서 <div> 같은 비-상호작용 요소로, 또는
  • <div> 같은 비-버튼에서 네이티브 <button>으로
const CustomButton = React.forwardRef(function CustomButton(props, ref) {
  return <div ref={ref} {...props} />;
})

<Button component={CustomButton} nativeButton={false}>
  OK
</Button>

nativeButton prop을 잘못 생략하거나, 결정된 요소가 prop의 값과 일치하지 않으면 개발 모드에서 경고가 표시됩니다.

이 prop은 <ButtonBase>, <Button>, <Fab>, <IconButton>, <ListItemButton>, <MenuItem>, <StepButton>, <Tab>, <ToggleButton>, <AccordionSummary>, <BottomNavigationAction>, <CardActionArea>, <TableSortLabel> 그리고 <PaginationItem>에 사용할 수 있습니다.

Dialog와 Modal

disableEscapeKeyDown prop이 제거되었습니다. 같은 동작은 onClose에서 reason 인자의 값을 확인해 구현할 수 있습니다.

  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>
  );

Modal에도 동일하게 적용됩니다.

GridLegacy

GridLegacy 컴포넌트는 제거되었습니다. 대신 Grid 컴포넌트를 사용하세요.

주요 API 차이는 다음과 같습니다.

  • item prop이 더 이상 필요하지 않습니다.
  • xs, sm, md, lg, xl prop이 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>

자세한 내용은 Grid v2 마이그레이션 가이드를 참고하세요.

MuiGridLegacy도 테마 components 타입(ComponentsProps, ComponentsOverrides, ComponentsVariants)에서 제거되었습니다.

Grid

direction="column"과 direction="column-reverse" 제거

Grid 컴포넌트는 더 이상 direction="column" 또는 direction="column-reverse"를 허용하지 않습니다. 이 값들은 이전 버전에서 사실상 지원되지 않았으며, 이제 TypeScript 타입과 prop 검증에서 제거되었습니다.

Grid는 레이아웃을 **열(columns)**로 세분화하도록 설계되었지, 행(rows)이 아닙니다. 세로로 쌓아야 한다면(필요 시 Grid 아이템 안에서도) Stack 컴포넌트를 사용하세요. 자세한 내용은 Grid 열 방향 제한을 참고하세요.

-import Grid from '@mui/material/Grid';
+import Stack from '@mui/material/Stack';

-<Grid container direction="column" spacing={2}>
-  <Grid size={12}>First item</Grid>
-  <Grid size={12}>Second item</Grid>
-</Grid>
+<Stack spacing={2}>
+  <div>First item</div>
+  <div>Second item</div>
+</Stack>

여전히 가로 열 세분화가 필요하다면, direction="row"(기본값) 또는 direction="row-reverse"인 Grid를 계속 사용하세요.

List

ListItemIcon의 기본 최소 너비가 메뉴 아이템과 일치하도록 36px로 변경되었습니다(이전에는 56px). 이제 하드코딩된 숫자 대신 theme.spacing을 사용합니다.

Material Icons

Outline("d" 없이)으로 끝나는 23개의 레거시 아이콘 export가 제거되었습니다. 이들은 각각의 Outlined 대응물과 정확히 중복이었습니다(예: InfoOutline은 InfoOutlined과 같은 SVG를 가졌습니다).

마이그레이션하려면 import를 Outlined 접미사를 사용하도록 이름을 바꾸세요.

-import InfoOutlineIcon from '@mui/icons-material/InfoOutline';
+import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined';

제거된 export 전체 목록: AddCircleOutline, ChatBubbleOutline, CheckCircleOutline, DeleteOutline, DoneOutline, DriveFileMoveOutline, ErrorOutline, HelpOutline, InfoOutline, LabelImportantOutline, LightbulbOutline, LockOutline, MailOutline, ModeEditOutline, PauseCircleOutline, PeopleOutline, PersonOutline, PieChartOutline, PlayCircleOutline, RemoveCircleOutline, StarOutline, WorkOutline, WorkspacesOutline.

이 아이콘들의 테마 변형(예: InfoOutlineRounded, DeleteOutlineSharp)은 영향을 받지 않으며 계속 사용할 수 있습니다.

variant="selectedMenu"를 사용할 때, 각 메뉴 아이템의 tabindex 속성이 Arrow Key, Home / End 또는 Character Key 내비게이션에 따라 변경됩니다. 이전에는 키보드 내비게이션이 포커스된 아이템의 tabindex를 업데이트하지 않고 DOM 포커스만 이동시켰습니다. 이제는 DOM 포커스를 이동하고 포커스된 요소에 tabindex="0"도 추가합니다. 이전에 포커스되었던 요소는 tabindex가 -1로 업데이트되어 한 번에 하나의 MenuItem만 포커스 가능하게 유지됩니다.

이 변경은 variant="selectedMenu"인 Menu와 MenuList 양쪽에 적용됩니다.

MenuList의 autoFocus prop은 더 이상 List 컴포넌트에 tabindex="0"을 설정하지 않습니다. 항상 -1로 유지됩니다.

MenuItem은 Menu 또는 MenuList 밖에서 렌더링되면 오류를 던집니다.

키보드 내비게이션은 이제 React.Fragment 안의 MenuItem을 지원합니다.

ListSubheader나 Divider 같은 커스텀 비-상호작용 메뉴 콘텐츠는 더 이상 메뉴의 포커스 관리에서 제외하기 위해 muiSkipListHighlight를 설정할 필요가 없습니다.

role="menuitem"을 설정하지만 MenuItem 컴포넌트를 감싸지 않는 커스텀 자식 요소는 Menu 또는 MenuList 안에서 더 이상 지원되지 않습니다.

Slider

Slider 컴포넌트는 마우스 이벤트 대신 포인터 이벤트를 사용합니다. 이전에는 onMouseDown={(event) => event.preventDefault()}가 드래그 시작을 취소했습니다. 이제는 onPointerDown을 대신 사용해야 합니다.

Stepper, Step와 StepButton

Stepper와 Step의 마크업이 시맨틱을 개선하기 위해 변경되었습니다.

  • Stepper는 <div> 대신 <ol> 요소를 반환합니다.
  • Step은 <div> 대신 <li> 요소를 반환합니다.

Stepper 컴포넌트는 이제 StepButton 후손과 함께 사용될 때 키보드 내비게이션을 지원합니다. 내비게이션은 roving tabindex로 구현되며, Arrow Keys와 Home, End를 지원합니다. tabindex="0"을 가진 하나의 StepButton만 포커스 가능하고 나머지는 모두 tabindex="-1"입니다. Arrow Keys나 Home / End로 선택이 변경되면 tabindex 값도 함께 업데이트됩니다.

StepButton 후손이 있는 Stepper의 마크업은 이 동작을 반영하기 위해 더 변경되었습니다. 이 변경은 위에서 설명한 태그 변경 위에 적용됩니다.

이제 Stepper는:

  • tablist의 role을 가집니다.
  • aria-orientation이 추가됩니다. 값은 orientation prop에 따라 horizontal 또는 vertical입니다.

StepButton은:

  • tab의 role을 가집니다.
  • aria-current가 aria-selected로 변경됩니다. 스텝이 선택되면 값이 true, 아니면 false입니다.
  • aria-setsize가 추가됩니다. 값은 전체 스텝 수입니다.
  • aria-posinset이 추가됩니다. 값은 리스트 안의 스텝 인덱스로 1부터 시작합니다.

TablePagination 숫자는 기본적으로 포맷됩니다

TablePagination의 페이지네이션 숫자는 이제 로캘에 따라 Intl.NumberFormat을 사용해 포맷됩니다. 예를 들어 103177은 en-US에서는 103,177로, de-DE에서는 103.177로 표시됩니다.

숫자 포맷을 해제하려면 커스텀 labelDisplayedRows 함수를 제공하세요.

<TablePagination
  labelDisplayedRows={({ from, to, count }) =>
    `${from}–${to} of ${count !== -1 ? count : `more than ${to}`}`
  }
/>

또는 로캘을 사용할 때:

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}`}`,
        },
      },
    },
  },
);

Tabs

각 탭의 tabindex 속성이 Arrow Key 또는 Home / End 내비게이션 시 변경됩니다. 이전에는 키보드 내비게이션이 포커스된 Tab의 tabindex를 업데이트하지 않고 DOM 포커스를 이동시켰습니다. 이제는 DOM 포커스를 이동하고 포커스된 Tab에 tabindex="0"도 추가합니다. 다른 탭들은 tabindex="-1"을 가져 한 번에 하나의 Tab만 포커스 가능하게 유지됩니다.

Tab을 선택하면 이전과 같이 포커스와 tabindex가 업데이트됩니다.

Tabs 밖에 배치된 Tab은 이제 오류를 던집니다.

TextField

<TextField select />를 지정해 <Select>를 렌더링하면, 내부 <InputLabel>이 네이티브 <label> 요소 대신 <div>를 렌더링합니다. 이는 <InputLabel> 단독 사용에는 영향을 주지 않습니다.

Theme

MuiTouchRipple이 테마 components 타입(ComponentsProps, ComponentsOverrides, ComponentsVariants)에서 제거되었습니다. TouchRipple은 v5부터 내부 컴포넌트였고 테마 오버라이드나 기본 props를 소비한 적이 없으므로, 해당 타입들은 오해를 불러일으키는 것이었습니다.

테마에서 MuiTouchRipple을 사용하고 있었다면 제거하고, MuiTouchRipple-* 클래스 이름을 사용한 전역 CSS로 대체하세요.

 const theme = createTheme({
   components: {
-    MuiTouchRipple: {
-      styleOverrides: {
-        root: { color: 'red' },
-      },
-    },
+    MuiButtonBase: {
+      styleOverrides: {
+        root: {
+          '& .MuiTouchRipple-root': { color: 'red' },
+        },
+      },
+    },
   },
 });

jsdom 지원

테스트 환경에서 컴포넌트의 동작이 더 안정적으로 개선되었습니다. process.env.NODE_ENV === 'test' 사용은 코드의 의도를 더 정확히 반영하는 곳마다 feature detection 또는 user-agent sniffing으로 대체되었습니다. 이 변경은 대부분의 사용자에게 영향을 주지 않지만, 의도치 않은 CI 변경을 초래할 수는 있습니다. 예를 들어 jsdom과 happy-dom처럼 레이아웃을 지원하지 않는 DOM 환경을 user-agent sniffing으로 자동 감지하도록 코드가 업데이트되었습니다.

제거된 Deprecated API (Breaking)

이전에 deprecated 처리되었던 API들이 v9에서 제거되었습니다.

Accordion props

아래 accordion-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/accordion-props <path>

다음 deprecated props가 Accordion 컴포넌트에서 제거되었습니다.

  • TransitionComponent → slots.transition 사용
  • TransitionProps → slotProps.transition 사용
 <Accordion
-  TransitionComponent={CustomTransition}
-  TransitionProps={{ unmountOnExit: true }}
+  slots={{ transition: CustomTransition }}
+  slotProps={{ transition: { unmountOnExit: true } }}
 >

AccordionSummary CSS 클래스

아래 accordion-summary-classes codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/accordion-summary-classes <path>

deprecated AccordionSummary CSS 클래스 contentGutters가 제거되었습니다. 대신 .MuiAccordionSummary-gutters와 .MuiAccordionSummary-content 클래스의 조합을 사용하세요.

-.MuiAccordionSummary-contentGutters {
+.MuiAccordionSummary-gutters .MuiAccordionSummary-content {
   margin: 20px 0;
 }

Alert CSS 클래스

아래 alert-classes codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/alert-classes <path>

다음 deprecated Alert CSS 클래스들이 제거되었습니다.

  • standardSuccess → .MuiAlert-standard.MuiAlert-colorSuccess 사용
  • standardInfo → .MuiAlert-standard.MuiAlert-colorInfo 사용
  • standardWarning → .MuiAlert-standard.MuiAlert-colorWarning 사용
  • standardError → .MuiAlert-standard.MuiAlert-colorError 사용
  • outlinedSuccess → .MuiAlert-outlined.MuiAlert-colorSuccess 사용
  • outlinedInfo → .MuiAlert-outlined.MuiAlert-colorInfo 사용
  • outlinedWarning → .MuiAlert-outlined.MuiAlert-colorWarning 사용
  • outlinedError → .MuiAlert-outlined.MuiAlert-colorError 사용
  • filledSuccess → .MuiAlert-filled.MuiAlert-colorSuccess 사용
  • filledInfo → .MuiAlert-filled.MuiAlert-colorInfo 사용
  • filledWarning → .MuiAlert-filled.MuiAlert-colorWarning 사용
  • filledError → .MuiAlert-filled.MuiAlert-colorError 사용

테마에서 이러한 deprecated 클래스 이름을 styleOverrides 키로 사용하고 있었다면, root 오버라이드 안의 variants 배열을 사용하세요.

 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' } },
+          ],
+        },
       },
     },
   },
 });

Alert props

아래 alert-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/alert-props <path>

다음 deprecated props가 Alert 컴포넌트에서 제거되었습니다.

  • components → slots 사용
  • componentsProps → 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' } }}
 />

Avatar props

아래 avatar-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/avatar-props <path>

다음 deprecated prop이 Avatar 컴포넌트에서 제거되었습니다.

  • imgProps → slotProps.img 사용
-<Avatar imgProps={{ crossOrigin: 'anonymous', referrerPolicy: 'no-referrer' }} />
+<Avatar slotProps={{ img: { crossOrigin: 'anonymous', referrerPolicy: 'no-referrer' } }} />

AvatarGroup props

아래 avatar-group-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/avatar-group-props <path>

다음 deprecated props가 AvatarGroup 컴포넌트에서 제거되었습니다.

  • componentsProps → slotProps 사용 (additionalAvatar 키는 surplus로 이름이 바뀌었습니다)
-<AvatarGroup componentsProps={{ additionalAvatar: { className: 'my-class' } }}>
+<AvatarGroup slotProps={{ surplus: { className: 'my-class' } }}>

이미 componentsProps를 통해 surplus 키를 사용하고 있었다면 slotProps로 옮기세요.

-<AvatarGroup componentsProps={{ surplus: { className: 'my-class' } }}>
+<AvatarGroup slotProps={{ surplus: { className: 'my-class' } }}>

Autocomplete props

아래 autocomplete-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/autocomplete-props <path>

다음 deprecated props가 Autocomplete 컴포넌트에서 제거되었습니다.

  • ChipProps → slotProps.chip 사용
  • componentsProps → slotProps 사용
  • ListboxComponent → slots.listbox 사용
  • ListboxProps → slotProps.listbox 사용
  • PaperComponent → slots.paper 사용
  • PopperComponent → slots.popper 사용
  • renderTags → 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 })} />
+    ))
+  }
 />

useAutocomplete 필드

아래 autocomplete-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/autocomplete-props <path>

다음 deprecated 멤버들이 useAutocomplete 훅 반환 값에서 제거되었습니다.

  • getTagProps → getItemProps 사용
  • focusedTag → focusedItem 사용

getTagProps

 const {
-  getTagProps,
+  getItemProps,
 } = useAutocomplete(props);

 // ...
-<Chip {...getTagProps({ index })} />
+<Chip {...getItemProps({ index })} />

focusedTag

 const {
-  focusedTag,
+  focusedItem,
 } = useAutocomplete(props);

Backdrop props

아래 backdrop-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/backdrop-props <path>

다음 deprecated Backdrop props가 제거되었습니다.

  • components — slots 사용
  • componentsProps — slotProps 사용
  • TransitionComponent — slots.transition 사용
 <Backdrop
-  components={{ Root: CustomRoot }}
-  componentsProps={{ root: { className: 'my-class' } }}
-  TransitionComponent={CustomTransition}
+  slots={{ root: CustomRoot, transition: CustomTransition }}
+  slotProps={{ root: { className: 'my-class' } }}

Badge props

아래 badge-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/badge-props <path>

다음 deprecated props가 Badge 컴포넌트에서 제거되었습니다.

  • components → slots 사용
  • componentsProps → 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' } }}
 />

Button CSS 클래스

아래 button-classes codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/button-classes <path>

다음 deprecated Button CSS 클래스들이 제거되었습니다.

  • textInherit → .MuiButton-text.MuiButton-colorInherit 사용
  • textPrimary → .MuiButton-text.MuiButton-colorPrimary 사용
  • textSecondary → .MuiButton-text.MuiButton-colorSecondary 사용
  • textSuccess → .MuiButton-text.MuiButton-colorSuccess 사용
  • textError → .MuiButton-text.MuiButton-colorError 사용
  • textInfo → .MuiButton-text.MuiButton-colorInfo 사용
  • textWarning → .MuiButton-text.MuiButton-colorWarning 사용
  • outlinedInherit → .MuiButton-outlined.MuiButton-colorInherit 사용
  • outlinedPrimary → .MuiButton-outlined.MuiButton-colorPrimary 사용
  • outlinedSecondary → .MuiButton-outlined.MuiButton-colorSecondary 사용
  • outlinedSuccess → .MuiButton-outlined.MuiButton-colorSuccess 사용
  • outlinedError → .MuiButton-outlined.MuiButton-colorError 사용
  • outlinedInfo → .MuiButton-outlined.MuiButton-colorInfo 사용
  • outlinedWarning → .MuiButton-outlined.MuiButton-colorWarning 사용
  • containedInherit → .MuiButton-contained.MuiButton-colorInherit 사용
  • containedPrimary → .MuiButton-contained.MuiButton-colorPrimary 사용
  • containedSecondary → .MuiButton-contained.MuiButton-colorSecondary 사용
  • containedSuccess → .MuiButton-contained.MuiButton-colorSuccess 사용
  • containedError → .MuiButton-contained.MuiButton-colorError 사용
  • containedInfo → .MuiButton-contained.MuiButton-colorInfo 사용
  • containedWarning → .MuiButton-contained.MuiButton-colorWarning 사용
  • textSizeSmall → .MuiButton-text.MuiButton-sizeSmall 사용
  • textSizeMedium → .MuiButton-text.MuiButton-sizeMedium 사용
  • textSizeLarge → .MuiButton-text.MuiButton-sizeLarge 사용
  • outlinedSizeSmall → .MuiButton-outlined.MuiButton-sizeSmall 사용
  • outlinedSizeMedium → .MuiButton-outlined.MuiButton-sizeMedium 사용
  • outlinedSizeLarge → .MuiButton-outlined.MuiButton-sizeLarge 사용
  • containedSizeSmall → .MuiButton-contained.MuiButton-sizeSmall 사용
  • containedSizeMedium → .MuiButton-contained.MuiButton-sizeMedium 사용
  • containedSizeLarge → .MuiButton-contained.MuiButton-sizeLarge 사용
  • iconSizeSmall → .MuiButton-root.MuiButton-sizeSmall > .MuiButton-icon 사용
  • iconSizeMedium → .MuiButton-root.MuiButton-sizeMedium > .MuiButton-icon 사용
  • iconSizeLarge → .MuiButton-root.MuiButton-sizeLarge > .MuiButton-icon 사용

테마에서 이러한 deprecated 클래스 이름을 styleOverrides 키로 사용하고 있었다면, root 오버라이드 안의 variants 배열을 사용하세요.

 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' } } },
+          ],
+        },
       },
     },
   },
 });

ButtonGroup CSS 클래스

아래 button-group-classes codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/button-group-classes <path>

다음 deprecated ButtonGroup CSS 클래스들이 제거되었습니다.

  • groupedHorizontal → .MuiButtonGroup-horizontal > .MuiButtonGroup-grouped 사용
  • groupedVertical → .MuiButtonGroup-vertical > .MuiButtonGroup-grouped 사용
  • groupedText → .MuiButtonGroup-text > .MuiButtonGroup-grouped 사용
  • groupedTextHorizontal → .MuiButtonGroup-text.MuiButtonGroup-horizontal > .MuiButtonGroup-grouped 사용
  • groupedTextVertical → .MuiButtonGroup-text.MuiButtonGroup-vertical > .MuiButtonGroup-grouped 사용
  • groupedTextPrimary → .MuiButtonGroup-text.MuiButtonGroup-colorPrimary > .MuiButtonGroup-grouped 사용
  • groupedTextSecondary → .MuiButtonGroup-text.MuiButtonGroup-colorSecondary > .MuiButtonGroup-grouped 사용
  • groupedOutlined → .MuiButtonGroup-outlined > .MuiButtonGroup-grouped 사용
  • groupedOutlinedHorizontal → .MuiButtonGroup-outlined.MuiButtonGroup-horizontal > .MuiButtonGroup-grouped 사용
  • groupedOutlinedVertical → .MuiButtonGroup-outlined.MuiButtonGroup-vertical > .MuiButtonGroup-grouped 사용
  • groupedOutlinedPrimary → .MuiButtonGroup-outlined.MuiButtonGroup-colorPrimary > .MuiButtonGroup-grouped 사용
  • groupedOutlinedSecondary → .MuiButtonGroup-outlined.MuiButtonGroup-colorSecondary > .MuiButtonGroup-grouped 사용
  • groupedContained → .MuiButtonGroup-contained > .MuiButtonGroup-grouped 사용
  • groupedContainedHorizontal → .MuiButtonGroup-contained.MuiButtonGroup-horizontal > .MuiButtonGroup-grouped 사용
  • groupedContainedVertical → .MuiButtonGroup-contained.MuiButtonGroup-vertical > .MuiButtonGroup-grouped 사용
  • groupedContainedPrimary → .MuiButtonGroup-contained.MuiButtonGroup-colorPrimary > .MuiButtonGroup-grouped 사용
  • groupedContainedSecondary → .MuiButtonGroup-contained.MuiButtonGroup-colorSecondary > .MuiButtonGroup-grouped 사용

테마에서 이러한 deprecated 클래스 이름을 styleOverrides 키로 사용하고 있었다면, root 오버라이드 안의 variants 배열을 사용하세요.

 const theme = createTheme({
   components: {
     MuiButtonGroup: {
       styleOverrides: {
-        groupedContainedPrimary: { borderColor: 'red' },
+        root: {
+          variants: [
+            {
+              props: { variant: 'contained', color: 'primary' },
+              style: {
+                '& > .MuiButtonGroup-grouped': { borderColor: 'red' },
+              },
+            },
+          ],
+        },
       },
     },
   },
 });

CardHeader props

아래 card-header-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/card-header-props <path>

다음 deprecated props가 CardHeader 컴포넌트에서 제거되었습니다.

  • titleTypographyProps → slotProps.title 사용
  • subheaderTypographyProps → slotProps.subheader 사용
 <CardHeader
-  titleTypographyProps={{ className: 'my-title' }}
-  subheaderTypographyProps={{ className: 'my-subheader' }}
+  slotProps={{ title: { className: 'my-title' }, subheader: { className: 'my-subheader' } }}
 />

Checkbox props

아래 checkbox-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/checkbox-props <path>

다음 deprecated Checkbox props가 제거되었습니다.

  • inputProps — slotProps.input 사용
  • inputRef — slotProps.input.ref 사용
 <Checkbox
-  inputProps={{ 'aria-label': 'Checkbox' }}
-  inputRef={ref}
+  slotProps={{ input: { 'aria-label': 'Checkbox', ref } }}
 />

Chip CSS 클래스

아래 chip-classes codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/chip-classes <path>

다음 deprecated Chip CSS 클래스들이 제거되었습니다.

  • clickableColorPrimary → .MuiChip-clickable.MuiChip-colorPrimary 사용
  • clickableColorSecondary → .MuiChip-clickable.MuiChip-colorSecondary 사용
  • deletableColorPrimary → .MuiChip-deletable.MuiChip-colorPrimary 사용
  • deletableColorSecondary → .MuiChip-deletable.MuiChip-colorSecondary 사용
  • outlinedPrimary → .MuiChip-outlined.MuiChip-colorPrimary 사용
  • outlinedSecondary → .MuiChip-outlined.MuiChip-colorSecondary 사용
  • filledPrimary → .MuiChip-filled.MuiChip-colorPrimary 사용
  • filledSecondary → .MuiChip-filled.MuiChip-colorSecondary 사용
  • avatarSmall → .MuiChip-sizeSmall > .MuiChip-avatar 사용
  • avatarMedium → .MuiChip-sizeMedium > .MuiChip-avatar 사용
  • avatarColorPrimary → .MuiChip-colorPrimary > .MuiChip-avatar 사용
  • avatarColorSecondary → .MuiChip-colorSecondary > .MuiChip-avatar 사용
  • iconSmall → .MuiChip-sizeSmall > .MuiChip-icon 사용
  • iconMedium → .MuiChip-sizeMedium > .MuiChip-icon 사용
  • iconColorPrimary → .MuiChip-colorPrimary > .MuiChip-icon 사용
  • iconColorSecondary → .MuiChip-colorSecondary > .MuiChip-icon 사용
  • labelSmall → .MuiChip-sizeSmall > .MuiChip-label 사용
  • labelMedium → .MuiChip-sizeMedium > .MuiChip-label 사용
  • deleteIconSmall → .MuiChip-sizeSmall > .MuiChip-deleteIcon 사용
  • deleteIconMedium → .MuiChip-sizeMedium > .MuiChip-deleteIcon 사용
  • deleteIconColorPrimary → .MuiChip-colorPrimary > .MuiChip-deleteIcon 사용
  • deleteIconColorSecondary → .MuiChip-colorSecondary > .MuiChip-deleteIcon 사용
  • deleteIconOutlinedColorPrimary → .MuiChip-outlined.MuiChip-colorPrimary > .MuiChip-deleteIcon 사용
  • deleteIconOutlinedColorSecondary → .MuiChip-outlined.MuiChip-colorSecondary > .MuiChip-deleteIcon 사용
  • deleteIconFilledColorPrimary → .MuiChip-filled.MuiChip-colorPrimary > .MuiChip-deleteIcon 사용
  • deleteIconFilledColorSecondary → .MuiChip-filled.MuiChip-colorSecondary > .MuiChip-deleteIcon 사용

테마에서 이러한 deprecated 클래스 이름을 styleOverrides 키로 사용하고 있었다면, root 오버라이드 안의 variants 배열을 사용하세요. avatar, icon, deleteIcon 같은 자식 요소를 타깃으로 했던 클래스는 독립 스타일 슬롯이 아니므로 root variants 안에서 CSS 자식 선택자를 사용하세요. label 슬롯은 제대로 된 styled 컴포넌트이므로 styleOverrides.label에서 variants를 직접 사용할 수 있습니다.

 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' } },
+          ],
+        },
       },
     },
   },
 });

CircularProgress CSS 클래스

아래 circular-progress-classes codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/circular-progress-classes <path>

다음 deprecated CircularProgress CSS 클래스들이 제거되었습니다.

  • circleDeterminate → .MuiCircularProgress-determinate .MuiCircularProgress-circle 사용
  • circleIndeterminate → .MuiCircularProgress-indeterminate .MuiCircularProgress-circle 사용

테마에서 이러한 deprecated 클래스 이름을 styleOverrides 키로 사용하고 있었다면, circle 오버라이드 안의 variants 배열을 사용하세요.

 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' },
+            },
+          ],
+        },
       },
     },
   },
 });

Dialog CSS 클래스

아래 dialog-classes codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/dialog-classes <path>

다음 deprecated Dialog CSS 클래스들이 제거되었습니다.

  • paperScrollPaper → .MuiDialog-scrollPaper > .MuiDialog-paper 사용
  • paperScrollBody → .MuiDialog-scrollBody > .MuiDialog-paper 사용

styleOverrides에서 이러한 클래스를 사용하고 있었다면, paper 슬롯 안의 variants 배열을 사용하세요.

 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',
+              },
+            },
+          ],
+        },
       },
     },
   },
 });

Dialog props

아래 dialog-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/dialog-props <path>

다음 deprecated props가 Dialog 컴포넌트에서 제거되었습니다.

  • BackdropComponent → slots.backdrop 사용
  • BackdropProps → slotProps.backdrop 사용
  • PaperProps → slotProps.paper 사용
  • TransitionComponent → slots.transition 사용
  • TransitionProps → 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 } }}
 />

Drawer props

아래 drawer-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/drawer-props <path>

다음 deprecated props가 Drawer 컴포넌트에서 제거되었습니다.

  • BackdropComponent → slots.backdrop 사용
  • BackdropProps → slotProps.backdrop 사용
  • PaperProps → slotProps.paper 사용
  • SlideProps → slotProps.transition 사용
  • TransitionComponent → 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 } }}
 />

Drawer CSS 클래스

아래 drawer-classes codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/drawer-classes <path>

다음 deprecated 클래스들이 제거되었습니다.

  • paperAnchorLeft — .MuiDrawer-anchorLeft와 .MuiDrawer-paper를 결합하세요
  • paperAnchorRight — .MuiDrawer-anchorRight와 .MuiDrawer-paper를 결합하세요
  • paperAnchorTop — .MuiDrawer-anchorTop와 .MuiDrawer-paper를 결합하세요
  • paperAnchorBottom — .MuiDrawer-anchorBottom와 .MuiDrawer-paper를 결합하세요
  • paperAnchorDockedLeft — .MuiDrawer-anchorLeft, .MuiDrawer-docked, .MuiDrawer-paper를 결합하세요
  • paperAnchorDockedRight — .MuiDrawer-anchorRight, .MuiDrawer-docked, .MuiDrawer-paper를 결합하세요
  • paperAnchorDockedTop — .MuiDrawer-anchorTop, .MuiDrawer-docked, .MuiDrawer-paper를 결합하세요
  • paperAnchorDockedBottom — .MuiDrawer-anchorBottom, .MuiDrawer-docked, .MuiDrawer-paper를 결합하세요
-.MuiDrawer-paperAnchorLeft
+.MuiDrawer-anchorLeft > .MuiDrawer-paper

-.MuiDrawer-paperAnchorDockedLeft
+.MuiDrawer-anchorLeft.MuiDrawer-docked > .MuiDrawer-paper

Divider props

아래 codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/divider-props <path>

deprecated Divider prop이 제거되었습니다. sx={{ opacity: 0.6 }}(또는 임의의 opacity)를 사용하세요.

 <Divider
-  light
+  sx={{ opacity: 0.6 }}
 />

Divider CSS 클래스

다음 deprecated 클래스가 제거되었습니다.

  • withChildrenVertical — .MuiDivider-withChildren와 .MuiDivider-vertical 클래스를 결합하세요
-.MuiDivider-withChildrenVertical
+.MuiDivider-withChildren.MuiDivider-vertical

FormControlLabel props

아래 form-control-label-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/form-control-label-props <path>

다음 deprecated prop이 제거되었습니다.

  • componentsProps — slotProps 사용
 <FormControlLabel
-  componentsProps={{ typography: { fontWeight: 'bold' } }}
+  slotProps={{ typography: { fontWeight: 'bold' } }}
 />

FilledInput props

아래 filled-input-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/filled-input-props <path>

다음 deprecated FilledInput props가 제거되었습니다.

  • components → slots 사용
  • componentsProps → slotProps 사용
 <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' } }}
 />

ImageListItemBar CSS 클래스

아래 image-list-item-bar-classes codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/image-list-item-bar-classes <path>

다음 deprecated ImageListItemBar CSS 클래스들이 제거되었습니다.

  • titleWrapBelow → 루트에 .MuiImageListItemBar-positionBelow를 사용한 .MuiImageListItemBar-titleWrap 사용
  • titleWrapActionPosLeft → 루트에 .MuiImageListItemBar-actionPositionLeft를 사용한 .MuiImageListItemBar-titleWrap 사용
  • titleWrapActionPosRight → 루트에 .MuiImageListItemBar-actionPositionRight를 사용한 .MuiImageListItemBar-titleWrap 사용
  • actionIconActionPosLeft → 루트에 .MuiImageListItemBar-actionPositionLeft를 사용한 .MuiImageListItemBar-actionIcon 사용

Input props

아래 input-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/input-props <path>

다음 deprecated Input props가 제거되었습니다.

  • components → slots 사용
  • componentsProps → slotProps 사용
 <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' } }}
 />

InputBase CSS 클래스

아래 input-base-classes codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/input-base-classes <path>

다음 deprecated InputBase CSS 클래스들이 제거되었습니다.

  • inputSizeSmall → .MuiInputBase-sizeSmall > .MuiInputBase-input 사용
  • inputMultiline → .MuiInputBase-multiline > .MuiInputBase-input 사용
  • inputAdornedStart → .MuiInputBase-adornedStart > .MuiInputBase-input 사용
  • inputAdornedEnd → .MuiInputBase-adornedEnd > .MuiInputBase-input 사용
  • inputHiddenLabel → .MuiInputBase-hiddenLabel > .MuiInputBase-input 사용

테마에서 이러한 deprecated 클래스 이름을 styleOverrides 키로 사용하고 있었다면, 결합된 클래스 선택자를 가진 root 슬롯을 사용하세요.

 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 },
+        },
       },
     },
   },
 });

InputBase props

아래 input-base-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/input-base-props <path>

다음 deprecated InputBase props가 제거되었습니다.

  • components → slots 사용
  • componentsProps → slotProps 사용
 <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' } }}
 />

LinearProgress CSS 클래스

아래 linear-progress-classes codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/linear-progress-classes <path>

다음 deprecated LinearProgress CSS 클래스들이 제거되었습니다.

  • bar1Buffer → .MuiLinearProgress-buffer > .MuiLinearProgress-bar1 사용
  • bar1Determinate → .MuiLinearProgress-determinate > .MuiLinearProgress-bar1 사용
  • bar1Indeterminate → .MuiLinearProgress-indeterminate > .MuiLinearProgress-bar1 사용
  • bar2Buffer → .MuiLinearProgress-buffer > .MuiLinearProgress-bar2 사용
  • bar2Indeterminate → .MuiLinearProgress-indeterminate > .MuiLinearProgress-bar2 사용
  • barColorPrimary → .MuiLinearProgress-colorPrimary > .MuiLinearProgress-bar 사용
  • barColorSecondary → .MuiLinearProgress-colorSecondary > .MuiLinearProgress-bar 사용
  • dashedColorPrimary → .MuiLinearProgress-colorPrimary > .MuiLinearProgress-dashed 사용
  • dashedColorSecondary → .MuiLinearProgress-colorSecondary > .MuiLinearProgress-dashed 사용

테마에서 이러한 deprecated 클래스 이름을 styleOverrides 키로 사용하고 있었다면, 해당 슬롯 오버라이드 안의 variants 배열을 사용하세요.

 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' } },
+          ],
+        },
       },
     },
   },
 });

ListItem props

아래 list-item-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/list-item-props <path>

다음 deprecated props가 제거되었습니다.

  • components — slots 사용
  • componentsProps — slotProps 사용
  • ContainerComponent — component 또는 slots.root 사용
  • ContainerProps — slotProps.root 사용
 <ListItem
-  components={{ Root: CustomRoot }}
-  componentsProps={{ root: { className: 'custom' } }}
+  slots={{ root: CustomRoot }}
+  slotProps={{ root: { className: 'custom' } }}
 />

테마의 styleOverrides 키 secondaryAction은 이제 root 슬롯 대신 secondaryAction 슬롯을 타깃합니다.

 const theme = createTheme({
   components: {
     MuiListItem: {
       styleOverrides: {
-        secondaryAction: {
-          [`& .${listItemClasses.secondaryAction}`]: {
-            // styles
-          },
-        },
+        secondaryAction: {
+          // styles applied directly to the secondaryAction slot
+        },
       },
     },
   },
 });

ListItemText props

아래 list-item-text-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/list-item-text-props <path>

다음 deprecated props가 제거되었습니다.

  • primaryTypographyProps — slotProps.primary 사용
  • secondaryTypographyProps — slotProps.secondary 사용
 <ListItemText
-  primaryTypographyProps={{ variant: 'h6' }}
-  secondaryTypographyProps={{ color: 'textSecondary' }}
+  slotProps={{
+    primary: { variant: 'h6' },
+    secondary: { color: 'textSecondary' },
+  }}
 />

아래 menu-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/menu-props <path>

다음 deprecated props가 제거되었습니다.

  • MenuListProps — slotProps.list 사용
  • PaperProps — slotProps.paper 사용
  • TransitionProps — slotProps.transition 사용
 <Menu
-  MenuListProps={{ disablePadding: true }}
-  PaperProps={{ elevation: 12 }}
-  TransitionProps={{ timeout: 500 }}
+  slotProps={{
+    list: { disablePadding: true },
+    paper: { elevation: 12 },
+    transition: { timeout: 500 },
+  }}
 />

이 props를 Select의 MenuProps로 전달한다면 같은 방식으로 업데이트하세요.

 <Select
   MenuProps={{
-    PaperProps: { style: { maxHeight: 200 } },
-    MenuListProps: { disablePadding: true },
-    TransitionProps: { timeout: 500 },
+    slotProps: {
+      paper: { style: { maxHeight: 200 } },
+      list: { disablePadding: true },
+      transition: { timeout: 500 },
+    },
   }}
 />

MobileStepper props

아래 mobile-stepper-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/mobile-stepper-props <path>

다음 deprecated prop이 제거되었습니다.

  • LinearProgressProps — slotProps.progress 사용
 <MobileStepper
-  LinearProgressProps={{ className: 'progress' }}
+  slotProps={{ progress: { className: 'progress' } }}
 />

아래 modal-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/modal-props <path>

다음 deprecated props가 Modal 컴포넌트에서 제거되었습니다.

  • BackdropComponent → slots.backdrop 사용
  • BackdropProps → slotProps.backdrop 사용
  • components → slots 사용
  • componentsProps → 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' } }}
 />

OutlinedInput props

아래 outlined-input-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/outlined-input-props <path>

다음 deprecated OutlinedInput props가 제거되었습니다.

  • components → slots 사용
  • componentsProps → slotProps 사용
 <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' } }}
 />

PaginationItem props

아래 pagination-item-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/pagination-item-props <path>

다음 deprecated prop이 제거되었습니다.

  • components — slots 사용
 <PaginationItem
-  components={{
-    first: MyFirstIcon,
-    last: MyLastIcon,
-    previous: MyPreviousIcon,
-    next: MyNextIcon,
-  }}
+  slots={{
+    first: MyFirstIcon,
+    last: MyLastIcon,
+    previous: MyPreviousIcon,
+    next: MyNextIcon,
+  }}
 />

PaginationItem CSS 클래스

아래 pagination-item-classes codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/pagination-item-classes <path>

다음 deprecated 클래스들이 제거되었습니다.

  • textPrimary — .MuiPaginationItem-text와 .MuiPaginationItem-colorPrimary 클래스를 결합하세요
  • textSecondary — .MuiPaginationItem-text와 .MuiPaginationItem-colorSecondary 클래스를 결합하세요
  • outlinedPrimary — .MuiPaginationItem-outlined와 .MuiPaginationItem-colorPrimary 클래스를 결합하세요
  • outlinedSecondary — .MuiPaginationItem-outlined와 .MuiPaginationItem-colorSecondary 클래스를 결합하세요
-.MuiPaginationItem-textPrimary
+.MuiPaginationItem-text.MuiPaginationItem-colorPrimary

-.MuiPaginationItem-outlinedPrimary
+.MuiPaginationItem-outlined.MuiPaginationItem-colorPrimary

Popper props

아래 popper-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/popper-props <path>

다음 deprecated props가 제거되었습니다.

  • components — slots 사용
  • componentsProps — slotProps 사용
 <Popper
-  components={{ Root: CustomRoot }}
-  componentsProps={{ root: { className: 'custom' } }}
+  slots={{ root: CustomRoot }}
+  slotProps={{ root: { className: 'custom' } }}
 />

Popover props

아래 popover-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/popover-props <path>

다음 deprecated props가 제거되었습니다.

  • BackdropComponent — slots.backdrop 사용
  • BackdropProps — slotProps.backdrop 사용
  • PaperProps — slotProps.paper 사용
  • TransitionComponent — slots.transition 사용
  • TransitionProps — slotProps.transition 사용
 <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 },
+  }}
 />

Radio props

아래 radio-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/radio-props <path>

다음 deprecated Radio props가 제거되었습니다.

  • inputProps — slotProps.input 사용
  • inputRef — slotProps.input.ref 사용
 <Radio
-  inputProps={{ 'aria-label': 'Radio' }}
-  inputRef={ref}
+  slotProps={{ input: { 'aria-label': 'Radio', ref } }}
 />

Rating props

아래 rating-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/rating-props <path>

다음 deprecated prop이 제거되었습니다.

  • IconContainerComponent — slotProps.icon.component 사용
 <Rating
-  IconContainerComponent={CustomIconContainer}
+  slotProps={{ icon: { component: CustomIconContainer } }}
 />

Select CSS 클래스

아래 select-classes codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/select-classes <path>

다음 deprecated Select CSS 클래스들이 제거되었습니다.

  • iconFilled → .MuiSelect-filled ~ .MuiSelect-icon 사용
  • iconOutlined → .MuiSelect-outlined ~ .MuiSelect-icon 사용
  • iconStandard → .MuiSelect-standard ~ .MuiSelect-icon 사용

테마에서 이러한 deprecated 클래스 이름을 styleOverrides로 사용하고 있었다면, root 오버라이드 안에서 형제(sibling) 선택자를 사용하세요.

 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',
           },
         },
       },
     },
   },
 });

Slider props

아래 slider-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/slider-props <path>

다음 deprecated props가 Slider 컴포넌트에서 제거되었습니다.

  • components — slots 사용
  • componentsProps — slotProps 사용
 <Slider
-  components={{ Track: CustomTrack }}
-  componentsProps={{ track: { testid: 'test-id' } }}
+  slots={{ track: CustomTrack }}
+  slotProps={{ track: { testid: 'test-id' } }}
 />

Slider CSS 클래스

아래 slider-classes codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/slider-classes <path>

다음 deprecated 클래스들이 제거되었습니다.

  • thumbColorPrimary — .MuiSlider-colorPrimary > .MuiSlider-thumb 사용
  • thumbColorSecondary — .MuiSlider-colorSecondary > .MuiSlider-thumb 사용
  • thumbColorError — .MuiSlider-colorError > .MuiSlider-thumb 사용
  • thumbColorInfo — .MuiSlider-colorInfo > .MuiSlider-thumb 사용
  • thumbColorSuccess — .MuiSlider-colorSuccess > .MuiSlider-thumb 사용
  • thumbColorWarning — .MuiSlider-colorWarning > .MuiSlider-thumb 사용
  • thumbSizeSmall — .MuiSlider-sizeSmall > .MuiSlider-thumb 사용
-.MuiSlider-thumbColorPrimary
+.MuiSlider-colorPrimary > .MuiSlider-thumb

-.MuiSlider-thumbColorSecondary
+.MuiSlider-colorSecondary > .MuiSlider-thumb

-.MuiSlider-thumbSizeSmall
+.MuiSlider-sizeSmall > .MuiSlider-thumb

Snackbar props

아래 snackbar-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/snackbar-props <path>

다음 deprecated Snackbar props가 제거되었습니다.

  • ClickAwayListenerProps — slotProps.clickAwayListener 사용
  • ContentProps — slotProps.content 사용
  • TransitionComponent — slots.transition 사용
  • TransitionProps — slotProps.transition 사용
 <Snackbar
-  ClickAwayListenerProps={CustomClickAwayListenerProps}
-  ContentProps={CustomContentProps}
-  TransitionComponent={CustomTransition}
-  TransitionProps={CustomTransitionProps}
+  slots={{ transition: CustomTransition }}
+  slotProps={{
+    clickAwayListener: CustomClickAwayListenerProps,
+    content: CustomContentProps,
+    transition: CustomTransitionProps,
+  }}
 />

StepConnector CSS 클래스

아래 step-connector-classes codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/step-connector-classes <path>

다음 deprecated StepConnector CSS 클래스들이 제거되었습니다.

  • lineHorizontal → .MuiStepConnector-horizontal .MuiStepConnector-line 사용
  • lineVertical → .MuiStepConnector-vertical .MuiStepConnector-line 사용

테마에서 이러한 deprecated 클래스 이름을 styleOverrides 키로 사용하고 있었다면, line 오버라이드 안의 variants 배열을 사용하세요.

 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 } },
+          ],
+        },
       },
     },
   },
 });

StepContent props

아래 step-content-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/step-content-props <path>

다음 deprecated StepContent props가 제거되었습니다.

  • TransitionComponent → slots.transition 사용
  • TransitionProps → slotProps.transition 사용
 <StepContent
-  TransitionComponent={CustomTransition}
-  TransitionProps={{ unmountOnExit: true }}
+  slots={{ transition: CustomTransition }}
+  slotProps={{ transition: { unmountOnExit: true } }}
 />

StepLabel props

아래 step-label-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/step-label-props <path>

다음 deprecated StepLabel props가 제거되었습니다.

  • componentsProps → slotProps 사용
  • StepIconComponent → slots.stepIcon 사용
  • StepIconProps → slotProps.stepIcon 사용
 <StepLabel
-  StepIconComponent={CustomIcon}
-  StepIconProps={{ error: true }}
-  componentsProps={{ label: { className: 'my-label' } }}
+  slots={{ stepIcon: CustomIcon }}
+  slotProps={{ stepIcon: { error: true }, label: { className: 'my-label' } }}
 />

SpeedDial props

아래 speed-dial-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/speed-dial-props <path>

deprecated SpeedDial props가 제거되었습니다. 대신 slots와 slotProps props를 사용하세요.

 <SpeedDial
-  TransitionComponent={CustomTransition}
-  TransitionProps={{ timeout: 500 }}
+  slots={{ transition: CustomTransition }}
+  slotProps={{ transition: { timeout: 500 } }}
 >

SpeedDialAction props

아래 speed-dial-action-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/speed-dial-action-props <path>

deprecated SpeedDialAction props가 제거되었습니다. 대신 slotProps prop을 사용하세요.

 <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' },
+    },

Switch props

아래 switch-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/switch-props <path>

다음 deprecated Switch props가 제거되었습니다.

  • inputProps — slotProps.input 사용
  • inputRef — slotProps.input.ref 사용
 <Switch
-  inputProps={{ 'aria-label': 'Switch' }}
-  inputRef={ref}
+  slotProps={{ input: { 'aria-label': 'Switch', ref } }}
 />

SwipeableDrawer props

아래 drawer-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/drawer-props <path>

다음 deprecated props가 SwipeableDrawer 컴포넌트에서 제거되었습니다.

  • BackdropComponent → slots.backdrop 사용
  • BackdropProps → slotProps.backdrop 사용
  • SwipeAreaProps → slotProps.swipeArea 사용
 <SwipeableDrawer
-  BackdropComponent={CustomBackdrop}
-  BackdropProps={{ invisible: true }}
-  SwipeAreaProps={{ className: 'custom' }}
+  slots={{ backdrop: CustomBackdrop }}
+  slotProps={{ backdrop: { invisible: true }, swipeArea: { className: 'custom' } }}
 />

TablePagination props

아래 table-pagination-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/table-pagination-props <path>

다음 deprecated props가 제거되었습니다.

  • backIconButtonProps — slotProps.actions.previousButton 사용
  • nextIconButtonProps — slotProps.actions.nextButton 사용
  • SelectProps — slotProps.select 사용
 <TablePagination
-  backIconButtonProps={{ disabled: true }}
-  nextIconButtonProps={{ disabled: true }}
-  SelectProps={{ variant: 'outlined' }}
+  slotProps={{
+    actions: {
+      previousButton: { disabled: true },
+      nextButton: { disabled: true },
+    },
+    select: { variant: 'outlined' },
+  }}
 />

TableSortLabel CSS 클래스

아래 table-sort-label-classes codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/table-sort-label-classes <path>

다음 deprecated 클래스들이 제거되었습니다.

  • iconDirectionDesc — .MuiTableSortLabel-directionDesc와 .MuiTableSortLabel-icon 클래스를 결합하세요
  • iconDirectionAsc — .MuiTableSortLabel-directionAsc와 .MuiTableSortLabel-icon 클래스를 결합하세요
-.MuiTableSortLabel-iconDirectionDesc
+.MuiTableSortLabel-directionDesc > .MuiTableSortLabel-icon

-.MuiTableSortLabel-iconDirectionAsc
+.MuiTableSortLabel-directionAsc > .MuiTableSortLabel-icon

테마에서 이러한 deprecated 클래스 이름을 styleOverrides 키로 사용하고 있었다면, icon 오버라이드 안의 variants 배열을 사용하세요.

 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 } },
+          ],
+        },
       },
     },
   },
 });

Tabs props

아래 tabs-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/tabs-props <path>

다음 deprecated props가 제거되었습니다.

  • ScrollButtonComponent — slots.scrollButtons 사용
  • TabIndicatorProps — slotProps.indicator 사용
  • TabScrollButtonProps — slotProps.scrollButtons 사용
  • slots.StartScrollButtonIcon — slots.startScrollButtonIcon 사용
  • slots.EndScrollButtonIcon — slots.endScrollButtonIcon 사용
 <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 }}
 />

Tab CSS 클래스

아래 tab-classes codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/tab-classes <path>

다음 deprecated 클래스가 제거되었습니다.

  • iconWrapper — icon 클래스 사용
-.MuiTab-iconWrapper
+.MuiTab-icon

Tabs CSS 클래스

다음 deprecated 클래스들이 제거되었습니다.

  • flexContainer — list 클래스 사용
  • flexContainerVertical — list와 vertical 클래스를 결합하세요
-.MuiTabs-flexContainer
+.MuiTabs-list

-.MuiTabs-flexContainerVertical
+.MuiTabs-list.MuiTabs-vertical

ToggleButtonGroup CSS 클래스

아래 toggle-button-group-classes codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/toggle-button-group-classes <path>

다음 deprecated ToggleButtonGroup CSS 클래스들이 제거되었습니다.

  • groupedHorizontal → .MuiToggleButtonGroup-horizontal > .MuiToggleButtonGroup-grouped 사용
  • groupedVertical → .MuiToggleButtonGroup-vertical > .MuiToggleButtonGroup-grouped 사용

테마에서 이러한 deprecated 클래스 이름을 styleOverrides 키로 사용하고 있었다면, grouped 오버라이드 안의 variants 배열을 사용하세요.

 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 } },
+          ],
+        },
       },
     },
   },
 });

TextField props

아래 text-field-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/text-field-props <path>

다음 deprecated props가 TextField 컴포넌트에서 제거되었습니다.

  • InputProps → slotProps.input 사용
  • inputProps → slotProps.htmlInput 사용
  • SelectProps → slotProps.select 사용
  • InputLabelProps → slotProps.inputLabel 사용
  • FormHelperTextProps → slotProps.formHelperText 사용
 <TextField
-  InputProps={CustomInputProps}
-  inputProps={CustomHtmlInputProps}
-  SelectProps={CustomSelectProps}
-  InputLabelProps={CustomInputLabelProps}
-  FormHelperTextProps={CustomFormHelperTextProps}
+  slotProps={{
+    input: CustomInputProps,
+    htmlInput: CustomHtmlInputProps,
+    select: CustomSelectProps,
+    inputLabel: CustomInputLabelProps,
+    formHelperText: CustomFormHelperTextProps,
+  }}
 />

아래 autocomplete-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/autocomplete-props <path>

Autocomplete에서 TextField를 렌더링한다면, params 형태도 새 TextField API에 맞게 변경되었습니다.

 <Autocomplete
   renderInput={(params) => (
     <TextField
       {...params}
-      inputProps={{
-        ...params.inputProps,
-        autoComplete: 'new-password',
+      slotProps={{
+        ...params.slotProps,
+        htmlInput: {
+          ...params.slotProps.htmlInput,
+          autoComplete: 'new-password',
+        },
       }}
     />
   )}

Tooltip props

아래 tooltip-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/tooltip-props <path>

다음 deprecated props가 Tooltip 컴포넌트에서 제거되었습니다.

  • components → slots 사용
  • componentsProps → slotProps 사용
  • PopperComponent → slots.popper 사용
  • PopperProps → slotProps.popper 사용
  • TransitionComponent → slots.transition 사용
  • TransitionProps → 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' },
+  }}
 />

Typography CSS 클래스

deprecated paragraph CSS 클래스가 제거되었습니다. 문단 요소에 커스텀 스타일을 적용하려면 CSS .MuiTypography-root:where(p)를 사용하세요.

-.MuiTypography-paragraph {
-  margin-bottom: 16px;
-}
+.MuiTypography-root:where(p) {
+  margin-bottom: 16px;
+}

Typography props

아래 typography-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest deprecations/typography-props <path>

다음 deprecated props가 Typography 컴포넌트에서 제거되었습니다.

  • paragraph → 하단 margin을 추가하려면 sx prop을 사용하세요
-<Typography paragraph />
+<Typography sx={{ marginBottom: '16px' }} />

System props

아래 system-props codemod를 사용해 다음 섹션에 설명된 대로 코드를 마이그레이션하세요.

npx @mui/codemod@latest v9.0.0/system-props <path/to/folder>

추가로 마이그레이션할 JSX 태그를 지정하려면 --jsx를 사용하세요. import 감지를 건너뜁니다.

npx @mui/codemod@latest v9.0.0/system-props <path/to/folder> -- --jsx=Box,Typography,Stack,Link,Grid,DialogContentText

이 옵션은 Material UI 컴포넌트를 명시적인 import 문 없이 사용할 수 있게 하는 auto-import 플러그인(예: unplugin-auto-import)을 쓰는 프로젝트에 유용합니다.

다음 컴포넌트들에서 deprecated system props가 제거되었습니다.

  • Box
  • DialogContentText
  • Grid
  • Link
  • Stack
  • Typography
  • TimelineContent
  • TimelineOppositeContent
-<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' }} />

이 변경은 color 같은 props가 컴포넌트에 의해 소비되어 component prop으로 렌더링되는 요소로 전달되지 않던 문제도 해결합니다.

// `color` is now correctly forwarded to Button
<Grid component={Button} color="secondary" variant="contained">
  hello
</Grid>

더 알아보기 (Learn more)

  • Material UI 마이그레이션 가이드