@mui/codemod 5.7.0 → 5.8.3
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 +135 -53
- package/node/v5.0.0/jss-to-tss-react.js +460 -0
- package/node/v5.0.0/jss-to-tss-react.test/actual-from-material-ui-core-styles.js +52 -0
- package/node/v5.0.0/jss-to-tss-react.test/actual-from-material-ui-core.js +75 -0
- package/node/v5.0.0/jss-to-tss-react.test/actual-from-mui-styles.js +53 -0
- package/node/v5.0.0/jss-to-tss-react.test/actual-mixins-pattern.js +51 -0
- package/node/v5.0.0/jss-to-tss-react.test/actual-todo-comments.js +82 -0
- package/node/v5.0.0/jss-to-tss-react.test/actual-typescript-docs-example-params.js +59 -0
- package/node/v5.0.0/jss-to-tss-react.test/actual-typescript-docs-example.js +55 -0
- package/node/v5.0.0/jss-to-tss-react.test/actual-typescript.js +73 -0
- package/node/v5.0.0/jss-to-tss-react.test/actual-withStyles.js +123 -0
- package/node/v5.0.0/jss-to-tss-react.test/expected-from-material-ui-core-styles.js +56 -0
- package/node/v5.0.0/jss-to-tss-react.test/expected-from-material-ui-core.js +80 -0
- package/node/v5.0.0/jss-to-tss-react.test/expected-from-mui-styles.js +57 -0
- package/node/v5.0.0/jss-to-tss-react.test/expected-mixins-pattern.js +54 -0
- package/node/v5.0.0/jss-to-tss-react.test/expected-todo-comments.js +96 -0
- package/node/v5.0.0/jss-to-tss-react.test/expected-typescript-docs-example-params.js +61 -0
- package/node/v5.0.0/jss-to-tss-react.test/expected-typescript-docs-example.js +54 -0
- package/node/v5.0.0/jss-to-tss-react.test/expected-typescript.js +79 -0
- package/node/v5.0.0/jss-to-tss-react.test/expected-withStyles.js +124 -0
- package/node/v5.0.0/modal-props.js +1 -1
- package/node/v5.0.0/modal-props.test/expected.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = transformer;
|
|
7
|
+
const ruleEndRegEx = /[^a-zA-Z0-9_]+/;
|
|
8
|
+
|
|
9
|
+
function transformNestedKeys(j, comments, propValueNode, ruleRegEx, nestedKeys) {
|
|
10
|
+
propValueNode.properties.forEach(prop => {
|
|
11
|
+
var _prop$value, _prop$value2;
|
|
12
|
+
|
|
13
|
+
if (((_prop$value = prop.value) == null ? void 0 : _prop$value.type) === 'ObjectExpression') {
|
|
14
|
+
if (typeof prop.key.value === 'string' && ruleRegEx !== null) {
|
|
15
|
+
let ruleIndex = prop.key.value.search(ruleRegEx);
|
|
16
|
+
let searchStartIndex = 0;
|
|
17
|
+
const elements = [];
|
|
18
|
+
const identifiers = [];
|
|
19
|
+
|
|
20
|
+
while (ruleIndex >= 0) {
|
|
21
|
+
const valueStartingAtRuleName = prop.key.value.substring(ruleIndex + 1);
|
|
22
|
+
const ruleEndIndex = valueStartingAtRuleName.search(ruleEndRegEx);
|
|
23
|
+
const ruleName = ruleEndIndex >= 0 ? prop.key.value.substring(ruleIndex + 1, ruleIndex + 1 + ruleEndIndex) : valueStartingAtRuleName;
|
|
24
|
+
|
|
25
|
+
if (!nestedKeys.includes(ruleName)) {
|
|
26
|
+
nestedKeys.push(ruleName);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const before = prop.key.value.substring(searchStartIndex, ruleIndex);
|
|
30
|
+
elements.push(j.templateElement({
|
|
31
|
+
raw: `${before}.`,
|
|
32
|
+
cooked: `${before}.`
|
|
33
|
+
}, false));
|
|
34
|
+
identifiers.push(j.identifier(`classes.${ruleName}`));
|
|
35
|
+
searchStartIndex = ruleIndex + ruleName.length + 1;
|
|
36
|
+
const after = prop.key.value.substring(searchStartIndex);
|
|
37
|
+
ruleIndex = after.search(ruleRegEx);
|
|
38
|
+
|
|
39
|
+
if (ruleIndex >= 0) {
|
|
40
|
+
ruleIndex += searchStartIndex;
|
|
41
|
+
} else {
|
|
42
|
+
elements.push(j.templateElement({
|
|
43
|
+
raw: after,
|
|
44
|
+
cooked: after
|
|
45
|
+
}, false));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (identifiers.length > 0) {
|
|
50
|
+
prop.key = j.templateLiteral(elements, identifiers);
|
|
51
|
+
prop.computed = true;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
transformNestedKeys(j, comments, prop.value, ruleRegEx, nestedKeys);
|
|
56
|
+
} else if (((_prop$value2 = prop.value) == null ? void 0 : _prop$value2.type) === 'ArrowFunctionExpression') {
|
|
57
|
+
comments.push(j.commentLine(' TODO jss-to-tss-react codemod: Unable to handle style definition reliably. ArrowFunctionExpression in CSS prop.', true));
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function transformStylesExpression(j, comments, stylesExpression, nestedKeys, setStylesExpression) {
|
|
63
|
+
const ruleNames = [];
|
|
64
|
+
const paramNames = [];
|
|
65
|
+
let objectExpression;
|
|
66
|
+
|
|
67
|
+
if (stylesExpression.type === 'ObjectExpression') {
|
|
68
|
+
objectExpression = stylesExpression;
|
|
69
|
+
} else if (stylesExpression.type === 'ArrowFunctionExpression') {
|
|
70
|
+
if (stylesExpression.body.type === 'BlockStatement') {
|
|
71
|
+
const returnStatement = stylesExpression.body.body.find(b => b.type === 'ReturnStatement');
|
|
72
|
+
|
|
73
|
+
if (returnStatement.argument.type === 'ObjectExpression') {
|
|
74
|
+
objectExpression = returnStatement.argument;
|
|
75
|
+
}
|
|
76
|
+
} else if (stylesExpression.body.type === 'ObjectExpression') {
|
|
77
|
+
objectExpression = stylesExpression.body;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (objectExpression !== undefined) {
|
|
82
|
+
objectExpression.properties.forEach(prop => {
|
|
83
|
+
var _prop$key, _prop$key2;
|
|
84
|
+
|
|
85
|
+
if ((_prop$key = prop.key) != null && _prop$key.name) {
|
|
86
|
+
ruleNames.push(prop.key.name);
|
|
87
|
+
} else if (((_prop$key2 = prop.key) == null ? void 0 : _prop$key2.value) === '@global') {
|
|
88
|
+
comments.push(j.commentLine(` TODO jss-to-tss-react codemod: '@global' is not supported by tss-react.`, true));
|
|
89
|
+
comments.push(j.commentLine(` See https://mui.com/material-ui/customization/how-to-customize/#4-global-css-override for alternatives.`, true));
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
let ruleRegExString = '(';
|
|
93
|
+
ruleNames.forEach((ruleName, index) => {
|
|
94
|
+
if (index > 0) {
|
|
95
|
+
ruleRegExString += '|';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
ruleRegExString += `\\$${ruleName}`;
|
|
99
|
+
});
|
|
100
|
+
ruleRegExString += ')';
|
|
101
|
+
const ruleRegEx = ruleNames.length === 0 ? null : new RegExp(ruleRegExString, 'g');
|
|
102
|
+
objectExpression.properties.forEach(prop => {
|
|
103
|
+
if (prop.value) {
|
|
104
|
+
if (prop.value.type !== 'ObjectExpression') {
|
|
105
|
+
if (prop.value.type === 'ArrowFunctionExpression' && prop.value.body.type === 'ObjectExpression' && prop.value.params[0].type === 'ObjectPattern') {
|
|
106
|
+
prop.value.params[0].properties.forEach(property => {
|
|
107
|
+
const name = property.key.name;
|
|
108
|
+
|
|
109
|
+
if (!paramNames.includes(name)) {
|
|
110
|
+
paramNames.push(name);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
prop.value = prop.value.body;
|
|
114
|
+
} else {
|
|
115
|
+
let extraComment = `Unexpected value type of ${prop.value.type}.`;
|
|
116
|
+
|
|
117
|
+
if (prop.value.type === 'ArrowFunctionExpression') {
|
|
118
|
+
if (prop.value.body.type === 'ObjectExpression') {
|
|
119
|
+
let example = '';
|
|
120
|
+
|
|
121
|
+
if (prop.value.params[0].type === 'Identifier') {
|
|
122
|
+
example = ' (e.g. `(props) => ({...})` instead of `({color}) => ({...})`)';
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
extraComment = ` Arrow function has parameter type of ${prop.value.params[0].type} instead of ObjectPattern${example}.`;
|
|
126
|
+
} else {
|
|
127
|
+
extraComment = ` Arrow function has body type of ${prop.value.body.type} instead of ObjectExpression.`;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
comments.push(j.commentLine(` TODO jss-to-tss-react codemod: Unable to handle style definition reliably. Unsupported arrow function syntax.`, true));
|
|
132
|
+
comments.push(j.commentLine(extraComment, true));
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
transformNestedKeys(j, comments, prop.value, ruleRegEx, nestedKeys);
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
if (paramNames.length > 0 || nestedKeys.length > 0) {
|
|
142
|
+
let arrowFunction;
|
|
143
|
+
|
|
144
|
+
if (stylesExpression.type === 'ArrowFunctionExpression') {
|
|
145
|
+
arrowFunction = stylesExpression;
|
|
146
|
+
} else {
|
|
147
|
+
arrowFunction = j.arrowFunctionExpression([], objectExpression);
|
|
148
|
+
setStylesExpression(arrowFunction);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (arrowFunction.params.length === 0) {
|
|
152
|
+
arrowFunction.params.push(j.identifier('_theme'));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
let paramsString = '_params';
|
|
156
|
+
|
|
157
|
+
if (paramNames.length > 0) {
|
|
158
|
+
paramsString = `{ ${paramNames.join(', ')} }`;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
arrowFunction.params.push(j.identifier(paramsString));
|
|
162
|
+
|
|
163
|
+
if (nestedKeys.length > 0) {
|
|
164
|
+
arrowFunction.params.push(j.identifier('classes'));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (arrowFunction.body.type === 'ObjectExpression') {
|
|
168
|
+
// In some cases, some needed parentheses were being lost without this.
|
|
169
|
+
arrowFunction.body = j.parenthesizedExpression(objectExpression);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function addCommentsToDeclaration(declaration, commentsToAdd) {
|
|
176
|
+
let commentsPath = declaration;
|
|
177
|
+
|
|
178
|
+
if (declaration.parentPath.node.type === 'ExportNamedDeclaration') {
|
|
179
|
+
commentsPath = declaration.parentPath;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (!commentsPath.node.comments) {
|
|
183
|
+
commentsPath.node.comments = [];
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
commentsPath.node.comments.push(...commentsToAdd);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function addComments(j, path, commentsToAdd) {
|
|
190
|
+
j(path).closest(j.VariableDeclaration).forEach(declaration => {
|
|
191
|
+
addCommentsToDeclaration(declaration, commentsToAdd);
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* @param {import('jscodeshift').FileInfo} file
|
|
196
|
+
* @param {import('jscodeshift').API} api
|
|
197
|
+
*/
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
function transformer(file, api, options) {
|
|
201
|
+
const j = api.jscodeshift;
|
|
202
|
+
const root = j(file.source);
|
|
203
|
+
const printOptions = options.printOptions || {
|
|
204
|
+
quote: 'single'
|
|
205
|
+
};
|
|
206
|
+
let importsChanged = false;
|
|
207
|
+
let foundCreateStyles = false;
|
|
208
|
+
let foundMakeStyles = false;
|
|
209
|
+
let foundWithStyles = false;
|
|
210
|
+
/**
|
|
211
|
+
* transform imports
|
|
212
|
+
*/
|
|
213
|
+
|
|
214
|
+
root.find(j.ImportDeclaration).forEach(path => {
|
|
215
|
+
const importSource = path.node.source.value;
|
|
216
|
+
|
|
217
|
+
if (importSource === '@material-ui/core/styles' || importSource === '@material-ui/core' || importSource === '@mui/styles') {
|
|
218
|
+
const specifiersToMove = [];
|
|
219
|
+
const specifiersToStay = [];
|
|
220
|
+
path.node.specifiers.forEach(specifier => {
|
|
221
|
+
if (specifier.type === 'ImportSpecifier') {
|
|
222
|
+
if (specifier.imported.name === 'makeStyles') {
|
|
223
|
+
foundMakeStyles = true;
|
|
224
|
+
specifiersToMove.push(specifier);
|
|
225
|
+
} else if (specifier.imported.name === 'withStyles') {
|
|
226
|
+
foundWithStyles = true;
|
|
227
|
+
specifiersToMove.push(specifier);
|
|
228
|
+
} else if (specifier.imported.name === 'createStyles') {
|
|
229
|
+
foundCreateStyles = true;
|
|
230
|
+
} else {
|
|
231
|
+
specifiersToStay.push(specifier);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
if (specifiersToMove.length > 0) {
|
|
237
|
+
path.replace(j.importDeclaration(specifiersToMove, j.stringLiteral('tss-react/mui')), specifiersToStay.length > 0 ? j.importDeclaration(specifiersToStay, j.stringLiteral(importSource)) : undefined);
|
|
238
|
+
importsChanged = true;
|
|
239
|
+
}
|
|
240
|
+
} else if (importSource === '@material-ui/styles/makeStyles') {
|
|
241
|
+
foundMakeStyles = true;
|
|
242
|
+
path.replace(j.importDeclaration([j.importSpecifier(j.identifier('makeStyles'))], j.stringLiteral('tss-react/mui')));
|
|
243
|
+
importsChanged = true;
|
|
244
|
+
} else if (importSource === '@material-ui/styles/withStyles') {
|
|
245
|
+
foundWithStyles = true;
|
|
246
|
+
path.replace(j.importDeclaration([j.importSpecifier(j.identifier('withStyles'))], j.stringLiteral('tss-react/mui')));
|
|
247
|
+
importsChanged = true;
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
if (!importsChanged) {
|
|
252
|
+
return file.source;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const isTypeScript = file.path.endsWith('.tsx') || file.path.endsWith('.ts');
|
|
256
|
+
|
|
257
|
+
if (foundMakeStyles) {
|
|
258
|
+
let clsxOrClassnamesName = null;
|
|
259
|
+
root.find(j.ImportDeclaration).forEach(path => {
|
|
260
|
+
const importSource = path.node.source.value;
|
|
261
|
+
|
|
262
|
+
if (importSource === 'clsx' || importSource === 'classnames') {
|
|
263
|
+
path.node.specifiers.forEach(specifier => {
|
|
264
|
+
if (specifier.type === 'ImportDefaultSpecifier') {
|
|
265
|
+
clsxOrClassnamesName = specifier.local.name;
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
j(path).remove();
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
/**
|
|
272
|
+
* Convert makeStyles syntax
|
|
273
|
+
*/
|
|
274
|
+
|
|
275
|
+
const styleHooks = [];
|
|
276
|
+
root.find(j.CallExpression, {
|
|
277
|
+
callee: {
|
|
278
|
+
name: 'makeStyles'
|
|
279
|
+
}
|
|
280
|
+
}).forEach(path => {
|
|
281
|
+
let paramsTypes = null;
|
|
282
|
+
|
|
283
|
+
if (foundCreateStyles) {
|
|
284
|
+
j(path).find(j.CallExpression, {
|
|
285
|
+
callee: {
|
|
286
|
+
name: 'createStyles'
|
|
287
|
+
}
|
|
288
|
+
}).replaceWith(createStylesPath => {
|
|
289
|
+
if (isTypeScript && createStylesPath.node.typeParameters && createStylesPath.node.typeParameters.params.length > 1) {
|
|
290
|
+
paramsTypes = createStylesPath.node.typeParameters.params[1];
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return createStylesPath.node.arguments[0];
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
const nestedKeys = [];
|
|
298
|
+
let makeStylesOptions = null;
|
|
299
|
+
|
|
300
|
+
if (path.node.arguments.length > 1) {
|
|
301
|
+
makeStylesOptions = path.node.arguments[1];
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
let stylesExpression = path.node.arguments[0];
|
|
305
|
+
const commentsToAdd = [];
|
|
306
|
+
transformStylesExpression(j, commentsToAdd, path.node.arguments[0], nestedKeys, newStylesExpression => {
|
|
307
|
+
stylesExpression = newStylesExpression;
|
|
308
|
+
});
|
|
309
|
+
addComments(j, path, commentsToAdd);
|
|
310
|
+
let makeStylesIdentifier = 'makeStyles';
|
|
311
|
+
|
|
312
|
+
if (isTypeScript && (nestedKeys.length > 0 || paramsTypes !== null)) {
|
|
313
|
+
let paramsTypeString = 'void';
|
|
314
|
+
|
|
315
|
+
if (paramsTypes !== null) {
|
|
316
|
+
paramsTypeString = j(paramsTypes).toSource(printOptions);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
let nestedKeysString = '';
|
|
320
|
+
|
|
321
|
+
if (nestedKeys.length > 0) {
|
|
322
|
+
const nestedKeysUnion = nestedKeys.join("' | '");
|
|
323
|
+
nestedKeysString = `, '${nestedKeysUnion}'`;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
makeStylesIdentifier += `<${paramsTypeString}${nestedKeysString}>`;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
j(path).replaceWith(j.callExpression(j.callExpression(j.identifier(makeStylesIdentifier), makeStylesOptions === null ? [] : [makeStylesOptions]), [stylesExpression]));
|
|
330
|
+
}).closest(j.VariableDeclarator).forEach(path => {
|
|
331
|
+
styleHooks.push(path.node.id.name);
|
|
332
|
+
j(path).closest(j.ExportNamedDeclaration).forEach(() => {
|
|
333
|
+
const comments = [j.commentLine(` TODO jss-to-tss-react codemod: usages of this hook outside of this file will not be converted.`, true)];
|
|
334
|
+
addComments(j, path, comments);
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
/**
|
|
338
|
+
* Convert classes assignment syntax in calls to the hook (e.g. useStyles) and
|
|
339
|
+
* convert usages of clsx or classnames to cx.
|
|
340
|
+
*/
|
|
341
|
+
|
|
342
|
+
styleHooks.forEach(hookName => {
|
|
343
|
+
root.find(j.CallExpression, {
|
|
344
|
+
callee: {
|
|
345
|
+
name: hookName
|
|
346
|
+
}
|
|
347
|
+
}).forEach(hookCall => {
|
|
348
|
+
if (hookCall.node.arguments.length === 1) {
|
|
349
|
+
const hookArg = hookCall.node.arguments[0];
|
|
350
|
+
|
|
351
|
+
if (hookArg.type === 'Identifier') {
|
|
352
|
+
const secondArg = j.objectExpression([]);
|
|
353
|
+
secondArg.properties.push(j.objectProperty(j.identifier('props'), j.identifier(hookArg.name)));
|
|
354
|
+
hookCall.node.arguments.push(secondArg);
|
|
355
|
+
} else if (hookArg.properties) {
|
|
356
|
+
const hookArgPropsMinusClasses = [];
|
|
357
|
+
let classesProp = null;
|
|
358
|
+
hookArg.properties.forEach(hookProp => {
|
|
359
|
+
if (hookProp.key.name === 'classes') {
|
|
360
|
+
classesProp = hookProp;
|
|
361
|
+
} else {
|
|
362
|
+
hookArgPropsMinusClasses.push(hookProp);
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
if (classesProp !== null) {
|
|
367
|
+
if (hookArgPropsMinusClasses.length === 0) {
|
|
368
|
+
hookCall.node.arguments[0] = j.identifier('undefined');
|
|
369
|
+
} else {
|
|
370
|
+
hookArg.properties = hookArgPropsMinusClasses;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
const secondArg = j.objectExpression([]);
|
|
374
|
+
secondArg.properties.push(j.objectProperty(j.identifier('props'), j.objectExpression([j.objectProperty(j.identifier('classes'), classesProp.value)])));
|
|
375
|
+
hookCall.node.arguments.push(secondArg);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}).closest(j.VariableDeclarator).forEach(path => {
|
|
380
|
+
let foundClsxOrClassnamesUsage = false;
|
|
381
|
+
const classesName = path.node.id.name;
|
|
382
|
+
const classesAssign = classesName === 'classes' ? 'classes' : `classes: ${classesName}`;
|
|
383
|
+
|
|
384
|
+
if (clsxOrClassnamesName !== null) {
|
|
385
|
+
j(path).closestScope().find(j.CallExpression, {
|
|
386
|
+
callee: {
|
|
387
|
+
name: clsxOrClassnamesName
|
|
388
|
+
}
|
|
389
|
+
}).forEach(callPath => {
|
|
390
|
+
callPath.node.callee.name = 'cx';
|
|
391
|
+
foundClsxOrClassnamesUsage = true;
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
if (foundClsxOrClassnamesUsage) {
|
|
396
|
+
path.node.id.name = `{ ${classesAssign}, cx }`;
|
|
397
|
+
} else {
|
|
398
|
+
path.node.id.name = `{ ${classesAssign} }`;
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
root.find(j.ExportDefaultDeclaration, {
|
|
402
|
+
declaration: {
|
|
403
|
+
name: hookName
|
|
404
|
+
}
|
|
405
|
+
}).forEach(path => {
|
|
406
|
+
const comments = [j.commentLine(` TODO jss-to-tss-react codemod: usages of this hook outside of this file will not be converted.`, true)];
|
|
407
|
+
addCommentsToDeclaration(path, comments);
|
|
408
|
+
});
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
if (foundWithStyles) {
|
|
413
|
+
/**
|
|
414
|
+
* Convert withStyles syntax
|
|
415
|
+
*/
|
|
416
|
+
const styleVariables = [];
|
|
417
|
+
root.find(j.CallExpression, {
|
|
418
|
+
callee: {
|
|
419
|
+
type: 'CallExpression',
|
|
420
|
+
callee: {
|
|
421
|
+
name: 'withStyles'
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}).replaceWith(path => {
|
|
425
|
+
const withStylesCall = path.node.callee;
|
|
426
|
+
const styles = path.node.callee.arguments[0];
|
|
427
|
+
|
|
428
|
+
if (styles.type === 'Identifier') {
|
|
429
|
+
styleVariables.push(styles.name);
|
|
430
|
+
} else {
|
|
431
|
+
const nestedKeys = [];
|
|
432
|
+
const commentsToAdd = [];
|
|
433
|
+
transformStylesExpression(j, commentsToAdd, styles, nestedKeys, newStylesExpression => {
|
|
434
|
+
path.node.callee.arguments[0] = newStylesExpression;
|
|
435
|
+
});
|
|
436
|
+
addComments(j, path, commentsToAdd);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
const component = path.node.arguments[0];
|
|
440
|
+
withStylesCall.arguments.unshift(component);
|
|
441
|
+
return withStylesCall;
|
|
442
|
+
});
|
|
443
|
+
styleVariables.forEach(styleVar => {
|
|
444
|
+
root.find(j.VariableDeclarator, {
|
|
445
|
+
id: {
|
|
446
|
+
name: styleVar
|
|
447
|
+
}
|
|
448
|
+
}).forEach(path => {
|
|
449
|
+
const nestedKeys = [];
|
|
450
|
+
const commentsToAdd = [];
|
|
451
|
+
transformStylesExpression(j, commentsToAdd, path.node.init, nestedKeys, newStylesExpression => {
|
|
452
|
+
path.node.init = newStylesExpression;
|
|
453
|
+
});
|
|
454
|
+
addComments(j, path, commentsToAdd);
|
|
455
|
+
});
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
return root.toSource(printOptions);
|
|
460
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.default = ComponentUsingStyles;
|
|
9
|
+
|
|
10
|
+
var _react = _interopRequireDefault(require("react"));
|
|
11
|
+
|
|
12
|
+
var _styles = require("@material-ui/core/styles");
|
|
13
|
+
|
|
14
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
15
|
+
|
|
16
|
+
var _InnerComponent;
|
|
17
|
+
|
|
18
|
+
/*
|
|
19
|
+
Sandboxes for verifying correct behavior:
|
|
20
|
+
JSS - https://codesandbox.io/s/case1-jss-dedp2f?file=/src/App.js
|
|
21
|
+
TSS - https://codesandbox.io/s/case1-tss-s0z7tx?file=/src/App.js
|
|
22
|
+
*/
|
|
23
|
+
const useStyles = (0, _styles.makeStyles)({
|
|
24
|
+
test: {
|
|
25
|
+
backgroundColor: "purple",
|
|
26
|
+
color: "white"
|
|
27
|
+
}
|
|
28
|
+
}, {
|
|
29
|
+
name: "TestName"
|
|
30
|
+
});
|
|
31
|
+
const useStyles2 = (0, _styles.makeStyles)(() => ({
|
|
32
|
+
test2: {
|
|
33
|
+
backgroundColor: "blue",
|
|
34
|
+
color: "lime"
|
|
35
|
+
}
|
|
36
|
+
}));
|
|
37
|
+
|
|
38
|
+
function InnerComponent() {
|
|
39
|
+
const classes = useStyles2();
|
|
40
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
41
|
+
className: classes.test2,
|
|
42
|
+
children: "Inner Test"
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function ComponentUsingStyles(props) {
|
|
47
|
+
const classes = useStyles();
|
|
48
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
49
|
+
className: classes.test,
|
|
50
|
+
children: ["Test", _InnerComponent || (_InnerComponent = /*#__PURE__*/(0, _jsxRuntime.jsx)(InnerComponent, {}))]
|
|
51
|
+
});
|
|
52
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.default = ComponentUsingStyles;
|
|
9
|
+
|
|
10
|
+
var _react = _interopRequireDefault(require("react"));
|
|
11
|
+
|
|
12
|
+
var _core = require("@material-ui/core");
|
|
13
|
+
|
|
14
|
+
var _clsx = _interopRequireDefault(require("clsx"));
|
|
15
|
+
|
|
16
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
17
|
+
|
|
18
|
+
var _InnerComponent;
|
|
19
|
+
|
|
20
|
+
const useStyles = (0, _core.makeStyles)(() => ({
|
|
21
|
+
test: {
|
|
22
|
+
backgroundColor: "purple",
|
|
23
|
+
color: "white",
|
|
24
|
+
"&$qualifier": {
|
|
25
|
+
textDecoration: "underline"
|
|
26
|
+
},
|
|
27
|
+
"&$qualifier$qualifier2": {
|
|
28
|
+
fontStyle: "italic"
|
|
29
|
+
},
|
|
30
|
+
"&$qualifier2 .testStuffInBetween $qualifier": {
|
|
31
|
+
color: "brown"
|
|
32
|
+
},
|
|
33
|
+
"&$qualifier:hover": {
|
|
34
|
+
backgroundColor: "red"
|
|
35
|
+
},
|
|
36
|
+
"&$qualifier2:not(:hover)": {
|
|
37
|
+
fontWeight: 700
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
qualifier: {},
|
|
41
|
+
qualifier2: {}
|
|
42
|
+
}));
|
|
43
|
+
const useStyles2 = (0, _core.makeStyles)({
|
|
44
|
+
test2: {
|
|
45
|
+
backgroundColor: "blue",
|
|
46
|
+
color: "lime"
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
function InnerComponent() {
|
|
51
|
+
const classes = useStyles2();
|
|
52
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
53
|
+
className: classes.test2,
|
|
54
|
+
children: "Inner Test"
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function ComponentUsingStyles(props) {
|
|
59
|
+
const classes = useStyles(props);
|
|
60
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
61
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
62
|
+
className: classes.test,
|
|
63
|
+
children: ["Test", _InnerComponent || (_InnerComponent = /*#__PURE__*/(0, _jsxRuntime.jsx)(InnerComponent, {}))]
|
|
64
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
65
|
+
className: (0, _clsx.default)(classes.test, classes.qualifier),
|
|
66
|
+
children: "Qualifier Test"
|
|
67
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
68
|
+
className: (0, _clsx.default)(classes.test, classes.qualifier2),
|
|
69
|
+
children: "Qualifier 2 Test"
|
|
70
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
71
|
+
className: (0, _clsx.default)(classes.test, classes.qualifier, classes.qualifier2),
|
|
72
|
+
children: "Qualifier & Qualifier 2 Test"
|
|
73
|
+
})]
|
|
74
|
+
});
|
|
75
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.default = ComponentUsingStyles;
|
|
9
|
+
|
|
10
|
+
var _react = _interopRequireDefault(require("react"));
|
|
11
|
+
|
|
12
|
+
var _styles = require("@mui/styles");
|
|
13
|
+
|
|
14
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
15
|
+
|
|
16
|
+
var _InnerComponent;
|
|
17
|
+
|
|
18
|
+
const useStyles = (0, _styles.makeStyles)({
|
|
19
|
+
test: {
|
|
20
|
+
backgroundColor: "purple",
|
|
21
|
+
color: "white"
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
const useStyles2 = (0, _styles.makeStyles)({
|
|
25
|
+
test: {
|
|
26
|
+
backgroundColor: "purple",
|
|
27
|
+
color: "white",
|
|
28
|
+
"& $test2": {
|
|
29
|
+
backgroundColor: "lime",
|
|
30
|
+
color: "blue"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
test2: {
|
|
34
|
+
backgroundColor: "blue",
|
|
35
|
+
color: "lime"
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
function InnerComponent() {
|
|
40
|
+
const classes = useStyles2();
|
|
41
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
42
|
+
className: classes.test2,
|
|
43
|
+
children: "Inner Test"
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function ComponentUsingStyles(props) {
|
|
48
|
+
const classes = useStyles();
|
|
49
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
50
|
+
className: classes.test,
|
|
51
|
+
children: ["Test", _InnerComponent || (_InnerComponent = /*#__PURE__*/(0, _jsxRuntime.jsx)(InnerComponent, {}))]
|
|
52
|
+
});
|
|
53
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.default = ComponentUsingStyles;
|
|
9
|
+
|
|
10
|
+
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
11
|
+
|
|
12
|
+
var _react = _interopRequireDefault(require("react"));
|
|
13
|
+
|
|
14
|
+
var _styles = require("@material-ui/core/styles");
|
|
15
|
+
|
|
16
|
+
var _clsx = _interopRequireDefault(require("clsx"));
|
|
17
|
+
|
|
18
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
19
|
+
|
|
20
|
+
function mixins() {
|
|
21
|
+
return {
|
|
22
|
+
test: {
|
|
23
|
+
backgroundColor: "purple",
|
|
24
|
+
color: "white"
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function cssProps() {
|
|
30
|
+
return {
|
|
31
|
+
paddingLeft: "8px"
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const useStyles = (0, _styles.makeStyles)(theme => {
|
|
36
|
+
return mixins();
|
|
37
|
+
});
|
|
38
|
+
const useStyles2 = (0, _styles.makeStyles)(theme => (0, _extends2.default)({}, mixins(), {
|
|
39
|
+
test2: (0, _extends2.default)({
|
|
40
|
+
color: "red"
|
|
41
|
+
}, cssProps())
|
|
42
|
+
}));
|
|
43
|
+
|
|
44
|
+
function ComponentUsingStyles(props) {
|
|
45
|
+
const classes = useStyles();
|
|
46
|
+
const classes2 = useStyles2();
|
|
47
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
48
|
+
className: (0, _clsx.default)(classes.test, classes2.test2),
|
|
49
|
+
children: "Test"
|
|
50
|
+
});
|
|
51
|
+
}
|