Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/data/material/migration/upgrade-to-v9/upgrade-to-v9.md
Original file line number Diff line number Diff line change
Expand Up @@ -2266,6 +2266,14 @@ Use the [system-props codemod](https://github.com/mui/material-ui/blob/master/pa
npx @mui/codemod@latest v9.0.0/system-props <path/to/folder>
```

Use `--jsx` to specify extra JSX tags to migrate, bypassing import detection:

```bash
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:

- `Box`
Expand Down
7 changes: 7 additions & 0 deletions packages/mui-codemod/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2545,6 +2545,13 @@ Compared to the v6 codemod, the v9 version also handles:
+<Link href="#" sx={{ color: "text.secondary" }} />
```

You can also pass `--jsx` to specify JSX element names directly, bypassing import detection.
This is useful for projects using auto-import plugins (for example `unplugin-auto-import`) where Material UI components are available without explicit import statements:

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

### v7.0.0

#### `theme-color-functions`
Expand Down
14 changes: 14 additions & 0 deletions packages/mui-codemod/src/v9.0.0/system-props/removeSystemProps.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,20 @@ export default function removeSystemProps(file, api, options) {
},
};
const elementReplacement = {};

if (options.jsx) {
options.jsx.split(',').forEach((name) => {
const trimmed = name.trim();
if (!trimmed) {
return;
}
deprecatedElements.push(trimmed);
if (customReplacement[trimmed]) {
elementReplacement[trimmed] = customReplacement[trimmed];
}
});
}

const packageName = options.packageName;
const importSources = ['@mui'];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,28 @@ describe('@mui/codemod', () => {
expect(actual).to.equal(expected, 'The transformed version should be correct');
});

it('transforms props for jsx option (auto-imported components)', () => {
const actual = transform(
{ source: read('./test-cases/system-props-jsx.actual.js') },
{ jscodeshift },
{ jsx: 'Box,Typography,Stack,Link' },
);

const expected = read('./test-cases/system-props-jsx.expected.js');
expect(actual).to.equal(expected, 'The transformed version should be correct');
});

it('accepts arbitrary component names in jsx option', () => {
const actual = transform(
{ source: read('./test-cases/system-props-jsx-custom.actual.js') },
{ jscodeshift },
{ jsx: 'DialogTitle,Skeleton,SvgIcon' },
);

const expected = read('./test-cases/system-props-jsx-custom.expected.js');
expect(actual).to.equal(expected, 'The transformed version should be correct');
});

it('does not transform similarly named packages', () => {
const actual = transform(
{ source: read('./test-cases/system-props-package-name-similar.actual.js') },
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// --jsx accepts arbitrary component names (e.g. DialogTitle, Skeleton, SvgIcon)
<DialogTitle display="flex" alignItems="center">Title</DialogTitle>;

<Skeleton height={60} width={100} mb={2} />;

<SvgIcon width="1rem" height="1rem" />;
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// --jsx accepts arbitrary component names (e.g. DialogTitle, Skeleton, SvgIcon)
<DialogTitle
sx={{
display: "flex",
alignItems: "center"
}}>Title</DialogTitle>;

<Skeleton
sx={{
height: 60,
width: 100,
mb: 2
}} />;

<SvgIcon
sx={{
width: "1rem",
height: "1rem"
}} />;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// No import statements — components are auto-imported
<Box display="flex" gap={2} p={3}>
<Typography fontSize={14} fontWeight={600}>Hello</Typography>
</Box>;

<Stack direction="row" spacing={2} mt={1} />;

<Link color="inherit" href="https://mui.com/" mb={2}>MUI</Link>;

const sx = { display: 'flex' };
<Box m={2} sx={sx} />;
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// No import statements — components are auto-imported
<Box
sx={{
display: "flex",
gap: 2,
p: 3
}}>
<Typography
sx={{
fontSize: 14,
fontWeight: 600
}}>Hello</Typography>
</Box>;

<Stack direction="row" spacing={2} sx={{
mt: 1
}} />;

<Link color="inherit" href="https://mui.com/" sx={{
mb: 2
}}>MUI</Link>;

const sx = { display: 'flex' };
<Box
sx={[{
m: 2
}, ...(Array.isArray(sx) ? sx : [sx])]} />;
Loading