@mui/codemod 9.0.0-alpha.1 → 9.0.0-alpha.4

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/CHANGELOG.md +219 -0
  2. package/README.md +141 -8
  3. package/deprecations/autocomplete-props/autocomplete-props.js +195 -0
  4. package/deprecations/autocomplete-props/test-cases/actual.js +31 -0
  5. package/deprecations/autocomplete-props/test-cases/expected.js +31 -0
  6. package/deprecations/autocomplete-props/test-cases/package.actual.js +11 -0
  7. package/deprecations/autocomplete-props/test-cases/package.expected.js +11 -0
  8. package/deprecations/autocomplete-props/test-cases/render-input-package.actual.js +34 -0
  9. package/deprecations/autocomplete-props/test-cases/render-input-package.expected.js +40 -0
  10. package/deprecations/autocomplete-props/test-cases/render-input.actual.js +81 -0
  11. package/deprecations/autocomplete-props/test-cases/render-input.expected.js +92 -0
  12. package/deprecations/autocomplete-props/test-cases/theme.actual.js +15 -0
  13. package/deprecations/autocomplete-props/test-cases/theme.expected.js +15 -0
  14. package/deprecations/circular-progress-classes/circular-progress-classes.js +16 -1
  15. package/deprecations/circular-progress-classes/postcss-plugin.js +2 -2
  16. package/deprecations/circular-progress-classes/test-cases/expected.js +4 -4
  17. package/deprecations/circular-progress-classes/test-cases/package.expected.js +4 -4
  18. package/deprecations/tabs-props/tabs-props.js +44 -0
  19. package/deprecations/tabs-props/test-cases/actual.js +11 -0
  20. package/deprecations/tabs-props/test-cases/expected.js +11 -0
  21. package/deprecations/tabs-props/test-cases/package.actual.js +6 -0
  22. package/deprecations/tabs-props/test-cases/package.expected.js +6 -0
  23. package/deprecations/tabs-props/test-cases/theme.actual.js +10 -0
  24. package/deprecations/tabs-props/test-cases/theme.expected.js +10 -0
  25. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,224 @@
1
1
  # [Versions](https://mui.com/versions/)
2
2
 
3
+ ## 9.0.0-alpha.4
4
+
5
+ <!-- generated comparing v9.0.0-alpha.3..master -->
6
+
7
+ _Mar 20, 2026_
8
+
9
+ A big thanks to the 11 contributors who made this release possible.
10
+
11
+ ### `@mui/material@9.0.0-alpha.4`
12
+
13
+ #### Breaking Changes
14
+
15
+ - [accordion] Remove deprecated props (#47963) @silviuaavram
16
+ - `TransitionComponent`
17
+ - `TransitionProps`
18
+ - [accordionsummary] Remove deprecated CSS class (#48006) @silviuaavram
19
+ - `contentGutters`
20
+ - [alert] Remove deprecated CSS classes (#48011) @silviuaavram
21
+ - `standardSuccess`
22
+ - `standardInfo`
23
+ - `standardWarning`
24
+ - `standardError`
25
+ - `outlinedSuccess`
26
+ - `outlinedInfo`
27
+ - `outlinedWarning`
28
+ - `outlinedError`
29
+ - `filledSuccess`
30
+ - `filledInfo`
31
+ - `filledWarning`
32
+ - `filledError`
33
+ - [alert] Remove deprecated props (#47965) @silviuaavram
34
+ - `components`
35
+ - `componentsProps`
36
+ - [autocomplete] Remove deprecated props (#47864) @ZeeshanTamboli
37
+ - `ChipProps`
38
+ - `componentsProps`
39
+ - `ListboxComponent`
40
+ - `ListboxProps`
41
+ - `PaperComponent`
42
+ - `PopperComponent`
43
+ - `renderTags`
44
+ - [avatar] Remove deprecated props (#47966) @silviuaavram
45
+ - `imgProps`
46
+ - [avatargroup] Remove deprecated props (#47968) @silviuaavram
47
+ - `componentsProps`
48
+ - [backdrop] Remove deprecated props (#47991) @silviuaavram
49
+ - `components`
50
+ - `componentsProps`
51
+ - `TransitionComponent`
52
+ - [badge] Remove deprecated props (#47993) @silviuaavram
53
+ - `components`
54
+ - `componentsProps`
55
+ - [button] Remove deprecated CSS classes (#48012) @silviuaavram
56
+ - Color variant classes: `textInherit`, `outlinedPrimary`, `containedSecondary`, etc.
57
+ - Size classes: `textSizeSmall`, `iconSizeMedium`, etc.
58
+ - [circularprogress] Remove deprecated CSS classes (#48014) @silviuaavram
59
+ - `circleDeterminate`
60
+ - `circleIndeterminate`
61
+ - [divider] Remove deprecated prop (#48013) @atharva3333
62
+ - `light`
63
+ - [formcontrollabel] Remove deprecated props (#48032) @atharva3333
64
+ - `componentsProps`
65
+ - [menu] Remove deprecated props (#48021) @siriwatknp
66
+ - `MenuListProps`
67
+ - `PaperProps`
68
+ - `TransitionProps`
69
+ - [mobilestepper] Remove deprecated props (#48041) @siriwatknp
70
+ - `LinearProgressProps`
71
+ - [popover] Remove deprecated props (#48021) @siriwatknp
72
+ - `BackdropComponent`
73
+ - `BackdropProps`
74
+ - `PaperProps`
75
+ - `TransitionComponent`
76
+ - `TransitionProps`
77
+ - [popper] Remove deprecated props (#48020) @siriwatknp
78
+ - `components`
79
+ - `componentsProps`
80
+ - [select] Remove deprecated props passed via `MenuProps` (#48021) @siriwatknp
81
+ - `MenuListProps`
82
+ - `PaperProps`
83
+ - `TransitionProps`
84
+ - [slider] Remove deprecated props (#47996) @siriwatknp
85
+ - `components`
86
+ - `componentsProps`
87
+ - [speeddial] Remove deprecated props (#47998) @siriwatknp
88
+ - `TransitionComponent`
89
+ - `TransitionProps`
90
+ - [speeddialaction] Remove deprecated props (#47998) @siriwatknp
91
+ - `FabProps`
92
+ - `tooltipTitle`
93
+ - `tooltipPlacement`
94
+ - `tooltipOpen`
95
+ - `TooltipClasses`
96
+ - [tabs] Remove deprecated props (#48017) @siriwatknp
97
+ - `ScrollButtonComponent`
98
+ - `TabIndicatorProps`
99
+ - `TabScrollButtonProps`
100
+ - `slots.StartScrollButtonIcon`
101
+ - `slots.EndScrollButtonIcon`
102
+ - [textfield] Remove deprecated props (#47878) @ZeeshanTamboli
103
+ - `InputProps`
104
+ - `inputProps`
105
+ - `SelectProps`
106
+ - `InputLabelProps`
107
+ - `FormHelperTextProps`
108
+ - [tooltip] Remove deprecated props (#47988) @siriwatknp
109
+ - `components`
110
+ - `componentsProps`
111
+ - `PopperComponent`
112
+ - `PopperProps`
113
+ - `TransitionComponent`
114
+ - `TransitionProps`
115
+ - [typography] Remove deprecated prop (#47986) @siriwatknp
116
+ - `paragraph`
117
+ - [buttonbase] Key handlers should not run on a disabled non-native button (#48003) @mj12albert
118
+ - [tablepagination] Format pagination numbers according to locale (#47803) @siriwatknp
119
+ - [textfield] Use non-native label for `<TextField select/>` (#47958) @mj12albert
120
+
121
+ Check out the [v9 upgrade guide](https://mui.com/material-ui/migration/upgrade-to-v9/).
122
+
123
+ #### Changes
124
+
125
+ - [autocomplete] Optimize selected option lookup (#47953) @anchmelev
126
+ - [buttonbase] Fix native button detection (#47985) @mj12albert
127
+ - [inputbase] Fix test using removed InputProps on TextField (#48000) @siriwatknp
128
+ - [popper] Add missing classes export (#48031) @mj12albert
129
+ - [select] Fix focus visible always set on menu item (#47912) @silviuaavram
130
+ - [slider] Fix focus visible styles incorrectly applied by pointer (#47894) @mj12albert
131
+ - [slider] Accept readonly array for the value prop (#47936) @pcorpet
132
+
133
+ ### `@mui/codemod@9.0.0-alpha.4`
134
+
135
+ - [codemod] Add slot key rename to `tabs-props` codemod and add to README (#48035) @siriwatknp
136
+ - [codemod] Add card-header-props migration guide (#48005) @siriwatknp
137
+
138
+ ### Docs
139
+
140
+ - [blog] Lowercase 2026-MUI-X-price-changes blog post URL (#47871) @Janpot
141
+ - [docs] Wide docs layout (#47950) @noraleonte
142
+ - [docs] Mention the list of props removed in upgrade guide (#48010) @silviuaavram
143
+ - [docs] Update Autocomplete deprecated props removal migration guide docs (#47990) @ZeeshanTamboli
144
+ - [docs-infra] Extract shared App component from \_app into @mui/docs (#47933) @brijeshb42
145
+ - [docs-infra] Expose global theme object (#47964) @Janpot
146
+ - [docs][system] Update `styled` API docs for easier understanding (#47957) @olivier-lxo
147
+
148
+ ### Core
149
+
150
+ - [code-infra] Add pkg-pr-new as dev dependency (#47992) @Janpot
151
+ - [code-infra] Remove CI coverage collection and upload to Codecov (#47930) @Janpot
152
+ - [core] Migrate to ESLint 10 (#47872) @brijeshb42
153
+ - [core] Remove GridLegacy component (#47956) @siriwatknp
154
+
155
+ All contributors of this release in alphabetical order: @anchmelev, @atharva3333, @brijeshb42, @Janpot, @mj12albert, @noraleonte, @olivier-lxo, @pcorpet, @silviuaavram, @siriwatknp, @ZeeshanTamboli
156
+
157
+ ## 9.0.0-alpha.3
158
+
159
+ <!-- generated comparing v9.0.0-alpha.2..master -->
160
+
161
+ _Mar 12, 2026_
162
+
163
+ A big thanks to the 10 contributors who made this release possible. Here are some highlights ✨:
164
+
165
+ - 📖 A new [Menubar](https://mui.com/material-ui/react-menubar/) component page integrated with [Base UI](https://base-ui.com/react/components/menubar)
166
+ - ♿️ Improved the Roving TabIndex keyboard navigation for the Stepper, Tabs and MenuList components.
167
+
168
+ ### `@mui/material@9.0.0-alpha.3`
169
+
170
+ - [autocomplete] Add `root` slot (#47852) @GerardasB
171
+ - [autocomplete] Fix popup reopening on window focus regain with openOnFocus (#47790) @aman44444
172
+ - [autocomplete] Support full slots for clearIndicator and popupIndicator (#47891) @silviuaavram
173
+ - [material-ui] Partially revert "[material-ui] Clean up duplicated CSS rules (#47838)" (#47927) @sai6855
174
+ - [stepper][menulist][tabs] Improve accessibility (#47687) @silviuaavram
175
+
176
+ ### Docs
177
+
178
+ - [docs][codemod] Add v7 migration docs for deprecated Autocomplete APIs and Autocomplete codemod (#47945) @ZeeshanTamboli
179
+ - [docs] Update faq about vendor chunks (#47747) @Janpot
180
+ - [docs] Use direct palette vars in Tailwind v4 snippet (#47940) @Ahmad-Alaziz
181
+ - [docs][menubar] Add Menubar component page (#47616) @siriwatknp
182
+
183
+ ### Core
184
+
185
+ - [core] Fix the release prepare steps (#47951) @silviuaavram
186
+ - [core] Remove Joy UI code and docs (#47939) @mnajdova
187
+ - [code-infra] Add previously missed export of themeCssVarsAugmentation (#47918) @brijeshb42
188
+ - [docs-infra] Import font module for nextjs transpilation (#47935) @brijeshb42
189
+ - [docs-infra] Migrate simpler modules from docs to mui-docs (#47897) @brijeshb42
190
+ - [test] Fix detached anchorEl elements in tests (#47929) @Janpot
191
+
192
+ All contributors of this release in alphabetical order: @Ahmad-Alaziz, @aman44444, @brijeshb42, @GerardasB, @Janpot, @mnajdova, @sai6855, @silviuaavram, @siriwatknp, @ZeeshanTamboli
193
+
194
+ ## 9.0.0-alpha.2
195
+
196
+ <!-- generated comparing v9.0.0-alpha.1..master -->
197
+
198
+ _Mar 5, 2026_
199
+
200
+ A big thanks to the 4 contributors who made this release possible.
201
+
202
+ ### @mui/material@9.0.0-alpha.2
203
+
204
+ - Clean up duplicated CSS rules (#47838) @sai6855
205
+
206
+ ### @mui/system@9.0.0-alpha.2
207
+
208
+ - Refactor sortContainerQueries to define regex outside of sort function (#47817) @sai6855
209
+
210
+ ### Docs
211
+
212
+ - Move shared components to @mui/docs package (#47672) @Janpot
213
+ - Fix small typo in NumberField page (#47877) @arthur-plazanet
214
+
215
+ ### Core
216
+
217
+ - [code-infra] Reduce paths for attw checks (#47896) @brijeshb42
218
+ - [docs-infra] Run syncTeamMembers (#47900) @Janpot
219
+
220
+ All contributors of this release in alphabetical order: @arthur-plazanet, @brijeshb42, @Janpot, @sai6855
221
+
3
222
  ## 9.0.0-alpha.1
4
223
 
5
224
  <!-- generated comparing v9.0.0-alpha.0..master -->
package/README.md CHANGED
@@ -278,6 +278,11 @@ npx @mui/codemod@next deprecations/alert-props <path>
278
278
  - PopperComponent={CustomPopper}
279
279
  - ListboxComponent={CustomListbox}
280
280
  - ListboxProps={{ height: 12 }}
281
+ - renderTags={(value, getTagProps, ownerState) =>
282
+ - value.map((option, index) => (
283
+ - <Chip label={option.label} {...getTagProps({ index })} />
284
+ - ))
285
+ - }
281
286
  - componentsProps={{
282
287
  - clearIndicator: { width: 10 },
283
288
  - paper: { width: 12 },
@@ -299,6 +304,11 @@ npx @mui/codemod@next deprecations/alert-props <path>
299
304
  + popper: { width: 14 },
300
305
  + popupIndicator: { width: 16 },
301
306
  + }}
307
+ + renderValue={(value, getItemProps, ownerState) =>
308
+ + value.map((option, index) => (
309
+ + <Chip label={option.label} {...getItemProps({ index })} />
310
+ + ))
311
+ + }
302
312
  />
303
313
  ```
304
314
 
@@ -310,6 +320,10 @@ npx @mui/codemod@next deprecations/alert-props <path>
310
320
  - PopperComponent: CustomPopper,
311
321
  - ListboxComponent: CustomListbox,
312
322
  - ListboxProps: { height: 12 },
323
+ - renderTags: (value, getTagProps, ownerState) =>
324
+ - value.map((option, index) => (
325
+ - <Chip label={option.label} {...getTagProps({ index })} />
326
+ - )),
313
327
  - componentsProps: {
314
328
  - clearIndicator: { width: 10 },
315
329
  - paper: { width: 12 },
@@ -331,10 +345,52 @@ npx @mui/codemod@next deprecations/alert-props <path>
331
345
  + popper: { width: 14 },
332
346
  + popupIndicator: { width: 16 },
333
347
  + },
348
+ + renderValue: (value, getItemProps, ownerState) =>
349
+ + value.map((option, index) => (
350
+ + <Chip label={option.label} {...getItemProps({ index })} />
351
+ + )),
334
352
  },
335
353
  },
336
354
  ```
337
355
 
356
+ ```diff
357
+ <Autocomplete
358
+ renderInput={(params) => (
359
+ <TextField
360
+ {...params}
361
+ - InputProps={{
362
+ - ...params.InputProps,
363
+ - endAdornment: (
364
+ - <React.Fragment>
365
+ - {params.InputProps.endAdornment}
366
+ - </React.Fragment>
367
+ - ),
368
+ - }}
369
+ + slotProps={{
370
+ + ...params.slotProps,
371
+ + input: {
372
+ + ...params.slotProps.input,
373
+ + endAdornment: (
374
+ + <React.Fragment>
375
+ + {params.slotProps.input.endAdornment}
376
+ + </React.Fragment>
377
+ + ),
378
+ + },
379
+ + }}
380
+ />
381
+ )}
382
+ />
383
+ ```
384
+
385
+ ```diff
386
+ const {
387
+ - getTagProps,
388
+ - focusedTag,
389
+ + getItemProps,
390
+ + focusedItem,
391
+ } = useAutocomplete(props);
392
+ ```
393
+
338
394
  ```bash
339
395
  npx @mui/codemod@next deprecations/autocomplete-props <path>
340
396
  ```
@@ -814,6 +870,36 @@ CSS transforms:
814
870
  npx @mui/codemod@next deprecations/button-group-classes <path>
815
871
  ```
816
872
 
873
+ #### `card-header-props`
874
+
875
+ ```diff
876
+ <CardHeader
877
+ - titleTypographyProps={{ variant: 'h6' }}
878
+ - subheaderTypographyProps={{ variant: 'body2' }}
879
+ + slotProps={{
880
+ + title: { variant: 'h6' },
881
+ + subheader: { variant: 'body2' }
882
+ + }}
883
+ />
884
+ ```
885
+
886
+ ```diff
887
+ MuiCardHeader: {
888
+ defaultProps: {
889
+ - titleTypographyProps: { variant: 'h6' },
890
+ - subheaderTypographyProps: { variant: 'body2' },
891
+ + slotProps: {
892
+ + title: { variant: 'h6' },
893
+ + subheader: { variant: 'body2' },
894
+ + },
895
+ },
896
+ },
897
+ ```
898
+
899
+ ```bash
900
+ npx @mui/codemod@next deprecations/card-header-props <path>
901
+ ```
902
+
817
903
  #### `chip-classes`
818
904
 
819
905
  JS transforms:
@@ -1006,11 +1092,11 @@ JS transforms:
1006
1092
  styleOverrides: {
1007
1093
  root: {
1008
1094
  - [`& .${circularProgressClasses.circleDeterminate}`]: {
1009
- + [`&.${circularProgressClasses.determinate} > .${circularProgressClasses.circle}`]: {
1095
+ + [`&.${circularProgressClasses.determinate} .${circularProgressClasses.circle}`]: {
1010
1096
  color: 'red',
1011
1097
  },
1012
1098
  - [`& .${circularProgressClasses.circleIndeterminate}`]: {
1013
- + [`&.${circularProgressClasses.indeterminate} > .${circularProgressClasses.circle}`]: {
1099
+ + [`&.${circularProgressClasses.indeterminate} .${circularProgressClasses.circle}`]: {
1014
1100
  color: 'red',
1015
1101
  },
1016
1102
  },
@@ -1022,12 +1108,12 @@ CSS transforms:
1022
1108
 
1023
1109
  ```diff
1024
1110
  -.MuiCircularProgress-circleDeterminate
1025
- +.MuiCircularProgress-determinate > .MuiCircularProgress-circle
1111
+ +.MuiCircularProgress-determinate .MuiCircularProgress-circle
1026
1112
  ```
1027
1113
 
1028
1114
  ```diff
1029
1115
  -.MuiCircularProgress-circleIndeterminate
1030
- +.MuiCircularProgress-indeterminate > .MuiCircularProgress-circle
1116
+ +.MuiCircularProgress-indeterminate .MuiCircularProgress-circle
1031
1117
  ```
1032
1118
 
1033
1119
  ```bash
@@ -1864,23 +1950,68 @@ CSS transforms:
1864
1950
  npx @mui/codemod@next deprecations/slider-classes <path>
1865
1951
  ```
1866
1952
 
1953
+ #### `tabs-props`
1954
+
1955
+ ```diff
1956
+ <Tabs
1957
+ - ScrollButtonComponent={CustomScrollButton}
1958
+ - TabIndicatorProps={{ className: 'indicator' }}
1959
+ - TabScrollButtonProps={{ disableRipple: true }}
1960
+ + slots={{ scrollButtons: CustomScrollButton }}
1961
+ + slotProps={{
1962
+ + indicator: { className: 'indicator' },
1963
+ + scrollButtons: { disableRipple: true },
1964
+ + }}
1965
+ />
1966
+ ```
1967
+
1968
+ ```diff
1969
+ <Tabs
1970
+ - slots={{ StartScrollButtonIcon: CustomIcon, EndScrollButtonIcon: CustomIcon2 }}
1971
+ + slots={{ startScrollButtonIcon: CustomIcon, endScrollButtonIcon: CustomIcon2 }}
1972
+ />
1973
+ ```
1974
+
1975
+ ```diff
1976
+ MuiTabs: {
1977
+ defaultProps: {
1978
+ - ScrollButtonComponent: CustomScrollButton,
1979
+ - TabScrollButtonProps: { disableRipple: true },
1980
+ - TabIndicatorProps: { className: 'indicator' },
1981
+ + slots: {
1982
+ + scrollButtons: CustomScrollButton,
1983
+ + },
1984
+ + slotProps: {
1985
+ + scrollButtons: { disableRipple: true },
1986
+ + indicator: { className: 'indicator' },
1987
+ + },
1988
+ },
1989
+ },
1990
+ ```
1991
+
1992
+ ```bash
1993
+ npx @mui/codemod@next deprecations/tabs-props <path>
1994
+ ```
1995
+
1867
1996
  #### `tooltip-props`
1868
1997
 
1869
1998
  ```diff
1870
1999
  <Tooltip
1871
- - components={{ Arrow: CustomArrow }}
1872
- - componentsProps={{ arrow: { testid: 'test-id' } }}
2000
+ - components={{ Arrow: CustomArrow, Tooltip: CustomTooltip }}
2001
+ - componentsProps={{ arrow: { testid: 'test-id' }, tooltip: { className: 'custom' } }}
1873
2002
  - PopperComponent={CustomPopperComponent}
1874
2003
  - TransitionComponent={CustomTransitionComponent}
1875
2004
  - PopperProps={CustomPopperProps}
1876
2005
  - TransitionProps={CustomTransitionProps}
1877
2006
  + slots={{
1878
2007
  + arrow: CustomArrow,
2008
+ + tooltip: CustomTooltip,
1879
2009
  + popper: CustomPopperComponent,
1880
2010
  + transition: CustomTransitionComponent,
1881
2011
  + }}
1882
2012
  + slotProps={{
1883
2013
  + arrow: { testid: 'test-id' },
2014
+ + tooltip: { className: 'custom' },
1884
2015
  + popper: CustomPopperProps,
1885
2016
  + transition: CustomTransitionProps,
1886
2017
  + }}
@@ -1894,15 +2025,17 @@ npx @mui/codemod@next deprecations/slider-classes <path>
1894
2025
  - TransitionComponent: CustomTransitionComponent,
1895
2026
  - PopperProps: CustomPopperProps,
1896
2027
  - TransitionProps: CustomTransitionProps,
1897
- - components: { Arrow: CustomArrow }
2028
+ - components: { Arrow: CustomArrow, Tooltip: CustomTooltip }
1898
2029
  + slots: {
1899
2030
  + arrow: CustomArrow,
2031
+ + tooltip: CustomTooltip,
1900
2032
  + popper: CustomPopperComponent,
1901
2033
  + transition: CustomTransitionComponent,
1902
2034
  + },
1903
- - componentsProps: { arrow: { testid: 'test-id' }}
2035
+ - componentsProps: { arrow: { testid: 'test-id' }, tooltip: { className: 'custom' } }
1904
2036
  + slotProps: {
1905
2037
  + arrow: { testid: 'test-id' },
2038
+ + tooltip: { className: 'custom' },
1906
2039
  + popper: CustomPopperProps,
1907
2040
  + transition: CustomTransitionProps,
1908
2041
  + },
@@ -12,6 +12,183 @@ var _findComponentJSX = _interopRequireDefault(require("../../util/findComponent
12
12
  var _findComponentDefaultProps = _interopRequireDefault(require("../../util/findComponentDefaultProps"));
13
13
  var _assignObject = _interopRequireDefault(require("../../util/assignObject"));
14
14
  var _appendAttribute = _interopRequireDefault(require("../../util/appendAttribute"));
15
+ function getImportedNames(j, root, packageName, componentName) {
16
+ const importNames = new Set();
17
+ root.find(j.ImportDeclaration).filter(path => path.node.source.value.match(new RegExp(`^${packageName}(/${componentName})?$`))).forEach(path => {
18
+ path.node.specifiers.forEach(specifier => {
19
+ if (specifier.type === 'ImportDefaultSpecifier') {
20
+ importNames.add(specifier.local.name);
21
+ }
22
+ if (specifier.type === 'ImportSpecifier' && specifier.imported.name === componentName) {
23
+ importNames.add(specifier.local.name);
24
+ }
25
+ });
26
+ });
27
+ return importNames;
28
+ }
29
+ function getAttributeIndex(element, attributeName) {
30
+ return element.openingElement.attributes.findIndex(attr => attr.type === 'JSXAttribute' && attr.name.name === attributeName);
31
+ }
32
+ function upsertSlotPropsAttribute(j, element, callback) {
33
+ const slotPropsIndex = getAttributeIndex(element, 'slotProps');
34
+ if (slotPropsIndex === -1) {
35
+ const slotPropsExpression = j.objectExpression([]);
36
+ callback(slotPropsExpression);
37
+ (0, _appendAttribute.default)(j, {
38
+ target: element,
39
+ attributeName: 'slotProps',
40
+ expression: slotPropsExpression
41
+ });
42
+ return;
43
+ }
44
+ const slotPropsAttribute = element.openingElement.attributes[slotPropsIndex];
45
+ const slotPropsExpression = slotPropsAttribute.value.expression;
46
+ if (slotPropsExpression.type === 'ObjectExpression') {
47
+ callback(slotPropsExpression);
48
+ return;
49
+ }
50
+ const nextSlotPropsExpression = j.objectExpression([j.spreadElement(slotPropsExpression)]);
51
+ callback(nextSlotPropsExpression);
52
+ slotPropsAttribute.value.expression = nextSlotPropsExpression;
53
+ }
54
+ function moveJsxPropIntoSlotProps(j, element, propName, slotName) {
55
+ const propIndex = getAttributeIndex(element, propName);
56
+ if (propIndex === -1) {
57
+ return;
58
+ }
59
+ const removedAttribute = element.openingElement.attributes.splice(propIndex, 1)[0];
60
+ const removedValue = removedAttribute.value.type === 'StringLiteral' ? j.literal(removedAttribute.value.value) : removedAttribute.value.expression;
61
+ upsertSlotPropsAttribute(j, element, slotPropsExpression => {
62
+ const existingSlotIndex = slotPropsExpression.properties.findIndex(property => property.type !== 'SpreadElement' && property.key?.name === slotName);
63
+ if (existingSlotIndex === -1) {
64
+ slotPropsExpression.properties.push(j.objectProperty(j.identifier(slotName), removedValue));
65
+ return;
66
+ }
67
+ const existingSlot = slotPropsExpression.properties[existingSlotIndex].value;
68
+ slotPropsExpression.properties[existingSlotIndex].value = j.objectExpression([j.spreadElement(removedValue), j.spreadElement(existingSlot)]);
69
+ });
70
+ }
71
+ function ensureParamsSlotPropsSpread(j, element, paramsName) {
72
+ const hasParamsSpread = element.openingElement.attributes.some(attribute => attribute.type === 'JSXSpreadAttribute' && attribute.argument.type === 'Identifier' && attribute.argument.name === paramsName);
73
+ if (!hasParamsSpread) {
74
+ return;
75
+ }
76
+ upsertSlotPropsAttribute(j, element, slotPropsExpression => {
77
+ const hasSlotPropsSpread = slotPropsExpression.properties.some(property => property.type === 'SpreadElement' && property.argument.type === 'MemberExpression' && property.argument.object.type === 'Identifier' && property.argument.object.name === paramsName && property.argument.property.type === 'Identifier' && property.argument.property.name === 'slotProps');
78
+ if (!hasSlotPropsSpread) {
79
+ slotPropsExpression.properties.unshift(j.spreadElement(j.memberExpression(j.identifier(paramsName), j.identifier('slotProps'))));
80
+ }
81
+ });
82
+ }
83
+ function replaceRenderInputParamsMembers(j, callbackRoot, paramsName) {
84
+ const slotPropByDeprecatedName = {
85
+ InputProps: 'input',
86
+ inputProps: 'htmlInput',
87
+ InputLabelProps: 'inputLabel'
88
+ };
89
+ callbackRoot.find(j.MemberExpression).filter(path => path.node.object.type === 'Identifier' && path.node.object.name === paramsName && path.node.property.type === 'Identifier' && slotPropByDeprecatedName[path.node.property.name]).replaceWith(path => j.memberExpression(j.memberExpression(j.identifier(paramsName), j.identifier('slotProps')), j.identifier(slotPropByDeprecatedName[path.node.property.name])));
90
+ }
91
+ function transformRenderInput(j, root, options) {
92
+ const packageName = options.packageName || '@mui/material';
93
+ const textFieldNames = getImportedNames(j, root, packageName, 'TextField');
94
+ (0, _findComponentJSX.default)(j, {
95
+ root,
96
+ packageName: options.packageName,
97
+ componentName: 'Autocomplete'
98
+ }, elementPath => {
99
+ const renderInputIndex = getAttributeIndex(elementPath.node, 'renderInput');
100
+ if (renderInputIndex === -1) {
101
+ return;
102
+ }
103
+ const renderInputAttribute = elementPath.node.openingElement.attributes[renderInputIndex];
104
+ const renderInputExpression = renderInputAttribute.value?.expression;
105
+ if (!renderInputExpression || !['ArrowFunctionExpression', 'FunctionExpression'].includes(renderInputExpression.type) || renderInputExpression.params.length === 0 || renderInputExpression.params[0].type !== 'Identifier') {
106
+ return;
107
+ }
108
+ const paramsName = renderInputExpression.params[0].name;
109
+ const callbackRoot = j(renderInputExpression.body);
110
+ replaceRenderInputParamsMembers(j, callbackRoot, paramsName);
111
+ textFieldNames.forEach(textFieldName => {
112
+ const textFieldElements = [];
113
+ if (renderInputExpression.body.type === 'JSXElement' && renderInputExpression.body.openingElement.name.type === 'JSXIdentifier' && renderInputExpression.body.openingElement.name.name === textFieldName) {
114
+ textFieldElements.push(renderInputExpression.body);
115
+ }
116
+ callbackRoot.find(j.JSXElement).filter(textFieldPath => textFieldPath.node.openingElement.name.type === 'JSXIdentifier' && textFieldPath.node.openingElement.name.name === textFieldName).forEach(textFieldPath => {
117
+ textFieldElements.push(textFieldPath.node);
118
+ });
119
+ textFieldElements.forEach(element => {
120
+ moveJsxPropIntoSlotProps(j, element, 'InputProps', 'input');
121
+ moveJsxPropIntoSlotProps(j, element, 'inputProps', 'htmlInput');
122
+ moveJsxPropIntoSlotProps(j, element, 'InputLabelProps', 'inputLabel');
123
+ moveJsxPropIntoSlotProps(j, element, 'SelectProps', 'select');
124
+ moveJsxPropIntoSlotProps(j, element, 'FormHelperTextProps', 'formHelperText');
125
+ if (getAttributeIndex(element, 'slotProps') !== -1) {
126
+ ensureParamsSlotPropsSpread(j, element, paramsName);
127
+ }
128
+ });
129
+ });
130
+ });
131
+ }
132
+ function isNonComputedKey(j, path) {
133
+ const parent = path.parent.node;
134
+ return (j.ObjectProperty.check(parent) || j.Property.check(parent)) && parent.key === path.node && !parent.computed;
135
+ }
136
+ function renameIdentifiersInScope(j, scopePath, oldName, newName) {
137
+ const bindingScope = scopePath.scope.lookup(oldName);
138
+ if (!bindingScope) {
139
+ return;
140
+ }
141
+ j(bindingScope.path).find(j.Identifier, {
142
+ name: oldName
143
+ }).filter(path => {
144
+ if (isNonComputedKey(j, path)) {
145
+ return false;
146
+ }
147
+ return path.scope.lookup(oldName) === bindingScope;
148
+ }).replaceWith(() => j.identifier(newName));
149
+ }
150
+ function renameRenderTagsCallback(j, callbackPath) {
151
+ const getTagPropsParam = callbackPath.node.params[1];
152
+ if (getTagPropsParam?.type === 'Identifier' && getTagPropsParam.name === 'getTagProps') {
153
+ renameIdentifiersInScope(j, callbackPath, 'getTagProps', 'getItemProps');
154
+ }
155
+ }
156
+ function renameRenderTagsProp(j, propertyPath) {
157
+ if (propertyPath.node.key.type === 'Identifier') {
158
+ propertyPath.node.key.name = 'renderValue';
159
+ }
160
+ if (propertyPath.node.value.type === 'ArrowFunctionExpression' || propertyPath.node.value.type === 'FunctionExpression') {
161
+ renameRenderTagsCallback(j, propertyPath.get('value'));
162
+ }
163
+ }
164
+ function renameUseAutocompleteReturnMembers(j, root) {
165
+ const renamedMembers = new Map([['getTagProps', 'getItemProps'], ['focusedTag', 'focusedItem']]);
166
+ root.find(j.VariableDeclarator).filter(path => {
167
+ const {
168
+ id,
169
+ init
170
+ } = path.node;
171
+ return id.type === 'ObjectPattern' && init?.type === 'CallExpression' && init.callee.type === 'Identifier' && init.callee.name === 'useAutocomplete';
172
+ }).forEach(path => {
173
+ path.node.id.properties.forEach(property => {
174
+ if (property.type !== 'ObjectProperty' || property.key.type !== 'Identifier') {
175
+ return;
176
+ }
177
+ const nextName = renamedMembers.get(property.key.name);
178
+ if (!nextName) {
179
+ return;
180
+ }
181
+ const isShorthand = property.shorthand === true;
182
+ const localName = property.value.type === 'Identifier' ? property.value.name : null;
183
+ property.key.name = nextName;
184
+ if (isShorthand && localName) {
185
+ renameIdentifiersInScope(j, path, localName, nextName);
186
+ property.shorthand = true;
187
+ }
188
+ });
189
+ });
190
+ }
191
+
15
192
  /**
16
193
  * @param {import('jscodeshift').FileInfo} file
17
194
  * @param {import('jscodeshift').API} api
@@ -53,6 +230,7 @@ function transformer(file, api, options) {
53
230
  packageName: options.packageName,
54
231
  componentName: 'Autocomplete'
55
232
  });
233
+ transformRenderInput(j, root, options);
56
234
 
57
235
  // Move ListboxComponent JSX prop into slotProps.listbox.component
58
236
  (0, _findComponentJSX.default)(j, {
@@ -61,6 +239,15 @@ function transformer(file, api, options) {
61
239
  componentName: 'Autocomplete'
62
240
  }, elementPath => {
63
241
  const element = elementPath.node;
242
+ element.openingElement.attributes.forEach((attribute, index) => {
243
+ if (attribute.type !== 'JSXAttribute' || attribute.name.name !== 'renderTags') {
244
+ return;
245
+ }
246
+ attribute.name.name = 'renderValue';
247
+ if (attribute.value?.type === 'JSXExpressionContainer' && (attribute.value.expression.type === 'ArrowFunctionExpression' || attribute.value.expression.type === 'FunctionExpression')) {
248
+ renameRenderTagsCallback(j, elementPath.get('openingElement', 'attributes', index, 'value', 'expression'));
249
+ }
250
+ });
64
251
  const propIndex = element.openingElement.attributes.findIndex(attr => attr.type === 'JSXAttribute' && attr.name.name === 'ListboxComponent');
65
252
  if (propIndex !== -1) {
66
253
  const removedValue = element.openingElement.attributes.splice(propIndex, 1)[0].value.expression;
@@ -127,5 +314,13 @@ function transformer(file, api, options) {
127
314
  }
128
315
  path.prune();
129
316
  });
317
+ defaultPropsPathCollection.find(j.ObjectProperty, {
318
+ key: {
319
+ name: 'renderTags'
320
+ }
321
+ }).forEach(path => {
322
+ renameRenderTagsProp(j, path);
323
+ });
324
+ renameUseAutocompleteReturnMembers(j, root);
130
325
  return root.toSource(printOptions);
131
326
  }