@react-spectrum/codemods 1.2.1 → 1.2.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.
Files changed (29) hide show
  1. package/dist/index.js +12 -10
  2. package/dist/s1-to-s2/src/codemods/codemod.js +33 -17
  3. package/dist/s1-to-s2/src/codemods/components/ActionGroup/transform.js +34 -11
  4. package/dist/s1-to-s2/src/codemods/components/Avatar/transform.js +5 -1
  5. package/dist/s1-to-s2/src/codemods/components/ContextualHelpTrigger/transform.js +1 -1
  6. package/dist/s1-to-s2/src/codemods/components/DialogContainer/transform.js +3 -4
  7. package/dist/s1-to-s2/src/codemods/components/DialogTrigger/transform.js +33 -11
  8. package/dist/s1-to-s2/src/codemods/components/Item/transform.js +28 -7
  9. package/dist/s1-to-s2/src/codemods/components/Link/transform.js +6 -4
  10. package/dist/s1-to-s2/src/codemods/components/Row/transform.js +12 -5
  11. package/dist/s1-to-s2/src/codemods/components/Section/transform.js +12 -3
  12. package/dist/s1-to-s2/src/codemods/components/TableView/transform.js +36 -19
  13. package/dist/s1-to-s2/src/codemods/components/Tabs/transform.js +25 -9
  14. package/dist/s1-to-s2/src/codemods/icons/iconMap.js +319 -1276
  15. package/dist/s1-to-s2/src/codemods/shared/dimensions.js +5 -32
  16. package/dist/s1-to-s2/src/codemods/shared/styleProps.js +55 -19
  17. package/dist/s1-to-s2/src/codemods/shared/transforms.js +130 -67
  18. package/dist/s1-to-s2/src/codemods/shared/unsafeStyle.js +102 -48
  19. package/dist/s1-to-s2/src/codemods/shared/utils.js +31 -28
  20. package/dist/s1-to-s2/src/getComponents.js +8 -8
  21. package/dist/s1-to-s2/src/index.js +10 -6
  22. package/dist/s1-to-s2/src/utils/installPackage.js +5 -1
  23. package/dist/s1-to-s2/src/utils/waitForKeypress.js +1 -1
  24. package/dist/test-utils-rc-update/src/codemod.js +236 -0
  25. package/dist/test-utils-rc-update/src/index.js +13 -0
  26. package/dist/use-monopackages/src/codemod.js +25 -27
  27. package/dist/use-subpaths/src/codemod.js +11 -5
  28. package/dist/use-subpaths/src/specifiers.js +3 -1
  29. package/package.json +24 -22
@@ -20,7 +20,10 @@ function transformUnsafeStyle(value, element) {
20
20
  if (consequent && alternate) {
21
21
  let test = property.value.test;
22
22
  // eslint-disable-next-line max-depth
23
- if (test.type === 'BinaryExpression' && test.operator === '===' && test.left.type === 'Identifier' && test.right.type === 'StringLiteral') {
23
+ if (test.type === 'BinaryExpression' &&
24
+ test.operator === '===' &&
25
+ test.left.type === 'Identifier' &&
26
+ test.right.type === 'StringLiteral') {
24
27
  res.macroValues.push({
25
28
  key: prop,
26
29
  value: { default: alternate, [test.left.name]: { [test.right.value]: consequent } }
@@ -99,7 +102,8 @@ function handleProperty(element, property, value) {
99
102
  case 'outlineColor':
100
103
  case 'fill':
101
104
  case 'stroke': {
102
- if ((element === 'View' || element === 'Flex' || element === 'Grid') && value.type === 'StringLiteral') {
105
+ if ((element === 'View' || element === 'Flex' || element === 'Grid') &&
106
+ value.type === 'StringLiteral') {
103
107
  return (0, colors_1.convertUnsafeStyleColor)(property, value.value);
104
108
  }
105
109
  break;
@@ -139,12 +143,18 @@ function handleProperty(element, property, value) {
139
143
  }
140
144
  if (value.type === 'NumericLiteral') {
141
145
  switch (value.value) {
142
- case 0: return 'none';
143
- case 2: return 'sm';
144
- case 4: return 'default';
145
- case 8: return 'lg';
146
- case 16: return 'xl';
147
- default: return `[${value.value}px]`;
146
+ case 0:
147
+ return 'none';
148
+ case 2:
149
+ return 'sm';
150
+ case 4:
151
+ return 'default';
152
+ case 8:
153
+ return 'lg';
154
+ case 16:
155
+ return 'xl';
156
+ default:
157
+ return `[${value.value}px]`;
148
158
  }
149
159
  }
150
160
  else if (value.type === 'StringLiteral') {
@@ -213,37 +223,63 @@ function handleProperty(element, property, value) {
213
223
  }
214
224
  if (value.type === 'NumericLiteral') {
215
225
  switch (value.value) {
216
- case 11: return 'ui-xs';
217
- case 12: return 'ui-sm';
218
- case 14: return 'ui';
219
- case 16: return 'ui-lg';
220
- case 18: return 'ui-xl';
221
- case 20: return 'ui-2xl';
222
- case 22: return 'ui-3xl';
223
- default: return `[${value.value / 16}rem]`;
226
+ case 11:
227
+ return 'ui-xs';
228
+ case 12:
229
+ return 'ui-sm';
230
+ case 14:
231
+ return 'ui';
232
+ case 16:
233
+ return 'ui-lg';
234
+ case 18:
235
+ return 'ui-xl';
236
+ case 20:
237
+ return 'ui-2xl';
238
+ case 22:
239
+ return 'ui-3xl';
240
+ default:
241
+ return `[${value.value / 16}rem]`;
224
242
  }
225
243
  }
226
244
  else if (value.type === 'StringLiteral') {
227
245
  let m = value.value.match(/^var\(--spectrum-global-dimension-font-size-(.+)\)$/);
228
246
  if (m) {
247
+ // oxlint-disable-next-line max-depth
229
248
  switch (m[1]) {
230
- case '25': return `[${10 / 16}rem]`;
231
- case '50': return 'xs';
232
- case '75': return 'ui-sm';
233
- case '100': return 'ui';
234
- case '150': return `[${15 / 16}rem]`;
235
- case '200': return 'ui-lg';
236
- case '300': return 'ui-xl';
237
- case '400': return 'body-xl';
238
- case '500': return 'body-2xl';
239
- case '600': return 'body-3xl';
240
- case '700': return 'heading-lg';
241
- case '800': return `[${32 / 16}rem]`;
242
- case '900': return 'heading-xl';
243
- case '1000': return `[${40 / 16}rem]`;
244
- case '1100': return 'heading-2xl';
245
- case '1200': return `[${50 / 16}rem]`;
246
- case '1300': return 'heading-3xl';
249
+ case '25':
250
+ return `[${10 / 16}rem]`;
251
+ case '50':
252
+ return 'xs';
253
+ case '75':
254
+ return 'ui-sm';
255
+ case '100':
256
+ return 'ui';
257
+ case '150':
258
+ return `[${15 / 16}rem]`;
259
+ case '200':
260
+ return 'ui-lg';
261
+ case '300':
262
+ return 'ui-xl';
263
+ case '400':
264
+ return 'body-xl';
265
+ case '500':
266
+ return 'body-2xl';
267
+ case '600':
268
+ return 'body-3xl';
269
+ case '700':
270
+ return 'heading-lg';
271
+ case '800':
272
+ return `[${32 / 16}rem]`;
273
+ case '900':
274
+ return 'heading-xl';
275
+ case '1000':
276
+ return `[${40 / 16}rem]`;
277
+ case '1100':
278
+ return 'heading-2xl';
279
+ case '1200':
280
+ return `[${50 / 16}rem]`;
281
+ case '1300':
282
+ return 'heading-3xl';
247
283
  }
248
284
  }
249
285
  }
@@ -255,6 +291,7 @@ function handleProperty(element, property, value) {
255
291
  if (value.type === 'StringLiteral') {
256
292
  let m = value.value.match(/^var\(--spectrum-global-font-weight-(.+)\)$/);
257
293
  if (m) {
294
+ // oxlint-disable-next-line max-depth
258
295
  switch (m[1]) {
259
296
  case 'light':
260
297
  case 'medium':
@@ -267,6 +304,7 @@ function handleProperty(element, property, value) {
267
304
  }
268
305
  }
269
306
  else {
307
+ // oxlint-disable-next-line max-depth
270
308
  switch (value.value) {
271
309
  case 'normal':
272
310
  case 'bold':
@@ -288,7 +326,8 @@ function handleProperty(element, property, value) {
288
326
  case 'gridRow':
289
327
  case 'gridRowEnd':
290
328
  case 'gridRowStart': {
291
- if ((value.type === 'StringLiteral' && !/^(var|calc)\(/.test(value.value)) || value.type === 'NumericLiteral') {
329
+ if ((value.type === 'StringLiteral' && !/^(var|calc)\(/.test(value.value)) ||
330
+ value.type === 'NumericLiteral') {
292
331
  return value.value;
293
332
  }
294
333
  break;
@@ -385,7 +424,8 @@ function handleProperty(element, property, value) {
385
424
  case 'transitionTimingFunction':
386
425
  case 'transitionDelay': {
387
426
  if (element === 'Flex' || element === 'Grid' || element === 'View') {
388
- if ((value.type === 'StringLiteral' && !/^(var|calc)\(/.test(value.value)) || value.type === 'NumericLiteral') {
427
+ if ((value.type === 'StringLiteral' && !/^(var|calc)\(/.test(value.value)) ||
428
+ value.type === 'NumericLiteral') {
389
429
  return value.value;
390
430
  }
391
431
  }
@@ -397,20 +437,34 @@ function handleProperty(element, property, value) {
397
437
  if (value.type === 'StringLiteral') {
398
438
  let m = value.value.match(/^var\(--spectrum-global-animation-duration-(.+)\)$/);
399
439
  if (m) {
440
+ // oxlint-disable-next-line max-depth
400
441
  switch (m[1]) {
401
- case '0': return 0;
402
- case '100': return 130;
403
- case '200': return 160;
404
- case '300': return 190;
405
- case '400': return 220;
406
- case '500': return 250;
407
- case '600': return 300;
408
- case '700': return 350;
409
- case '800': return 400;
410
- case '900': return 450;
411
- case '1000': return 500;
412
- case '2000': return 1000;
413
- case '4000': return 2000;
442
+ case '0':
443
+ return 0;
444
+ case '100':
445
+ return 130;
446
+ case '200':
447
+ return 160;
448
+ case '300':
449
+ return 190;
450
+ case '400':
451
+ return 220;
452
+ case '500':
453
+ return 250;
454
+ case '600':
455
+ return 300;
456
+ case '700':
457
+ return 350;
458
+ case '800':
459
+ return 400;
460
+ case '900':
461
+ return 450;
462
+ case '1000':
463
+ return 500;
464
+ case '2000':
465
+ return 1000;
466
+ case '4000':
467
+ return 2000;
414
468
  }
415
469
  }
416
470
  else if (/^\d+(s|ms)$/.test(value.value)) {
@@ -80,7 +80,9 @@ function nameFromExpression(expr) {
80
80
  case 'ParenthesizedExpression':
81
81
  return nameFromExpression(expr.expression);
82
82
  case 'JSXExpressionContainer':
83
- return expr.expression.type !== 'JSXEmptyExpression' ? nameFromExpression(expr.expression) : '';
83
+ return expr.expression.type !== 'JSXEmptyExpression'
84
+ ? nameFromExpression(expr.expression)
85
+ : '';
84
86
  case 'BinaryExpression':
85
87
  case 'LogicalExpression':
86
88
  case 'AssignmentExpression':
@@ -110,9 +112,9 @@ function addComment(node, comment) {
110
112
  });
111
113
  }
112
114
  function addComponentImport(path, newComponentName) {
113
- let existingImport = path.node.body.find((node) => t.isImportDeclaration(node) && node.source.value === '@react-spectrum/s2');
115
+ let existingImport = path.node.body.find(node => t.isImportDeclaration(node) && node.source.value === '@react-spectrum/s2');
114
116
  if (existingImport && t.isImportDeclaration(existingImport)) {
115
- let existingSpecifier = existingImport.specifiers.find((specifier) => {
117
+ let existingSpecifier = existingImport.specifiers.find(specifier => {
116
118
  return (t.isImportSpecifier(specifier) &&
117
119
  specifier.imported.type === 'Identifier' &&
118
120
  specifier.imported.name === newComponentName);
@@ -137,44 +139,43 @@ function addComponentImport(path, newComponentName) {
137
139
  existingImport.specifiers.push(t.importSpecifier(t.identifier(localName), t.identifier(newComponentName)));
138
140
  }
139
141
  else {
140
- let importDeclaration = t.importDeclaration([
141
- t.importSpecifier(t.identifier(localName), t.identifier(newComponentName))
142
- ], t.stringLiteral('@react-spectrum/s2'));
142
+ let importDeclaration = t.importDeclaration([t.importSpecifier(t.identifier(localName), t.identifier(newComponentName))], t.stringLiteral('@react-spectrum/s2'));
143
143
  path.node.body.unshift(importDeclaration);
144
144
  }
145
145
  return localName;
146
146
  }
147
147
  function removeComponentImport(path, component) {
148
148
  let imports = path.node.body.filter((node) => {
149
- return t.isImportDeclaration(node)
150
- && (node.source.value === '@adobe/react-spectrum'
151
- || (node.source.value.startsWith('@react-spectrum/') && node.source.value !== '@react-spectrum/s2'));
149
+ return (t.isImportDeclaration(node) &&
150
+ (node.source.value === '@adobe/react-spectrum' ||
151
+ (node.source.value.startsWith('@react-spectrum/') &&
152
+ node.source.value !== '@react-spectrum/s2')));
152
153
  });
153
154
  for (let importDecl of imports) {
154
155
  let previousLength = importDecl.specifiers.length;
155
- importDecl.specifiers = importDecl.specifiers.filter((specifier) => {
156
- return !(t.isImportSpecifier(specifier)
157
- && specifier.imported.type === 'Identifier'
158
- && specifier.imported.name === component);
156
+ importDecl.specifiers = importDecl.specifiers.filter(specifier => {
157
+ return !(t.isImportSpecifier(specifier) &&
158
+ specifier.imported.type === 'Identifier' &&
159
+ specifier.imported.name === component);
159
160
  });
160
161
  if (importDecl.specifiers.length === 0 && previousLength > 0) {
161
- path.node.body = path.node.body.filter((node) => node !== importDecl);
162
+ path.node.body = path.node.body.filter(node => node !== importDecl);
162
163
  }
163
164
  }
164
165
  }
165
166
  function removeComponentImportIfUnused(path, component) {
166
167
  path.scope.crawl();
167
168
  let imports = path.node.body.filter((node) => {
168
- return t.isImportDeclaration(node)
169
- && (node.source.value === '@adobe/react-spectrum'
170
- || node.source.value.startsWith('@react-spectrum/'));
169
+ return (t.isImportDeclaration(node) &&
170
+ (node.source.value === '@adobe/react-spectrum' ||
171
+ node.source.value.startsWith('@react-spectrum/')));
171
172
  });
172
173
  for (let importDecl of imports) {
173
174
  let previousLength = importDecl.specifiers.length;
174
- importDecl.specifiers = importDecl.specifiers.filter((specifier) => {
175
- if (t.isImportSpecifier(specifier)
176
- && specifier.imported.type === 'Identifier'
177
- && specifier.imported.name === component) {
175
+ importDecl.specifiers = importDecl.specifiers.filter(specifier => {
176
+ if (t.isImportSpecifier(specifier) &&
177
+ specifier.imported.type === 'Identifier' &&
178
+ specifier.imported.name === component) {
178
179
  let localName = specifier.local?.name ?? specifier.imported.name;
179
180
  let binding = path.scope.getBinding(localName);
180
181
  return !!binding?.referencePaths.length;
@@ -182,7 +183,7 @@ function removeComponentImportIfUnused(path, component) {
182
183
  return true;
183
184
  });
184
185
  if (importDecl.specifiers.length === 0 && previousLength > 0) {
185
- path.node.body = path.node.body.filter((node) => node !== importDecl);
186
+ path.node.body = path.node.body.filter(node => node !== importDecl);
186
187
  }
187
188
  }
188
189
  }
@@ -194,17 +195,17 @@ function removeUnusedImports(path, sources) {
194
195
  });
195
196
  for (let importDecl of imports) {
196
197
  let previousLength = importDecl.specifiers.length;
197
- importDecl.specifiers = importDecl.specifiers.filter((specifier) => {
198
- if (t.isImportSpecifier(specifier)
199
- || t.isImportDefaultSpecifier(specifier)
200
- || t.isImportNamespaceSpecifier(specifier)) {
198
+ importDecl.specifiers = importDecl.specifiers.filter(specifier => {
199
+ if (t.isImportSpecifier(specifier) ||
200
+ t.isImportDefaultSpecifier(specifier) ||
201
+ t.isImportNamespaceSpecifier(specifier)) {
201
202
  let binding = path.scope.getBinding(specifier.local.name);
202
203
  return !!binding?.referencePaths.length;
203
204
  }
204
205
  return true;
205
206
  });
206
207
  if (importDecl.specifiers.length === 0 && previousLength > 0) {
207
- path.node.body = path.node.body.filter((node) => node !== importDecl);
208
+ path.node.body = path.node.body.filter(node => node !== importDecl);
208
209
  }
209
210
  }
210
211
  }
@@ -214,7 +215,9 @@ function removeUnusedImports(path, sources) {
214
215
  */
215
216
  function getName(path, identifier) {
216
217
  let binding = path.scope.getBinding(identifier.name);
217
- if (binding && t.isImportSpecifier(binding.path.node) && t.isIdentifier(binding.path.node.imported)) {
218
+ if (binding &&
219
+ t.isImportSpecifier(binding.path.node) &&
220
+ t.isIdentifier(binding.path.node.imported)) {
218
221
  return binding.path.node.imported.name;
219
222
  }
220
223
  return identifier.name;
@@ -10,12 +10,7 @@ const path = require('path');
10
10
  const traverse_1 = __importDefault(require("@babel/traverse"));
11
11
  // These are exported but there are no codemods written for them yet.
12
12
  // Don't replace imports yet.
13
- const skipped = new Set([
14
- 'Accordion',
15
- 'Card',
16
- 'CardView',
17
- 'ActionBar'
18
- ]);
13
+ const skipped = new Set(['Accordion', 'Card', 'CardView', 'ActionBar']);
19
14
  function getComponents() {
20
15
  // Determine list of available components in S2 from index.ts
21
16
  let availableComponents = new Set();
@@ -31,12 +26,17 @@ function getComponents() {
31
26
  }
32
27
  indexPath = workspaceIndexPath;
33
28
  }
34
- let index = (0, parser_1.parse)((0, fs_1.readFileSync)(indexPath, 'utf8'), { sourceType: 'module', plugins: ['typescript'] });
29
+ let index = (0, parser_1.parse)((0, fs_1.readFileSync)(indexPath, 'utf8'), {
30
+ sourceType: 'module',
31
+ plugins: ['typescript']
32
+ });
35
33
  (0, traverse_1.default)(index, {
36
34
  ExportNamedDeclaration(path) {
37
35
  if (path.node.exportKind === 'value') {
38
36
  for (let specifier of path.node.specifiers) {
39
- let name = specifier.exported.type === 'Identifier' ? specifier.exported.name : specifier.exported.value;
37
+ let name = specifier.exported.type === 'Identifier'
38
+ ? specifier.exported.name
39
+ : specifier.exported.value;
40
40
  if (!skipped.has(name)) {
41
41
  availableComponents.add(name);
42
42
  }
@@ -12,7 +12,11 @@ const transform_js_1 = require("./transform.js");
12
12
  const waitForKeypress_js_1 = require("./utils/waitForKeypress.js");
13
13
  const boxen = require('boxen');
14
14
  function printNextSteps(nextSteps) {
15
- console.log(boxen(`Next steps:\n\n ${nextSteps.map((step, i) => `${i + 1}. ${step}`).join('\n\n\n')}`, { borderStyle: 'round', padding: 1, borderColor: 'green' }));
15
+ console.log(boxen(`Next steps:\n\n ${nextSteps.map((step, i) => `${i + 1}. ${step}`).join('\n\n\n')}`, {
16
+ borderStyle: 'round',
17
+ padding: 1,
18
+ borderColor: 'green'
19
+ }));
16
20
  }
17
21
  async function s1_to_s2(options) {
18
22
  if (options.agent) {
@@ -23,7 +27,7 @@ async function s1_to_s2(options) {
23
27
  printNextSteps([
24
28
  `Ensure ${chalk_1.default.bold('@react-spectrum/s2')} is installed.`,
25
29
  `If your bundler is not Parcel v2.12.0+, configure the Spectrum 2 style macro support. See: ${chalk_1.default.underline('https://react-spectrum.adobe.com/getting-started#framework-setup')}`,
26
- `Add ${chalk_1.default.bold('import \'@react-spectrum/s2/page.css\';')} to your entry component if needed.`,
30
+ `Add ${chalk_1.default.bold("import '@react-spectrum/s2/page.css';")} to your entry component if needed.`,
27
31
  `Search for ${chalk_1.default.bold('TODO(S2-upgrade)')} and resolve remaining manual migration updates.`,
28
32
  `Reference the migration guide: ${chalk_1.default.underline('https://react-spectrum.adobe.com/migrating')}`
29
33
  ]);
@@ -47,7 +51,7 @@ async function s1_to_s2(options) {
47
51
  logger_js_1.default.success('Upgrade complete!');
48
52
  let nextSteps = [
49
53
  'Add the following import to the entry component of your app: \n\n' +
50
- `${chalk_1.default.bold('import \'@react-spectrum/s2/page.css\';')}\n\n` +
54
+ `${chalk_1.default.bold("import '@react-spectrum/s2/page.css';")}\n\n` +
51
55
  'Note that unlike React Spectrum v3, a Provider is not required.'
52
56
  ];
53
57
  if (!isS2PackageInstalled) {
@@ -63,11 +67,11 @@ async function s1_to_s2(options) {
63
67
  ` - ESBuild: ${chalk_1.default.underline('https://github.com/adobe/react-spectrum/tree/main/examples/s2-esbuild-starter-app')}\n\n` +
64
68
  `or view documentation here: ${chalk_1.default.underline('https://react-spectrum.adobe.com/getting-started#framework-setup')}`);
65
69
  }
66
- nextSteps.push('Handle remaining upgrades and run your project\'s linter or formatter.\n\n' +
67
- 'There may have been some upgrades that we couldn\'t handle automatically. We marked these with comments containing:\n\n' +
70
+ nextSteps.push("Handle remaining upgrades and run your project's linter or formatter.\n\n" +
71
+ "There may have been some upgrades that we couldn't handle automatically. We marked these with comments containing:\n\n" +
68
72
  `${chalk_1.default.bold('TODO(S2-upgrade)')}\n\n` +
69
73
  'You should be able to search your codebase and handle these manually. \n\n' +
70
- 'We also recommend running your project\'s code formatter (i.e. Prettier, ESLint) after the upgrade process to clean up any extraneous formatting from the codemod.\n\n' +
74
+ "We also recommend running your project's code formatter (i.e. Prettier, ESLint) after the upgrade process to clean up any extraneous formatting from the codemod.\n\n" +
71
75
  `For additional help, reference the Spectrum 2 Migration Guide: ${chalk_1.default.underline('https://react-spectrum.adobe.com/migrating')}`);
72
76
  printNextSteps(nextSteps);
73
77
  process.exit(0);
@@ -39,7 +39,11 @@ async function installPackage(packageName, options) {
39
39
  try {
40
40
  logger_js_1.default.info(`Installing ${chalk_1.default.bold(packageName)} using ${chalk_1.default.bold(packageManager.name)}...`);
41
41
  const devFlag = options?.dev ? ['-D'] : [];
42
- await execa(packageManager.name, [packageManager.installCommand, `${packageName}@latest`, ...devFlag]);
42
+ await execa(packageManager.name, [
43
+ packageManager.installCommand,
44
+ `${packageName}@latest`,
45
+ ...devFlag
46
+ ]);
43
47
  logger_js_1.default.success(`Successfully installed ${chalk_1.default.bold(packageName)}!\n`);
44
48
  return true;
45
49
  }
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.waitForKeypress = waitForKeypress;
4
4
  async function waitForKeypress() {
5
- await new Promise((resolve) => {
5
+ await new Promise(resolve => {
6
6
  process.stdin.once('data', () => {
7
7
  resolve();
8
8
  });