@mui/x-codemod 6.0.0-beta.0 → 6.0.0-beta.1

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.
package/README.md CHANGED
@@ -87,9 +87,14 @@ The list includes these transformers
87
87
 
88
88
  - [`adapter-change-import`](#adapter-change-import)
89
89
  - [`view-components-rename`](#view-components-rename)
90
- - [`view-components-rename-value-prop`](#view-components-rename)
90
+ - [`view-components-rename-value-prop`](#view-components-rename-value-prop)
91
91
  - [`localization-provider-rename-locale`](#localization-provider-rename-locale)
92
92
  - [`text-props-to-localeText`](#text-props-to-localeText)
93
+ - [`replace-tabs-props`](#replace-tabs-props)
94
+ - [`replace-toolbar-props-by-slot`](#replace-toolbar-props-by-slot)
95
+ - [`migrate-to-components-componentsProps`](#migrate-to-components-componentsProps)
96
+ - [`replace-arrows-button-slot`](#replace-arrows-button-slot)
97
+ - [`rename-should-disable-time`](#rename-should-disable-time)
93
98
 
94
99
  #### `adapter-change-import`
95
100
 
@@ -196,6 +201,165 @@ If you were always using the same text value in all your components, consider mo
196
201
 
197
202
  You can find more details about Date and Time breaking changes in [the migration guide](https://next.mui.com/x/migration/migration-pickers-v5/).
198
203
 
204
+ #### `replace-tabs-props`
205
+
206
+ Replace props used for `Tabs` in DateTime pickers by `componentsProps.tabs` properties.
207
+
208
+ ```diff
209
+ <DateTimePicker
210
+ - hideTabs={false}
211
+ - dateRangeIcon={<LightModeIcon />}
212
+ - timeIcon={<AcUnitIcon />}
213
+ + componentsProps={{
214
+ + tabs: {
215
+ + hidden: false,
216
+ + dateIcon: <LightModeIcon />,
217
+ + timeIcon: <AcUnitIcon />,
218
+ + }
219
+ + }}
220
+ />
221
+ ```
222
+
223
+ ```sh
224
+ npx @mui/x-codemod v6.0.0/pickers/replace-tabs-props <path>
225
+ ```
226
+
227
+ #### `replace-toolbar-props-by-slot`
228
+
229
+ Replace props used to customize the `Toolbar` in pickers by slots properties and `localeText`.
230
+
231
+ ```diff
232
+ <DatePicker
233
+ - ToolbarComponent={MyToolbar}
234
+ + components={{ Toolbar: MyToolbar }}
235
+ - toolbarPlaceholder="__"
236
+ - toolbarFormat="DD / MM / YYYY"
237
+ - showToolbar
238
+ + componentsProps={{
239
+ + toolbar: {
240
+ + toolbarPlaceholder: "__",
241
+ + toolbarFormat: "DD / MM / YYYY",
242
+ + hidden: false,
243
+ + }
244
+ + }}
245
+ - toolbarTitle="Title"
246
+ + localeText={{ toolbarTitle: "Title" }}
247
+ ```
248
+
249
+ ```sh
250
+ npx @mui/x-codemod v6.0.0/pickers/replace-toolbar-props-by-slot <path>
251
+ ```
252
+
253
+ #### `migrate-to-components-componentsProps`
254
+
255
+ Replace customization props by their equivalent `components` and `componentsProps` properties.
256
+
257
+ ```diff
258
+ <DatePicker
259
+ - PopperProps={{ onClick: handleClick }}
260
+ + componentsProps={{ popper: { onClick: handleClick }}}
261
+ />
262
+
263
+ <DatePicker
264
+ - TransitionComponent={Fade}
265
+ + components={{ DesktopTransition: Fade }}
266
+ />
267
+
268
+ <DatePicker
269
+ - DialogProps={{ backgroundColor: 'red' }}
270
+ + componentsProps={{ dialog: { backgroundColor: 'red' }}}
271
+ />
272
+
273
+ <DatePicker
274
+ - PaperProps={{ backgroundColor: 'red' }}
275
+ + componentsProps={{ desktopPaper: { backgroundColor: 'red' }}}
276
+ />
277
+
278
+ <DatePicker
279
+ - TrapFocusProps={{ isEnabled: () => false }}
280
+ + componentsProps={{ desktopTrapFocus: { isEnabled: () => false }}}
281
+ />
282
+
283
+ <DatePicker
284
+ - InputProps={{ color: 'primary' }}
285
+ + componentsProps={{ textField: { InputProps: { color: 'primary' }}}}
286
+ />
287
+
288
+ <DatePicker
289
+ - InputAdornmentProps={{ position: 'start' }}
290
+ + componentsProps={{ inputAdornment: { position: 'start' }}}
291
+ />
292
+
293
+ <DatePicker
294
+ - OpenPickerButtonProps={{ ref: buttonRef }}
295
+ + componentsProps={{ openPickerButton: { ref: buttonRef }}}
296
+ />
297
+ ```
298
+
299
+ ```sh
300
+ npx @mui/x-codemod v6.0.0/pickers/migrate-to-components-componentsProps <path>
301
+ ```
302
+
303
+ #### `replace-arrows-button-slot`
304
+
305
+ Replace `LeftArrowButton` and `RightArrowButton` slots for navigation buttons by `PreviousIconButton` and `NextIconButton`.
306
+
307
+ ```diff
308
+ <DatePicker
309
+ components={{
310
+ - LeftArrowButton: CustomButton,
311
+ + PreviousIconButton: CustomButton,
312
+ - RightArrowButton: CustomButton,
313
+ + NextIconButton: CustomButton,
314
+ }}
315
+
316
+ componentsProps={{
317
+ - leftArrowButton: {},
318
+ + previousIconButton: {},
319
+ - rightArrowButton: {},
320
+ + nextIconButton: {},
321
+ }}
322
+ />
323
+ ```
324
+
325
+ ```sh
326
+ npx @mui/x-codemod v6.0.0/pickers/replace-arrows-button-slot <path>
327
+ ```
328
+
329
+ #### `rename-should-disable-time`
330
+
331
+ Replace `shouldDisableTime` by `shouldDisableClock`.
332
+
333
+ ```diff
334
+ <DateTimePicker
335
+ - shouldDisableTime={(timeValue, view) => view === 'hours' && timeValue < 12}
336
+ + shouldDisableClock={(timeValue, view) => view === 'hours' && timeValue < 12}
337
+ />
338
+ ```
339
+
340
+ ```sh
341
+ npx @mui/x-codemod v6.0.0/pickers/rename-should-disable-time <path>
342
+ ```
343
+
344
+ #### `rename-components-to-slots`
345
+
346
+ Renames the `components` and `componentsProps` props to `slots` and `slotProps`, respectively.
347
+
348
+ This change only affects pickers components.
349
+
350
+ ```diff
351
+ <DatePicker
352
+ - components={{ Toolbar: CustomToolbar }}
353
+ + slots={{ toolbar: CustomToolbar }}
354
+ - componentsProps={{ actionBar: { actions: ['clear'] } }}
355
+ + slotProps={{ actionBar: { actions: ['clear'] } }}
356
+ />;
357
+ ```
358
+
359
+ ```sh
360
+ npx @mui/x-codemod v6.0.0/pickers/rename-components-to-slots <path>
361
+ ```
362
+
199
363
  ### Data grid codemods
200
364
 
201
365
  #### `preset-safe` for data grid
@@ -209,25 +373,28 @@ npx @mui/x-codemod v6.0.0/data-grid/preset-safe <path|folder>
209
373
  The list includes these transformers
210
374
 
211
375
  - [`column-menu-components-rename`](#column-menu-components-rename)
376
+ - [`row-selection-props-rename`](#row-selection-props-rename)
377
+ - [`rename-rowsPerPageOptions-prop`](#rename-rowsPerPageOptions-prop)
212
378
  - [`remove-disableExtendRowFullWidth-prop`](#remove-disableExtendRowFullWidth-prop)
379
+ - [`rename-selectors-and-events`](#rename-selectors-and-events)
213
380
 
214
381
  #### `column-menu-components-rename`
215
382
 
216
383
  Replace column menu items that have been renamed.
217
384
 
218
385
  ```diff
219
- <CustomColumnMenu>
220
- - <GridFilterMenuItem column={column} onClick={hideMenu} />
221
- + <GridColumnMenuFilterItem colDef={column} onClick={hideMenu} />
222
- - <HideGridColMenuItem column={column} onClick={hideMenu} />
223
- + <GridColumnMenuHideItem colDef={column} onClick={hideMenu} />
224
- - <GridColumnsMenuItem column={column} onClick={hideMenu} />
225
- + <GridColumnMenuColumnsItem colDef={column} onClick={hideMenu} />
226
- - <SortGridMenuItems column={column} onClick={hideMenu} />
227
- + <GridColumnMenuSortItem colDef={column} onClick={hideMenu} />
228
- - <GridColumnPinningMenuItems column={column} onClick={hideMenu} />
229
- + <GridColumnMenuPinningItem colDef={column} onClick={hideMenu} />
230
- </CustomColumnMenu>
386
+ <CustomColumnMenu>
387
+ - <GridFilterMenuItem column={column} onClick={hideMenu} />
388
+ + <GridColumnMenuFilterItem colDef={column} onClick={hideMenu} />
389
+ - <HideGridColMenuItem column={column} onClick={hideMenu} />
390
+ + <GridColumnMenuHideItem colDef={column} onClick={hideMenu} />
391
+ - <GridColumnsMenuItem column={column} onClick={hideMenu} />
392
+ + <GridColumnMenuColumnsItem colDef={column} onClick={hideMenu} />
393
+ - <SortGridMenuItems column={column} onClick={hideMenu} />
394
+ + <GridColumnMenuSortItem colDef={column} onClick={hideMenu} />
395
+ - <GridColumnPinningMenuItems column={column} onClick={hideMenu} />
396
+ + <GridColumnMenuPinningItem colDef={column} onClick={hideMenu} />
397
+ </CustomColumnMenu>
231
398
  ```
232
399
 
233
400
  ```sh
@@ -236,18 +403,87 @@ npx @mui/x-codemod v6.0.0/data-grid/column-menu-components-rename <path>
236
403
 
237
404
  If you are using `GridRowGroupingColumnMenuItems` and `GridRowGroupableColumnMenuItems` for grouping, consider fixing them manually as these imports are replaced by `GridColumnMenuGroupingItem` and may require some extra work to port.
238
405
 
406
+ #### `row-selection-props-rename`
407
+
408
+ Data grid props that have been renamed.
409
+
410
+ ```diff
411
+ <DataGrid
412
+ - selectionModel={model}
413
+ + rowSelectionModel={model}
414
+ - onSelectionModelChange={handler}
415
+ + onRowSelectionModelChange={handler}
416
+ - disableSelectionOnClick
417
+ + disableRowSelectionOnClick
418
+ - disableMultipleSelection
419
+ + disableMultipleRowSelection
420
+ - showCellRightBorder
421
+ + showCellVerticalBorder
422
+ - showColumnRightBorder
423
+ + showColumnVerticalBorder
424
+ />
425
+ ```
426
+
427
+ ```sh
428
+ npx @mui/x-codemod v6.0.0/data-grid/row-selection-props-rename <path>
429
+ ```
430
+
431
+ #### `rename-rowsPerPageOptions-prop`
432
+
433
+ Rename `rowsPerPageOptions` prop to `pageSizeOptions`.
434
+
435
+ ```diff
436
+ <DataGrid
437
+ - rowsPerPageOptions={[5, 10, 20]}
438
+ + pageSizeOptions={[5, 10, 20]}
439
+ />
440
+ ```
441
+
442
+ ```sh
443
+ npx @mui/x-codemod v6.0.0/data-grid/rename-rowsPerPageOptions-prop <path>
444
+ ```
445
+
239
446
  #### `remove-disableExtendRowFullWidth-prop`
240
447
 
241
448
  Remove `disableExtendRowFullWidth` prop which is no longer supported.
242
449
 
243
450
  ```diff
244
- <DataGrid
245
- - disableExtendRowFullWidth
246
- />
451
+ <DataGrid
452
+ - disableExtendRowFullWidth
453
+ />
247
454
  ```
248
455
 
249
456
  ```sh
250
457
  npx @mui/x-codemod v6.0.0/data-grid/remove-disableExtendRowFullWidth-prop <path>
251
458
  ```
252
459
 
460
+ #### `rename-selectors-and-events`
461
+
462
+ Rename selectors and events.
463
+
464
+ ```diff
465
+ function App() {
466
+ - useGridApiEventHandler('selectionChange', handleEvent);
467
+ - apiRef.current.subscribeEvent('selectionChange', handleEvent);
468
+ - const selection = useGridSelector(apiRef, gridSelectionStateSelector);
469
+ - const sortedRowIds = useGridSelector(apiRef, gridVisibleSortedRowIdsSelector);
470
+ - const sortedRowEntries = useGridSelector(apiRef, gridVisibleSortedRowEntriesSelector);
471
+ - const rowCount = useGridSelector(apiRef, gridVisibleRowCountSelector);
472
+ - const sortedTopLevelRowEntries = useGridSelector(apiRef, gridVisibleSortedTopLevelRowEntriesSelector);
473
+ - const topLevelRowCount = useGridSelector(apiRef, gridVisibleTopLevelRowCountSelector);
474
+ + useGridApiEventHandler('rowSelectionChange', handleEvent);
475
+ + apiRef.current.subscribeEvent('rowSelectionChange', handleEvent);
476
+ + const selection = useGridSelector(apiRef, gridRowSelectionStateSelector);
477
+ + const sortedRowIds = useGridSelector(apiRef, gridExpandedSortedRowIdsSelector);
478
+ + const sortedRowEntries = useGridSelector(apiRef, gridExpandedSortedRowEntriesSelector);
479
+ + const rowCount = useGridSelector(apiRef, gridExpandedRowCountSelector);
480
+ + const sortedTopLevelRowEntries = useGridSelector(apiRef, gridFilteredSortedTopLevelRowEntriesSelector);
481
+ + const topLevelRowCount = useGridSelector(apiRef, gridFilteredTopLevelRowCountSelector);
482
+ }
483
+ ```
484
+
485
+ ```sh
486
+ npx @mui/x-codemod v6.0.0/data-grid/rename-selectors-and-events <path>
487
+ ```
488
+
253
489
  You can find more details about Data Grid breaking change in [the migration guide](https://next.mui.com/x/migration/migration-data-grid-v5/).
package/codemod.js CHANGED
@@ -57,7 +57,6 @@ function run(argv) {
57
57
  _yargs.default.command({
58
58
  command: '$0 <codemod> <paths...>',
59
59
  describe: 'Applies a `@mui/x-codemod` to the specified paths',
60
- // @ts-expect-error
61
60
  builder: command => {
62
61
  return command.positional('codemod', {
63
62
  description: 'The name of the codemod',
@@ -76,5 +75,6 @@ _yargs.default.command({
76
75
  type: 'array'
77
76
  });
78
77
  },
78
+ // @ts-expect-error
79
79
  handler: run
80
80
  }).scriptName('npx @mui/x-codemod').example('$0 v6.0.0/localization-provider-rename-locale src', 'Run "localization-provider-rename-locale" codemod on "src" path').example('$0 v6.0.0/component-rename-prop src -- --component=DataGrid --from=prop --to=newProp', 'Run "component-rename-prop" codemod in "src" path on "DataGrid" component with custom "from" and "to" arguments').help().parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/x-codemod",
3
- "version": "6.0.0-beta.0",
3
+ "version": "6.0.0-beta.1",
4
4
  "bin": "./codemod.js",
5
5
  "private": false,
6
6
  "author": "MUI Team",
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.transformNestedProp = exports.addItemToObject = void 0;
7
+ /**
8
+ * Recusive function that:
9
+ * Return a jscodeshift object with `value` associated to path.
10
+ * The path can be such as 'tabs.hidden' which will return `{ tabs: { hidden: value } }`.
11
+ * If object is not null, path/value will be added respecting the other properties of the object.
12
+ */
13
+ const addItemToObject = (path, value, object, j) => {
14
+ const splitedPath = path.split('.');
15
+
16
+ // Final case where we have to add the property to the object.
17
+ if (splitedPath.length === 1) {
18
+ const propertyToAdd = j.objectProperty(j.identifier(path), value);
19
+ if (object === null) {
20
+ return j.objectExpression([propertyToAdd]);
21
+ }
22
+ return j.objectExpression([...(object.properties ?? []).filter(property => property.key.name !== path), propertyToAdd]);
23
+ }
24
+ const remainingPath = splitedPath.slice(1).join('.');
25
+ const targetKey = splitedPath[0];
26
+ if (object === null) {
27
+ // Simplest case, no object to take into consideration
28
+ const propertyToAdd = j.objectProperty(j.identifier(targetKey), addItemToObject(remainingPath, value, null, j));
29
+ return j.objectExpression([propertyToAdd]);
30
+ }
31
+
32
+ // Look if the object we got already contains the property we have to use.
33
+ const correspondingObject = (object.properties ?? []).find(property => property.key.name === targetKey);
34
+ const propertyToAdd = j.objectProperty(j.identifier(targetKey),
35
+ // Here we use recursion to mix the new value with the current one
36
+ addItemToObject(remainingPath, value, correspondingObject?.value ?? null, j));
37
+ return j.objectExpression([...(object.properties ?? []).filter(property => property.key.name !== targetKey), propertyToAdd]);
38
+ };
39
+
40
+ /**
41
+ *
42
+ * @param elementPath jscodshift path of the element
43
+ * @param propName the name of the prop to edit (`'componentsProps'` for example)
44
+ * @param nestedPath path of the nested object keys with '.' to separate. ('tabs.hidden' for example)
45
+ * @param value the jscodeshift value to associate to the key
46
+ * @param j jscodeshift
47
+ */
48
+ exports.addItemToObject = addItemToObject;
49
+ const transformNestedProp = (elementPath, propName, nestedPath, value, j) => {
50
+ const initialAttribute = elementPath.value.openingElement.attributes?.find(attribute => attribute.name.name === propName);
51
+ // the object in JSX element
52
+ const initialValue = initialAttribute?.value.expression;
53
+
54
+ // Add the value
55
+ const withNewValues = addItemToObject(nestedPath, value, initialValue ?? null, j);
56
+
57
+ // Create a new component with the prop added
58
+ const newComponent = j.jsxElement(j.jsxOpeningElement(elementPath.node.openingElement.name, [...(elementPath.node.openingElement.attributes ?? []).filter(attribute => attribute.name.name !== propName),
59
+ // build and insert our new prop
60
+ j.jsxAttribute(j.jsxIdentifier(propName), j.jsxExpressionContainer(withNewValues))]), elementPath.node.closingElement, elementPath.node.children);
61
+ newComponent.openingElement.selfClosing = elementPath.node.closingElement === null;
62
+ newComponent.selfClosing = elementPath.node.closingElement === null;
63
+
64
+ // Replace our original component with our modified one
65
+ j(elementPath).replaceWith(newComponent);
66
+ };
67
+ exports.transformNestedProp = transformNestedProp;
@@ -13,6 +13,10 @@ function removeProps({
13
13
  return root.find(j.JSXElement).filter(path => {
14
14
  return componentNames.includes(path.value.openingElement.name.name);
15
15
  }).find(j.JSXAttribute).filter(attribute => props.includes(attribute.node.name.name)).forEach(attribute => {
16
- j(attribute).remove();
16
+ // Only remove props from components in componentNames. Not nested ones.
17
+ const attributeParent = attribute.parentPath.parentPath;
18
+ if (attributeParent.value.type === 'JSXOpeningElement' && componentNames.includes(attributeParent.value.name.name)) {
19
+ j(attribute).remove();
20
+ }
17
21
  });
18
22
  }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = renameComponentsSlots;
7
+ const lowerCase = key => `${key.slice(0, 1).toLowerCase()}${key.slice(1)}`;
8
+ const getSlotsTranslation = translations => {
9
+ const lowercasedTranslation = {};
10
+ Object.entries(translations).forEach(([key, value]) => {
11
+ lowercasedTranslation[lowerCase(key)] = lowerCase(value);
12
+ });
13
+ return lowercasedTranslation;
14
+ };
15
+ function renameComponentsSlots({
16
+ root,
17
+ componentNames,
18
+ translation,
19
+ j
20
+ }) {
21
+ return root.find(j.JSXElement).filter(path => {
22
+ return componentNames.includes(path.value.openingElement.name.name);
23
+ }).find(j.JSXAttribute).filter(attribute => ['components', 'componentsProps', 'slots', 'slotProps'].includes(attribute.node.name.name)).forEach(attribute => {
24
+ const usedTranslation = attribute.node.name.name === 'components' ? translation : getSlotsTranslation(translation);
25
+ j(attribute).find(j.Property).forEach(property => {
26
+ if (property.value.key.type === 'Identifier' && usedTranslation[property.value.key.name] !== undefined) {
27
+ property.value.key.name = usedTranslation[property.value.key.name];
28
+ }
29
+ });
30
+ });
31
+ }
@@ -12,9 +12,10 @@ const VARIABLES = {
12
12
  GridColumnsMenuItem: 'GridColumnMenuColumnsItem',
13
13
  SortGridMenuItems: 'GridColumnMenuSortItem',
14
14
  GridColumnPinningMenuItems: 'GridColumnMenuPinningItem',
15
- GridAggregationColumnMenuItem: 'GridColumnMenuAggregationItem'
15
+ GridAggregationColumnMenuItem: 'GridColumnMenuAggregationItem',
16
+ GridFilterItemProps: 'GridColumnMenuItemProps'
16
17
  };
17
- const PACKAGE_REGEXP = /@mui\/x-data-grid(-pro|-premium)(\/(.*)|)/;
18
+ const PACKAGE_REGEXP = /@mui\/x-data-grid(-pro|-premium)?/;
18
19
  const matchImport = path => (path.node.source.value?.toString() ?? '').match(PACKAGE_REGEXP);
19
20
  function transformer(file, api, options) {
20
21
  const j = api.jscodeshift;
@@ -6,9 +6,15 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.default = transformer;
8
8
  var _columnMenuComponentsRename = _interopRequireDefault(require("../column-menu-components-rename"));
9
+ var _rowSelectionPropsRename = _interopRequireDefault(require("../row-selection-props-rename"));
10
+ var _renameRowsPerPageOptionsProp = _interopRequireDefault(require("../rename-rowsPerPageOptions-prop"));
9
11
  var _removeDisableExtendRowFullWidthProp = _interopRequireDefault(require("../remove-disableExtendRowFullWidth-prop"));
12
+ var _renameSelectorsAndEvents = _interopRequireDefault(require("../rename-selectors-and-events"));
10
13
  function transformer(file, api, options) {
11
14
  file.source = (0, _columnMenuComponentsRename.default)(file, api, options);
15
+ file.source = (0, _rowSelectionPropsRename.default)(file, api, options);
16
+ file.source = (0, _renameRowsPerPageOptionsProp.default)(file, api, options);
12
17
  file.source = (0, _removeDisableExtendRowFullWidthProp.default)(file, api, options);
18
+ file.source = (0, _renameSelectorsAndEvents.default)(file, api, options);
13
19
  return file.source;
14
20
  }
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.default = transformer;
8
- var _removeProps = _interopRequireDefault(require("packages/x-codemod/src/util/removeProps"));
8
+ var _removeProps = _interopRequireDefault(require("../../../util/removeProps"));
9
9
  const componentNames = ['DataGrid', 'DataGridPro', 'DataGridPremium'];
10
10
  const props = ['disableExtendRowFullWidth'];
11
11
  function transformer(file, api, options) {
@@ -0,0 +1,26 @@
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 _renameProps = _interopRequireDefault(require("../../../util/renameProps"));
9
+ const componentNames = ['DataGrid', 'DataGridPro', 'DataGridPremium'];
10
+ const props = {
11
+ rowsPerPageOptions: 'pageSizeOptions'
12
+ };
13
+ function transformer(file, api, options) {
14
+ const j = api.jscodeshift;
15
+ const root = j(file.source);
16
+ const printOptions = options.printOptions || {
17
+ quote: 'single',
18
+ trailingComma: true
19
+ };
20
+ return (0, _renameProps.default)({
21
+ root,
22
+ j,
23
+ props,
24
+ componentNames
25
+ }).toSource(printOptions);
26
+ }
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = transformer;
7
+ const renamedSelectors = {
8
+ gridSelectionStateSelector: 'gridRowSelectionStateSelector',
9
+ gridVisibleSortedRowIdsSelector: 'gridExpandedSortedRowIdsSelector',
10
+ gridVisibleSortedRowEntriesSelector: 'gridExpandedSortedRowEntriesSelector',
11
+ gridVisibleRowCountSelector: 'gridExpandedRowCountSelector',
12
+ gridVisibleSortedTopLevelRowEntriesSelector: 'gridFilteredSortedTopLevelRowEntriesSelector',
13
+ gridVisibleTopLevelRowCountSelector: 'gridFilteredTopLevelRowCountSelector'
14
+ };
15
+ const renamedEvents = {
16
+ selectionChange: 'rowSelectionChange',
17
+ rowsScroll: 'scrollPositionChange'
18
+ };
19
+ function transformer(file, api, options) {
20
+ const j = api.jscodeshift;
21
+ const root = j(file.source);
22
+ const printOptions = options.printOptions || {
23
+ quote: 'single',
24
+ trailingComma: true
25
+ };
26
+
27
+ // Rename the import and usage of renamed selectors
28
+ // - import { gridSelectionStateSelector } from '@mui/x-data-grid'
29
+ // + import { gridRowSelectionStateSelector } from '@mui/x-data-grid'
30
+ root.find(j.Identifier).filter(path => !!renamedSelectors[path.node.name]).replaceWith(path => j.identifier(renamedSelectors[path.node.name]));
31
+
32
+ // Rename the usage of renamed event literals
33
+ // - useGridApiEventHandler('selectionChange', handleEvent);
34
+ // - apiRef.current.subscribeEvent('selectionChange', handleEvent);
35
+ // + useGridApiEventHandler('rowSelectionChange', handleEvent);
36
+ // + apiRef.current.subscribeEvent('rowSelectionChange', handleEvent);
37
+ root.find(j.CallExpression).find(j.Literal).filter(path => !!renamedEvents[path.node.value]).replaceWith(path => j.literal(renamedEvents[path.node.value]));
38
+ return root.toSource(printOptions);
39
+ }
@@ -0,0 +1,32 @@
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 _renameProps = _interopRequireDefault(require("../../../util/renameProps"));
9
+ const props = {
10
+ selectionModel: 'rowSelectionModel',
11
+ onSelectionModelChange: 'onRowSelectionModelChange',
12
+ disableSelectionOnClick: 'disableRowSelectionOnClick',
13
+ disableMultipleSelection: 'disableMultipleRowSelection',
14
+ showCellRightBorder: 'showCellVerticalBorder',
15
+ showColumnRightBorder: 'showColumnVerticalBorder',
16
+ headerHeight: 'columnHeaderHeight'
17
+ };
18
+ const componentNames = ['DataGrid', 'DataGridPro', 'DataGridPremium'];
19
+ function transformer(file, api, options) {
20
+ const j = api.jscodeshift;
21
+ const root = j(file.source);
22
+ const printOptions = options.printOptions || {
23
+ quote: 'single',
24
+ trailingComma: true
25
+ };
26
+ return (0, _renameProps.default)({
27
+ root,
28
+ componentNames,
29
+ props,
30
+ j
31
+ }).toSource(printOptions);
32
+ }
@@ -0,0 +1,101 @@
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 _addComponentsSlots = require("../../../util/addComponentsSlots");
9
+ var _removeProps = _interopRequireDefault(require("../../../util/removeProps"));
10
+ var _renameComponentsSlots = _interopRequireDefault(require("../../../util/renameComponentsSlots"));
11
+ const propsToSlots = {
12
+ // components
13
+ TransitionComponent: {
14
+ prop: 'components',
15
+ path: 'DesktopTransition'
16
+ },
17
+ // componentsProps
18
+ PopperProps: {
19
+ prop: 'componentsProps',
20
+ path: 'popper'
21
+ },
22
+ DialogProps: {
23
+ prop: 'componentsProps',
24
+ path: 'dialog'
25
+ },
26
+ PaperProps: {
27
+ prop: 'componentsProps',
28
+ path: 'desktopPaper'
29
+ },
30
+ TrapFocusProps: {
31
+ prop: 'componentsProps',
32
+ path: 'desktopTrapFocus'
33
+ },
34
+ InputProps: {
35
+ prop: 'componentsProps',
36
+ path: 'textField.InputProps'
37
+ },
38
+ InputAdornmentProps: {
39
+ prop: 'componentsProps',
40
+ path: 'inputAdornment'
41
+ },
42
+ OpenPickerButtonProps: {
43
+ prop: 'componentsProps',
44
+ path: 'openPickerButton'
45
+ }
46
+ };
47
+ function transformer(file, api, options) {
48
+ const j = api.jscodeshift;
49
+ const root = j(file.source);
50
+ const printOptions = options.printOptions || {
51
+ quote: 'single',
52
+ trailingComma: true
53
+ };
54
+ const componentNames = new Set();
55
+ root.find(j.ImportDeclaration).filter(({
56
+ node
57
+ }) => {
58
+ return node.source.value.startsWith('@mui/x-date-pickers');
59
+ }).forEach(path => {
60
+ path.node.specifiers.forEach(node => {
61
+ // Process only date-pickers components
62
+ root.findJSXElements(node.local.name).forEach(elementPath => {
63
+ if (elementPath.node.type !== 'JSXElement') {
64
+ return;
65
+ }
66
+ componentNames.add(node.local.name);
67
+ const attributesToTransform = j(elementPath).find(j.JSXAttribute).filter(attribute => {
68
+ const attributeParent = attribute.parentPath.parentPath;
69
+ if (attribute.parentPath.parentPath.value.type !== 'JSXOpeningElement' || attributeParent.value.name.name !== node.local.name) {
70
+ return false;
71
+ }
72
+ return Object.keys(propsToSlots).includes(attribute.value.name.name);
73
+ });
74
+ attributesToTransform.forEach(attribute => {
75
+ const attributeName = attribute.value.name.name;
76
+
77
+ // Get the value in case it's:
78
+ // - prop={value}
79
+ // - prop="value"
80
+ // - prop (which means true)
81
+ const value = attribute.value.value?.type === 'JSXExpressionContainer' ? attribute.value.value.expression : attribute.value.value || j.booleanLiteral(true);
82
+ (0, _addComponentsSlots.transformNestedProp)(elementPath, propsToSlots[attributeName].prop, propsToSlots[attributeName].path, value, j);
83
+ });
84
+ });
85
+ (0, _removeProps.default)({
86
+ root,
87
+ componentNames: [node.local.name],
88
+ props: Object.keys(propsToSlots),
89
+ j
90
+ });
91
+ });
92
+ });
93
+ return (0, _renameComponentsSlots.default)({
94
+ root,
95
+ componentNames: Array.from(componentNames),
96
+ translation: {
97
+ input: 'textField'
98
+ },
99
+ j
100
+ }).toSource(printOptions);
101
+ }
@@ -10,6 +10,11 @@ var _textPropsToLocaleText = _interopRequireDefault(require("../text-props-to-lo
10
10
  var _viewComponentsRename = _interopRequireDefault(require("../view-components-rename"));
11
11
  var _viewComponentsRenameValueProp = _interopRequireDefault(require("../view-components-rename-value-prop"));
12
12
  var _adapterChangeImport = _interopRequireDefault(require("../adapter-change-import"));
13
+ var _replaceTabsProps = _interopRequireDefault(require("../replace-tabs-props"));
14
+ var _replaceToolbarPropsBySlot = _interopRequireDefault(require("../replace-toolbar-props-by-slot"));
15
+ var _migrateToComponentsComponentsProps = _interopRequireDefault(require("../migrate-to-components-componentsProps"));
16
+ var _replaceArrowsButtonSlot = _interopRequireDefault(require("../replace-arrows-button-slot"));
17
+ var _renameShouldDisableTime = _interopRequireDefault(require("../rename-should-disable-time"));
13
18
  function transformer(file, api, options) {
14
19
  file.source = (0, _localizationProviderRenameLocale.default)(file, api, options);
15
20
 
@@ -18,5 +23,10 @@ function transformer(file, api, options) {
18
23
  file.source = (0, _viewComponentsRenameValueProp.default)(file, api, options);
19
24
  file.source = (0, _viewComponentsRename.default)(file, api, options);
20
25
  file.source = (0, _adapterChangeImport.default)(file, api, options);
26
+ file.source = (0, _replaceTabsProps.default)(file, api, options);
27
+ file.source = (0, _replaceToolbarPropsBySlot.default)(file, api, options);
28
+ file.source = (0, _migrateToComponentsComponentsProps.default)(file, api, options);
29
+ file.source = (0, _replaceArrowsButtonSlot.default)(file, api, options);
30
+ file.source = (0, _renameShouldDisableTime.default)(file, api, options);
21
31
  return file.source;
22
32
  }
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = transformer;
7
+ function transformComponentsProp(attributeNode) {
8
+ attributeNode.name.name = 'slots';
9
+ const valueExpression = attributeNode.value.expression;
10
+ if (valueExpression?.type !== 'ObjectExpression') {
11
+ return;
12
+ }
13
+ valueExpression.properties.forEach(property => {
14
+ property.key.name = property.key.name[0].toLowerCase() + property.key.name.slice(1);
15
+ if (property.shorthand) {
16
+ property.shorthand = false;
17
+ }
18
+ });
19
+ }
20
+ function transformComponentsPropsProp(attributeNode) {
21
+ attributeNode.name.name = 'slotProps';
22
+ }
23
+
24
+ /**
25
+ * @param {import('jscodeshift').FileInfo} file
26
+ * @param {import('jscodeshift').API} api
27
+ */
28
+ function transformer(file, api, options) {
29
+ const j = api.jscodeshift;
30
+ const printOptions = options.printOptions;
31
+ const root = j(file.source);
32
+ root.find(j.ImportDeclaration).filter(({
33
+ node
34
+ }) => {
35
+ return node.source.value.startsWith('@mui/x-date-pickers');
36
+ }).forEach(path => {
37
+ path.node.specifiers.forEach(node => {
38
+ // Process only date-pickers components
39
+ root.findJSXElements(node.local.name).forEach(elementPath => {
40
+ if (elementPath.node.type !== 'JSXElement') {
41
+ return;
42
+ }
43
+ elementPath.node.openingElement.attributes.forEach(elementNode => {
44
+ if (elementNode.type !== 'JSXAttribute') {
45
+ return;
46
+ }
47
+ switch (elementNode.name.name) {
48
+ case 'components':
49
+ transformComponentsProp(elementNode);
50
+ break;
51
+ case 'componentsProps':
52
+ transformComponentsPropsProp(elementNode);
53
+ break;
54
+ default:
55
+ }
56
+ });
57
+ });
58
+ });
59
+ });
60
+ const transformed = root.findJSXElements();
61
+ return transformed.toSource(printOptions);
62
+ }
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = transformer;
7
+ /**
8
+ * @param {import('jscodeshift').FileInfo} file
9
+ * @param {import('jscodeshift').API} api
10
+ */
11
+ function transformer(file, api, options) {
12
+ const j = api.jscodeshift;
13
+ const printOptions = options.printOptions;
14
+ const root = j(file.source);
15
+ root.find(j.ImportDeclaration).filter(({
16
+ node
17
+ }) => {
18
+ return node.source.value.startsWith('@mui/x-date-pickers');
19
+ }).forEach(path => {
20
+ path.node.specifiers.forEach(node => {
21
+ // Process only date-pickers components
22
+ root.findJSXElements(node.local.name).forEach(elementPath => {
23
+ if (elementPath.node.type !== 'JSXElement') {
24
+ return;
25
+ }
26
+ elementPath.node.openingElement.attributes.forEach(elementNode => {
27
+ if (elementNode.type !== 'JSXAttribute') {
28
+ return;
29
+ }
30
+ if (elementNode.name.name === 'shouldDisableTime') {
31
+ elementNode.name.name = 'shouldDisableClock';
32
+ }
33
+ });
34
+ });
35
+ });
36
+ });
37
+ const transformed = root.findJSXElements();
38
+ return transformed.toSource(printOptions);
39
+ }
@@ -0,0 +1,41 @@
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 _renameComponentsSlots = _interopRequireDefault(require("../../../util/renameComponentsSlots"));
9
+ function transformer(file, api, options) {
10
+ const j = api.jscodeshift;
11
+ const root = j(file.source);
12
+ const printOptions = options.printOptions || {
13
+ quote: 'single',
14
+ trailingComma: true
15
+ };
16
+ const componentNames = new Set();
17
+ root.find(j.ImportDeclaration).filter(({
18
+ node
19
+ }) => {
20
+ return node.source.value.startsWith('@mui/x-date-pickers');
21
+ }).forEach(path => {
22
+ path.node.specifiers.forEach(node => {
23
+ // Process only date-pickers components
24
+ root.findJSXElements(node.local.name).forEach(elementPath => {
25
+ if (elementPath.node.type !== 'JSXElement') {
26
+ return;
27
+ }
28
+ componentNames.add(node.local.name);
29
+ });
30
+ });
31
+ });
32
+ return (0, _renameComponentsSlots.default)({
33
+ root,
34
+ componentNames: Array.from(componentNames),
35
+ translation: {
36
+ LeftArrowButton: 'PreviousIconButton',
37
+ RightArrowButton: 'NextIconButton'
38
+ },
39
+ j
40
+ }).toSource(printOptions);
41
+ }
@@ -0,0 +1,53 @@
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 _renameComponentsSlots = _interopRequireDefault(require("../../../util/renameComponentsSlots"));
9
+ var _addComponentsSlots = require("../../../util/addComponentsSlots");
10
+ var _removeProps = _interopRequireDefault(require("../../../util/removeProps"));
11
+ const propsToComponentsProps = {
12
+ hideTabs: 'tabs.hidden',
13
+ dateRangeIcon: 'tabs.dateIcon',
14
+ timeIcon: 'tabs.timeIcon'
15
+ };
16
+ const COMPONENTS = ['DateTimePicker', 'MobileDateTimePicker', 'DesktopDateTimePicker', 'StaticDateTimePicker'];
17
+ function transformer(file, api, options) {
18
+ const j = api.jscodeshift;
19
+ const root = j(file.source);
20
+ const printOptions = options.printOptions || {
21
+ quote: 'single',
22
+ trailingComma: true
23
+ };
24
+ root.find(j.JSXElement).filter(path => {
25
+ return COMPONENTS.includes(path.value.openingElement.name.name);
26
+ }).forEach(path => {
27
+ const attributesToTransform = j(path).find(j.JSXAttribute).filter(attribute => Object.keys(propsToComponentsProps).includes(attribute.value.name.name));
28
+ attributesToTransform.forEach(attribute => {
29
+ const attributeName = attribute.value.name.name;
30
+
31
+ // Get the value in case it's:
32
+ // - prop={value}
33
+ // - prop="value"
34
+ // - prop (which means true)
35
+ const value = attribute.value.value?.type === 'JSXExpressionContainer' ? attribute.value.value.expression : attribute.value.value || j.booleanLiteral(true);
36
+ (0, _addComponentsSlots.transformNestedProp)(path, 'componentsProps', propsToComponentsProps[attributeName], value, j);
37
+ });
38
+ });
39
+ (0, _removeProps.default)({
40
+ root,
41
+ componentNames: COMPONENTS,
42
+ props: Object.keys(propsToComponentsProps),
43
+ j
44
+ });
45
+ return (0, _renameComponentsSlots.default)({
46
+ root,
47
+ componentNames: COMPONENTS,
48
+ translation: {
49
+ dateRangeIcon: 'dateIcon'
50
+ },
51
+ j
52
+ }).toSource(printOptions);
53
+ }
@@ -0,0 +1,69 @@
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 _addComponentsSlots = require("../../../util/addComponentsSlots");
9
+ var _removeProps = _interopRequireDefault(require("../../../util/removeProps"));
10
+ const propsToSlots = {
11
+ ToolbarComponent: {
12
+ prop: 'components',
13
+ path: 'Toolbar'
14
+ },
15
+ toolbarPlaceholder: {
16
+ prop: 'componentsProps',
17
+ path: 'toolbar.toolbarPlaceholder'
18
+ },
19
+ toolbarFormat: {
20
+ prop: 'componentsProps',
21
+ path: 'toolbar.toolbarFormat'
22
+ },
23
+ showToolbar: {
24
+ prop: 'componentsProps',
25
+ path: 'toolbar.hidden'
26
+ },
27
+ toolbarTitle: {
28
+ prop: 'localeText',
29
+ path: 'toolbarTitle'
30
+ }
31
+ };
32
+ const COMPONENTS = ['DateTimePicker', 'MobileDateTimePicker', 'DesktopDateTimePicker', 'StaticDateTimePicker', 'DatePicker', 'MobileDatePicker', 'DesktopDatePicker', 'StaticDatePicker', 'TimePicker', 'MobileTimePicker', 'DesktopTimePicker', 'StaticTimePicker', 'DateRangePicker', 'MobileDateRangePicker', 'DesktopDateRangePicker', 'StaticDateRangePicker'];
33
+ function transformer(file, api, options) {
34
+ const j = api.jscodeshift;
35
+ const root = j(file.source);
36
+ const printOptions = options.printOptions || {
37
+ quote: 'single',
38
+ trailingComma: true
39
+ };
40
+ root.find(j.JSXElement).filter(path => {
41
+ return COMPONENTS.includes(path.value.openingElement.name.name);
42
+ }).forEach(path => {
43
+ const attributesToTransform = j(path).find(j.JSXAttribute).filter(attribute => Object.keys(propsToSlots).includes(attribute.value.name.name));
44
+ attributesToTransform.forEach(attribute => {
45
+ const attributeName = attribute.value.name.name;
46
+
47
+ // Get the value in case it's:
48
+ // - prop={value}
49
+ // - prop="value"
50
+ // - prop (which means true)
51
+ let value = attribute.value.value?.type === 'JSXExpressionContainer' ? attribute.value.value.expression : attribute.value.value || j.booleanLiteral(true);
52
+ if (attributeName === 'showToolbar') {
53
+ if (value.type === 'BooleanLiteral' || value.type === 'Literal' && typeof value.value === 'boolean') {
54
+ value.value = !value.value;
55
+ } else {
56
+ value = j.unaryExpression('!', value);
57
+ }
58
+ }
59
+ (0, _addComponentsSlots.transformNestedProp)(path, propsToSlots[attributeName].prop, propsToSlots[attributeName].path, value, j);
60
+ });
61
+ });
62
+ (0, _removeProps.default)({
63
+ root,
64
+ componentNames: COMPONENTS,
65
+ props: Object.keys(propsToSlots),
66
+ j
67
+ });
68
+ return root.toSource(printOptions);
69
+ }