@mui/codemod 5.7.0 → 5.8.0

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 (22) hide show
  1. package/README.md +82 -0
  2. package/codemod.js +0 -0
  3. package/node/v5.0.0/jss-to-tss-react.js +457 -0
  4. package/node/v5.0.0/jss-to-tss-react.test/actual-from-material-ui-core-styles.js +52 -0
  5. package/node/v5.0.0/jss-to-tss-react.test/actual-from-material-ui-core.js +75 -0
  6. package/node/v5.0.0/jss-to-tss-react.test/actual-from-mui-styles.js +53 -0
  7. package/node/v5.0.0/jss-to-tss-react.test/actual-mixins-pattern.js +51 -0
  8. package/node/v5.0.0/jss-to-tss-react.test/actual-todo-comments.js +74 -0
  9. package/node/v5.0.0/jss-to-tss-react.test/actual-typescript-docs-example-params.js +59 -0
  10. package/node/v5.0.0/jss-to-tss-react.test/actual-typescript-docs-example.js +55 -0
  11. package/node/v5.0.0/jss-to-tss-react.test/actual-typescript.js +73 -0
  12. package/node/v5.0.0/jss-to-tss-react.test/actual-withStyles.js +123 -0
  13. package/node/v5.0.0/jss-to-tss-react.test/expected-from-material-ui-core-styles.js +56 -0
  14. package/node/v5.0.0/jss-to-tss-react.test/expected-from-material-ui-core.js +80 -0
  15. package/node/v5.0.0/jss-to-tss-react.test/expected-from-mui-styles.js +57 -0
  16. package/node/v5.0.0/jss-to-tss-react.test/expected-mixins-pattern.js +54 -0
  17. package/node/v5.0.0/jss-to-tss-react.test/expected-todo-comments.js +86 -0
  18. package/node/v5.0.0/jss-to-tss-react.test/expected-typescript-docs-example-params.js +61 -0
  19. package/node/v5.0.0/jss-to-tss-react.test/expected-typescript-docs-example.js +54 -0
  20. package/node/v5.0.0/jss-to-tss-react.test/expected-typescript.js +79 -0
  21. package/node/v5.0.0/jss-to-tss-react.test/expected-withStyles.js +124 -0
  22. package/package.json +1 -1
package/README.md CHANGED
@@ -605,6 +605,88 @@ You can find more details about this breaking change in [the migration guide](ht
605
605
  > **Note:** This approach converts the first element in the return statement into styled component but also increases CSS specificity to override nested children.
606
606
  > This codemod should be adopted after handling all breaking changes, [check out the migration documentation](https://mui.com/material-ui/guides/migration-v4/)
607
607
 
608
+ #### `jss-to-tss-react`
609
+
610
+ Migrate JSS styling with `makeStyles` or `withStyles` to the corresponding `tss-react` API.
611
+
612
+ ```diff
613
+ -import clsx from 'clsx';
614
+ -import {makeStyles, createStyles} from '@material-ui/core/styles';
615
+ +import { makeStyles } from 'tss-react/mui';
616
+
617
+ -const useStyles = makeStyles((theme) => createStyles<
618
+ - 'root' | 'small' | 'child', {color: 'primary' | 'secondary', padding: number}
619
+ ->
620
+ -({
621
+ - root: ({color, padding}) => ({
622
+ +const useStyles = makeStyles<{color: 'primary' | 'secondary', padding: number}, 'child' | 'small'>({name: 'App'})((theme, { color, padding }, classes) => ({
623
+ + root: {
624
+ padding: padding,
625
+ - '&:hover $child': {
626
+ + [`&:hover .${classes.child}`]: {
627
+ backgroundColor: theme.palette[color].main,
628
+ }
629
+ - }),
630
+ + },
631
+ small: {},
632
+ child: {
633
+ border: '1px solid black',
634
+ height: 50,
635
+ - '&$small': {
636
+ + [`&.${classes.small}`]: {
637
+ height: 30
638
+ }
639
+ }
640
+ -}), {name: 'App'});
641
+ +}));
642
+
643
+ function App({classes: classesProp}: {classes?: any}) {
644
+ - const classes = useStyles({color: 'primary', padding: 30, classes: classesProp});
645
+ + const { classes, cx } = useStyles({
646
+ + color: 'primary',
647
+ + padding: 30
648
+ + }, {
649
+ + props: {
650
+ + classes: classesProp
651
+ + }
652
+ + });
653
+
654
+ return (
655
+ <div className={classes.root}>
656
+ <div className={classes.child}>
657
+ The Background take the primary theme color when the mouse hovers the parent.
658
+ </div>
659
+ - <div className={clsx(classes.child, classes.small)}>
660
+ + <div className={cx(classes.child, classes.small)}>
661
+ The Background take the primary theme color when the mouse hovers the parent.
662
+ I am smaller than the other child.
663
+ </div>
664
+ </div>
665
+ );
666
+ }
667
+
668
+ export default App;
669
+ ```
670
+
671
+ ```sh
672
+ npx @mui/codemod v5.0.0/jss-to-tss-react <path>
673
+ ```
674
+
675
+ The following scenarios are not currently handled by this codemod and will be marked with a
676
+ "TODO jss-to-tss-react codemod" comment:
677
+
678
+ - If the hook returned by `makeStyles` (e.g. `useStyles`) is exported and used in another file,
679
+ the usages in other files will not be converted.
680
+ - Arrow functions as the value for a CSS prop will not be converted. Arrow functions **are**
681
+ supported at the rule level, though with some caveats listed below.
682
+ - In order for arrow functions at the rule level to be converted, the parameter must use object
683
+ destructuring (e.g. `root: ({color, padding}) => (...)`). If the parameter is not destructured
684
+ (e.g. `root: (props) => (...)`), it will not be converted.
685
+ - If an arrow function at the rule level contains a code block (i.e. contains an explicit `return`
686
+ statement) rather than just an object expression, it will not be converted.
687
+
688
+ You can find more details about migrating from JSS to tss-react in [the migration guide](https://mui.com/guides/migration-v4/#2-use-tss-react).
689
+
608
690
  #### `link-underline-hover`
609
691
 
610
692
  Apply `underline="hover"` to `<Link />` that does not define `underline` prop (to get the same behavior as in v4).
package/codemod.js CHANGED
File without changes
@@ -0,0 +1,457 @@
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') {
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;
84
+
85
+ if ((_prop$key = prop.key) != null && _prop$key.name) {
86
+ ruleNames.push(prop.key.name);
87
+ }
88
+ });
89
+ let ruleRegExString = '(';
90
+ ruleNames.forEach((ruleName, index) => {
91
+ if (index > 0) {
92
+ ruleRegExString += '|';
93
+ }
94
+
95
+ ruleRegExString += `\\$${ruleName}`;
96
+ });
97
+ ruleRegExString += ')';
98
+ const ruleRegEx = new RegExp(ruleRegExString, 'g');
99
+ objectExpression.properties.forEach(prop => {
100
+ if (prop.value) {
101
+ if (prop.value.type !== 'ObjectExpression') {
102
+ if (prop.value.type === 'ArrowFunctionExpression' && prop.value.body.type === 'ObjectExpression' && prop.value.params[0].type === 'ObjectPattern') {
103
+ prop.value.params[0].properties.forEach(property => {
104
+ const name = property.key.name;
105
+
106
+ if (!paramNames.includes(name)) {
107
+ paramNames.push(name);
108
+ }
109
+ });
110
+ prop.value = prop.value.body;
111
+ } else {
112
+ let extraComment = `Unexpected value type of ${prop.value.type}.`;
113
+
114
+ if (prop.value.type === 'ArrowFunctionExpression') {
115
+ if (prop.value.body.type === 'ObjectExpression') {
116
+ let example = '';
117
+
118
+ if (prop.value.params[0].type === 'Identifier') {
119
+ example = ' (e.g. `(props) => ({...})` instead of `({color}) => ({...})`)';
120
+ }
121
+
122
+ extraComment = ` Arrow function has parameter type of ${prop.value.params[0].type} instead of ObjectPattern${example}.`;
123
+ } else {
124
+ extraComment = ` Arrow function has body type of ${prop.value.body.type} instead of ObjectExpression.`;
125
+ }
126
+ }
127
+
128
+ comments.push(j.commentLine(` TODO jss-to-tss-react codemod: Unable to handle style definition reliably. Unsupported arrow function syntax.`, true));
129
+ comments.push(j.commentLine(extraComment, true));
130
+ return;
131
+ }
132
+ }
133
+
134
+ transformNestedKeys(j, comments, prop.value, ruleRegEx, nestedKeys);
135
+ }
136
+ });
137
+
138
+ if (paramNames.length > 0 || nestedKeys.length > 0) {
139
+ let arrowFunction;
140
+
141
+ if (stylesExpression.type === 'ArrowFunctionExpression') {
142
+ arrowFunction = stylesExpression;
143
+ } else {
144
+ arrowFunction = j.arrowFunctionExpression([], objectExpression);
145
+ setStylesExpression(arrowFunction);
146
+ }
147
+
148
+ if (arrowFunction.params.length === 0) {
149
+ arrowFunction.params.push(j.identifier('_theme'));
150
+ }
151
+
152
+ let paramsString = '_params';
153
+
154
+ if (paramNames.length > 0) {
155
+ paramsString = `{ ${paramNames.join(', ')} }`;
156
+ }
157
+
158
+ arrowFunction.params.push(j.identifier(paramsString));
159
+
160
+ if (nestedKeys.length > 0) {
161
+ arrowFunction.params.push(j.identifier('classes'));
162
+ }
163
+
164
+ if (arrowFunction.body.type === 'ObjectExpression') {
165
+ // In some cases, some needed parentheses were being lost without this.
166
+ arrowFunction.body = j.parenthesizedExpression(objectExpression);
167
+ }
168
+ }
169
+ }
170
+ }
171
+
172
+ function addCommentsToDeclaration(declaration, commentsToAdd) {
173
+ let commentsPath = declaration;
174
+
175
+ if (declaration.parentPath.node.type === 'ExportNamedDeclaration') {
176
+ commentsPath = declaration.parentPath;
177
+ }
178
+
179
+ if (!commentsPath.node.comments) {
180
+ commentsPath.node.comments = [];
181
+ }
182
+
183
+ commentsPath.node.comments.push(...commentsToAdd);
184
+ }
185
+
186
+ function addComments(j, path, commentsToAdd) {
187
+ j(path).closest(j.VariableDeclaration).forEach(declaration => {
188
+ addCommentsToDeclaration(declaration, commentsToAdd);
189
+ });
190
+ }
191
+ /**
192
+ * @param {import('jscodeshift').FileInfo} file
193
+ * @param {import('jscodeshift').API} api
194
+ */
195
+
196
+
197
+ function transformer(file, api, options) {
198
+ const j = api.jscodeshift;
199
+ const root = j(file.source);
200
+ const printOptions = options.printOptions || {
201
+ quote: 'single'
202
+ };
203
+ let importsChanged = false;
204
+ let foundCreateStyles = false;
205
+ let foundMakeStyles = false;
206
+ let foundWithStyles = false;
207
+ /**
208
+ * transform imports
209
+ */
210
+
211
+ root.find(j.ImportDeclaration).forEach(path => {
212
+ const importSource = path.node.source.value;
213
+
214
+ if (importSource === '@material-ui/core/styles' || importSource === '@material-ui/core' || importSource === '@mui/styles') {
215
+ const specifiersToMove = [];
216
+ const specifiersToStay = [];
217
+ path.node.specifiers.forEach(specifier => {
218
+ if (specifier.type === 'ImportSpecifier') {
219
+ if (specifier.imported.name === 'makeStyles') {
220
+ foundMakeStyles = true;
221
+ specifiersToMove.push(specifier);
222
+ } else if (specifier.imported.name === 'withStyles') {
223
+ foundWithStyles = true;
224
+ specifiersToMove.push(specifier);
225
+ } else if (specifier.imported.name === 'createStyles') {
226
+ foundCreateStyles = true;
227
+ } else {
228
+ specifiersToStay.push(specifier);
229
+ }
230
+ }
231
+ });
232
+
233
+ if (specifiersToMove.length > 0) {
234
+ path.replace(j.importDeclaration(specifiersToMove, j.stringLiteral('tss-react/mui')), specifiersToStay.length > 0 ? j.importDeclaration(specifiersToStay, j.stringLiteral(importSource)) : undefined);
235
+ importsChanged = true;
236
+ }
237
+ } else if (importSource === '@material-ui/styles/makeStyles') {
238
+ foundMakeStyles = true;
239
+ path.replace(j.importDeclaration([j.importSpecifier(j.identifier('makeStyles'))], j.stringLiteral('tss-react/mui')));
240
+ importsChanged = true;
241
+ } else if (importSource === '@material-ui/styles/withStyles') {
242
+ foundWithStyles = true;
243
+ path.replace(j.importDeclaration([j.importSpecifier(j.identifier('withStyles'))], j.stringLiteral('tss-react/mui')));
244
+ importsChanged = true;
245
+ }
246
+ });
247
+
248
+ if (!importsChanged) {
249
+ return file.source;
250
+ }
251
+
252
+ const isTypeScript = file.path.endsWith('.tsx') || file.path.endsWith('.ts');
253
+
254
+ if (foundMakeStyles) {
255
+ let clsxOrClassnamesName = null;
256
+ root.find(j.ImportDeclaration).forEach(path => {
257
+ const importSource = path.node.source.value;
258
+
259
+ if (importSource === 'clsx' || importSource === 'classnames') {
260
+ path.node.specifiers.forEach(specifier => {
261
+ if (specifier.type === 'ImportDefaultSpecifier') {
262
+ clsxOrClassnamesName = specifier.local.name;
263
+ }
264
+ });
265
+ j(path).remove();
266
+ }
267
+ });
268
+ /**
269
+ * Convert makeStyles syntax
270
+ */
271
+
272
+ const styleHooks = [];
273
+ root.find(j.CallExpression, {
274
+ callee: {
275
+ name: 'makeStyles'
276
+ }
277
+ }).forEach(path => {
278
+ let paramsTypes = null;
279
+
280
+ if (foundCreateStyles) {
281
+ j(path).find(j.CallExpression, {
282
+ callee: {
283
+ name: 'createStyles'
284
+ }
285
+ }).replaceWith(createStylesPath => {
286
+ if (isTypeScript && createStylesPath.node.typeParameters && createStylesPath.node.typeParameters.params.length > 1) {
287
+ paramsTypes = createStylesPath.node.typeParameters.params[1];
288
+ }
289
+
290
+ return createStylesPath.node.arguments[0];
291
+ });
292
+ }
293
+
294
+ const nestedKeys = [];
295
+ let makeStylesOptions = null;
296
+
297
+ if (path.node.arguments.length > 1) {
298
+ makeStylesOptions = path.node.arguments[1];
299
+ }
300
+
301
+ let stylesExpression = path.node.arguments[0];
302
+ const commentsToAdd = [];
303
+ transformStylesExpression(j, commentsToAdd, path.node.arguments[0], nestedKeys, newStylesExpression => {
304
+ stylesExpression = newStylesExpression;
305
+ });
306
+ addComments(j, path, commentsToAdd);
307
+ let makeStylesIdentifier = 'makeStyles';
308
+
309
+ if (isTypeScript && (nestedKeys.length > 0 || paramsTypes !== null)) {
310
+ let paramsTypeString = 'void';
311
+
312
+ if (paramsTypes !== null) {
313
+ paramsTypeString = j(paramsTypes).toSource(printOptions);
314
+ }
315
+
316
+ let nestedKeysString = '';
317
+
318
+ if (nestedKeys.length > 0) {
319
+ const nestedKeysUnion = nestedKeys.join("' | '");
320
+ nestedKeysString = `, '${nestedKeysUnion}'`;
321
+ }
322
+
323
+ makeStylesIdentifier += `<${paramsTypeString}${nestedKeysString}>`;
324
+ }
325
+
326
+ j(path).replaceWith(j.callExpression(j.callExpression(j.identifier(makeStylesIdentifier), makeStylesOptions === null ? [] : [makeStylesOptions]), [stylesExpression]));
327
+ }).closest(j.VariableDeclarator).forEach(path => {
328
+ styleHooks.push(path.node.id.name);
329
+ j(path).closest(j.ExportNamedDeclaration).forEach(() => {
330
+ const comments = [j.commentLine(` TODO jss-to-tss-react codemod: usages of this hook outside of this file will not be converted.`, true)];
331
+ addComments(j, path, comments);
332
+ });
333
+ });
334
+ /**
335
+ * Convert classes assignment syntax in calls to the hook (e.g. useStyles) and
336
+ * convert usages of clsx or classnames to cx.
337
+ */
338
+
339
+ styleHooks.forEach(hookName => {
340
+ root.find(j.CallExpression, {
341
+ callee: {
342
+ name: hookName
343
+ }
344
+ }).forEach(hookCall => {
345
+ if (hookCall.node.arguments.length === 1) {
346
+ const hookArg = hookCall.node.arguments[0];
347
+
348
+ if (hookArg.type === 'Identifier') {
349
+ const secondArg = j.objectExpression([]);
350
+ secondArg.properties.push(j.objectProperty(j.identifier('props'), j.identifier(hookArg.name)));
351
+ hookCall.node.arguments.push(secondArg);
352
+ } else if (hookArg.properties) {
353
+ const hookArgPropsMinusClasses = [];
354
+ let classesProp = null;
355
+ hookArg.properties.forEach(hookProp => {
356
+ if (hookProp.key.name === 'classes') {
357
+ classesProp = hookProp;
358
+ } else {
359
+ hookArgPropsMinusClasses.push(hookProp);
360
+ }
361
+ });
362
+
363
+ if (classesProp !== null) {
364
+ if (hookArgPropsMinusClasses.length === 0) {
365
+ hookCall.node.arguments[0] = j.identifier('undefined');
366
+ } else {
367
+ hookArg.properties = hookArgPropsMinusClasses;
368
+ }
369
+
370
+ const secondArg = j.objectExpression([]);
371
+ secondArg.properties.push(j.objectProperty(j.identifier('props'), j.objectExpression([j.objectProperty(j.identifier('classes'), classesProp.value)])));
372
+ hookCall.node.arguments.push(secondArg);
373
+ }
374
+ }
375
+ }
376
+ }).closest(j.VariableDeclarator).forEach(path => {
377
+ let foundClsxOrClassnamesUsage = false;
378
+ const classesName = path.node.id.name;
379
+ const classesAssign = classesName === 'classes' ? 'classes' : `classes: ${classesName}`;
380
+
381
+ if (clsxOrClassnamesName !== null) {
382
+ j(path).closestScope().find(j.CallExpression, {
383
+ callee: {
384
+ name: clsxOrClassnamesName
385
+ }
386
+ }).forEach(callPath => {
387
+ callPath.node.callee.name = 'cx';
388
+ foundClsxOrClassnamesUsage = true;
389
+ });
390
+ }
391
+
392
+ if (foundClsxOrClassnamesUsage) {
393
+ path.node.id.name = `{ ${classesAssign}, cx }`;
394
+ } else {
395
+ path.node.id.name = `{ ${classesAssign} }`;
396
+ }
397
+ });
398
+ root.find(j.ExportDefaultDeclaration, {
399
+ declaration: {
400
+ name: hookName
401
+ }
402
+ }).forEach(path => {
403
+ const comments = [j.commentLine(` TODO jss-to-tss-react codemod: usages of this hook outside of this file will not be converted.`, true)];
404
+ addCommentsToDeclaration(path, comments);
405
+ });
406
+ });
407
+ }
408
+
409
+ if (foundWithStyles) {
410
+ /**
411
+ * Convert withStyles syntax
412
+ */
413
+ const styleVariables = [];
414
+ root.find(j.CallExpression, {
415
+ callee: {
416
+ type: 'CallExpression',
417
+ callee: {
418
+ name: 'withStyles'
419
+ }
420
+ }
421
+ }).replaceWith(path => {
422
+ const withStylesCall = path.node.callee;
423
+ const styles = path.node.callee.arguments[0];
424
+
425
+ if (styles.type === 'Identifier') {
426
+ styleVariables.push(styles.name);
427
+ } else {
428
+ const nestedKeys = [];
429
+ const commentsToAdd = [];
430
+ transformStylesExpression(j, commentsToAdd, styles, nestedKeys, newStylesExpression => {
431
+ path.node.callee.arguments[0] = newStylesExpression;
432
+ });
433
+ addComments(j, path, commentsToAdd);
434
+ }
435
+
436
+ const component = path.node.arguments[0];
437
+ withStylesCall.arguments.unshift(component);
438
+ return withStylesCall;
439
+ });
440
+ styleVariables.forEach(styleVar => {
441
+ root.find(j.VariableDeclarator, {
442
+ id: {
443
+ name: styleVar
444
+ }
445
+ }).forEach(path => {
446
+ const nestedKeys = [];
447
+ const commentsToAdd = [];
448
+ transformStylesExpression(j, commentsToAdd, path.node.init, nestedKeys, newStylesExpression => {
449
+ path.node.init = newStylesExpression;
450
+ });
451
+ addComments(j, path, commentsToAdd);
452
+ });
453
+ });
454
+ }
455
+
456
+ return root.toSource(printOptions);
457
+ }
@@ -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
+ }