@react-spectrum/codemods 0.2.1 → 0.3.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.
- package/dist/index.js +0 -0
- package/dist/s1-to-s2/src/codemods/changes.js +57 -0
- package/dist/s1-to-s2/src/codemods/codemod.js +3 -1
- package/dist/s1-to-s2/src/codemods/dimensions.js +7 -7
- package/dist/s1-to-s2/src/codemods/styleProps.js +19 -5
- package/dist/s1-to-s2/src/codemods/transforms.js +167 -4
- package/dist/s1-to-s2/src/codemods/unsafeStyle.js +8 -3
- package/dist/s1-to-s2/src/iconMap.js +16 -4
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
File without changes
|
|
@@ -22,6 +22,39 @@ exports.changes = {
|
|
|
22
22
|
}
|
|
23
23
|
]
|
|
24
24
|
},
|
|
25
|
+
ActionGroup: {
|
|
26
|
+
changes: [
|
|
27
|
+
{
|
|
28
|
+
description: 'Comment out overflowMode',
|
|
29
|
+
reason: 'It has not been implemented yet',
|
|
30
|
+
function: {
|
|
31
|
+
name: 'commentOutProp',
|
|
32
|
+
args: { propToComment: 'overflowMode' }
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
description: 'Comment out buttonLabelBehavior',
|
|
37
|
+
reason: 'It has not been implemented yet',
|
|
38
|
+
function: {
|
|
39
|
+
name: 'commentOutProp',
|
|
40
|
+
args: { propToComment: 'buttonLabelBehavior' }
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
description: 'Comment out summaryIcon',
|
|
45
|
+
reason: 'It has not been implemented yet',
|
|
46
|
+
function: {
|
|
47
|
+
name: 'commentOutProp',
|
|
48
|
+
args: { propToComment: 'summaryIcon' }
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
description: 'Replace with ActionButtonGroup or ToggleButtonGroup',
|
|
53
|
+
reason: 'The API has changed',
|
|
54
|
+
function: { name: 'updateActionGroup', args: {} }
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
},
|
|
25
58
|
ActionMenu: {
|
|
26
59
|
changes: [
|
|
27
60
|
{
|
|
@@ -334,6 +367,30 @@ exports.changes = {
|
|
|
334
367
|
name: 'moveRenderPropsToChild',
|
|
335
368
|
args: { newChildComponent: 'Dialog' }
|
|
336
369
|
}
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
description: 'Rename isDismissable to isDismissible',
|
|
373
|
+
reason: 'Fixed spelling',
|
|
374
|
+
function: { name: 'updatePropName', args: { oldProp: 'isDismissable', newProp: 'isDismissible' } }
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
description: 'Update Dialog child to Popover or FullscreenDialog depending on type prop',
|
|
378
|
+
reason: 'Updated API',
|
|
379
|
+
function: { name: 'updateDialogChild', args: {} }
|
|
380
|
+
}
|
|
381
|
+
]
|
|
382
|
+
},
|
|
383
|
+
DialogContainer: {
|
|
384
|
+
changes: [
|
|
385
|
+
{
|
|
386
|
+
description: 'Rename isDismissable to isDismissible',
|
|
387
|
+
reason: 'Fixed spelling',
|
|
388
|
+
function: { name: 'updatePropName', args: { oldProp: 'isDismissable', newProp: 'isDismissible' } }
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
description: 'Update Dialog child to Popover or FullscreenDialog depending on type prop',
|
|
392
|
+
reason: 'Updated API',
|
|
393
|
+
function: { name: 'updateDialogChild', args: {} }
|
|
337
394
|
}
|
|
338
395
|
]
|
|
339
396
|
},
|
|
@@ -49,6 +49,8 @@ availableComponents.add('Item');
|
|
|
49
49
|
availableComponents.add('Section');
|
|
50
50
|
// Don't update v3 Provider
|
|
51
51
|
availableComponents.delete('Provider');
|
|
52
|
+
// Replaced by ActionButtonGroup and ToggleButtonGroup
|
|
53
|
+
availableComponents.add('ActionGroup');
|
|
52
54
|
function transformer(file, api, options) {
|
|
53
55
|
let j = api.jscodeshift.withParser({
|
|
54
56
|
parse(source) {
|
|
@@ -227,7 +229,7 @@ function transformer(file, api, options) {
|
|
|
227
229
|
if (importedComponents.size) {
|
|
228
230
|
// Add imports to existing @react-spectrum/s2 import if it exists, otherwise add a new one.
|
|
229
231
|
let importSpecifiers = new Set([...importedComponents]
|
|
230
|
-
.filter(([c]) => c !== 'Flex' && c !== 'Grid' && c !== 'View' && c !== 'Item' && c !== 'Section')
|
|
232
|
+
.filter(([c]) => c !== 'Flex' && c !== 'Grid' && c !== 'View' && c !== 'Item' && c !== 'Section' && c !== 'ActionGroup')
|
|
231
233
|
.map(([, specifier]) => specifier));
|
|
232
234
|
let existingImport = root.find(j.ImportDeclaration, {
|
|
233
235
|
source: { value: '@react-spectrum/s2' }
|
|
@@ -140,7 +140,7 @@ const UNIT_RE = /(%|px|em|rem|vw|vh|auto|cm|mm|in|pt|pc|ex|ch|rem|vmin|vmax|fr)$
|
|
|
140
140
|
const FUNC_RE = /^\s*\w+\(/;
|
|
141
141
|
// const SPECTRUM_VARIABLE_RE = /(static-)?size-\d+|single-line-(height|width)/g;
|
|
142
142
|
const SIZING_RE = /auto|100vh|min-content|max-content|fit-content/;
|
|
143
|
-
function convertDimension(value,
|
|
143
|
+
function convertDimension(value, type) {
|
|
144
144
|
let pixelValue;
|
|
145
145
|
if (typeof value === 'number') {
|
|
146
146
|
pixelValue = value;
|
|
@@ -170,10 +170,10 @@ function convertDimension(value, toPixels = false) {
|
|
|
170
170
|
if (pixelValue == null) {
|
|
171
171
|
throw new Error('invalid dimension: ' + value);
|
|
172
172
|
}
|
|
173
|
-
if (
|
|
173
|
+
if (type === 'px') {
|
|
174
174
|
return `${pixelValue}px`;
|
|
175
175
|
}
|
|
176
|
-
if (spacingValues.includes(pixelValue)) {
|
|
176
|
+
if (type === 'size' || spacingValues.includes(pixelValue)) {
|
|
177
177
|
return pixelValue;
|
|
178
178
|
}
|
|
179
179
|
// TODO: Convert to rems? Find nearest value?
|
|
@@ -184,16 +184,16 @@ function convertGridTrack(value, toPixels = false) {
|
|
|
184
184
|
return value;
|
|
185
185
|
}
|
|
186
186
|
else {
|
|
187
|
-
return convertDimension(value, toPixels);
|
|
187
|
+
return convertDimension(value, toPixels ? 'px' : 'space');
|
|
188
188
|
}
|
|
189
189
|
}
|
|
190
|
-
function convertUnsafeDimension(value) {
|
|
190
|
+
function convertUnsafeDimension(value, type) {
|
|
191
191
|
if (typeof value === 'number') {
|
|
192
|
-
return convertDimension(value);
|
|
192
|
+
return convertDimension(value, type);
|
|
193
193
|
}
|
|
194
194
|
let m = value.match(/^var\(--spectrum-global-dimension-(static-)?size-(.*)\)$/);
|
|
195
195
|
if (m) {
|
|
196
|
-
return convertDimension(`${m[1] || ''}size-${m[2]}
|
|
196
|
+
return convertDimension(`${m[1] || ''}size-${m[2]}`, type);
|
|
197
197
|
}
|
|
198
198
|
return null;
|
|
199
199
|
}
|
|
@@ -63,7 +63,21 @@ function getStylePropValue(prop, value, element, colorVersion, condition = '') {
|
|
|
63
63
|
case 'maxWidth':
|
|
64
64
|
case 'height':
|
|
65
65
|
case 'minHeight':
|
|
66
|
-
case 'maxHeight':
|
|
66
|
+
case 'maxHeight': {
|
|
67
|
+
if (value.type === 'StringLiteral' || value.type === 'NumericLiteral') {
|
|
68
|
+
let val = (0, dimensions_1.convertDimension)(value.value, 'size');
|
|
69
|
+
if (val != null) {
|
|
70
|
+
return {
|
|
71
|
+
macroValues: [{ key: mappedProp, value: val }]
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else if (value.type === 'ObjectExpression') {
|
|
76
|
+
return getResponsiveValue(prop, value, element, colorVersion);
|
|
77
|
+
}
|
|
78
|
+
// return [mappedProp, customProp, [[customProp, value]]];
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
67
81
|
case 'margin':
|
|
68
82
|
case 'marginStart':
|
|
69
83
|
case 'marginEnd':
|
|
@@ -79,7 +93,7 @@ function getStylePropValue(prop, value, element, colorVersion, condition = '') {
|
|
|
79
93
|
case 'end':
|
|
80
94
|
case 'flexBasis': {
|
|
81
95
|
if (value.type === 'StringLiteral' || value.type === 'NumericLiteral') {
|
|
82
|
-
let val = (0, dimensions_1.convertDimension)(value.value);
|
|
96
|
+
let val = (0, dimensions_1.convertDimension)(value.value, 'space');
|
|
83
97
|
if (val != null) {
|
|
84
98
|
return {
|
|
85
99
|
macroValues: [{ key: mappedProp, value: val }]
|
|
@@ -182,7 +196,7 @@ function getStylePropValue(prop, value, element, colorVersion, condition = '') {
|
|
|
182
196
|
case 'rowGap':
|
|
183
197
|
if (element === 'Flex' || element === 'Grid') {
|
|
184
198
|
if (value.type === 'StringLiteral' || value.type === 'NumericLiteral') {
|
|
185
|
-
let val = (0, dimensions_1.convertDimension)(value.value);
|
|
199
|
+
let val = (0, dimensions_1.convertDimension)(value.value, 'space');
|
|
186
200
|
if (val != null) {
|
|
187
201
|
return {
|
|
188
202
|
macroValues: [{ key: mappedProp, value: val }]
|
|
@@ -308,7 +322,7 @@ function getStylePropValue(prop, value, element, colorVersion, condition = '') {
|
|
|
308
322
|
case 'paddingBottom':
|
|
309
323
|
if (element === 'View') {
|
|
310
324
|
if (value.type === 'StringLiteral' || value.type === 'NumericLiteral') {
|
|
311
|
-
let val = (0, dimensions_1.convertDimension)(value.value);
|
|
325
|
+
let val = (0, dimensions_1.convertDimension)(value.value, 'space');
|
|
312
326
|
if (val != null) {
|
|
313
327
|
return {
|
|
314
328
|
macroValues: [{ key: mappedProp, value: val }]
|
|
@@ -410,7 +424,7 @@ function getStylePropValue(prop, value, element, colorVersion, condition = '') {
|
|
|
410
424
|
// Try to automatically convert size prop to a macro value for components that supported size.
|
|
411
425
|
if (element === 'ColorArea' || element === 'ColorWheel') {
|
|
412
426
|
if (value.type === 'StringLiteral' || value.type === 'NumericLiteral') {
|
|
413
|
-
let val = (0, dimensions_1.convertDimension)(value.value);
|
|
427
|
+
let val = (0, dimensions_1.convertDimension)(value.value, 'size');
|
|
414
428
|
if (val != null) {
|
|
415
429
|
return {
|
|
416
430
|
macroValues: [{ key: 'size', value: val }]
|
|
@@ -285,7 +285,16 @@ function moveRenderPropsToChild(path, options) {
|
|
|
285
285
|
t.isArrowFunctionExpression(renderFunction.expression) &&
|
|
286
286
|
t.isJSXElement(renderFunction.expression.body)) {
|
|
287
287
|
const dialogElement = renderFunction.expression.body;
|
|
288
|
-
const
|
|
288
|
+
const originalParam = renderFunction.expression.params[0];
|
|
289
|
+
if (!t.isIdentifier(originalParam)) {
|
|
290
|
+
(0, utils_1.addComment)(path.node.children[renderFunctionIndex], ' TODO(S2-upgrade): Could not automatically move the render props. You\'ll need to update this manually.');
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
const paramName = originalParam.name;
|
|
294
|
+
const objectPattern = t.objectPattern([
|
|
295
|
+
t.objectProperty(t.identifier(paramName), t.identifier(paramName), false, true)
|
|
296
|
+
]);
|
|
297
|
+
const newRenderFunction = t.jsxExpressionContainer(t.arrowFunctionExpression([objectPattern], t.jsxFragment(t.jsxOpeningFragment(), t.jsxClosingFragment(), dialogElement.children)));
|
|
289
298
|
let removedOnDismiss = false;
|
|
290
299
|
const attributes = dialogElement.openingElement.attributes.filter((attr) => {
|
|
291
300
|
if (t.isJSXAttribute(attr) && attr.name.name === 'onDismiss') {
|
|
@@ -358,7 +367,7 @@ function updateComponentWithinCollection(path, options) {
|
|
|
358
367
|
* Example: If they're declaring declaring Items somewhere above the collection.
|
|
359
368
|
*/
|
|
360
369
|
function commentIfParentCollectionNotDetected(path) {
|
|
361
|
-
const collectionItemParents = new Set(['Menu', 'ActionMenu', 'TagGroup', 'Breadcrumbs', 'Picker', 'ComboBox', 'ListBox', 'TabList', 'TabPanels', 'ActionGroup', 'ListBox', 'ListView', 'Collection', 'SearchAutocomplete', 'Accordion', 'ActionBar', 'StepList']);
|
|
370
|
+
const collectionItemParents = new Set(['Menu', 'ActionMenu', 'TagGroup', 'Breadcrumbs', 'Picker', 'ComboBox', 'ListBox', 'TabList', 'TabPanels', 'ActionGroup', 'ActionButtonGroup', 'ToggleButtonGroup', 'ListBox', 'ListView', 'Collection', 'SearchAutocomplete', 'Accordion', 'ActionBar', 'StepList']);
|
|
362
371
|
if (t.isJSXElement(path.node)) {
|
|
363
372
|
// Find closest parent collection component
|
|
364
373
|
let closestParentCollection = path.findParent((p) => t.isJSXElement(p.node) &&
|
|
@@ -532,7 +541,7 @@ function convertDimensionValueToPx(path, options) {
|
|
|
532
541
|
if (attrPath && t.isJSXAttribute(attrPath.node) && attrPath.node.name.name === propToConvertValue) {
|
|
533
542
|
if (t.isStringLiteral(attrPath.node.value)) {
|
|
534
543
|
try {
|
|
535
|
-
let value = (0, dimensions_1.convertDimension)(attrPath.node.value.value);
|
|
544
|
+
let value = (0, dimensions_1.convertDimension)(attrPath.node.value.value, 'size');
|
|
536
545
|
if (value && typeof value === 'number') {
|
|
537
546
|
attrPath.node.value = t.jsxExpressionContainer(t.numericLiteral(value));
|
|
538
547
|
}
|
|
@@ -685,6 +694,158 @@ function updateLegacyLink(path) {
|
|
|
685
694
|
}
|
|
686
695
|
}
|
|
687
696
|
}
|
|
697
|
+
/**
|
|
698
|
+
* Updates DialogTrigger and DialogContainer to the new API.
|
|
699
|
+
*
|
|
700
|
+
* Example:
|
|
701
|
+
* - When `type="popover"`, replaces Dialog with `<Popover>`.
|
|
702
|
+
* - When `type="fullscreen"`, replaces Dialog with `<FullscreenDialog>`.
|
|
703
|
+
* - When `type="fullscreenTakeover"`, replaces Dialog with `<FullscreenDialog variant="fullscreenTakeover">`.
|
|
704
|
+
*/
|
|
705
|
+
function updateDialogChild(path) {
|
|
706
|
+
let typePath = path.get('openingElement').get('attributes').find((attr) => t.isJSXAttribute(attr.node) && attr.node.name.name === 'type');
|
|
707
|
+
let type = typePath?.node.value?.type === 'StringLiteral' ? typePath.node.value?.value : 'modal';
|
|
708
|
+
let newComponent = 'Dialog';
|
|
709
|
+
let props = [];
|
|
710
|
+
if (type === 'popover') {
|
|
711
|
+
newComponent = 'Popover';
|
|
712
|
+
}
|
|
713
|
+
else if (type === 'fullscreen' || type === 'fullscreenTakeover') {
|
|
714
|
+
newComponent = 'FullscreenDialog';
|
|
715
|
+
if (type === 'fullscreenTakeover') {
|
|
716
|
+
props.push(t.jsxAttribute(t.jsxIdentifier('variant'), t.stringLiteral(type)));
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
for (let prop of ['isDismissible', 'mobileType', 'hideArrow', 'placement', 'shouldFlip', 'isKeyboardDismissDisabled', 'containerPadding', 'offset', 'crossOffset']) {
|
|
720
|
+
let attr = path.get('openingElement').get('attributes').find(attr => attr.isJSXAttribute() && attr.node.name.name === prop);
|
|
721
|
+
if (attr) {
|
|
722
|
+
props.push(attr.node);
|
|
723
|
+
attr.remove();
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
typePath?.remove();
|
|
727
|
+
let localName = newComponent;
|
|
728
|
+
if (newComponent !== 'Dialog' && availableComponents.has(newComponent)) {
|
|
729
|
+
let program = path.findParent((p) => t.isProgram(p.node));
|
|
730
|
+
localName = (0, utils_1.addComponentImport)(program, newComponent);
|
|
731
|
+
}
|
|
732
|
+
path.traverse({
|
|
733
|
+
JSXElement(dialog) {
|
|
734
|
+
if (!t.isJSXIdentifier(dialog.node.openingElement.name) || (0, utils_1.getName)(dialog, dialog.node.openingElement.name) !== 'Dialog') {
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
dialog.node.openingElement.name = t.jsxIdentifier(localName);
|
|
738
|
+
if (dialog.node.closingElement) {
|
|
739
|
+
dialog.node.closingElement.name = t.jsxIdentifier(localName);
|
|
740
|
+
}
|
|
741
|
+
dialog.node.openingElement.attributes.push(...props);
|
|
742
|
+
}
|
|
743
|
+
});
|
|
744
|
+
}
|
|
745
|
+
function updateActionGroup(path) {
|
|
746
|
+
let selectionModePath = path.get('openingElement').get('attributes').find((attr) => t.isJSXAttribute(attr.node) && attr.node.name.name === 'selectionMode');
|
|
747
|
+
let selectionMode = t.isStringLiteral(selectionModePath?.node.value) ? selectionModePath.node.value.value : 'none';
|
|
748
|
+
let newComponent, childComponent;
|
|
749
|
+
if (selectionMode === 'none') {
|
|
750
|
+
newComponent = 'ActionButtonGroup';
|
|
751
|
+
childComponent = 'ActionButton';
|
|
752
|
+
selectionModePath?.remove();
|
|
753
|
+
}
|
|
754
|
+
else {
|
|
755
|
+
newComponent = 'ToggleButtonGroup';
|
|
756
|
+
childComponent = 'ToggleButton';
|
|
757
|
+
}
|
|
758
|
+
let localName = newComponent;
|
|
759
|
+
if (availableComponents.has(newComponent)) {
|
|
760
|
+
let program = path.findParent((p) => t.isProgram(p.node));
|
|
761
|
+
localName = (0, utils_1.addComponentImport)(program, newComponent);
|
|
762
|
+
}
|
|
763
|
+
let localChildName = childComponent;
|
|
764
|
+
if (availableComponents.has(childComponent)) {
|
|
765
|
+
let program = path.findParent((p) => t.isProgram(p.node));
|
|
766
|
+
localChildName = (0, utils_1.addComponentImport)(program, childComponent);
|
|
767
|
+
}
|
|
768
|
+
// Convert dynamic collection to an array.map.
|
|
769
|
+
let items = path.get('openingElement').get('attributes').find((attr) => t.isJSXAttribute(attr.node) && attr.node.name.name === 'items');
|
|
770
|
+
let itemArg;
|
|
771
|
+
if (items && t.isJSXExpressionContainer(items.node.value) && t.isExpression(items.node.value.expression)) {
|
|
772
|
+
let child = path.get('children').find(c => c.isJSXExpressionContainer());
|
|
773
|
+
if (child && child.isJSXExpressionContainer() && t.isFunction(child.node.expression)) {
|
|
774
|
+
let arg = child.node.expression.params[0];
|
|
775
|
+
if (t.isIdentifier(arg)) {
|
|
776
|
+
itemArg = arg;
|
|
777
|
+
}
|
|
778
|
+
child.replaceWith(t.jsxExpressionContainer(t.callExpression(t.memberExpression(items.node.value.expression, t.identifier('map')), [child.node.expression])));
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
items?.remove();
|
|
782
|
+
let onAction = path.get('openingElement').get('attributes').find((attr) => t.isJSXAttribute(attr.node) && attr.node.name.name === 'onAction');
|
|
783
|
+
// Pull disabledKeys prop out into a variable, converted to a Set.
|
|
784
|
+
// Then we can check it in the isDisabled prop of each item.
|
|
785
|
+
let disabledKeysPath = path.get('openingElement').get('attributes').find((attr) => t.isJSXAttribute(attr.node) && attr.node.name.name === 'disabledKeys');
|
|
786
|
+
let disabledKeys;
|
|
787
|
+
if (disabledKeysPath && t.isJSXExpressionContainer(disabledKeysPath.node.value) && t.isExpression(disabledKeysPath.node.value.expression)) {
|
|
788
|
+
disabledKeys = path.scope.generateUidIdentifier('disabledKeys');
|
|
789
|
+
path.scope.push({
|
|
790
|
+
id: disabledKeys,
|
|
791
|
+
init: t.newExpression(t.identifier('Set'), [disabledKeysPath.node.value.expression]),
|
|
792
|
+
kind: 'let'
|
|
793
|
+
});
|
|
794
|
+
disabledKeysPath.remove();
|
|
795
|
+
}
|
|
796
|
+
path.traverse({
|
|
797
|
+
JSXElement(child) {
|
|
798
|
+
if (t.isJSXIdentifier(child.node.openingElement.name) && child.node.openingElement.name.name === 'Item') {
|
|
799
|
+
// Replace Item with ActionButton or ToggleButton.
|
|
800
|
+
let childNode = t.cloneNode(child.node);
|
|
801
|
+
childNode.openingElement.name = t.jsxIdentifier(localChildName);
|
|
802
|
+
if (childNode.closingElement) {
|
|
803
|
+
childNode.closingElement.name = t.jsxIdentifier(localChildName);
|
|
804
|
+
}
|
|
805
|
+
// If there is no key prop and we are using dynamic collections, add a default computed from item.key ?? item.id.
|
|
806
|
+
let key = childNode.openingElement.attributes.find(attr => t.isJSXAttribute(attr) && attr.name.name === 'key');
|
|
807
|
+
if (!key && itemArg) {
|
|
808
|
+
let id = t.jsxExpressionContainer(t.logicalExpression('??', t.memberExpression(itemArg, t.identifier('key')), t.memberExpression(itemArg, t.identifier('id'))));
|
|
809
|
+
key = t.jsxAttribute(t.jsxIdentifier('key'), id);
|
|
810
|
+
childNode.openingElement.attributes.push(key);
|
|
811
|
+
}
|
|
812
|
+
// If this is a ToggleButtonGroup, add an id prop in addition to key when needed.
|
|
813
|
+
if (key && newComponent === 'ToggleButtonGroup') {
|
|
814
|
+
// If we are in an array.map we need both key and id. Otherwise, we only need id.
|
|
815
|
+
if (itemArg) {
|
|
816
|
+
childNode.openingElement.attributes.push(t.jsxAttribute(t.jsxIdentifier('id'), key.value));
|
|
817
|
+
}
|
|
818
|
+
else {
|
|
819
|
+
key.name.name = 'id';
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
let keyValue = undefined;
|
|
823
|
+
if (key && t.isJSXExpressionContainer(key.value) && t.isExpression(key.value.expression)) {
|
|
824
|
+
keyValue = key.value.expression;
|
|
825
|
+
}
|
|
826
|
+
else if (key && t.isStringLiteral(key.value)) {
|
|
827
|
+
keyValue = key.value;
|
|
828
|
+
}
|
|
829
|
+
// Add an onPress to each item that calls the previous onAction, passing in the key.
|
|
830
|
+
if (onAction && t.isJSXExpressionContainer(onAction.node.value) && t.isExpression(onAction.node.value.expression)) {
|
|
831
|
+
childNode.openingElement.attributes.push(t.jsxAttribute(t.jsxIdentifier('onPress'), t.jsxExpressionContainer(keyValue
|
|
832
|
+
? t.arrowFunctionExpression([], t.callExpression(onAction.node.value.expression, [keyValue]))
|
|
833
|
+
: onAction.node.value.expression)));
|
|
834
|
+
}
|
|
835
|
+
// Add an isDisabled prop to each item, testing whether it is in disabledKeys.
|
|
836
|
+
if (disabledKeys && keyValue) {
|
|
837
|
+
childNode.openingElement.attributes.push(t.jsxAttribute(t.jsxIdentifier('isDisabled'), t.jsxExpressionContainer(t.callExpression(t.memberExpression(disabledKeys, t.identifier('has')), [keyValue]))));
|
|
838
|
+
}
|
|
839
|
+
child.replaceWith(childNode);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
});
|
|
843
|
+
onAction?.remove();
|
|
844
|
+
path.node.openingElement.name = t.jsxIdentifier(localName);
|
|
845
|
+
if (path.node.closingElement) {
|
|
846
|
+
path.node.closingElement.name = t.jsxIdentifier(localName);
|
|
847
|
+
}
|
|
848
|
+
}
|
|
688
849
|
exports.functionMap = {
|
|
689
850
|
updatePropNameAndValue,
|
|
690
851
|
updatePropValueAndAddNewProp,
|
|
@@ -704,5 +865,7 @@ exports.functionMap = {
|
|
|
704
865
|
updatePlacementToSingleValue,
|
|
705
866
|
removeComponentIfWithinParent,
|
|
706
867
|
updateAvatarSize,
|
|
707
|
-
updateLegacyLink
|
|
868
|
+
updateLegacyLink,
|
|
869
|
+
updateDialogChild,
|
|
870
|
+
updateActionGroup
|
|
708
871
|
};
|
|
@@ -160,7 +160,12 @@ function handleProperty(element, property, value) {
|
|
|
160
160
|
case 'maxWidth':
|
|
161
161
|
case 'height':
|
|
162
162
|
case 'minHeight':
|
|
163
|
-
case 'maxHeight':
|
|
163
|
+
case 'maxHeight': {
|
|
164
|
+
if (value.type === 'NumericLiteral' || value.type === 'StringLiteral') {
|
|
165
|
+
return (0, dimensions_1.convertUnsafeDimension)(value.value, 'size');
|
|
166
|
+
}
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
164
169
|
case 'margin':
|
|
165
170
|
case 'marginInlineStart':
|
|
166
171
|
case 'marginInlineEnd':
|
|
@@ -178,7 +183,7 @@ function handleProperty(element, property, value) {
|
|
|
178
183
|
case 'insetInlineEnd':
|
|
179
184
|
case 'flexBasis': {
|
|
180
185
|
if (value.type === 'NumericLiteral' || value.type === 'StringLiteral') {
|
|
181
|
-
return (0, dimensions_1.convertUnsafeDimension)(value.value);
|
|
186
|
+
return (0, dimensions_1.convertUnsafeDimension)(value.value, 'space');
|
|
182
187
|
}
|
|
183
188
|
break;
|
|
184
189
|
}
|
|
@@ -196,7 +201,7 @@ function handleProperty(element, property, value) {
|
|
|
196
201
|
case 'columnGap': {
|
|
197
202
|
if (element === 'View' || element === 'Flex' || element === 'Grid') {
|
|
198
203
|
if (value.type === 'NumericLiteral' || value.type === 'StringLiteral') {
|
|
199
|
-
return (0, dimensions_1.convertUnsafeDimension)(value.value);
|
|
204
|
+
return (0, dimensions_1.convertUnsafeDimension)(value.value, 'space');
|
|
200
205
|
}
|
|
201
206
|
}
|
|
202
207
|
break;
|
|
@@ -155,10 +155,6 @@ exports.iconMap = new Map([
|
|
|
155
155
|
'Channel',
|
|
156
156
|
'Channel'
|
|
157
157
|
],
|
|
158
|
-
[
|
|
159
|
-
'ChatAdd',
|
|
160
|
-
'Channel'
|
|
161
|
-
],
|
|
162
158
|
[
|
|
163
159
|
'Checkmark',
|
|
164
160
|
'CheckmarkSize300'
|
|
@@ -711,10 +707,22 @@ exports.iconMap = new Map([
|
|
|
711
707
|
'Pause',
|
|
712
708
|
'Pause'
|
|
713
709
|
],
|
|
710
|
+
[
|
|
711
|
+
'PauseCircle',
|
|
712
|
+
'PauseCircle'
|
|
713
|
+
],
|
|
714
714
|
[
|
|
715
715
|
'Pending',
|
|
716
716
|
'ClockPending'
|
|
717
717
|
],
|
|
718
|
+
[
|
|
719
|
+
'PinOff',
|
|
720
|
+
'PinOff'
|
|
721
|
+
],
|
|
722
|
+
[
|
|
723
|
+
'PinOn',
|
|
724
|
+
'PinOn'
|
|
725
|
+
],
|
|
718
726
|
[
|
|
719
727
|
'Play',
|
|
720
728
|
'Play'
|
|
@@ -991,6 +999,10 @@ exports.iconMap = new Map([
|
|
|
991
999
|
'TextBulleted',
|
|
992
1000
|
'ListBulleted'
|
|
993
1001
|
],
|
|
1002
|
+
[
|
|
1003
|
+
'TextIncrease',
|
|
1004
|
+
'TextIncrease'
|
|
1005
|
+
],
|
|
994
1006
|
[
|
|
995
1007
|
'TextItalic',
|
|
996
1008
|
'TextItalic'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-spectrum/codemods",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"source": "src/index.ts",
|
|
6
6
|
"bin": "dist/index.js",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"@babel/parser": "^7.24.5",
|
|
25
25
|
"@babel/traverse": "^7.24.5",
|
|
26
26
|
"@babel/types": "^7.24.5",
|
|
27
|
-
"@react-spectrum/s2": "^0.
|
|
28
|
-
"@react-types/shared": "^3.
|
|
27
|
+
"@react-spectrum/s2": "^0.5.0",
|
|
28
|
+
"@react-types/shared": "^3.26.0",
|
|
29
29
|
"@types/node": "^20",
|
|
30
30
|
"boxen": "^5.1.2",
|
|
31
31
|
"build": "^0.1.4",
|
|
@@ -48,5 +48,5 @@
|
|
|
48
48
|
"publishConfig": {
|
|
49
49
|
"access": "public"
|
|
50
50
|
},
|
|
51
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "71f0ef23053f9e03ee7e97df736e8b083e006849"
|
|
52
52
|
}
|