Skip to content

Commit

Permalink
[material-ui][InputBase] Deprecate composed classes (#45366)
Browse files Browse the repository at this point in the history
  • Loading branch information
siriwatknp authored Feb 25, 2025
1 parent 3bfa70e commit 6af576b
Show file tree
Hide file tree
Showing 16 changed files with 460 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1337,6 +1337,57 @@ Use the [codemod](https://github.com/mui/material-ui/tree/HEAD/packages/mui-code

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

### Composed CSS classes

The CSS classes that composed the `input` class with other props `size`, `type`, `multiline`, `adornedStart`, `adornedEnd`, and `hiddenLabel` have been removed.

Here's how to migrate:

```diff
-.MuiInputBase-root .MuiInputBase-inputSizeSmall
+.MuiInputBase-root.MuiInputBase-sizeSmall > .MuiInputBase-input
-.MuiInputBase-root .MuiInputBase-inputMultiline
+.MuiInputBase-root.MuiInputBase-multiline > .MuiInputBase-input
-.MuiInputBase-root .MuiInputBase-inputAdornedStart
+.MuiInputBase-root.MuiInputBase-adornedStart > .MuiInputBase-input
-.MuiInputBase-root .MuiInputBase-inputAdornedEnd
+.MuiInputBase-root.MuiInputBase-adornedEnd > .MuiInputBase-input
-.MuiInputBase-root .MuiInputBase-inputHiddenLabel
+.MuiInputBase-root.MuiInputBase-hiddenLabel > .MuiInputBase-input
```

```diff
import { inputBaseClasses } from '@mui/material/InputBase';

MuiInputBase: {
styleOverrides: {
root: {
- [`& .${inputBaseClasses.inputSizeSmall}`]: {
+ [`&.${inputBaseClasses.sizeSmall} > .${inputBaseClasses.input}`]: {
color: 'red',
},
- [`& .${inputBaseClasses.inputMultiline}`]: {
+ [`&.${inputBaseClasses.multiline} > .${inputBaseClasses.input}`]: {
color: 'red',
},
- [`& .${inputBaseClasses.inputAdornedStart}`]: {
+ [`&.${inputBaseClasses.adornedStart} > .${inputBaseClasses.input}`]: {
color: 'red',
},
- [`& .${inputBaseClasses.inputAdornedEnd}`]: {
+ [`&.${inputBaseClasses.adornedEnd} > .${inputBaseClasses.input}`]: {
color: 'red',
},
- [`& .${inputBaseClasses.inputHiddenLabel}`]: {
+ [`&.${inputBaseClasses.hiddenLabel} > .${inputBaseClasses.input}`]: {
color: 'red',
},
},
},
},
```

### components
Expand Down
17 changes: 11 additions & 6 deletions docs/pages/material-ui/api/input-base.json
Original file line number Diff line number Diff line change
Expand Up @@ -147,36 +147,41 @@
"key": "inputAdornedEnd",
"className": "MuiInputBase-inputAdornedEnd",
"description": "Styles applied to the input element if `endAdornment` is provided.",
"isGlobal": false
"isGlobal": false,
"isDeprecated": true
},
{
"key": "inputAdornedStart",
"className": "MuiInputBase-inputAdornedStart",
"description": "Styles applied to the input element if `startAdornment` is provided.",
"isGlobal": false
"isGlobal": false,
"isDeprecated": true
},
{
"key": "inputHiddenLabel",
"className": "MuiInputBase-inputHiddenLabel",
"description": "Styles applied to the input element if `hiddenLabel={true}`.",
"isGlobal": false
"isGlobal": false,
"isDeprecated": true
},
{
"key": "inputMultiline",
"className": "MuiInputBase-inputMultiline",
"description": "Styles applied to the input element if `multiline={true}`.",
"isGlobal": false
"isGlobal": false,
"isDeprecated": true
},
{
"key": "inputSizeSmall",
"className": "MuiInputBase-inputSizeSmall",
"description": "Styles applied to the input element if `size=\"small\"`.",
"isGlobal": false
"isGlobal": false,
"isDeprecated": true
},
{
"key": "inputTypeSearch",
"className": "MuiInputBase-inputTypeSearch",
"description": "Styles applied to the input element if `type=\"search\"`.",
"description": "",
"isGlobal": false
},
{
Expand Down
21 changes: 11 additions & 10 deletions docs/translations/api-docs/input-base/input-base.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,33 +143,34 @@
"inputAdornedEnd": {
"description": "Styles applied to {{nodeName}} if {{conditions}}.",
"nodeName": "the input element",
"conditions": "<code>endAdornment</code> is provided"
"conditions": "<code>endAdornment</code> is provided",
"deprecationInfo": "Combine the <a href=\"/material-ui/api/input-base/#inputbase-classes-input\">.MuiInputBase-input</a> and <a href=\"/material-ui/api/input-base/#inputbase-classes-adornedEnd\">.MuiInputBase-adornedEnd</a> classes instead. See <a href=\"/material-ui/migration/migrating-from-deprecated-apis/\">Migrating from deprecated APIs</a> for more details."
},
"inputAdornedStart": {
"description": "Styles applied to {{nodeName}} if {{conditions}}.",
"nodeName": "the input element",
"conditions": "<code>startAdornment</code> is provided"
"conditions": "<code>startAdornment</code> is provided",
"deprecationInfo": "Combine the <a href=\"/material-ui/api/input-base/#inputbase-classes-input\">.MuiInputBase-input</a> and <a href=\"/material-ui/api/input-base/#inputbase-classes-adornedStart\">.MuiInputBase-adornedStart</a> classes instead. See <a href=\"/material-ui/migration/migrating-from-deprecated-apis/\">Migrating from deprecated APIs</a> for more details."
},
"inputHiddenLabel": {
"description": "Styles applied to {{nodeName}} if {{conditions}}.",
"nodeName": "the input element",
"conditions": "<code>hiddenLabel={true}</code>"
"conditions": "<code>hiddenLabel={true}</code>",
"deprecationInfo": "Combine the <a href=\"/material-ui/api/input-base/#inputbase-classes-input\">.MuiInputBase-input</a> and <a href=\"/material-ui/api/input-base/#inputbase-classes-hiddenLabel\">.MuiInputBase-hiddenLabel</a> classes instead. See <a href=\"/material-ui/migration/migrating-from-deprecated-apis/\">Migrating from deprecated APIs</a> for more details."
},
"inputMultiline": {
"description": "Styles applied to {{nodeName}} if {{conditions}}.",
"nodeName": "the input element",
"conditions": "<code>multiline={true}</code>"
"conditions": "<code>multiline={true}</code>",
"deprecationInfo": "Combine the <a href=\"/material-ui/api/input-base/#inputbase-classes-input\">.MuiInputBase-input</a> and <a href=\"/material-ui/api/input-base/#inputbase-classes-multiline\">.MuiInputBase-multiline</a> classes instead. See <a href=\"/material-ui/migration/migrating-from-deprecated-apis/\">Migrating from deprecated APIs</a> for more details."
},
"inputSizeSmall": {
"description": "Styles applied to {{nodeName}} if {{conditions}}.",
"nodeName": "the input element",
"conditions": "<code>size=\"small\"</code>"
},
"inputTypeSearch": {
"description": "Styles applied to {{nodeName}} if {{conditions}}.",
"nodeName": "the input element",
"conditions": "<code>type=\"search\"</code>"
"conditions": "<code>size=\"small\"</code>",
"deprecationInfo": "Combine the <a href=\"/material-ui/api/input-base/#inputbase-classes-input\">.MuiInputBase-input</a> and <a href=\"/material-ui/api/input-base/#inputbase-classes-sizeSmall\">.MuiInputBase-sizeSmall</a> classes instead. See <a href=\"/material-ui/migration/migrating-from-deprecated-apis/\">Migrating from deprecated APIs</a> for more details."
},
"inputTypeSearch": { "description": "" },
"multiline": {
"description": "Styles applied to {{nodeName}} if {{conditions}}.",
"nodeName": "the root element",
Expand Down
54 changes: 54 additions & 0 deletions packages/mui-codemod/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1288,6 +1288,60 @@ npx @mui/codemod@latest deprecations/image-list-item-bar-classes <path>
npx @mui/codemod@latest deprecations/input-base-props <path>
```

#### `input-base-classes`

JS transforms:

```diff
import { inputBaseClasses } from '@mui/material/InputBase';

MuiInputBase: {
styleOverrides: {
root: {
- [`& .${inputBaseClasses.inputSizeSmall}`]: {
+ [`&.${inputBaseClasses.sizeSmall} > .${inputBaseClasses.input}`]: {
color: 'red',
},
- [`& .${inputBaseClasses.inputMultiline}`]: {
+ [`&.${inputBaseClasses.multiline} > .${inputBaseClasses.input}`]: {
color: 'red',
},
- [`& .${inputBaseClasses.inputAdornedStart}`]: {
+ [`&.${inputBaseClasses.adornedStart} > .${inputBaseClasses.input}`]: {
color: 'red',
},
- [`& .${inputBaseClasses.inputAdornedEnd}`]: {
+ [`&.${inputBaseClasses.adornedEnd} > .${inputBaseClasses.input}`]: {
color: 'red',
},
- [`& .${inputBaseClasses.inputHiddenLabel}`]: {
+ [`&.${inputBaseClasses.hiddenLabel} > .${inputBaseClasses.input}`]: {
color: 'red',
},
},
},
},
```

CSS transforms:

```diff
-.MuiInputBase-root .MuiInputBase-inputSizeSmall
+.MuiInputBase-root.MuiInputBase-sizeSmall > .MuiInputBase-input
-.MuiInputBase-root .MuiInputBase-inputMultiline
+.MuiInputBase-root.MuiInputBase-multiline > .MuiInputBase-input
-.MuiInputBase-root .MuiInputBase-inputAdornedStart
+.MuiInputBase-root.MuiInputBase-adornedStart > .MuiInputBase-input
-.MuiInputBase-root .MuiInputBase-inputAdornedEnd
+.MuiInputBase-root.MuiInputBase-adornedEnd > .MuiInputBase-input
-.MuiInputBase-root .MuiInputBase-inputHiddenLabel
+.MuiInputBase-root.MuiInputBase-hiddenLabel > .MuiInputBase-input
```

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

#### `input-props`

```diff
Expand Down
2 changes: 2 additions & 0 deletions packages/mui-codemod/src/deprecations/all/deprecations-all.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import transformFilledInputProps from '../filled-input-props';
import transformFormControlLabelProps from '../form-control-label-props';
import transformImageListItemBarClasses from '../image-list-item-bar-classes';
import transformInputBaseProps from '../input-base-props';
import transformInputBaseClasses from '../input-base-classes';
import transformInputProps from '../input-props';
import transformListItemTextProps from '../list-item-text-props';
import transformLinearProgressClasses from '../linear-progress-classes';
Expand Down Expand Up @@ -64,6 +65,7 @@ export default function deprecationsAll(file, api, options) {
file.source = transformFormControlLabelProps(file, api, options);
file.source = transformImageListItemBarClasses(file, api, options);
file.source = transformInputBaseProps(file, api, options);
file.source = transformInputBaseClasses(file, api, options);
file.source = transformInputProps(file, api, options);
file.source = transformListItemTextProps(file, api, options);
file.source = transformLinearProgressClasses(file, api, options);
Expand Down
2 changes: 2 additions & 0 deletions packages/mui-codemod/src/deprecations/all/postcss.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const {
const {
plugin: circularProgressClassesPlugin,
} = require('../circular-progress-classes/postcss-plugin');
const { plugin: inputBaseClassesPlugin } = require('../input-base-classes/postcss-plugin');
const {
plugin: linearProgressClassesPlugin,
} = require('../linear-progress-classes/postcss-plugin');
Expand All @@ -34,6 +35,7 @@ module.exports = {
buttonGroupClassesPlugin,
chipClassesPlugin,
circularProgressClassesPlugin,
inputBaseClassesPlugin,
linearProgressClassesPlugin,
drawerClassesPlugin,
paginationItemClassesPlugin,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './input-base-classes';
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { classes } from './postcss-plugin';

/**
* @param {import('jscodeshift').FileInfo} file
* @param {import('jscodeshift').API} api
*/
export default function transformer(file, api, options) {
const j = api.jscodeshift;
const root = j(file.source);
const printOptions = options.printOptions;
classes.forEach(({ deprecatedClass, replacementSelector }) => {
const replacementSelectorPrefix = '&';
root
.find(j.ImportDeclaration)
.filter((path) => path.node.source.value.match(/^@mui\/material\/InputBase$/))
.forEach((path) => {
path.node.specifiers.forEach((specifier) => {
if (
specifier.type === 'ImportSpecifier' &&
specifier.imported.name === 'inputBaseClasses'
) {
const deprecatedAtomicClass = deprecatedClass.replace(
`${deprecatedClass.split('-')[0]}-`,
'',
);
root
.find(j.MemberExpression, {
object: { name: specifier.local.name },
property: { name: deprecatedAtomicClass },
})
.forEach((memberExpression) => {
const parent = memberExpression.parentPath.parentPath.value;
if (parent.type === j.TemplateLiteral.name) {
const memberExpressionIndex = parent.expressions.findIndex(
(expression) => expression === memberExpression.value,
);
const precedingTemplateElement = parent.quasis[memberExpressionIndex];
const atomicClasses = replacementSelector
.replaceAll('MuiInputBase-', '')
.replaceAll(replacementSelectorPrefix, '')
.replaceAll(' > ', '')
.split('.')
.filter(Boolean);

if (
precedingTemplateElement.value.raw.endsWith(
deprecatedClass.startsWith(' ')
? `${replacementSelectorPrefix} .`
: `${replacementSelectorPrefix}.`,
)
) {
parent.expressions.splice(
memberExpressionIndex,
1,
j.memberExpression(
memberExpression.value.object,
j.identifier(atomicClasses[0]),
),

j.memberExpression(
memberExpression.value.object,
j.identifier(atomicClasses[1]),
),
);

if (replacementSelector.includes(' > ')) {
parent.quasis.splice(
memberExpressionIndex,
1,
j.templateElement(
{
raw: precedingTemplateElement.value.raw.replace(' ', ''),
cooked: precedingTemplateElement.value.cooked.replace(' ', ''),
},
false,
),
j.templateElement({ raw: ' > .', cooked: ' > .' }, false),
);
} else {
parent.quasis.splice(
memberExpressionIndex,
1,
j.templateElement(
{
raw: precedingTemplateElement.value.raw,
cooked: precedingTemplateElement.value.cooked,
},
false,
),

j.templateElement({ raw: '.', cooked: '.' }, false),
);
}
}
}
});
}
});
});

const selectorRegex = new RegExp(`^${replacementSelectorPrefix}${deprecatedClass}`);
root
.find(
j.Literal,
(literal) => typeof literal.value === 'string' && literal.value.match(selectorRegex),
)
.forEach((path) => {
path.replace(
j.literal(
path.value.value.replace(
selectorRegex,
`${replacementSelectorPrefix}${replacementSelector}`,
),
),
);
});
});
return root.toSource(printOptions);
}
Loading

0 comments on commit 6af576b

Please sign in to comment.