@mui/codemod 6.0.0-alpha.1 → 6.0.0-alpha.4

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 (56) hide show
  1. package/README.md +153 -2
  2. package/node/deprecations/accordion-props/accordion-props.js +11 -71
  3. package/node/deprecations/accordion-props/test-cases/actual.js +16 -0
  4. package/node/deprecations/accordion-props/test-cases/expected.js +14 -0
  5. package/node/deprecations/accordion-props/test-cases/theme.actual.js +24 -0
  6. package/node/deprecations/accordion-props/test-cases/theme.expected.js +24 -0
  7. package/node/deprecations/all/deprecations-all.js +4 -0
  8. package/node/deprecations/all/postcss.config.js +7 -1
  9. package/node/deprecations/avatar-props/avatar-props.js +5 -39
  10. package/node/deprecations/avatar-props/test-cases/actual.js +10 -0
  11. package/node/deprecations/avatar-props/test-cases/expected.js +10 -0
  12. package/node/deprecations/avatar-props/test-cases/theme.actual.js +14 -0
  13. package/node/deprecations/avatar-props/test-cases/theme.expected.js +15 -0
  14. package/node/deprecations/backdrop-props/backdrop-props.js +5 -61
  15. package/node/deprecations/backdrop-props/test-cases/actual.js +8 -7
  16. package/node/deprecations/backdrop-props/test-cases/expected.js +7 -7
  17. package/node/deprecations/backdrop-props/test-cases/theme.actual.js +11 -0
  18. package/node/deprecations/backdrop-props/test-cases/theme.expected.js +12 -2
  19. package/node/deprecations/step-connector-classes/index.js +13 -0
  20. package/node/deprecations/step-connector-classes/postcss-plugin.js +33 -0
  21. package/node/deprecations/step-connector-classes/postcss.config.js +8 -0
  22. package/node/deprecations/step-connector-classes/step-connector-classes.js +77 -0
  23. package/node/deprecations/step-connector-classes/test-cases/actual.js +7 -0
  24. package/node/deprecations/step-connector-classes/test-cases/expected.js +7 -0
  25. package/node/deprecations/step-label-props/step-label-props.js +14 -0
  26. package/node/deprecations/step-label-props/test-cases/actual.js +23 -0
  27. package/node/deprecations/step-label-props/test-cases/expected.js +24 -0
  28. package/node/deprecations/step-label-props/test-cases/theme.actual.js +22 -0
  29. package/node/deprecations/step-label-props/test-cases/theme.expected.js +25 -0
  30. package/node/deprecations/toggle-button-group-classes/index.js +13 -0
  31. package/node/deprecations/toggle-button-group-classes/postcss-plugin.js +33 -0
  32. package/node/deprecations/toggle-button-group-classes/postcss.config.js +8 -0
  33. package/node/deprecations/toggle-button-group-classes/test-cases/actual.js +7 -0
  34. package/node/deprecations/toggle-button-group-classes/test-cases/expected.js +7 -0
  35. package/node/deprecations/toggle-button-group-classes/toggle-button-group-classes.js +77 -0
  36. package/node/deprecations/utils/movePropIntoSlotProps.js +111 -0
  37. package/node/deprecations/utils/movePropIntoSlots.js +101 -0
  38. package/node/v5.0.0/base-remove-unstyled-suffix.js +4 -4
  39. package/node/v5.0.0/styled-engine-provider.test/theme-provider.expected.js +3 -3
  40. package/node/v6.0.0/styled/index.js +13 -0
  41. package/node/v6.0.0/styled/styled-v6.js +493 -0
  42. package/node/v6.0.0/styled/test-cases/BasicStyled.actual.js +78 -0
  43. package/node/v6.0.0/styled/test-cases/BasicStyled.expected.js +144 -0
  44. package/node/v6.0.0/styled/test-cases/ConditionalStyled.actual.js +115 -0
  45. package/node/v6.0.0/styled/test-cases/ConditionalStyled.expected.js +206 -0
  46. package/node/v6.0.0/styled/test-cases/LogicalStyled.actual.js +28 -0
  47. package/node/v6.0.0/styled/test-cases/LogicalStyled.expected.js +52 -0
  48. package/node/v6.0.0/styled/test-cases/NestedSpread.actual.js +42 -0
  49. package/node/v6.0.0/styled/test-cases/NestedSpread.expected.js +85 -0
  50. package/node/v6.0.0/styled/test-cases/ObjectMap.actual.js +36 -0
  51. package/node/v6.0.0/styled/test-cases/ObjectMap.expected.js +109 -0
  52. package/node/v6.0.0/styled/test-cases/ThemePaletteMode.actual.js +62 -0
  53. package/node/v6.0.0/styled/test-cases/ThemePaletteMode.expected.js +76 -0
  54. package/node/v6.0.0/styled/test-cases/VariantAndModeStyled.actual.js +11 -0
  55. package/node/v6.0.0/styled/test-cases/VariantAndModeStyled.expected.js +19 -0
  56. package/package.json +3 -3
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = movePropIntoSlots;
8
+ var _findComponentJSX = _interopRequireDefault(require("../../util/findComponentJSX"));
9
+ var _findComponentDefaultProps = _interopRequireDefault(require("../../util/findComponentDefaultProps"));
10
+ var _assignObject = _interopRequireDefault(require("../../util/assignObject"));
11
+ var _appendAttribute = _interopRequireDefault(require("../../util/appendAttribute"));
12
+ function moveJsxPropIntoSlots(j, element, propName, slotName) {
13
+ const index = element.openingElement.attributes.findIndex(attr => attr.type === 'JSXAttribute' && attr.name.name === propName);
14
+ if (index !== -1) {
15
+ const removedValue = element.openingElement.attributes.splice(index, 1)[0].value.expression;
16
+ let hasSlots = false;
17
+ element.openingElement.attributes.forEach(attr => {
18
+ var _attr$name;
19
+ if (((_attr$name = attr.name) == null ? void 0 : _attr$name.name) === 'slots') {
20
+ hasSlots = true;
21
+ const slotIndex = attr.value.expression.properties.findIndex(prop => {
22
+ var _prop$key;
23
+ return (prop == null || (_prop$key = prop.key) == null ? void 0 : _prop$key.name) === slotName;
24
+ });
25
+ if (slotIndex === -1) {
26
+ (0, _assignObject.default)(j, {
27
+ target: attr,
28
+ key: slotName,
29
+ expression: removedValue
30
+ });
31
+ }
32
+ }
33
+ });
34
+ if (!hasSlots) {
35
+ (0, _appendAttribute.default)(j, {
36
+ target: element,
37
+ attributeName: 'slots',
38
+ expression: j.objectExpression([j.objectProperty(j.identifier(slotName), removedValue)])
39
+ });
40
+ }
41
+ }
42
+ }
43
+ function moveDefaultPropsPropIntoSlots(j, defaultPropsPathCollection, propName, slotName) {
44
+ defaultPropsPathCollection.find(j.ObjectProperty, {
45
+ key: {
46
+ name: propName
47
+ }
48
+ }).forEach(path => {
49
+ const removedValue = path.value.value;
50
+ const defaultProps = path.parent.value;
51
+ let hasSlots = false;
52
+ defaultProps.properties.forEach(property => {
53
+ var _property$key;
54
+ if (((_property$key = property.key) == null ? void 0 : _property$key.name) === 'slots') {
55
+ hasSlots = true;
56
+ const slots = property.value;
57
+ const slotIndex = slots.properties.findIndex(prop => {
58
+ var _prop$key2;
59
+ return (prop == null || (_prop$key2 = prop.key) == null ? void 0 : _prop$key2.name) === slotName;
60
+ });
61
+ if (slotIndex === -1) {
62
+ slots.properties.push(j.objectProperty(j.identifier(slotName), removedValue));
63
+ }
64
+ }
65
+ });
66
+ if (!hasSlots) {
67
+ defaultProps.properties.push(j.property('init', j.identifier('slots'), j.objectExpression([j.objectProperty(j.identifier(slotName), removedValue)])));
68
+ }
69
+ path.prune();
70
+ });
71
+ }
72
+
73
+ /**
74
+ * Moves prop into slots.
75
+ * If the slots prop exists, it will add the prop to the slots.
76
+ * If there are duplicated values, the slots values will be used.
77
+ *
78
+ * @param {import('jscodeshift')} j
79
+ * @param {{ root: import('jscodeshift').Collection; componentName: string, propName: string, slotName: string }} options
80
+ *
81
+ * @example <Component TransitionComponent={CustomTransition} /> => <Component slots={{ transition: CustomTransition }} />
82
+ */
83
+ function movePropIntoSlots(j, options) {
84
+ const {
85
+ root,
86
+ componentName,
87
+ propName,
88
+ slotName
89
+ } = options;
90
+ (0, _findComponentJSX.default)(j, {
91
+ root,
92
+ componentName
93
+ }, elementPath => {
94
+ moveJsxPropIntoSlots(j, elementPath.node, propName, slotName);
95
+ });
96
+ const defaultPropsPathCollection = (0, _findComponentDefaultProps.default)(j, {
97
+ root,
98
+ componentName
99
+ });
100
+ moveDefaultPropsPropIntoSlots(j, defaultPropsPathCollection, propName, slotName);
101
+ }
@@ -15,12 +15,12 @@ function transformer(file, api) {
15
15
  node
16
16
  }) => {
17
17
  const sourceVal = node.source.value;
18
- if (sourceVal.startsWith('@mui/base')) {
19
- node.source.value = sourceVal.replace(/unstyled/im, '');
20
- node.source.raw = sourceVal.replace(/unstyled/im, '');
21
- }
22
18
  return sourceVal.startsWith('@mui/base');
23
19
  }).forEach(path => {
20
+ const sourceVal = path.node.source.value;
21
+ if (sourceVal.startsWith('@mui/base')) {
22
+ path.node.source = j.stringLiteral(sourceVal.replace(/unstyled/im, ''));
23
+ }
24
24
  const specifiers = [];
25
25
  path.node.specifiers.forEach(elementNode => {
26
26
  var _elementNode$imported;
@@ -14,14 +14,14 @@ var _OtherProvider;
14
14
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
15
15
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
16
16
  const App = () => {
17
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_styles.StyledEngineProvider, {
17
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_styles.StyledEngineProvider, {
18
18
  injectFirst: true,
19
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_styles.ThemeProvider, {
19
+ children: ["(", /*#__PURE__*/(0, _jsxRuntime.jsx)(_styles.ThemeProvider, {
20
20
  theme: (0, _styles.createTheme)(),
21
21
  children: _OtherProvider || (_OtherProvider = /*#__PURE__*/(0, _jsxRuntime.jsx)(_contexts.OtherProvider, {
22
22
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_pages.default, {})
23
23
  }))
24
- })
24
+ }), ")"]
25
25
  });
26
26
  };
27
27
  var _default = exports.default = App;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ Object.defineProperty(exports, "default", {
8
+ enumerable: true,
9
+ get: function () {
10
+ return _styledV.default;
11
+ }
12
+ });
13
+ var _styledV = _interopRequireDefault(require("./styled-v6"));
@@ -0,0 +1,493 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = styledV6;
8
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
+ const MAX_DEPTH = 20;
10
+
11
+ /**
12
+ * @param {import('jscodeshift').FileInfo} file
13
+ * @param {import('jscodeshift').API} api
14
+ */
15
+ function styledV6(file, api, options) {
16
+ const j = api.jscodeshift;
17
+ const root = j(file.source);
18
+ const printOptions = options.printOptions;
19
+ function createBuildStyle(key, upperBuildStyle) {
20
+ return function buildStyle(styleExpression) {
21
+ if (key) {
22
+ if (key.type === 'Identifier' || key.type === 'StringLiteral') {
23
+ return upperBuildStyle(j.objectExpression([j.objectProperty(key, styleExpression)]));
24
+ }
25
+ if (key.type === 'TemplateLiteral') {
26
+ return upperBuildStyle(j.objectExpression([(0, _extends2.default)({}, j.objectProperty(key, styleExpression), {
27
+ computed: true
28
+ })]));
29
+ }
30
+ }
31
+ return upperBuildStyle ? upperBuildStyle(styleExpression) : styleExpression;
32
+ };
33
+ }
34
+
35
+ /**
36
+ *
37
+ * @param {import('ast-types').namedTypes.MemberExpression | import('ast-types').namedTypes.Identifier} node
38
+ */
39
+ function getIdentifierKey(node) {
40
+ if (node.type === 'MemberExpression') {
41
+ return node.property;
42
+ }
43
+ return node;
44
+ }
45
+
46
+ /**
47
+ *
48
+ * @param {import('ast-types').namedTypes.UnaryExpression | import('ast-types').namedTypes.MemberExpression | import('ast-types').namedTypes.Identifier} node
49
+ */
50
+ function getObjectKey(node) {
51
+ let tempNode = (0, _extends2.default)({}, node);
52
+ while (tempNode.type === 'UnaryExpression') {
53
+ tempNode = tempNode.argument;
54
+ }
55
+ while (tempNode.type === 'MemberExpression') {
56
+ tempNode = tempNode.object;
57
+ }
58
+ return tempNode;
59
+ }
60
+
61
+ /**
62
+ *
63
+ * @param {import('ast-types').namedTypes.ObjectExpression} objectExpression
64
+ * @param {import('ast-types').namedTypes.BinaryExpression} addtional
65
+ */
66
+ function objectToArrowFunction(objectExpression, addtional) {
67
+ const paramKeys = new Set();
68
+ let left;
69
+ objectExpression.properties.forEach((prop, index) => {
70
+ paramKeys.add(prop.key.name);
71
+ const result = j.binaryExpression('===', prop.key, prop.value);
72
+ if (index === 0) {
73
+ left = result;
74
+ } else {
75
+ left = j.logicalExpression('&&', left, result);
76
+ }
77
+ });
78
+ if (addtional) {
79
+ paramKeys.add(getObjectKey(addtional.left).name);
80
+ }
81
+ return buildArrowFunctionAST(paramKeys, addtional ? j.logicalExpression('&&', left, addtional) : left);
82
+ }
83
+
84
+ /**
85
+ *
86
+ * @param {import('ast-types').namedTypes.Identifier | import('ast-types').namedTypes.BinaryExpression | import('ast-types').namedTypes.UnaryExpression} node
87
+ */
88
+ function inverseBinaryExpression(node) {
89
+ if (node.type === 'Identifier') {
90
+ return j.unaryExpression('!', node);
91
+ }
92
+ if (node.operator === '===') {
93
+ return (0, _extends2.default)({}, node, {
94
+ operator: '!=='
95
+ });
96
+ }
97
+ if (node.operator === '!==') {
98
+ return (0, _extends2.default)({}, node, {
99
+ operator: '==='
100
+ });
101
+ }
102
+ if (node.operator === '!') {
103
+ var _node$argument;
104
+ if (((_node$argument = node.argument) == null ? void 0 : _node$argument.operator) === '!') {
105
+ return node.argument;
106
+ }
107
+ return j.unaryExpression('!', node);
108
+ }
109
+ return node;
110
+ }
111
+
112
+ /**
113
+ *
114
+ * @param {import('ast-types').namedTypes.ObjectExpression} node
115
+ */
116
+ function removeProperty(parentNode, child) {
117
+ if (parentNode) {
118
+ if (parentNode.type === 'ObjectExpression') {
119
+ parentNode.properties = parentNode.properties.filter(prop => prop !== child && prop.value !== child);
120
+ }
121
+ }
122
+ }
123
+ function buildObjectAST(jsObject) {
124
+ const result = j.objectExpression([]);
125
+ Object.entries(jsObject).forEach(([key, value]) => {
126
+ result.properties.push(j.objectProperty(j.identifier(key), value));
127
+ });
128
+ return result;
129
+ }
130
+ function buildArrowFunctionAST(params, body) {
131
+ return j.arrowFunctionExpression([j.objectPattern([...params].map(k => (0, _extends2.default)({}, j.objectProperty(j.identifier(k), j.identifier(k)), {
132
+ shorthand: true
133
+ })))], body);
134
+ }
135
+
136
+ /**
137
+ *
138
+ * @param {{ properties: any[] }} node
139
+ * @param {Record<string, any[]>} modeStyles
140
+ */
141
+ function appendPaletteModeStyles(node, modeStyles) {
142
+ Object.entries(modeStyles).forEach(([mode, objectStyles]) => {
143
+ node.properties.push(j.spreadElement(j.callExpression(j.memberExpression(j.identifier('theme'), j.identifier('applyStyles')), [j.stringLiteral(mode), j.objectExpression(objectStyles)])));
144
+ });
145
+ }
146
+
147
+ /**
148
+ *
149
+ * @param {import('ast-types').namedTypes.LogicalExpression | import('ast-types').namedTypes.BinaryExpression | import('ast-types').namedTypes.UnaryExpression | import('ast-types').namedTypes.MemberExpression} node
150
+ */
151
+ function buildProps(node) {
152
+ const properties = [];
153
+ const variables = new Set();
154
+ let isAllEqual = true;
155
+ let tempNode = (0, _extends2.default)({}, node);
156
+ function assignProperties(_node) {
157
+ if (_node.type === 'BinaryExpression') {
158
+ variables.add(getObjectKey(_node.left).name);
159
+ if (_node.operator === '===') {
160
+ properties.push(j.objectProperty(getIdentifierKey(_node.left), _node.right));
161
+ } else {
162
+ isAllEqual = false;
163
+ }
164
+ }
165
+ if (_node.type === 'MemberExpression' || _node.type === 'Identifier') {
166
+ isAllEqual = false;
167
+ variables.add(getObjectKey(_node).name);
168
+ }
169
+ if (_node.type === 'UnaryExpression') {
170
+ isAllEqual = false;
171
+ if (_node.argument.type === 'UnaryExpression') {
172
+ // handle `!!variable`
173
+ variables.add(getObjectKey(_node.argument.argument).name);
174
+ } else {
175
+ // handle `!variable`
176
+ variables.add(getObjectKey(_node.argument).name);
177
+ }
178
+ }
179
+ }
180
+ let counter = 0;
181
+ if (tempNode.type !== 'LogicalExpression') {
182
+ assignProperties(tempNode);
183
+ } else {
184
+ while (tempNode.type === 'LogicalExpression' && counter < MAX_DEPTH) {
185
+ counter += 1;
186
+ if (tempNode.operator !== '&&') {
187
+ isAllEqual = false;
188
+ }
189
+ assignProperties(tempNode.right);
190
+ if (tempNode.left.type !== 'LogicalExpression') {
191
+ assignProperties(tempNode.left);
192
+ break;
193
+ }
194
+ tempNode = (0, _extends2.default)({}, tempNode.left);
195
+ }
196
+ }
197
+ if (!isAllEqual) {
198
+ return buildArrowFunctionAST(variables, node);
199
+ }
200
+ return j.objectExpression(properties);
201
+ }
202
+ function mergeProps(parentProps, currentProps) {
203
+ if (parentProps.type === 'ObjectExpression' && currentProps.type === 'ObjectExpression') {
204
+ return j.objectExpression([...parentProps.properties, ...currentProps.properties]);
205
+ }
206
+ const parentArrow = parentProps.type === 'ObjectExpression' ? objectToArrowFunction(parentProps) : parentProps;
207
+ const currentArrow = currentProps.type === 'ObjectExpression' ? objectToArrowFunction(currentProps) : currentProps;
208
+ const variables = new Set();
209
+ [...parentArrow.params[0].properties, ...currentArrow.params[0].properties].forEach(param => {
210
+ variables.add(param.key.name);
211
+ });
212
+ return buildArrowFunctionAST(variables, j.logicalExpression('&&', parentArrow.body, currentArrow.body));
213
+ }
214
+ function isThemePaletteMode(node) {
215
+ return node.type === 'MemberExpression' && node.object.type === 'MemberExpression' && node.object.object.name === 'theme' && node.object.property.name === 'palette' && node.property.name === 'mode';
216
+ }
217
+ let shouldTransform = false;
218
+ root.find(j.CallExpression).forEach(path => {
219
+ const styles = [];
220
+ let args = [];
221
+
222
+ // styled('div')(...arguments)
223
+ if (path.node.callee.type === 'Identifier' && path.node.callee.name === 'styled' && path.parentPath.node.type === 'CallExpression') {
224
+ args = path.parentPath.node.arguments;
225
+ }
226
+
227
+ // styled.div(...arguments)
228
+ if (path.node.callee.type === 'MemberExpression' && path.node.callee.object.type === 'Identifier' && path.node.callee.object.name === 'styled') {
229
+ args = path.node.arguments;
230
+ }
231
+
232
+ // 1. collecting styles that should be tranformed
233
+ args.forEach(arg => {
234
+ if (arg.type === 'ArrowFunctionExpression' && arg.params[0] && arg.params[0].type === 'ObjectPattern') {
235
+ styles.push(arg);
236
+ }
237
+ });
238
+ if (!shouldTransform && styles.length > 0) {
239
+ shouldTransform = true;
240
+ }
241
+
242
+ // 2. Find logical spread expressions to convert to variants
243
+ styles.forEach(style => {
244
+ const parameters = new Set();
245
+ style.params.forEach(param => {
246
+ if (param.type === 'ObjectPattern') {
247
+ param.properties.forEach(prop => {
248
+ parameters.add(prop.key.name);
249
+ });
250
+ }
251
+ });
252
+ const variants = [];
253
+ if (style.body.type === 'LogicalExpression') {
254
+ if (style.params[0] && style.params[0].type === 'ObjectPattern' && style.params[0].properties.some(prop => prop.key.name !== 'theme')) {
255
+ // case: ({ theme, ownerState }) => ownerState.variant === 'regular' && theme.mixins.toolbar
256
+ style.body = j.objectExpression([j.objectProperty(j.identifier('variants'), j.arrayExpression([j.objectExpression([j.objectProperty(j.identifier('props'), buildProps(style.body.left)), j.objectProperty(j.identifier('style'), style.body.right)])]))]);
257
+ }
258
+ } else if (style.body.type === 'ConditionalExpression') {
259
+ // skip ConditionalExpression
260
+ } else {
261
+ let objectExpression = style.body;
262
+ let counter = 0;
263
+ while (objectExpression.type !== 'ObjectExpression' && counter < MAX_DEPTH) {
264
+ counter += 1;
265
+ if (objectExpression.type === 'BlockStatement') {
266
+ objectExpression = objectExpression.body.find(item => item.type === 'ReturnStatement').argument;
267
+ }
268
+ }
269
+ recurseObjectExpression({
270
+ node: objectExpression,
271
+ buildStyle: createBuildStyle()
272
+ });
273
+ if (variants.length) {
274
+ objectExpression.properties.push(j.objectProperty(j.identifier('variants'), j.arrayExpression(variants.filter(variant => {
275
+ const props = variant.properties.find(prop => prop.key.name === 'props');
276
+ const styleVal = variant.properties.find(prop => prop.key.name === 'style');
277
+ return props && styleVal && styleVal.value.properties.length > 0 && (props.value.type === 'ArrowFunctionExpression' || props.value.properties.length > 0);
278
+ }))));
279
+ }
280
+ }
281
+ function recurseObjectExpression(data) {
282
+ if (data.node.type === 'ObjectExpression') {
283
+ const modeStyles = {}; // to collect styles from `theme.palette.mode === '...'`
284
+ data.node.properties.forEach(prop => {
285
+ if (prop.type === 'ObjectProperty') {
286
+ recurseObjectExpression((0, _extends2.default)({}, data, {
287
+ node: prop.value,
288
+ parentNode: data.node,
289
+ key: prop.key,
290
+ buildStyle: createBuildStyle(prop.key, data.buildStyle),
291
+ replaceValue: newValue => {
292
+ prop.value = newValue;
293
+ },
294
+ modeStyles
295
+ }));
296
+ } else {
297
+ recurseObjectExpression((0, _extends2.default)({}, data, {
298
+ node: prop,
299
+ parentNode: data.node,
300
+ buildStyle: createBuildStyle(prop.key, data.buildStyle)
301
+ }));
302
+ }
303
+ });
304
+ appendPaletteModeStyles(data.node, modeStyles);
305
+ }
306
+ if (data.node.type === 'SpreadElement') {
307
+ if (data.node.argument.type === 'LogicalExpression') {
308
+ var _getObjectKey;
309
+ const paramName = (_getObjectKey = getObjectKey(data.node.argument.left)) == null ? void 0 : _getObjectKey.name;
310
+ if (paramName && !parameters.has(paramName)) {
311
+ return;
312
+ }
313
+ const scopeProps = buildProps(data.node.argument.left);
314
+ const variant = {
315
+ props: data.props ? mergeProps(data.props, scopeProps) : scopeProps,
316
+ style: data.node.argument.right
317
+ };
318
+ const lastLength = variants.push({}); // preserve the order of the recursive calls
319
+
320
+ const modeStyles = {}; // to collect styles from `theme.palette.mode === '...'`
321
+ variant.style.properties.forEach(prop => {
322
+ if (prop.type === 'ObjectProperty') {
323
+ recurseObjectExpression((0, _extends2.default)({}, data, {
324
+ node: prop.value,
325
+ parentNode: variant.style,
326
+ props: variant.props,
327
+ key: prop.key,
328
+ buildStyle: createBuildStyle(prop.key, data.buildStyle),
329
+ replaceValue: newValue => {
330
+ prop.value = newValue;
331
+ },
332
+ modeStyles
333
+ }));
334
+ } else {
335
+ recurseObjectExpression((0, _extends2.default)({}, data, {
336
+ node: prop,
337
+ parentNode: variant.style,
338
+ props: variant.props,
339
+ buildStyle: createBuildStyle(prop.key, data.buildStyle)
340
+ }));
341
+ }
342
+ });
343
+ appendPaletteModeStyles(variant.style, modeStyles);
344
+ variant.style = data.buildStyle(variant.style);
345
+ variants[lastLength - 1] = buildObjectAST(variant);
346
+ removeProperty(data.parentNode, data.node);
347
+ }
348
+ if (data.node.argument.type === 'ConditionalExpression') {
349
+ recurseObjectExpression((0, _extends2.default)({}, data, {
350
+ node: data.node.argument,
351
+ parentNode: data.node
352
+ }));
353
+ removeProperty(data.parentNode, data.node);
354
+ }
355
+ }
356
+ if (data.node.type === 'ConditionalExpression') {
357
+ if (data.node.test.type === 'BinaryExpression' || data.node.test.type === 'UnaryExpression' || data.node.test.type === 'Identifier') {
358
+ var _getObjectKey2, _data$parentNode2, _data$node$test;
359
+ let leftName = (_getObjectKey2 = getObjectKey(data.node.test)) == null ? void 0 : _getObjectKey2.name;
360
+ if (data.node.test.left) {
361
+ var _getObjectKey3;
362
+ leftName = (_getObjectKey3 = getObjectKey(data.node.test.left)) == null ? void 0 : _getObjectKey3.name;
363
+ }
364
+ if (data.node.test.argument) {
365
+ var _getObjectKey4;
366
+ leftName = (_getObjectKey4 = getObjectKey(data.node.test.argument)) == null ? void 0 : _getObjectKey4.name;
367
+ }
368
+ if (parameters.has(leftName) && leftName !== 'theme') {
369
+ var _data$parentNode;
370
+ let props = buildProps(data.node.test);
371
+ if (data.props) {
372
+ props = mergeProps(data.props, props);
373
+ }
374
+ const styleVal = data.buildStyle(data.node.consequent);
375
+ const variant = {
376
+ props,
377
+ style: styleVal
378
+ };
379
+ variants.push(buildObjectAST(variant));
380
+
381
+ // create another variant with inverted condition
382
+ let props2 = buildProps(inverseBinaryExpression(data.node.test));
383
+ if (data.props) {
384
+ props2 = mergeProps(data.props, props2);
385
+ }
386
+ const styleVal2 = data.buildStyle(data.node.alternate);
387
+ const variant2 = {
388
+ props: props2,
389
+ style: styleVal2
390
+ };
391
+ variants.push(buildObjectAST(variant2));
392
+ if (((_data$parentNode = data.parentNode) == null ? void 0 : _data$parentNode.type) === 'ObjectExpression') {
393
+ removeProperty(data.parentNode, data.node);
394
+ }
395
+ }
396
+ if (leftName === 'theme' && ((_data$parentNode2 = data.parentNode) == null ? void 0 : _data$parentNode2.type) === 'ObjectExpression' && ((_data$node$test = data.node.test) == null ? void 0 : _data$node$test.type) === 'BinaryExpression' && isThemePaletteMode(data.node.test.left)) {
397
+ if (data.node.consequent.type !== 'ObjectExpression' && data.node.alternate.type !== 'ObjectExpression') {
398
+ var _data$replaceValue;
399
+ if (data.modeStyles) {
400
+ if (!data.modeStyles[data.node.test.right.value]) {
401
+ data.modeStyles[data.node.test.right.value] = [];
402
+ }
403
+ data.modeStyles[data.node.test.right.value].push(j.objectProperty(data.key, data.node.consequent));
404
+ }
405
+ (_data$replaceValue = data.replaceValue) == null || _data$replaceValue.call(data, data.node.alternate);
406
+ }
407
+ }
408
+ }
409
+ }
410
+ if (data.node.type === 'TemplateLiteral') {
411
+ var _data$parentNode3;
412
+ if (((_data$parentNode3 = data.parentNode) == null ? void 0 : _data$parentNode3.type) === 'ObjectExpression') {
413
+ const modeStyles = {};
414
+ data.node.expressions.forEach((expression, index) => {
415
+ recurseObjectExpression((0, _extends2.default)({}, data, {
416
+ node: expression,
417
+ parentNode: data.parentNode,
418
+ buildStyle: createBuildStyle(data.key, data.buildStyle),
419
+ replaceValue: newValue => {
420
+ data.node.expressions[index] = newValue;
421
+ },
422
+ modeStyles
423
+ }));
424
+ });
425
+ if (data.modeStyles) {
426
+ Object.entries(modeStyles).forEach(([mode, objectStyles]) => {
427
+ const clonedNode = (0, _extends2.default)({}, data.node, {
428
+ expressions: data.node.expressions.map(expression => (0, _extends2.default)({}, expression))
429
+ });
430
+ clonedNode.expressions = objectStyles.map(item => item.value);
431
+ if (!data.modeStyles[mode]) {
432
+ data.modeStyles[mode] = [];
433
+ }
434
+ data.modeStyles[mode].push(j.objectProperty(data.key, clonedNode));
435
+ });
436
+ }
437
+ }
438
+ }
439
+ if (data.key && data.key.type === 'Identifier' && data.node.type === 'MemberExpression' && data.node.object.type === 'ObjectExpression' && parameters.has(getObjectKey(data.node.property).name)) {
440
+ data.node.object.properties.forEach(prop => {
441
+ variants.push(buildObjectAST({
442
+ props: j.objectExpression([j.objectProperty(getIdentifierKey(data.node.property), j.stringLiteral(prop.key.name))]),
443
+ style: data.buildStyle(prop.value)
444
+ }));
445
+ });
446
+ removeProperty(data.parentNode, data.node);
447
+ }
448
+ }
449
+ style.params.forEach(param => {
450
+ if (param.type === 'ObjectPattern') {
451
+ param.properties = param.properties.filter(prop => prop.key.name === 'theme');
452
+ }
453
+ });
454
+ });
455
+
456
+ // Replace arrow function with object expression if the arg properties is empty
457
+ args.forEach((arg, index) => {
458
+ if (arg.type === 'ArrowFunctionExpression' && arg.params[0] && arg.params[0].type === 'ObjectPattern' && arg.params[0].properties.length === 0) {
459
+ if (arg.body.type === 'ObjectExpression') {
460
+ args[index] = arg.body;
461
+ }
462
+ if (arg.body.type === 'BlockStatement') {
463
+ const returnStatement = arg.body.body.find(item => item.type === 'ReturnStatement');
464
+ if (returnStatement) {
465
+ args[index] = returnStatement.argument;
466
+ }
467
+ }
468
+ }
469
+ });
470
+ });
471
+ const transformed = root.toSource(printOptions);
472
+ if (shouldTransform) {
473
+ // recast adds extra newlines that we don't want, https://github.com/facebook/jscodeshift/issues/249
474
+ // need to remove them manually
475
+ const lines = [];
476
+ let isInStyled = false;
477
+ transformed.split('\n').forEach((line, index, array) => {
478
+ if (!isInStyled) {
479
+ lines.push(line);
480
+ } else if (line !== '' || line === '' && array[index + 1] && array[index + 1].includes('return')) {
481
+ if (line.match(/^}\)+(\({}\)|\(\))?;?$/) || line.match(/^\);?$/)) {
482
+ isInStyled = false;
483
+ }
484
+ lines.push(line);
485
+ }
486
+ if (line.includes('styled.') || line.includes('styled(')) {
487
+ isInStyled = true;
488
+ }
489
+ });
490
+ return lines.join('\n');
491
+ }
492
+ return transformed;
493
+ }