@react-spectrum/codemods 1.0.0 → 1.1.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/s1-to-s2/src/codemods/codemod.js +31 -7
- package/dist/s1-to-s2/src/codemods/components/ContextualHelpTrigger/transform.js +68 -0
- package/dist/s1-to-s2/src/codemods/components/Item/transform.js +3 -0
- package/dist/s1-to-s2/src/codemods/components/ListView/transform.js +13 -0
- package/dist/s1-to-s2/src/codemods/shared/styleProps.js +1 -1
- package/dist/s1-to-s2/src/codemods/shared/transforms.js +4 -4
- package/package.json +5 -5
|
@@ -59,6 +59,10 @@ availableComponents.add('Section');
|
|
|
59
59
|
availableComponents.delete('Provider');
|
|
60
60
|
// Replaced by ActionButtonGroup and ToggleButtonGroup
|
|
61
61
|
availableComponents.add('ActionGroup');
|
|
62
|
+
// components renamed between v3 and S2
|
|
63
|
+
let renamedComponents = {
|
|
64
|
+
ContextualHelpTrigger: 'UnavailableMenuItemTrigger'
|
|
65
|
+
};
|
|
62
66
|
function transformer(file, api, options) {
|
|
63
67
|
let j = api.jscodeshift.withParser({
|
|
64
68
|
parse(source) {
|
|
@@ -69,6 +73,8 @@ function transformer(file, api, options) {
|
|
|
69
73
|
});
|
|
70
74
|
let root = j(file.source);
|
|
71
75
|
let componentsToTransform = options.components ? new Set(options.components.split(',').filter(s => availableComponents.has(s))) : availableComponents;
|
|
76
|
+
let v3ComponentsToRename = new Set(Object.keys(renamedComponents));
|
|
77
|
+
let S2ComponentsToImport = new Set();
|
|
72
78
|
let bindings = [];
|
|
73
79
|
let importedComponents = new Map();
|
|
74
80
|
let elements = [];
|
|
@@ -87,9 +93,19 @@ function transformer(file, api, options) {
|
|
|
87
93
|
if (binding) {
|
|
88
94
|
let isUsed = false;
|
|
89
95
|
for (let path of binding.referencePaths) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
96
|
+
let propName = path.parentPath?.isJSXMemberExpression() && path.parentPath.node.property.name;
|
|
97
|
+
if (propName && path.parentPath.parentPath?.parentPath?.isJSXElement()) {
|
|
98
|
+
if (componentsToTransform.has(propName)) {
|
|
99
|
+
importedComponents.set(propName, clonedSpecifier);
|
|
100
|
+
elements.push([propName, path.parentPath.parentPath.parentPath]);
|
|
101
|
+
}
|
|
102
|
+
else if (v3ComponentsToRename.has(propName)) {
|
|
103
|
+
S2ComponentsToImport.add(renamedComponents[propName]);
|
|
104
|
+
elements.push([propName, path.parentPath.parentPath.parentPath]);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
isUsed = true;
|
|
108
|
+
}
|
|
93
109
|
}
|
|
94
110
|
else {
|
|
95
111
|
isUsed = true;
|
|
@@ -112,11 +128,16 @@ function transformer(file, api, options) {
|
|
|
112
128
|
typeof specifier.local.name === 'string' &&
|
|
113
129
|
specifier.imported.type === 'Identifier' &&
|
|
114
130
|
typeof specifier.imported.name === 'string' &&
|
|
115
|
-
componentsToTransform.has(specifier.imported.name)) {
|
|
116
|
-
// e.g. import {Button} from '@adobe/react-spectrum';
|
|
131
|
+
(componentsToTransform.has(specifier.imported.name) || v3ComponentsToRename.has(specifier.imported.name))) {
|
|
132
|
+
// e.g. import {Button} from '@adobe/react-spectrum'; or import {ContextualHelpTrigger} from '@adobe/react-spectrum';
|
|
117
133
|
let binding = path.scope.getBinding(specifier.local.name);
|
|
118
134
|
if (binding) {
|
|
119
|
-
|
|
135
|
+
if (componentsToTransform.has(specifier.imported.name)) {
|
|
136
|
+
importedComponents.set(specifier.imported.name, specifier);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
S2ComponentsToImport.add(renamedComponents[specifier.imported.name]);
|
|
140
|
+
}
|
|
120
141
|
bindings.push(binding);
|
|
121
142
|
for (let path of binding.referencePaths) {
|
|
122
143
|
if (path.parentPath?.isJSXOpeningElement() && path.parentPath.parentPath.isJSXElement()) {
|
|
@@ -234,11 +255,14 @@ function transformer(file, api, options) {
|
|
|
234
255
|
macroImport.assertions = [t.importAttribute(t.identifier('type'), t.stringLiteral('macro'))];
|
|
235
256
|
lastImportPath.insertAfter(macroImport);
|
|
236
257
|
}
|
|
237
|
-
if (importedComponents.size) {
|
|
258
|
+
if (importedComponents.size || S2ComponentsToImport.size) {
|
|
238
259
|
// Add imports to existing @react-spectrum/s2 import if it exists, otherwise add a new one.
|
|
239
260
|
let importSpecifiers = new Set([...importedComponents]
|
|
240
261
|
.filter(([c]) => c !== 'Flex' && c !== 'Grid' && c !== 'View' && c !== 'Item' && c !== 'Section' && c !== 'ActionGroup')
|
|
241
262
|
.map(([, specifier]) => specifier));
|
|
263
|
+
for (let s2Name of S2ComponentsToImport) {
|
|
264
|
+
importSpecifiers.add(t.importSpecifier(t.identifier(s2Name), t.identifier(s2Name)));
|
|
265
|
+
}
|
|
242
266
|
let existingImport = root.find(j.ImportDeclaration, {
|
|
243
267
|
source: { value: '@react-spectrum/s2' }
|
|
244
268
|
});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.default = transformContextualHelpTrigger;
|
|
37
|
+
const utils_1 = require("../../shared/utils");
|
|
38
|
+
const getComponents_1 = require("../../../getComponents");
|
|
39
|
+
const t = __importStar(require("@babel/types"));
|
|
40
|
+
let availableComponents = (0, getComponents_1.getComponents)();
|
|
41
|
+
/**
|
|
42
|
+
* Transforms ContextualHelpTrigger:
|
|
43
|
+
* - Rename ContextualHelpTrigger to UnavailableMenuItemTrigger.
|
|
44
|
+
* - Replace the old Dialog with ContextualHelpPopover.
|
|
45
|
+
*/
|
|
46
|
+
function transformContextualHelpTrigger(path) {
|
|
47
|
+
let program = path.findParent((p) => t.isProgram(p.node));
|
|
48
|
+
let localName = (0, utils_1.addComponentImport)(program, 'UnavailableMenuItemTrigger');
|
|
49
|
+
// replace ContextualHelpTrigger with UnavailableMenuItemTrigger
|
|
50
|
+
path.node.openingElement.name = t.jsxIdentifier(localName);
|
|
51
|
+
if (path.node.closingElement) {
|
|
52
|
+
path.node.closingElement.name = t.jsxIdentifier(localName);
|
|
53
|
+
}
|
|
54
|
+
// replace Dialog with ContextualHelpPopover
|
|
55
|
+
let dialog = path.node.children.filter((c) => t.isJSXElement(c))[1];
|
|
56
|
+
if (dialog && t.isJSXIdentifier(dialog.openingElement.name)) {
|
|
57
|
+
let name = (0, utils_1.getName)(path, dialog.openingElement.name);
|
|
58
|
+
if (name === 'Dialog') {
|
|
59
|
+
let contextualHelpPopover = availableComponents.has('ContextualHelpPopover')
|
|
60
|
+
? (0, utils_1.addComponentImport)(program, 'ContextualHelpPopover')
|
|
61
|
+
: 'ContextualHelpPopover';
|
|
62
|
+
dialog.openingElement.name = t.jsxIdentifier(contextualHelpPopover);
|
|
63
|
+
if (dialog.closingElement) {
|
|
64
|
+
dialog.closingElement.name = t.jsxIdentifier(contextualHelpPopover);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -10,16 +10,19 @@ const transforms_1 = require("../../shared/transforms");
|
|
|
10
10
|
* - If within Breadcrumbs: Update Item to be a Breadcrumb.
|
|
11
11
|
* - If within Picker: Update Item to be a PickerItem.
|
|
12
12
|
* - If within ComboBox: Update Item to be a ComboBoxItem.
|
|
13
|
+
* - If within ListView: Update Item to be a ListViewItem.
|
|
13
14
|
* - Update key to id (and keep key if rendered inside array.map).
|
|
14
15
|
*/
|
|
15
16
|
function transformItem(path) {
|
|
16
17
|
// Update Items based on parent collection component
|
|
17
18
|
(0, transforms_1.updateComponentWithinCollection)(path, { parentComponentName: 'Menu', newComponentName: 'MenuItem' });
|
|
18
19
|
(0, transforms_1.updateComponentWithinCollection)(path, { parentComponentName: 'ActionMenu', newComponentName: 'MenuItem' });
|
|
20
|
+
(0, transforms_1.updateComponentWithinCollection)(path, { parentComponentName: 'ContextualHelpTrigger', newComponentName: 'MenuItem' });
|
|
19
21
|
(0, transforms_1.updateComponentWithinCollection)(path, { parentComponentName: 'TagGroup', newComponentName: 'Tag' });
|
|
20
22
|
(0, transforms_1.updateComponentWithinCollection)(path, { parentComponentName: 'Breadcrumbs', newComponentName: 'Breadcrumb' });
|
|
21
23
|
(0, transforms_1.updateComponentWithinCollection)(path, { parentComponentName: 'Picker', newComponentName: 'PickerItem' });
|
|
22
24
|
(0, transforms_1.updateComponentWithinCollection)(path, { parentComponentName: 'ComboBox', newComponentName: 'ComboBoxItem' });
|
|
25
|
+
(0, transforms_1.updateComponentWithinCollection)(path, { parentComponentName: 'ListView', newComponentName: 'ListViewItem' });
|
|
23
26
|
// Comment if parent collection not detected
|
|
24
27
|
(0, transforms_1.commentIfParentCollectionNotDetected)(path);
|
|
25
28
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = transformListView;
|
|
4
|
+
const transforms_1 = require("../../shared/transforms");
|
|
5
|
+
/**
|
|
6
|
+
* Transforms ListView:
|
|
7
|
+
* - Comment out density (it has not been implemented yet).
|
|
8
|
+
* - Comment out dragAndDropHooks (it has not been implemented yet).
|
|
9
|
+
*/
|
|
10
|
+
function transformListView(path) {
|
|
11
|
+
(0, transforms_1.commentOutProp)(path, { propName: 'density' });
|
|
12
|
+
(0, transforms_1.commentOutProp)(path, { propName: 'dragAndDropHooks' });
|
|
13
|
+
}
|
|
@@ -680,7 +680,7 @@ function transformStyleProps(path, element) {
|
|
|
680
680
|
if (isDOMElement) {
|
|
681
681
|
let index = path.node.openingElement.attributes?.findIndex(a => a.type === 'JSXAttribute' && a.name.name === 'className');
|
|
682
682
|
if (index != null && index >= 0) {
|
|
683
|
-
classNameAttribute = path.get('openingElement').get('attributes')
|
|
683
|
+
classNameAttribute = path.get('openingElement').get('attributes')[index];
|
|
684
684
|
}
|
|
685
685
|
}
|
|
686
686
|
let valueToAST = (v) => {
|
|
@@ -346,9 +346,9 @@ function moveRenderPropsToChild(path, options) {
|
|
|
346
346
|
*/
|
|
347
347
|
function updateComponentWithinCollection(path, options) {
|
|
348
348
|
const { parentComponentName, newComponentName } = options;
|
|
349
|
-
// Collections currently implemented
|
|
350
|
-
// TODO: Add 'ActionGroup', 'ListBox'
|
|
351
|
-
const collectionItemParents = new Set(['Menu', 'ActionMenu', 'TagGroup', 'Breadcrumbs', 'Picker', 'ComboBox', 'ListBox', 'TabList', 'TabPanels', 'Collection']);
|
|
349
|
+
// Collections currently implemented.
|
|
350
|
+
// TODO: Add 'ActionGroup', 'ListBox' once implemented
|
|
351
|
+
const collectionItemParents = new Set(['Menu', 'ActionMenu', 'TagGroup', 'Breadcrumbs', 'Picker', 'ComboBox', 'ListBox', 'ListView', 'TabList', 'TabPanels', 'Collection', 'ContextualHelpTrigger']);
|
|
352
352
|
if (t.isJSXElement(path.node) &&
|
|
353
353
|
t.isJSXIdentifier(path.node.openingElement.name)) {
|
|
354
354
|
// Find closest parent collection component
|
|
@@ -377,7 +377,7 @@ function updateComponentWithinCollection(path, options) {
|
|
|
377
377
|
* Example: If they're declaring declaring Items somewhere above the collection.
|
|
378
378
|
*/
|
|
379
379
|
function commentIfParentCollectionNotDetected(path) {
|
|
380
|
-
const collectionItemParents = new Set(['Menu', 'ActionMenu', 'TagGroup', 'Breadcrumbs', 'Picker', 'ComboBox', 'ListBox', 'TabList', 'TabPanels', 'ActionGroup', 'ActionButtonGroup', 'ToggleButtonGroup', 'ListBox', 'ListView', 'Collection', 'SearchAutocomplete', 'Accordion', 'ActionBar', 'StepList']);
|
|
380
|
+
const collectionItemParents = new Set(['Menu', 'ActionMenu', 'TagGroup', 'Breadcrumbs', 'Picker', 'ComboBox', 'ListBox', 'TabList', 'TabPanels', 'ActionGroup', 'ActionButtonGroup', 'ToggleButtonGroup', 'ListBox', 'ListView', 'Collection', 'SearchAutocomplete', 'Accordion', 'ActionBar', 'StepList', 'ContextualHelpTrigger']);
|
|
381
381
|
if (t.isJSXElement(path.node)) {
|
|
382
382
|
// Find closest parent collection component
|
|
383
383
|
let closestParentCollection = path.findParent((p) => t.isJSXElement(p.node) &&
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-spectrum/codemods",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"source": "src/index.ts",
|
|
6
6
|
"bin": "dist/index.js",
|
|
@@ -24,9 +24,9 @@
|
|
|
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": "^1.
|
|
28
|
-
"@react-types/shared": "^3.
|
|
29
|
-
"@types/node": "^
|
|
27
|
+
"@react-spectrum/s2": "^1.2.0",
|
|
28
|
+
"@react-types/shared": "^3.33.1",
|
|
29
|
+
"@types/node": "^24",
|
|
30
30
|
"boxen": "^5.1.2",
|
|
31
31
|
"chalk": "^4.0.0",
|
|
32
32
|
"execa": "^5.1.1",
|
|
@@ -49,5 +49,5 @@
|
|
|
49
49
|
"publishConfig": {
|
|
50
50
|
"access": "public"
|
|
51
51
|
},
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "8df187370053aa35f553cb388ad670f65e1ab371"
|
|
53
53
|
}
|