Skip to content

Commit 7a830f3

Browse files
committed
Craete codemod for Joy renaming components and componentsProps to slots and slotProps
1 parent 8ebc521 commit 7a830f3

File tree

4 files changed

+94
-0
lines changed

4 files changed

+94
-0
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
function transformComponentsProp(attributeNode) {
2+
attributeNode.name.name = 'slots';
3+
4+
const valueExpression = attributeNode.value.expression;
5+
if (valueExpression?.type !== 'ObjectExpression') {
6+
return;
7+
}
8+
9+
valueExpression.properties.forEach((property) => {
10+
property.key.name = property.key.name[0].toLowerCase() + property.key.name.slice(1);
11+
12+
if (property.shorthand) {
13+
property.shorthand = false;
14+
}
15+
});
16+
}
17+
18+
function transformComponentsPropsProp(attributeNode) {
19+
attributeNode.name.name = 'slotProps';
20+
}
21+
22+
/**
23+
* @param {import('jscodeshift').FileInfo} file
24+
* @param {import('jscodeshift').API} api
25+
*/
26+
export default function transformer(file, api, options) {
27+
const j = api.jscodeshift;
28+
const root = j(file.source);
29+
const printOptions = options.printOptions;
30+
31+
const transformed = root.findJSXElements().forEach((path) => {
32+
if (path.node.type !== "JSXElement") {
33+
return;
34+
}
35+
36+
path.node.openingElement.attributes.forEach((node) => {
37+
if (node.type !== 'JSXAttribute') {
38+
return;
39+
}
40+
41+
switch (node.name.name) {
42+
case 'components':
43+
transformComponentsProp(node);
44+
break;
45+
46+
case 'componentsProps':
47+
transformComponentsPropsProp(node);
48+
break;
49+
50+
default:
51+
}
52+
});
53+
});
54+
55+
return transformed.toSource(printOptions);
56+
}
57+
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import path from 'path';
2+
import { expect } from 'chai';
3+
import jscodeshift from 'jscodeshift';
4+
import transform from './joy-rename-components-to-slots';
5+
import readFile from '../util/readFile';
6+
7+
function read(fileName) {
8+
return readFile(path.join(__dirname, fileName));
9+
}
10+
11+
describe('@mui/codemod', () => {
12+
describe('v5.0.0', () => {
13+
describe('joy-rename-components-to-slots', () => {
14+
it('transforms props as needed', () => {
15+
const actual = transform(
16+
{
17+
source: read('./joy-rename-components-to-slots.test/actual.js'),
18+
path: require.resolve('./joy-rename-components-to-slots.test/actual.js'),
19+
},
20+
{ jscodeshift },
21+
{},
22+
);
23+
24+
const expected = read('./joy-rename-components-to-slots.test/expected.js');
25+
expect(actual).to.equal(expected, 'The transformed version should be correct');
26+
});
27+
});
28+
});
29+
});
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<Autocomplete
2+
components={{ Root, Input: CustomInput }}
3+
componentsProps={{ root: { className: 'root' }, input: { 'data-testid': 'input' } }}
4+
/>;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<Autocomplete
2+
slots={{ root: Root, input: CustomInput }}
3+
slotProps={{ root: { className: 'root' }, input: { 'data-testid': 'input' } }}
4+
/>;

0 commit comments

Comments
 (0)