Files
react-test/packages/mui-codemod/src/deprecations/button-classes/button-classes.js
how2ice 005cf56baf
Some checks failed
No response / noResponse (push) Has been cancelled
CI / Continuous releases (push) Has been cancelled
CI / test-dev (macos-latest) (push) Has been cancelled
CI / test-dev (ubuntu-latest) (push) Has been cancelled
CI / test-dev (windows-latest) (push) Has been cancelled
Maintenance / main (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
init project
2025-12-12 14:26:25 +09:00

121 lines
4.4 KiB
JavaScript

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(
new RegExp(`^${options.packageName || '@mui/material'}(/Button)?$`),
),
)
.forEach((path) => {
path.node.specifiers.forEach((specifier) => {
if (specifier.type === 'ImportSpecifier' && specifier.imported.name === 'buttonClasses') {
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('MuiButton-', '')
.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);
}