@mui/codemod 5.15.10 → 5.15.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/README.md +137 -1
  2. package/codemod.js +80 -7
  3. package/node/deprecations/accordion-summary-classes/accordion-summary-classes.js +55 -0
  4. package/node/deprecations/accordion-summary-classes/index.js +13 -0
  5. package/node/deprecations/accordion-summary-classes/postcss-plugin.js +28 -0
  6. package/node/deprecations/accordion-summary-classes/postcss.config.js +8 -0
  7. package/node/deprecations/accordion-summary-classes/test-cases/actual.js +54 -0
  8. package/node/deprecations/accordion-summary-classes/test-cases/expected.js +54 -0
  9. package/node/deprecations/alert-props/alert-props.js +22 -0
  10. package/node/deprecations/alert-props/index.js +13 -0
  11. package/node/deprecations/alert-props/test-cases/actual.js +43 -0
  12. package/node/deprecations/alert-props/test-cases/expected.js +33 -0
  13. package/node/deprecations/alert-props/test-cases/theme.actual.js +52 -0
  14. package/node/deprecations/alert-props/test-cases/theme.expected.js +42 -0
  15. package/node/deprecations/all/deprecations-all.js +4 -0
  16. package/node/deprecations/all/postcss.config.js +11 -0
  17. package/node/deprecations/pagination-item-classes/index.js +13 -0
  18. package/node/deprecations/pagination-item-classes/pagination-item-classes.js +58 -0
  19. package/node/deprecations/pagination-item-classes/postcss-plugin.js +39 -0
  20. package/node/deprecations/pagination-item-classes/postcss.config.js +8 -0
  21. package/node/deprecations/pagination-item-classes/test-cases/actual.js +108 -0
  22. package/node/deprecations/pagination-item-classes/test-cases/expected.js +108 -0
  23. package/node/deprecations/utils/replaceComponentsWithSlots.js +184 -0
  24. package/node/util/findComponentDefaultProps.js +30 -0
  25. package/package.json +3 -1
package/README.md CHANGED
@@ -7,6 +7,7 @@
7
7
 
8
8
  This repository contains a collection of codemod scripts based for use with
9
9
  [jscodeshift](https://github.com/facebook/jscodeshift) that help update the APIs.
10
+ Some of the codemods also run [postcss](https://github.com/postcss/postcss) plugins to update CSS files.
10
11
 
11
12
  ## Setup & run
12
13
 
@@ -91,6 +92,76 @@ A combination of all deprecations.
91
92
  npx @mui/codemod@latest deprecations/accordion-props <path>
92
93
  ```
93
94
 
95
+ #### `accordion-summary-classes`
96
+
97
+ JS transforms:
98
+
99
+ ```diff
100
+ import { accordionSummaryClasses } from '@mui/material/AccordionSummary';
101
+
102
+ MuiAccordionSummary: {
103
+ styleOverrides: {
104
+ root: {
105
+ - [`& .${accordionSummaryClasses.contentGutters}`]: {
106
+ + [`&.${accordionSummaryClasses.gutters} .${accordionSummaryClasses.content}`]: {
107
+ color: 'red',
108
+ },
109
+ },
110
+ },
111
+ },
112
+ ```
113
+
114
+ ```diff
115
+ MuiAccordionSummary: {
116
+ styleOverrides: {
117
+ root: {
118
+ - '& .MuiAccordionSummary-contentGutters': {
119
+ + '&.MuiAccordionSummary-gutters .MuiAccordionSummary-content': {
120
+ color: 'red',
121
+ },
122
+ },
123
+ },
124
+ },
125
+ ```
126
+
127
+ CSS transforms:
128
+
129
+ ```diff
130
+ -.MuiAccordionSummary-root .MuiAccordionSummary-contentGutters
131
+ +.MuiAccordionSummary-root.MuiAccordionSummary-gutters .MuiAccordionSummary-content
132
+ />
133
+ ```
134
+
135
+ ```bash
136
+ npx @mui/codemod@latest deprecations/accordion-summary-classes <path>
137
+ ```
138
+
139
+ #### `alert-props`
140
+
141
+ ```diff
142
+ <Alert
143
+ - components={{ CloseButton: CustomButton }}
144
+ + slots={{ closeButton: CustomButton }}
145
+ - componentsProps={{ closeButton: { testid: 'test-id' } }}
146
+ + slotProps={{ closeButton: { testid: 'test-id' } }}
147
+ />
148
+ ```
149
+
150
+ ```diff
151
+ MuiAlert: {
152
+ defaultProps: {
153
+ - components: { CloseButton: CustomButton }
154
+ + slots: { closeButton: CustomButton },
155
+ - componentsProps: { closeButton: { testid: 'test-id' }}
156
+ + slotProps: { closeButton: { testid: 'test-id' } },
157
+ },
158
+ },
159
+ ```
160
+
161
+ ```bash
162
+ npx @mui/codemod@latest deprecations/alert-props <path>
163
+ ```
164
+
94
165
  #### `avatar-props`
95
166
 
96
167
  ```diff
@@ -120,6 +191,71 @@ npx @mui/codemod@latest deprecations/accordion-props <path>
120
191
  npx @mui/codemod@latest deprecations/divider-props <path>
121
192
  ```
122
193
 
194
+ #### `pagination-item-classes`
195
+
196
+ JS transforms:
197
+
198
+ ```diff
199
+ import { paginationItemClasses } from '@mui/material/PaginationItem';
200
+
201
+ MuiPaginationItem: {
202
+ styleOverrides: {
203
+ root: {
204
+ - [`&.${paginationItemClasses.textPrimary}`]: {
205
+ + [`&.${paginationItemClasses.text}.${paginationItemClasses.colorPrimary}`]: {
206
+ color: 'red',
207
+ },
208
+ - [`&.${paginationItemClasses.textSecondary}`]: {
209
+ + [`&.${paginationItemClasses.text}.${paginationItemClasses.colorSecondary}`]: {
210
+ color: 'red',
211
+ },
212
+ - [`&.${paginationItemClasses.outlinedPrimary}`]: {
213
+ + [`&.${paginationItemClasses.outlined}.${paginationItemClasses.colorPrimary}`]: {
214
+ color: 'red',
215
+ },
216
+ - [`&.${paginationItemClasses.outlinedSecondary}`]: {
217
+ + [`&.${paginationItemClasses.outlined}.${paginationItemClasses.colorSecondary}`]: {
218
+ color: 'red',
219
+ },
220
+ - '&.MuiPaginationItem-textPrimary': {
221
+ + '&.MuiPaginationItem-text.MuiPaginationItem-colorPrimary': {
222
+ color: 'red',
223
+ },
224
+ - '&.MuiPaginationItem-textSecondary': {
225
+ + '&.MuiPaginationItem-text.MuiPaginationItem-colorSecondary': {
226
+ color: 'red',
227
+ },
228
+ - '&.MuiPaginationItem-outlinedPrimary': {
229
+ + '&.MuiPaginationItem-outlined.MuiPaginationItem-colorPrimary': {
230
+ color: 'red',
231
+ },
232
+ - '&.MuiPaginationItem-outlinedSecondary': {
233
+ + '&.MuiPaginationItem-outlined.MuiPaginationItem-colorSecondary': {
234
+ color: 'red',
235
+ },
236
+ },
237
+ },
238
+ },
239
+ ```
240
+
241
+ CSS transforms:
242
+
243
+ ```diff
244
+ -.MuiPaginationItem-textPrimary
245
+ +.MuiPaginationItem-text.MuiPaginationItem-primary
246
+ -.MuiPaginationItem-textSecondary
247
+ +.MuiPaginationItem-text.MuiPaginationItem-secondary
248
+ -.MuiPaginationItem-outlinedPrimary
249
+ +.MuiPaginationItem-outlined.MuiPaginationItem-primary
250
+ -.MuiPaginationItem-outlinedSecondary
251
+ +.MuiPaginationItem-outlined.MuiPaginationItem-secondary
252
+ />
253
+ ```
254
+
255
+ ```bash
256
+ npx @mui/codemod@latest deprecations/pagination-item-classes <path>
257
+ ```
258
+
123
259
  ### v5.0.0
124
260
 
125
261
  #### `base-use-named-exports`
@@ -1234,7 +1370,7 @@ You can find more details about this breaking change in the migration guide.
1234
1370
 
1235
1371
  #### `theme-augment`
1236
1372
 
1237
- Adds `DefaultTheme` module augmentation to typescript projects.
1373
+ Adds `DefaultTheme` module augmentation to TypeScript projects.
1238
1374
 
1239
1375
  ```bash
1240
1376
  npx @mui/codemod@latest v5.0.0/theme-augment <path>
package/codemod.js CHANGED
@@ -5,11 +5,15 @@ const { promises: fs } = require('fs');
5
5
  const path = require('path');
6
6
  const yargs = require('yargs');
7
7
  const jscodeshiftPackage = require('jscodeshift/package.json');
8
+ const postcssCliPackage = require('postcss-cli/package.json');
8
9
 
9
10
  const jscodeshiftDirectory = path.dirname(require.resolve('jscodeshift'));
10
11
  const jscodeshiftExecutable = path.join(jscodeshiftDirectory, jscodeshiftPackage.bin.jscodeshift);
11
12
 
12
- async function runTransform(transform, files, flags, codemodFlags) {
13
+ const postcssCliDirectory = path.dirname(require.resolve('postcss-cli'));
14
+ const postcssExecutable = path.join(postcssCliDirectory, postcssCliPackage.bin.postcss);
15
+
16
+ async function runJscodeshiftTransform(transform, files, flags, codemodFlags) {
13
17
  const paths = [
14
18
  path.resolve(__dirname, './src', `${transform}/index.js`),
15
19
  path.resolve(__dirname, './src', `${transform}.js`),
@@ -57,6 +61,8 @@ async function runTransform(transform, files, flags, codemodFlags) {
57
61
  flags.parser || 'tsx',
58
62
  '--ignore-pattern',
59
63
  '**/node_modules/**',
64
+ '--ignore-pattern',
65
+ '**/*.css',
60
66
  ];
61
67
 
62
68
  if (flags.dry) {
@@ -80,15 +86,82 @@ async function runTransform(transform, files, flags, codemodFlags) {
80
86
  }
81
87
  }
82
88
 
89
+ const parseCssFilePaths = async (files) => {
90
+ const cssFiles = await Promise.all(
91
+ files.map(async (filePath) => {
92
+ const stat = await fs.stat(filePath);
93
+ if (stat.isDirectory()) {
94
+ return `${filePath}/**/*.css`;
95
+ }
96
+ if (filePath.endsWith('.css')) {
97
+ return filePath;
98
+ }
99
+
100
+ return null;
101
+ }),
102
+ );
103
+
104
+ return cssFiles.filter(Boolean);
105
+ };
106
+
107
+ async function runPostcssTransform(transform, files) {
108
+ // local postcss plugins are loaded through config files https://github.com/postcss/postcss-load-config/issues/17#issuecomment-253125559
109
+ const paths = [
110
+ path.resolve(__dirname, './src', `${transform}/postcss.config.js`),
111
+ path.resolve(__dirname, './node', `${transform}/postcss.config.js`),
112
+ ];
113
+
114
+ let configPath;
115
+ let error;
116
+ // eslint-disable-next-line no-restricted-syntax
117
+ for (const item of paths) {
118
+ try {
119
+ // eslint-disable-next-line no-await-in-loop
120
+ await fs.stat(item);
121
+ error = undefined;
122
+ configPath = item;
123
+ break;
124
+ } catch (srcPathError) {
125
+ error = srcPathError;
126
+ continue;
127
+ }
128
+ }
129
+
130
+ if (error) {
131
+ // don't throw if the file is not found, postcss transform is optional
132
+ if (error?.code !== 'ENOENT') {
133
+ throw error;
134
+ }
135
+ } else {
136
+ const cssPaths = await parseCssFilePaths(files);
137
+
138
+ if (cssPaths.length > 0) {
139
+ const args = [
140
+ postcssExecutable,
141
+ ...cssPaths,
142
+ '--config',
143
+ configPath,
144
+ '--replace',
145
+ '--verbose',
146
+ ];
147
+
148
+ // eslint-disable-next-line no-console -- debug information
149
+ console.log(`Executing command: postcss ${args.join(' ')}`);
150
+ const postcssProcess = childProcess.spawnSync('node', args, { stdio: 'inherit' });
151
+
152
+ if (postcssProcess.error) {
153
+ throw postcssProcess.error;
154
+ }
155
+ }
156
+ }
157
+ }
158
+
83
159
  function run(argv) {
84
160
  const { codemod, paths, ...flags } = argv;
161
+ const files = paths.map((filePath) => path.resolve(filePath));
85
162
 
86
- return runTransform(
87
- codemod,
88
- paths.map((filePath) => path.resolve(filePath)),
89
- flags,
90
- argv._,
91
- );
163
+ runJscodeshiftTransform(codemod, files, flags, argv._);
164
+ runPostcssTransform(codemod, files);
92
165
  }
93
166
 
94
167
  yargs
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = transformer;
7
+ var _postcssPlugin = require("./postcss-plugin");
8
+ /**
9
+ * @param {import('jscodeshift').FileInfo} file
10
+ * @param {import('jscodeshift').API} api
11
+ */
12
+ function transformer(file, api, options) {
13
+ const j = api.jscodeshift;
14
+ const root = j(file.source);
15
+ const printOptions = options.printOptions;
16
+
17
+ // contentGutters is a special case as it's applied to the content child
18
+ // but gutters is applied to the parent element, so the gutter class needs to go on the parent
19
+
20
+ root.find(j.ImportDeclaration).filter(path => path.node.source.value.match(/^@mui\/material\/AccordionSummary$/)).forEach(path => {
21
+ path.node.specifiers.forEach(specifier => {
22
+ if (specifier.type === 'ImportSpecifier' && specifier.imported.name === 'accordionSummaryClasses') {
23
+ root.find(j.MemberExpression, {
24
+ object: {
25
+ name: specifier.local.name
26
+ },
27
+ property: {
28
+ name: 'contentGutters'
29
+ }
30
+ }).forEach(memberExpression => {
31
+ const parent = memberExpression.parentPath.parentPath.value;
32
+ if (parent.type === j.TemplateLiteral.name) {
33
+ const memberExpressionIndex = parent.expressions.findIndex(expression => expression === memberExpression.value);
34
+ const precedingTemplateElement = parent.quasis[memberExpressionIndex];
35
+ if (precedingTemplateElement.value.raw.endsWith(' .')) {
36
+ parent.expressions.splice(memberExpressionIndex, 1, j.memberExpression(memberExpression.value.object, j.identifier('gutters')), j.memberExpression(memberExpression.value.object, j.identifier('content')));
37
+ parent.quasis.splice(memberExpressionIndex, 1, j.templateElement({
38
+ raw: precedingTemplateElement.value.raw.replace(' ', ''),
39
+ cooked: precedingTemplateElement.value.cooked.replace(' ', '')
40
+ }, false), j.templateElement({
41
+ raw: ' .',
42
+ cooked: ' .'
43
+ }, false));
44
+ }
45
+ }
46
+ });
47
+ }
48
+ });
49
+ });
50
+ const selectorRegex = new RegExp(`^& ${_postcssPlugin.deprecatedClass}`);
51
+ root.find(j.Literal, literal => typeof literal.value === 'string' && literal.value.match(selectorRegex)).forEach(path => {
52
+ path.replace(j.literal(path.value.value.replace(selectorRegex, `&${_postcssPlugin.replacementSelector}`)));
53
+ });
54
+ return root.toSource(printOptions);
55
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ Object.defineProperty(exports, "default", {
8
+ enumerable: true,
9
+ get: function () {
10
+ return _accordionSummaryClasses.default;
11
+ }
12
+ });
13
+ var _accordionSummaryClasses = _interopRequireDefault(require("./accordion-summary-classes"));
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+
3
+ const deprecatedClass = '.MuiAccordionSummary-contentGutters';
4
+ const replacementSelector = '.MuiAccordionSummary-gutters .MuiAccordionSummary-content';
5
+ const plugin = () => {
6
+ return {
7
+ postcssPlugin: `Replace ${deprecatedClass} with ${replacementSelector}`,
8
+ Rule(rule) {
9
+ const {
10
+ selector
11
+ } = rule;
12
+
13
+ // contentGutters is a special case as it's applied to the content child
14
+ // but gutters is applied to the parent element, so the gutter class needs to go on the parent
15
+
16
+ const selectorRegex = new RegExp(` ${deprecatedClass}`);
17
+ if (selector.match(selectorRegex)) {
18
+ rule.selector = selector.replace(selectorRegex, replacementSelector);
19
+ }
20
+ }
21
+ };
22
+ };
23
+ plugin.postcss = true;
24
+ module.exports = {
25
+ plugin,
26
+ deprecatedClass,
27
+ replacementSelector
28
+ };
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+
3
+ const {
4
+ plugin
5
+ } = require('./postcss-plugin');
6
+ module.exports = {
7
+ plugins: [plugin]
8
+ };
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+
3
+ var _AccordionSummary = require("@mui/material/AccordionSummary");
4
+ var _jsxRuntime = require("react/jsx-runtime");
5
+ fn({
6
+ MuiAccordionSummary: {
7
+ styleOverrides: {
8
+ root: {
9
+ '& .MuiAccordionSummary-contentGutters': {
10
+ color: 'red'
11
+ }
12
+ }
13
+ }
14
+ }
15
+ });
16
+ fn({
17
+ MuiAccordionSummary: {
18
+ styleOverrides: {
19
+ root: {
20
+ [`& .${_AccordionSummary.accordionSummaryClasses.contentGutters}`]: {
21
+ color: 'red'
22
+ }
23
+ }
24
+ }
25
+ }
26
+ });
27
+ styled(Component)(() => {
28
+ return {
29
+ '& .MuiAccordionSummary-contentGutters': {
30
+ color: 'red'
31
+ }
32
+ };
33
+ });
34
+ styled(Component)(() => {
35
+ return {
36
+ [`& .${_AccordionSummary.accordionSummaryClasses.contentGutters}`]: {
37
+ color: 'red'
38
+ }
39
+ };
40
+ });
41
+ /*#__PURE__*/(0, _jsxRuntime.jsx)(AccordionSummary, {
42
+ sx: {
43
+ '& .MuiAccordionSummary-contentGutters': {
44
+ color: 'red'
45
+ }
46
+ }
47
+ });
48
+ /*#__PURE__*/(0, _jsxRuntime.jsx)(AccordionSummary, {
49
+ sx: {
50
+ [`& .${_AccordionSummary.accordionSummaryClasses.contentGutters}`]: {
51
+ color: 'red'
52
+ }
53
+ }
54
+ });
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+
3
+ var _AccordionSummary = require("@mui/material/AccordionSummary");
4
+ var _jsxRuntime = require("react/jsx-runtime");
5
+ fn({
6
+ MuiAccordionSummary: {
7
+ styleOverrides: {
8
+ root: {
9
+ '&.MuiAccordionSummary-gutters .MuiAccordionSummary-content': {
10
+ color: 'red'
11
+ }
12
+ }
13
+ }
14
+ }
15
+ });
16
+ fn({
17
+ MuiAccordionSummary: {
18
+ styleOverrides: {
19
+ root: {
20
+ [`&.${_AccordionSummary.accordionSummaryClasses.gutters} .${_AccordionSummary.accordionSummaryClasses.content}`]: {
21
+ color: 'red'
22
+ }
23
+ }
24
+ }
25
+ }
26
+ });
27
+ styled(Component)(() => {
28
+ return {
29
+ '&.MuiAccordionSummary-gutters .MuiAccordionSummary-content': {
30
+ color: 'red'
31
+ }
32
+ };
33
+ });
34
+ styled(Component)(() => {
35
+ return {
36
+ [`&.${_AccordionSummary.accordionSummaryClasses.gutters} .${_AccordionSummary.accordionSummaryClasses.content}`]: {
37
+ color: 'red'
38
+ }
39
+ };
40
+ });
41
+ /*#__PURE__*/(0, _jsxRuntime.jsx)(AccordionSummary, {
42
+ sx: {
43
+ '&.MuiAccordionSummary-gutters .MuiAccordionSummary-content': {
44
+ color: 'red'
45
+ }
46
+ }
47
+ });
48
+ /*#__PURE__*/(0, _jsxRuntime.jsx)(AccordionSummary, {
49
+ sx: {
50
+ [`&.${_AccordionSummary.accordionSummaryClasses.gutters} .${_AccordionSummary.accordionSummaryClasses.content}`]: {
51
+ color: 'red'
52
+ }
53
+ }
54
+ });
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = transformer;
8
+ var _replaceComponentsWithSlots = _interopRequireDefault(require("../utils/replaceComponentsWithSlots"));
9
+ /**
10
+ * @param {import('jscodeshift').FileInfo} file
11
+ * @param {import('jscodeshift').API} api
12
+ */
13
+ function transformer(file, api, options) {
14
+ const j = api.jscodeshift;
15
+ const root = j(file.source);
16
+ const printOptions = options.printOptions;
17
+ (0, _replaceComponentsWithSlots.default)(j, {
18
+ root,
19
+ componentName: 'Alert'
20
+ });
21
+ return root.toSource(printOptions);
22
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ Object.defineProperty(exports, "default", {
8
+ enumerable: true,
9
+ get: function () {
10
+ return _alertProps.default;
11
+ }
12
+ });
13
+ var _alertProps = _interopRequireDefault(require("./alert-props"));
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _Alert = _interopRequireDefault(require("@mui/material/Alert"));
5
+ var _jsxRuntime = require("react/jsx-runtime");
6
+ /*#__PURE__*/(0, _jsxRuntime.jsx)(_Alert.default, {
7
+ components: {
8
+ CloseButton: ComponentsButton
9
+ },
10
+ componentsProps: {
11
+ closeButton: componentsButtonProps
12
+ }
13
+ });
14
+ /*#__PURE__*/(0, _jsxRuntime.jsx)(_Alert.default, {
15
+ slots: {
16
+ closeIcon: SlotsIcon
17
+ },
18
+ components: {
19
+ CloseButton: ComponentsButton
20
+ },
21
+ slotProps: {
22
+ closeIcon: slotsIconProps
23
+ },
24
+ componentsProps: {
25
+ closeButton: componentsButtonProps
26
+ }
27
+ });
28
+ /*#__PURE__*/(0, _jsxRuntime.jsx)(_Alert.default, {
29
+ slots: {
30
+ closeIcon: SlotsIcon,
31
+ closeButton: SlotsButton
32
+ },
33
+ components: {
34
+ CloseButton: ComponentsButton
35
+ },
36
+ slotProps: {
37
+ closeIcon: slotsIconProps,
38
+ closeButton: slotsButtonProps
39
+ },
40
+ componentsProps: {
41
+ closeButton: componentsButtonProps
42
+ }
43
+ });
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _Alert = _interopRequireDefault(require("@mui/material/Alert"));
5
+ var _jsxRuntime = require("react/jsx-runtime");
6
+ /*#__PURE__*/(0, _jsxRuntime.jsx)(_Alert.default, {
7
+ slots: {
8
+ closeButton: ComponentsButton
9
+ },
10
+ slotProps: {
11
+ closeButton: componentsButtonProps
12
+ }
13
+ });
14
+ /*#__PURE__*/(0, _jsxRuntime.jsx)(_Alert.default, {
15
+ slots: {
16
+ closeIcon: SlotsIcon,
17
+ closeButton: ComponentsButton
18
+ },
19
+ slotProps: {
20
+ closeIcon: slotsIconProps,
21
+ closeButton: componentsButtonProps
22
+ }
23
+ });
24
+ /*#__PURE__*/(0, _jsxRuntime.jsx)(_Alert.default, {
25
+ slots: {
26
+ closeIcon: SlotsIcon,
27
+ closeButton: SlotsButton
28
+ },
29
+ slotProps: {
30
+ closeIcon: slotsIconProps,
31
+ closeButton: slotsButtonProps
32
+ }
33
+ });
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+
3
+ fn({
4
+ MuiAlert: {
5
+ defaultProps: {
6
+ components: {
7
+ CloseButton: ComponentsButton
8
+ },
9
+ componentsProps: {
10
+ closeButton: componentsButtonProps
11
+ }
12
+ }
13
+ }
14
+ });
15
+ fn({
16
+ MuiAlert: {
17
+ defaultProps: {
18
+ components: {
19
+ CloseButton: ComponentsButton
20
+ },
21
+ slots: {
22
+ closeIcon: SlotsIcon
23
+ },
24
+ componentsProps: {
25
+ closeButton: componentsButtonProps
26
+ },
27
+ slotProps: {
28
+ closeIcon: slotsIconProps
29
+ }
30
+ }
31
+ }
32
+ });
33
+ fn({
34
+ MuiAlert: {
35
+ defaultProps: {
36
+ components: {
37
+ CloseButton: ComponentsButton
38
+ },
39
+ slots: {
40
+ closeIcon: SlotsIcon,
41
+ closeButton: SlotsButton
42
+ },
43
+ componentsProps: {
44
+ closeButton: componentsButtonProps
45
+ },
46
+ slotProps: {
47
+ closeIcon: slotsIconProps,
48
+ closeButton: slotsButtonProps
49
+ }
50
+ }
51
+ }
52
+ });
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+
3
+ fn({
4
+ MuiAlert: {
5
+ defaultProps: {
6
+ slots: {
7
+ closeButton: ComponentsButton
8
+ },
9
+ slotProps: {
10
+ closeButton: componentsButtonProps
11
+ }
12
+ }
13
+ }
14
+ });
15
+ fn({
16
+ MuiAlert: {
17
+ defaultProps: {
18
+ slots: {
19
+ closeButton: ComponentsButton,
20
+ closeIcon: SlotsIcon
21
+ },
22
+ slotProps: {
23
+ closeButton: componentsButtonProps,
24
+ closeIcon: slotsIconProps
25
+ }
26
+ }
27
+ }
28
+ });
29
+ fn({
30
+ MuiAlert: {
31
+ defaultProps: {
32
+ slots: {
33
+ closeButton: SlotsButton,
34
+ closeIcon: SlotsIcon
35
+ },
36
+ slotProps: {
37
+ closeButton: slotsButtonProps,
38
+ closeIcon: slotsIconProps
39
+ }
40
+ }
41
+ }
42
+ });
@@ -8,6 +8,8 @@ exports.default = deprecationsAll;
8
8
  var _accordionProps = _interopRequireDefault(require("../accordion-props"));
9
9
  var _avatarProps = _interopRequireDefault(require("../avatar-props"));
10
10
  var _dividerProps = _interopRequireDefault(require("../divider-props"));
11
+ var _accordionSummaryClasses = _interopRequireDefault(require("../accordion-summary-classes"));
12
+ var _paginationItemClasses = _interopRequireDefault(require("../pagination-item-classes"));
11
13
  /**
12
14
  * @param {import('jscodeshift').FileInfo} file
13
15
  * @param {import('jscodeshift').API} api
@@ -16,5 +18,7 @@ function deprecationsAll(file, api, options) {
16
18
  file.source = (0, _accordionProps.default)(file, api, options);
17
19
  file.source = (0, _avatarProps.default)(file, api, options);
18
20
  file.source = (0, _dividerProps.default)(file, api, options);
21
+ file.source = (0, _accordionSummaryClasses.default)(file, api, options);
22
+ file.source = (0, _paginationItemClasses.default)(file, api, options);
19
23
  return file.source;
20
24
  }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+
3
+ const {
4
+ plugin: accordionSummaryClassesPlugin
5
+ } = require('../accordion-summary-classes/postcss-plugin');
6
+ const {
7
+ plugin: paginationItemClassesPlugin
8
+ } = require('../pagination-item-classes/postcss-plugin');
9
+ module.exports = {
10
+ plugins: [accordionSummaryClassesPlugin, paginationItemClassesPlugin]
11
+ };
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ Object.defineProperty(exports, "default", {
8
+ enumerable: true,
9
+ get: function () {
10
+ return _paginationItemClasses.default;
11
+ }
12
+ });
13
+ var _paginationItemClasses = _interopRequireDefault(require("./pagination-item-classes"));
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = transformer;
7
+ var _postcssPlugin = require("./postcss-plugin");
8
+ /**
9
+ * @param {import('jscodeshift').FileInfo} file
10
+ * @param {import('jscodeshift').API} api
11
+ */
12
+ function transformer(file, api, options) {
13
+ const j = api.jscodeshift;
14
+ const root = j(file.source);
15
+ const printOptions = options.printOptions;
16
+ _postcssPlugin.classes.forEach(({
17
+ deprecatedClass,
18
+ replacementSelector
19
+ }) => {
20
+ root.find(j.ImportDeclaration).filter(path => path.node.source.value.match(/^@mui\/material\/PaginationItem$/)).forEach(path => {
21
+ path.node.specifiers.forEach(specifier => {
22
+ if (specifier.type === 'ImportSpecifier' && specifier.imported.name === 'paginationItemClasses') {
23
+ const deprecatedAtomicClass = deprecatedClass.replace('.MuiPaginationItem-', '');
24
+ root.find(j.MemberExpression, {
25
+ object: {
26
+ name: specifier.local.name
27
+ },
28
+ property: {
29
+ name: deprecatedAtomicClass
30
+ }
31
+ }).forEach(memberExpression => {
32
+ const parent = memberExpression.parentPath.parentPath.value;
33
+ if (parent.type === j.TemplateLiteral.name) {
34
+ const memberExpressionIndex = parent.expressions.findIndex(expression => expression === memberExpression.value);
35
+ const precedingTemplateElement = parent.quasis[memberExpressionIndex];
36
+ const atomicClasses = replacementSelector.replaceAll('MuiPaginationItem-', '').replaceAll('&.', '').split('.').filter(Boolean);
37
+ if (precedingTemplateElement.value.raw.endsWith('&.')) {
38
+ parent.expressions.splice(memberExpressionIndex, 1, j.memberExpression(memberExpression.value.object, j.identifier(atomicClasses[0])), j.memberExpression(memberExpression.value.object, j.identifier(atomicClasses[1])));
39
+ parent.quasis.splice(memberExpressionIndex, 1, j.templateElement({
40
+ raw: precedingTemplateElement.value.raw,
41
+ cooked: precedingTemplateElement.value.cooked
42
+ }, false), j.templateElement({
43
+ raw: '.',
44
+ cooked: '.'
45
+ }, false));
46
+ }
47
+ }
48
+ });
49
+ }
50
+ });
51
+ });
52
+ const selectorRegex = new RegExp(`^&${deprecatedClass}`);
53
+ root.find(j.Literal, literal => typeof literal.value === 'string' && literal.value.match(selectorRegex)).forEach(path => {
54
+ path.replace(j.literal(path.value.value.replace(selectorRegex, `&${replacementSelector}`)));
55
+ });
56
+ });
57
+ return root.toSource(printOptions);
58
+ }
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+
3
+ const classes = [{
4
+ deprecatedClass: '.MuiPaginationItem-textPrimary',
5
+ replacementSelector: '.MuiPaginationItem-text.MuiPaginationItem-colorPrimary'
6
+ }, {
7
+ deprecatedClass: '.MuiPaginationItem-textSecondary',
8
+ replacementSelector: '.MuiPaginationItem-text.MuiPaginationItem-colorSecondary'
9
+ }, {
10
+ deprecatedClass: '.MuiPaginationItem-outlinedPrimary',
11
+ replacementSelector: '.MuiPaginationItem-outlined.MuiPaginationItem-colorPrimary'
12
+ }, {
13
+ deprecatedClass: '.MuiPaginationItem-outlinedSecondary',
14
+ replacementSelector: '.MuiPaginationItem-outlined.MuiPaginationItem-colorSecondary'
15
+ }];
16
+ const plugin = () => {
17
+ return {
18
+ postcssPlugin: `Replace deperecated PaginationItem classes with new classes`,
19
+ Rule(rule) {
20
+ const {
21
+ selector
22
+ } = rule;
23
+ classes.forEach(({
24
+ deprecatedClass,
25
+ replacementSelector
26
+ }) => {
27
+ const selectorRegex = new RegExp(`${deprecatedClass}`);
28
+ if (selector.match(selectorRegex)) {
29
+ rule.selector = selector.replace(selectorRegex, replacementSelector);
30
+ }
31
+ });
32
+ }
33
+ };
34
+ };
35
+ plugin.postcss = true;
36
+ module.exports = {
37
+ plugin,
38
+ classes
39
+ };
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+
3
+ const {
4
+ plugin
5
+ } = require('./postcss-plugin');
6
+ module.exports = {
7
+ plugins: [plugin]
8
+ };
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+
3
+ var _PaginationItem = require("@mui/material/PaginationItem");
4
+ var _jsxRuntime = require("react/jsx-runtime");
5
+ fn({
6
+ MuiPaginationItem: {
7
+ styleOverrides: {
8
+ root: {
9
+ '&.MuiPaginationItem-textPrimary': {
10
+ color: 'red'
11
+ },
12
+ '&.MuiPaginationItem-textSecondary': {
13
+ color: 'red'
14
+ },
15
+ '&.MuiPaginationItem-outlinedPrimary': {
16
+ color: 'red'
17
+ },
18
+ '&.MuiPaginationItem-outlinedSecondary': {
19
+ color: 'red'
20
+ }
21
+ }
22
+ }
23
+ }
24
+ });
25
+ fn({
26
+ MuiPaginationItem: {
27
+ styleOverrides: {
28
+ root: {
29
+ [`&.${_PaginationItem.paginationItemClasses.textPrimary}`]: {
30
+ color: 'red'
31
+ },
32
+ [`&.${_PaginationItem.paginationItemClasses.textSecondary}`]: {
33
+ color: 'red'
34
+ },
35
+ [`&.${_PaginationItem.paginationItemClasses.outlinedPrimary}`]: {
36
+ color: 'red'
37
+ },
38
+ [`&.${_PaginationItem.paginationItemClasses.outlinedSecondary}`]: {
39
+ color: 'red'
40
+ }
41
+ }
42
+ }
43
+ }
44
+ });
45
+ styled(Component)(() => {
46
+ return {
47
+ '&.MuiPaginationItem-textPrimary': {
48
+ color: 'red'
49
+ },
50
+ '&.MuiPaginationItem-textSecondary': {
51
+ color: 'red'
52
+ },
53
+ '&.MuiPaginationItem-outlinedPrimary': {
54
+ color: 'red'
55
+ },
56
+ '&.MuiPaginationItem-outlinedSecondary': {
57
+ color: 'red'
58
+ }
59
+ };
60
+ });
61
+ styled(Component)(() => {
62
+ return {
63
+ [`&.${_PaginationItem.paginationItemClasses.textPrimary}`]: {
64
+ color: 'red'
65
+ },
66
+ [`&.${_PaginationItem.paginationItemClasses.textSecondary}`]: {
67
+ color: 'red'
68
+ },
69
+ [`&.${_PaginationItem.paginationItemClasses.outlinedPrimary}`]: {
70
+ color: 'red'
71
+ },
72
+ [`&.${_PaginationItem.paginationItemClasses.outlinedSecondary}`]: {
73
+ color: 'red'
74
+ }
75
+ };
76
+ });
77
+ /*#__PURE__*/(0, _jsxRuntime.jsx)(PaginationItem, {
78
+ sx: {
79
+ '&.MuiPaginationItem-textPrimary': {
80
+ color: 'red'
81
+ },
82
+ '&.MuiPaginationItem-textSecondary': {
83
+ color: 'red'
84
+ },
85
+ '&.MuiPaginationItem-outlinedPrimary': {
86
+ color: 'red'
87
+ },
88
+ '&.MuiPaginationItem-outlinedSecondary': {
89
+ color: 'red'
90
+ }
91
+ }
92
+ });
93
+ /*#__PURE__*/(0, _jsxRuntime.jsx)(PaginationItem, {
94
+ sx: {
95
+ [`&.${_PaginationItem.paginationItemClasses.textPrimary}`]: {
96
+ color: 'red'
97
+ },
98
+ [`&.${_PaginationItem.paginationItemClasses.textSecondary}`]: {
99
+ color: 'red'
100
+ },
101
+ [`&.${_PaginationItem.paginationItemClasses.outlinedPrimary}`]: {
102
+ color: 'red'
103
+ },
104
+ [`&.${_PaginationItem.paginationItemClasses.outlinedSecondary}`]: {
105
+ color: 'red'
106
+ }
107
+ }
108
+ });
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+
3
+ var _PaginationItem = require("@mui/material/PaginationItem");
4
+ var _jsxRuntime = require("react/jsx-runtime");
5
+ fn({
6
+ MuiPaginationItem: {
7
+ styleOverrides: {
8
+ root: {
9
+ "&.MuiPaginationItem-text.MuiPaginationItem-colorPrimary": {
10
+ color: 'red'
11
+ },
12
+ "&.MuiPaginationItem-text.MuiPaginationItem-colorSecondary": {
13
+ color: 'red'
14
+ },
15
+ "&.MuiPaginationItem-outlined.MuiPaginationItem-colorPrimary": {
16
+ color: 'red'
17
+ },
18
+ "&.MuiPaginationItem-outlined.MuiPaginationItem-colorSecondary": {
19
+ color: 'red'
20
+ }
21
+ }
22
+ }
23
+ }
24
+ });
25
+ fn({
26
+ MuiPaginationItem: {
27
+ styleOverrides: {
28
+ root: {
29
+ [`&.${_PaginationItem.paginationItemClasses.text}.${_PaginationItem.paginationItemClasses.colorPrimary}`]: {
30
+ color: 'red'
31
+ },
32
+ [`&.${_PaginationItem.paginationItemClasses.text}.${_PaginationItem.paginationItemClasses.colorSecondary}`]: {
33
+ color: 'red'
34
+ },
35
+ [`&.${_PaginationItem.paginationItemClasses.outlined}.${_PaginationItem.paginationItemClasses.colorPrimary}`]: {
36
+ color: 'red'
37
+ },
38
+ [`&.${_PaginationItem.paginationItemClasses.outlined}.${_PaginationItem.paginationItemClasses.colorSecondary}`]: {
39
+ color: 'red'
40
+ }
41
+ }
42
+ }
43
+ }
44
+ });
45
+ styled(Component)(() => {
46
+ return {
47
+ "&.MuiPaginationItem-text.MuiPaginationItem-colorPrimary": {
48
+ color: 'red'
49
+ },
50
+ "&.MuiPaginationItem-text.MuiPaginationItem-colorSecondary": {
51
+ color: 'red'
52
+ },
53
+ "&.MuiPaginationItem-outlined.MuiPaginationItem-colorPrimary": {
54
+ color: 'red'
55
+ },
56
+ "&.MuiPaginationItem-outlined.MuiPaginationItem-colorSecondary": {
57
+ color: 'red'
58
+ }
59
+ };
60
+ });
61
+ styled(Component)(() => {
62
+ return {
63
+ [`&.${_PaginationItem.paginationItemClasses.text}.${_PaginationItem.paginationItemClasses.colorPrimary}`]: {
64
+ color: 'red'
65
+ },
66
+ [`&.${_PaginationItem.paginationItemClasses.text}.${_PaginationItem.paginationItemClasses.colorSecondary}`]: {
67
+ color: 'red'
68
+ },
69
+ [`&.${_PaginationItem.paginationItemClasses.outlined}.${_PaginationItem.paginationItemClasses.colorPrimary}`]: {
70
+ color: 'red'
71
+ },
72
+ [`&.${_PaginationItem.paginationItemClasses.outlined}.${_PaginationItem.paginationItemClasses.colorSecondary}`]: {
73
+ color: 'red'
74
+ }
75
+ };
76
+ });
77
+ /*#__PURE__*/(0, _jsxRuntime.jsx)(PaginationItem, {
78
+ sx: {
79
+ "&.MuiPaginationItem-text.MuiPaginationItem-colorPrimary": {
80
+ color: 'red'
81
+ },
82
+ "&.MuiPaginationItem-text.MuiPaginationItem-colorSecondary": {
83
+ color: 'red'
84
+ },
85
+ "&.MuiPaginationItem-outlined.MuiPaginationItem-colorPrimary": {
86
+ color: 'red'
87
+ },
88
+ "&.MuiPaginationItem-outlined.MuiPaginationItem-colorSecondary": {
89
+ color: 'red'
90
+ }
91
+ }
92
+ });
93
+ /*#__PURE__*/(0, _jsxRuntime.jsx)(PaginationItem, {
94
+ sx: {
95
+ [`&.${_PaginationItem.paginationItemClasses.text}.${_PaginationItem.paginationItemClasses.colorPrimary}`]: {
96
+ color: 'red'
97
+ },
98
+ [`&.${_PaginationItem.paginationItemClasses.text}.${_PaginationItem.paginationItemClasses.colorSecondary}`]: {
99
+ color: 'red'
100
+ },
101
+ [`&.${_PaginationItem.paginationItemClasses.outlined}.${_PaginationItem.paginationItemClasses.colorPrimary}`]: {
102
+ color: 'red'
103
+ },
104
+ [`&.${_PaginationItem.paginationItemClasses.outlined}.${_PaginationItem.paginationItemClasses.colorSecondary}`]: {
105
+ color: 'red'
106
+ }
107
+ }
108
+ });
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = replaceComponentsWithSlots;
8
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
+ var _findComponentJSX = _interopRequireDefault(require("../../util/findComponentJSX"));
10
+ var _findComponentDefaultProps = _interopRequireDefault(require("../../util/findComponentDefaultProps"));
11
+ var _assignObject = _interopRequireDefault(require("../../util/assignObject"));
12
+ var _appendAttribute = _interopRequireDefault(require("../../util/appendAttribute"));
13
+ function componentsKeyToSlotsKey(str) {
14
+ return str[0].toLowerCase() + str.slice(1);
15
+ }
16
+ function replaceJsxComponentsProp(j, elementPath) {
17
+ const element = elementPath.node;
18
+ const index = element.openingElement.attributes.findIndex(attr => attr.type === 'JSXAttribute' && attr.name.name === 'components');
19
+ if (index !== -1) {
20
+ const removed = element.openingElement.attributes.splice(index, 1);
21
+ const camelCaseComponents = removed[0].value.expression.properties.reduce((acc, prop) => {
22
+ return (0, _extends2.default)({}, acc, {
23
+ [componentsKeyToSlotsKey(prop.key.name)]: prop.value
24
+ });
25
+ }, {});
26
+ let hasNode = false;
27
+ element.openingElement.attributes.forEach(attr => {
28
+ var _attr$name;
29
+ if (((_attr$name = attr.name) == null ? void 0 : _attr$name.name) === 'slots') {
30
+ hasNode = true;
31
+ const slots = attr.value.expression.properties.reduce((acc, prop) => {
32
+ return (0, _extends2.default)({}, acc, {
33
+ [prop.key.name]: prop.value
34
+ });
35
+ }, {});
36
+ Object.entries(camelCaseComponents).forEach(([slot, value]) => {
37
+ if (!slots[slot]) {
38
+ (0, _assignObject.default)(j, {
39
+ target: attr,
40
+ key: slot,
41
+ expression: value
42
+ });
43
+ }
44
+ });
45
+ }
46
+ });
47
+ if (!hasNode) {
48
+ (0, _appendAttribute.default)(j, {
49
+ target: element,
50
+ attributeName: 'slots',
51
+ expression: j.objectExpression(Object.entries(camelCaseComponents).map(([slot, value]) => {
52
+ return j.objectProperty(j.identifier(slot), value);
53
+ }))
54
+ });
55
+ }
56
+ }
57
+ }
58
+ function replaceJsxComponentsPropsProp(j, element) {
59
+ const index = element.openingElement.attributes.findIndex(attr => attr.type === 'JSXAttribute' && attr.name.name === 'componentsProps');
60
+ if (index !== -1) {
61
+ const removed = element.openingElement.attributes.splice(index, 1);
62
+ let hasNode = false;
63
+ element.openingElement.attributes.forEach(attr => {
64
+ var _attr$name2;
65
+ if (((_attr$name2 = attr.name) == null ? void 0 : _attr$name2.name) === 'slotProps') {
66
+ hasNode = true;
67
+ const slotProps = attr.value.expression.properties.reduce((acc, prop) => {
68
+ return (0, _extends2.default)({}, acc, {
69
+ [prop.key.name]: prop.value
70
+ });
71
+ }, {});
72
+ removed[0].value.expression.properties.forEach(prop => {
73
+ if (!slotProps[prop.key.name]) {
74
+ (0, _assignObject.default)(j, {
75
+ target: attr,
76
+ key: prop.key.name,
77
+ expression: prop.value
78
+ });
79
+ }
80
+ });
81
+ }
82
+ });
83
+ if (!hasNode) {
84
+ (0, _appendAttribute.default)(j, {
85
+ target: element,
86
+ attributeName: 'slotProps',
87
+ expression: removed[0].value.expression
88
+ });
89
+ }
90
+ }
91
+ }
92
+ function replaceDefaultPropsComponentsProp(j, defaultPropsPathCollection) {
93
+ defaultPropsPathCollection.find(j.ObjectProperty, {
94
+ key: {
95
+ name: 'components'
96
+ }
97
+ }).forEach(path => {
98
+ const {
99
+ properties: defaultPropsProperties
100
+ } = path.parent.value;
101
+ const components = path.value.value.properties.reduce((acc, prop) => {
102
+ return (0, _extends2.default)({}, acc, {
103
+ [componentsKeyToSlotsKey(prop.key.name)]: prop.value
104
+ });
105
+ }, {});
106
+ const existingSlots = defaultPropsProperties.find(prop => prop.key.name === 'slots');
107
+ const slots = existingSlots ? existingSlots.value.properties.reduce((acc, prop) => {
108
+ return (0, _extends2.default)({}, acc, {
109
+ [prop.key.name]: prop.value
110
+ });
111
+ }, {}) : {};
112
+ const updatedSlots = j.objectExpression(Object.entries((0, _extends2.default)({}, components, slots)).map(([slot, value]) => {
113
+ return j.objectProperty(j.identifier(slot), value);
114
+ }));
115
+ if (existingSlots) {
116
+ existingSlots.value = updatedSlots;
117
+ } else {
118
+ defaultPropsProperties.push(j.property('init', j.identifier('slots'), updatedSlots));
119
+ }
120
+ path.prune();
121
+ });
122
+ }
123
+ function replaceDefaultPropsComponentsPropsProp(j, defaultPropsPathCollection) {
124
+ defaultPropsPathCollection.find(j.ObjectProperty, {
125
+ key: {
126
+ name: 'componentsProps'
127
+ }
128
+ }).forEach(path => {
129
+ const {
130
+ properties: defaultPropsProperties
131
+ } = path.parent.value;
132
+ const components = path.value.value.properties.reduce((acc, prop) => {
133
+ return (0, _extends2.default)({}, acc, {
134
+ [prop.key.name]: prop.value
135
+ });
136
+ }, {});
137
+ const existingSlots = defaultPropsProperties.find(prop => prop.key.name === 'slotProps');
138
+ const slots = existingSlots ? existingSlots.value.properties.reduce((acc, prop) => {
139
+ return (0, _extends2.default)({}, acc, {
140
+ [prop.key.name]: prop.value
141
+ });
142
+ }, {}) : {};
143
+ const updatedSlots = j.objectExpression(Object.entries((0, _extends2.default)({}, components, slots)).map(([slot, value]) => {
144
+ return j.objectProperty(j.identifier(slot), value);
145
+ }));
146
+ if (existingSlots) {
147
+ existingSlots.value = updatedSlots;
148
+ } else {
149
+ defaultPropsProperties.push(j.property('init', j.identifier('slotProps'), updatedSlots));
150
+ }
151
+ path.prune();
152
+ });
153
+ }
154
+
155
+ /**
156
+ * Replaces components and componentsProps props with slots and slotProps.
157
+ * Handles local object and variable declaration.
158
+ * If the slots prop exists, it will add the components to the slots.
159
+ * If there are duplicated values, the slots values will be used.
160
+ *
161
+ * @param {import('jscodeshift')} j
162
+ * @param {{ element: import('jscodeshift').JSXElement }} options
163
+ *
164
+ * @example <Component componentsProps={{ root: { 'testid': 'root-id'} }} /> => <Component slotProps={{ root: { 'testid': 'root-id'} }} />
165
+ */
166
+ function replaceComponentsWithSlots(j, options) {
167
+ const {
168
+ root,
169
+ componentName
170
+ } = options;
171
+ (0, _findComponentJSX.default)(j, {
172
+ root,
173
+ componentName
174
+ }, elementPath => {
175
+ replaceJsxComponentsProp(j, elementPath);
176
+ replaceJsxComponentsPropsProp(j, elementPath.node);
177
+ });
178
+ const defaultPropsPathCollection = (0, _findComponentDefaultProps.default)(j, {
179
+ root,
180
+ componentName
181
+ });
182
+ replaceDefaultPropsComponentsProp(j, defaultPropsPathCollection);
183
+ replaceDefaultPropsComponentsPropsProp(j, defaultPropsPathCollection);
184
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = findComponentDefaultProps;
7
+ /**
8
+ * Find all the default props path of a given component name.
9
+ *
10
+ * @param {import('jscodeshift')} j
11
+ * @param {{ root: import('jscodeshift').Collection; componentName: string }} options
12
+ * @returns {import('jscodeshift').Collection}
13
+ *
14
+ */
15
+ function findComponentDefaultProps(j, options) {
16
+ const {
17
+ root,
18
+ componentName
19
+ } = options;
20
+ const defaultPropsPathCollection = root.find(j.ObjectProperty, {
21
+ key: {
22
+ name: `Mui${componentName}`
23
+ }
24
+ }).find(j.ObjectProperty, {
25
+ key: {
26
+ name: 'defaultProps'
27
+ }
28
+ });
29
+ return defaultPropsPathCollection;
30
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/codemod",
3
- "version": "5.15.10",
3
+ "version": "5.15.11",
4
4
  "bin": "./codemod.js",
5
5
  "private": false,
6
6
  "author": "MUI Team",
@@ -29,6 +29,8 @@
29
29
  "@babel/traverse": "^7.23.9",
30
30
  "jscodeshift": "^0.13.1",
31
31
  "jscodeshift-add-imports": "^1.0.10",
32
+ "postcss": "^8.4.33",
33
+ "postcss-cli": "^8.0.0",
32
34
  "yargs": "^17.7.2"
33
35
  },
34
36
  "devDependencies": {