@carbon/upgrade 10.17.0-rc.0 → 11.0.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/cli.js +839 -520
- package/package.json +7 -7
- package/transforms/ARCHITECTURE.md +47 -0
- package/transforms/__testfixtures__/icons-react-size-prop-object-key.input.js +16 -0
- package/transforms/__testfixtures__/icons-react-size-prop-object-key.output.js +16 -0
- package/transforms/__testfixtures__/icons-react-size-prop-rename.input.js +44 -0
- package/transforms/__testfixtures__/icons-react-size-prop-rename.output.js +44 -0
- package/transforms/__testfixtures__/icons-react-size-prop-with-prop.input.js +19 -0
- package/transforms/__testfixtures__/icons-react-size-prop-with-prop.output.js +22 -0
- package/transforms/__testfixtures__/size-prop-update.input.js +143 -0
- package/transforms/__testfixtures__/size-prop-update.output.js +143 -0
- package/transforms/__testfixtures__/small-to-size-prop.input.js +11 -0
- package/transforms/__testfixtures__/small-to-size-prop.output.js +11 -0
- package/transforms/__testfixtures__/sort-prop-types.input.js +7 -0
- package/transforms/__testfixtures__/sort-prop-types.output.js +7 -0
- package/transforms/__testfixtures__/sort-prop-types2.input.js +7 -0
- package/transforms/__testfixtures__/sort-prop-types2.output.js +7 -0
- package/transforms/__testfixtures__/update-carbon-components-react-import-to-scoped.input.js +8 -0
- package/transforms/__testfixtures__/update-carbon-components-react-import-to-scoped.output.js +8 -0
- package/transforms/__tests__/icons-react-size-prop.js +64 -0
- package/transforms/__tests__/size-prop-update-test.js +12 -0
- package/transforms/__tests__/small-to-size-test.js +12 -0
- package/transforms/__tests__/sort-prop-types-test.js +13 -0
- package/transforms/__tests__/update-carbon-components-react-import-to-scoped.js +12 -0
- package/transforms/icons-react-size-prop.js +324 -0
- package/transforms/size-prop-update.js +140 -0
- package/transforms/small-to-size-prop.js +56 -0
- package/transforms/sort-prop-types.js +88 -0
- package/transforms/update-carbon-components-react-import-to-scoped.js +33 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2016, 2020
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
const { defineTest } = require('jscodeshift/dist/testUtils');
|
|
11
|
+
|
|
12
|
+
describe('icons-react-size-prop', () => {
|
|
13
|
+
let mock;
|
|
14
|
+
|
|
15
|
+
beforeEach(() => {
|
|
16
|
+
mock = jest.spyOn(console, 'log').mockImplementation(() => {});
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
afterEach(() => {
|
|
20
|
+
mock.mockRestore();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
defineTest(
|
|
24
|
+
__dirname,
|
|
25
|
+
'icons-react-size-prop',
|
|
26
|
+
{
|
|
27
|
+
printOptions: {
|
|
28
|
+
quote: 'single',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
'icons-react-size-prop-rename',
|
|
32
|
+
{
|
|
33
|
+
parser: 'babylon',
|
|
34
|
+
}
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
defineTest(
|
|
38
|
+
__dirname,
|
|
39
|
+
'icons-react-size-prop',
|
|
40
|
+
{
|
|
41
|
+
printOptions: {
|
|
42
|
+
quote: 'single',
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
'icons-react-size-prop-with-prop',
|
|
46
|
+
{
|
|
47
|
+
parser: 'babylon',
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
defineTest(
|
|
52
|
+
__dirname,
|
|
53
|
+
'icons-react-size-prop',
|
|
54
|
+
{
|
|
55
|
+
printOptions: {
|
|
56
|
+
quote: 'single',
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
'icons-react-size-prop-object-key',
|
|
60
|
+
{
|
|
61
|
+
parser: 'babylon',
|
|
62
|
+
}
|
|
63
|
+
);
|
|
64
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2016, 2020
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
const { defineTest } = require('jscodeshift/dist/testUtils');
|
|
11
|
+
|
|
12
|
+
defineTest(__dirname, 'size-prop-update');
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2016, 2020
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
const { defineTest } = require('jscodeshift/dist/testUtils');
|
|
11
|
+
|
|
12
|
+
defineTest(__dirname, 'small-to-size-prop');
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2016, 2020
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
const { defineTest } = require('jscodeshift/dist/testUtils');
|
|
11
|
+
|
|
12
|
+
defineTest(__dirname, 'sort-prop-types');
|
|
13
|
+
defineTest(__dirname, 'sort-prop-types', null, 'sort-prop-types2');
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2016, 2020
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
const { defineTest } = require('jscodeshift/dist/testUtils');
|
|
11
|
+
|
|
12
|
+
defineTest(__dirname, 'update-carbon-components-react-import-to-scoped');
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2016, 2020
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
const defaultOptions = {
|
|
11
|
+
quote: 'auto',
|
|
12
|
+
trailingComma: true,
|
|
13
|
+
};
|
|
14
|
+
const defaultSize = 16;
|
|
15
|
+
|
|
16
|
+
function transform(fileInfo, api, options) {
|
|
17
|
+
const printOptions = options.printOptions || defaultOptions;
|
|
18
|
+
const j = api.jscodeshift;
|
|
19
|
+
const root = j(fileInfo.source);
|
|
20
|
+
|
|
21
|
+
// Find all the import declarations that come from `@carbon/icons-react`
|
|
22
|
+
const matches = root.find(j.ImportDeclaration, {
|
|
23
|
+
source: {
|
|
24
|
+
value: '@carbon/icons-react',
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// If we cannot find any, then there is no work to do
|
|
29
|
+
if (matches.size() === 0) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (matches.size() > 1) {
|
|
34
|
+
throw new Error(
|
|
35
|
+
`Expected only one import to @carbon/icons-react, instead found: ` +
|
|
36
|
+
`${matches.size()} imports`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// For now, these icons are available under @carbon/icons-react/next
|
|
41
|
+
// TODO: remove in v11
|
|
42
|
+
matches.forEach((path) => {
|
|
43
|
+
path.get('source').get('value').replace('@carbon/icons-react');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Otherwise, we will get our import to icons and update the imported icons to
|
|
47
|
+
// use the new format
|
|
48
|
+
const iconsImport = matches.get();
|
|
49
|
+
const importSpecifiers = new Set();
|
|
50
|
+
|
|
51
|
+
// Iterate through each of the imported icons, get their size and name, and
|
|
52
|
+
// update the import and all matches in the file
|
|
53
|
+
j(iconsImport)
|
|
54
|
+
.find(j.ImportSpecifier)
|
|
55
|
+
.forEach((path) => {
|
|
56
|
+
const rootScope = path.scope;
|
|
57
|
+
const SIZE_REGEX = /(.+)(\d\d)$/g;
|
|
58
|
+
const { imported, local } = path.node;
|
|
59
|
+
const match = SIZE_REGEX.exec(imported.name);
|
|
60
|
+
|
|
61
|
+
if (match === null) {
|
|
62
|
+
throw new Error(`Expected to find size for: ${imported.name}`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const name = match[1];
|
|
66
|
+
const size = parseInt(match[2], 10);
|
|
67
|
+
|
|
68
|
+
if (isNaN(size)) {
|
|
69
|
+
throw new Error(`Unable to parse size for ${imported.name}`);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// If they renamed the icon in the import, use that as the local name
|
|
73
|
+
// import { IconName32 as CustomName } from '@carbon/icons-react';
|
|
74
|
+
const newBinding =
|
|
75
|
+
imported.name === local.name ? j.identifier(getSafeBinding()) : local;
|
|
76
|
+
|
|
77
|
+
function getSafeBinding() {
|
|
78
|
+
if (rootScope.declares(name)) {
|
|
79
|
+
return `${name}Icon`;
|
|
80
|
+
}
|
|
81
|
+
return name;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Update the imported binding from IconName32 to IconName. Only do this
|
|
85
|
+
// replacement once if we have imports of the same icon but in different
|
|
86
|
+
// sizes.
|
|
87
|
+
if (!importSpecifiers.has(newBinding.name)) {
|
|
88
|
+
importSpecifiers.add(newBinding.name);
|
|
89
|
+
j(path).replaceWith(j.importSpecifier(j.identifier(name), newBinding));
|
|
90
|
+
} else {
|
|
91
|
+
j(path).remove();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Finally, find all instances where we refer to this import and update
|
|
95
|
+
// its binding
|
|
96
|
+
root
|
|
97
|
+
.find(j.Identifier, { name: local.name })
|
|
98
|
+
.filter((path) => {
|
|
99
|
+
const { node: parent } = path.parent;
|
|
100
|
+
|
|
101
|
+
if (
|
|
102
|
+
j.MemberExpression.check(parent) &&
|
|
103
|
+
parent.property === path.node &&
|
|
104
|
+
!parent.computed
|
|
105
|
+
) {
|
|
106
|
+
// obj.oldName
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (
|
|
111
|
+
j.ObjectProperty.check(parent) &&
|
|
112
|
+
parent.key === path.node &&
|
|
113
|
+
!parent.computed
|
|
114
|
+
) {
|
|
115
|
+
// { oldName: 3 }
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (
|
|
120
|
+
j.MethodDefinition.check(parent) &&
|
|
121
|
+
parent.key === path.node &&
|
|
122
|
+
!parent.computed
|
|
123
|
+
) {
|
|
124
|
+
// class A { oldName() {} }
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (
|
|
129
|
+
j.ClassProperty.check(parent) &&
|
|
130
|
+
parent.key === path.node &&
|
|
131
|
+
!parent.computed
|
|
132
|
+
) {
|
|
133
|
+
// class A { oldName = 3 }
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (
|
|
138
|
+
j.JSXAttribute.check(parent) &&
|
|
139
|
+
parent.name === path.node &&
|
|
140
|
+
!parent.computed
|
|
141
|
+
) {
|
|
142
|
+
// <Foo oldName={oldName} />
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
return true;
|
|
146
|
+
})
|
|
147
|
+
.forEach((path) => {
|
|
148
|
+
let scope = path.scope;
|
|
149
|
+
while (scope && scope !== rootScope) {
|
|
150
|
+
// If a scope already declares this binding, return early as it does
|
|
151
|
+
// not relate to our icon import
|
|
152
|
+
if (scope.declares(local.name)) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
scope = scope.parent;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (!scope) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const { node: parent } = path.parent;
|
|
163
|
+
|
|
164
|
+
// Replace the identifier name with the new binding name. If the parent
|
|
165
|
+
// node is an `ImportSpecifier`, we won't do this replacement as it is
|
|
166
|
+
// handled above
|
|
167
|
+
if (!j.ImportSpecifier.check(parent)) {
|
|
168
|
+
path.replace(newBinding);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// If our identifier is inside of a JSXOpeningElement, then we need to
|
|
172
|
+
// check to see if we need to add in the `size` prop that is now
|
|
173
|
+
// needed
|
|
174
|
+
if (j.JSXOpeningElement.check(parent) && size !== defaultSize) {
|
|
175
|
+
parent.attributes.unshift(
|
|
176
|
+
j.jsxAttribute(
|
|
177
|
+
j.jsxIdentifier('size'),
|
|
178
|
+
j.jsxExpressionContainer(j.numericLiteral(size))
|
|
179
|
+
)
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Handle cases where the icon is referred to in an object, for
|
|
184
|
+
// example:
|
|
185
|
+
//
|
|
186
|
+
// from:
|
|
187
|
+
// const alias = { name: IconName24 };
|
|
188
|
+
//
|
|
189
|
+
// to:
|
|
190
|
+
// const alias = { name: (props) => <IconName size={24} {...props} /> };
|
|
191
|
+
//
|
|
192
|
+
// Since the `size` information needs to be provided, otherwise the
|
|
193
|
+
// default size will be used
|
|
194
|
+
if (j.ObjectProperty.check(parent)) {
|
|
195
|
+
let replacement = null;
|
|
196
|
+
|
|
197
|
+
// map to React.createElement instead of using as the JSX Opening
|
|
198
|
+
// Element directly
|
|
199
|
+
if (newBinding.name[0] === newBinding.name[0].toLowerCase()) {
|
|
200
|
+
// Builds up this structure:
|
|
201
|
+
// (props) => React.createElement(iconName, {
|
|
202
|
+
// size: 20,
|
|
203
|
+
// ...props,
|
|
204
|
+
// });
|
|
205
|
+
replacement = j.arrowFunctionExpression(
|
|
206
|
+
[j.identifier('props')],
|
|
207
|
+
j.callExpression(
|
|
208
|
+
j.memberExpression(
|
|
209
|
+
j.identifier('React'),
|
|
210
|
+
j.identifier('createElement')
|
|
211
|
+
),
|
|
212
|
+
[
|
|
213
|
+
newBinding,
|
|
214
|
+
j.objectExpression([
|
|
215
|
+
j.objectProperty(
|
|
216
|
+
j.identifier('size'),
|
|
217
|
+
j.numericLiteral(size)
|
|
218
|
+
),
|
|
219
|
+
j.spreadElement(j.identifier('props')),
|
|
220
|
+
]),
|
|
221
|
+
]
|
|
222
|
+
)
|
|
223
|
+
);
|
|
224
|
+
} else {
|
|
225
|
+
// Build up this structure:
|
|
226
|
+
// (props) => <IconName size={20} {...props} />
|
|
227
|
+
replacement = j.arrowFunctionExpression(
|
|
228
|
+
[j.identifier('props')],
|
|
229
|
+
j.jsxElement(
|
|
230
|
+
j.jsxOpeningElement(
|
|
231
|
+
j.jsxIdentifier(newBinding.name),
|
|
232
|
+
[
|
|
233
|
+
j.jsxAttribute(
|
|
234
|
+
j.jsxIdentifier('size'),
|
|
235
|
+
j.jsxExpressionContainer(j.numericLiteral(size))
|
|
236
|
+
),
|
|
237
|
+
j.jsxSpreadAttribute(j.identifier('props')),
|
|
238
|
+
],
|
|
239
|
+
true
|
|
240
|
+
)
|
|
241
|
+
)
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
warn(fileInfo.path);
|
|
246
|
+
|
|
247
|
+
// Sometimes consumers will use the icon module name as a shorthand
|
|
248
|
+
// in an object property.
|
|
249
|
+
//
|
|
250
|
+
// Input:
|
|
251
|
+
// const o = { Add16, Add32 };
|
|
252
|
+
// Output:
|
|
253
|
+
// const o = { Add16: Add, Add32: (props) => <Add size={32} {...props} />
|
|
254
|
+
if (
|
|
255
|
+
parent.key.name !== newBinding.name &&
|
|
256
|
+
parent.shorthand === true
|
|
257
|
+
) {
|
|
258
|
+
path.parent.get('shorthand').replace(false);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (size !== defaultSize) {
|
|
262
|
+
path.parent.get('value').replace(replacement);
|
|
263
|
+
} else {
|
|
264
|
+
path.parent.get('value').replace(newBinding);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Support `renderIcon` style props where you pass in an Icon by itself
|
|
269
|
+
// to the prop
|
|
270
|
+
//
|
|
271
|
+
// from:
|
|
272
|
+
// <Component renderIcon={Icon24} />
|
|
273
|
+
//
|
|
274
|
+
// to:
|
|
275
|
+
// <Component renderIcon={(props) => <Icon size={24} {...props} />} />
|
|
276
|
+
if (j.JSXExpressionContainer.check(parent) && size !== defaultSize) {
|
|
277
|
+
warn(fileInfo.path);
|
|
278
|
+
path.parentPath.replace(
|
|
279
|
+
j.jsxExpressionContainer(
|
|
280
|
+
j.arrowFunctionExpression(
|
|
281
|
+
[j.identifier('props')],
|
|
282
|
+
j.jsxElement(
|
|
283
|
+
j.jsxOpeningElement(
|
|
284
|
+
j.jsxIdentifier(path.node.name),
|
|
285
|
+
[
|
|
286
|
+
j.jsxAttribute(
|
|
287
|
+
j.jsxIdentifier('size'),
|
|
288
|
+
j.jsxExpressionContainer(j.numericLiteral(size))
|
|
289
|
+
),
|
|
290
|
+
j.jsxSpreadAttribute(j.identifier('props')),
|
|
291
|
+
],
|
|
292
|
+
true
|
|
293
|
+
)
|
|
294
|
+
)
|
|
295
|
+
)
|
|
296
|
+
)
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
return root.toSource(printOptions);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
const manualCheckWarning = `[carbon] ${'='.repeat(71)}
|
|
306
|
+
We have updated the file: %s to the new icon API.
|
|
307
|
+
|
|
308
|
+
However, it may be that this update is missing a \`ref\` on the prop where the
|
|
309
|
+
icon is used. Please make sure to verify that this update is correct.
|
|
310
|
+
|
|
311
|
+
For more information, check out our migration guide: https://bit.ly/3o2vVQW\n`;
|
|
312
|
+
|
|
313
|
+
const files = new Set();
|
|
314
|
+
|
|
315
|
+
function warn(filepath) {
|
|
316
|
+
if (files.has(filepath)) {
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
files.add(filepath);
|
|
321
|
+
console.log(manualCheckWarning, filepath);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
module.exports = transform;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2016, 2020
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
const defaultOptions = {
|
|
11
|
+
quote: 'auto',
|
|
12
|
+
trailingComma: true,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
function transform(fileInfo, api, options) {
|
|
16
|
+
const printOptions = options.printOptions || defaultOptions;
|
|
17
|
+
const j = api.jscodeshift;
|
|
18
|
+
const root = j(fileInfo.source);
|
|
19
|
+
|
|
20
|
+
function replacePropForComponent(name) {
|
|
21
|
+
// Multiselect.Filterable has a different AST structure, so we need to
|
|
22
|
+
// adjust the query to find it properly. If it is not 'Filterable', we use
|
|
23
|
+
// the default query
|
|
24
|
+
let isFilterable = name === 'Filterable';
|
|
25
|
+
let openingElementQuery = {
|
|
26
|
+
name: {
|
|
27
|
+
name,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
if (isFilterable) {
|
|
31
|
+
openingElementQuery = {
|
|
32
|
+
name: {
|
|
33
|
+
object: {
|
|
34
|
+
name: 'MultiSelect',
|
|
35
|
+
},
|
|
36
|
+
property: {
|
|
37
|
+
name: name,
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
root
|
|
43
|
+
.find(j.JSXOpeningElement, openingElementQuery)
|
|
44
|
+
.forEach((openingElement) => {
|
|
45
|
+
// Multiselect.Filterable has a different AST structure, so the name is located differently
|
|
46
|
+
const { name } = isFilterable
|
|
47
|
+
? openingElement.node.name.property
|
|
48
|
+
: openingElement.node.name;
|
|
49
|
+
|
|
50
|
+
// Some components were originally set to `xl`, but are being reduced to `lg`
|
|
51
|
+
const downsizedComponents = [
|
|
52
|
+
'Accordion',
|
|
53
|
+
'ComboBox',
|
|
54
|
+
'ContentSwitcher',
|
|
55
|
+
'DatePickerInput',
|
|
56
|
+
'Dropdown',
|
|
57
|
+
'MultiSelect',
|
|
58
|
+
'Filterable',
|
|
59
|
+
'NumberInput',
|
|
60
|
+
'OverflowMenu',
|
|
61
|
+
'Search',
|
|
62
|
+
'Select',
|
|
63
|
+
'TextInput',
|
|
64
|
+
'TimePicker',
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
const isDownsized = downsizedComponents.includes(name);
|
|
68
|
+
|
|
69
|
+
j(openingElement)
|
|
70
|
+
.find(j.JSXAttribute, {
|
|
71
|
+
name: {
|
|
72
|
+
name: 'size',
|
|
73
|
+
},
|
|
74
|
+
})
|
|
75
|
+
.forEach((path) => {
|
|
76
|
+
j(path).replaceWith((nodePath) => {
|
|
77
|
+
const { node } = nodePath;
|
|
78
|
+
const { value } = node.value;
|
|
79
|
+
|
|
80
|
+
switch (value) {
|
|
81
|
+
case 'compact':
|
|
82
|
+
node.value.value = 'xs';
|
|
83
|
+
return node;
|
|
84
|
+
case 'short':
|
|
85
|
+
case 'small':
|
|
86
|
+
node.value.value = 'sm';
|
|
87
|
+
return node;
|
|
88
|
+
case 'field':
|
|
89
|
+
node.value.value = 'md';
|
|
90
|
+
return node;
|
|
91
|
+
case 'default':
|
|
92
|
+
case 'normal':
|
|
93
|
+
node.value.value = 'lg';
|
|
94
|
+
return node;
|
|
95
|
+
case 'tall':
|
|
96
|
+
case 'lg':
|
|
97
|
+
node.value.value = isDownsized ? 'md' : 'xl';
|
|
98
|
+
return node;
|
|
99
|
+
case 'xl':
|
|
100
|
+
node.value.value = isDownsized ? 'lg' : '2xl';
|
|
101
|
+
return node;
|
|
102
|
+
}
|
|
103
|
+
return node;
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const components = [
|
|
110
|
+
'Accordion',
|
|
111
|
+
'Button',
|
|
112
|
+
'ComboBox',
|
|
113
|
+
'ContentSwitcher',
|
|
114
|
+
'DataTable',
|
|
115
|
+
'DatePickerInput',
|
|
116
|
+
'Dropdown',
|
|
117
|
+
'FileUploader',
|
|
118
|
+
'FileUploaderButton',
|
|
119
|
+
'FileUploaderDropContainer',
|
|
120
|
+
'FileUploaderItem',
|
|
121
|
+
'MultiSelect',
|
|
122
|
+
'Filterable',
|
|
123
|
+
'NumberInput',
|
|
124
|
+
'OverflowMenu',
|
|
125
|
+
'Search',
|
|
126
|
+
'Select',
|
|
127
|
+
'Table',
|
|
128
|
+
'TableToolbar',
|
|
129
|
+
'TextInput',
|
|
130
|
+
'TimePicker',
|
|
131
|
+
];
|
|
132
|
+
|
|
133
|
+
for (const component of components) {
|
|
134
|
+
replacePropForComponent(component);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return root.toSource(printOptions);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
module.exports = transform;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2016, 2020
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
const defaultOptions = {
|
|
11
|
+
quote: 'auto',
|
|
12
|
+
trailingComma: true,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
function transform(fileInfo, api, options) {
|
|
16
|
+
const printOptions = options.printOptions || defaultOptions;
|
|
17
|
+
const j = api.jscodeshift;
|
|
18
|
+
const root = j(fileInfo.source);
|
|
19
|
+
|
|
20
|
+
const sizeProp = j.jsxAttribute(j.jsxIdentifier('size'), j.literal('sm'));
|
|
21
|
+
|
|
22
|
+
function replacePropForComponent(name) {
|
|
23
|
+
root
|
|
24
|
+
.find(j.JSXOpeningElement, {
|
|
25
|
+
name: {
|
|
26
|
+
name,
|
|
27
|
+
},
|
|
28
|
+
})
|
|
29
|
+
.forEach((openingElement) => {
|
|
30
|
+
j(openingElement)
|
|
31
|
+
.find(j.JSXAttribute, {
|
|
32
|
+
name: {
|
|
33
|
+
name: 'small',
|
|
34
|
+
},
|
|
35
|
+
})
|
|
36
|
+
.forEach((path) => {
|
|
37
|
+
j(path).replaceWith(sizeProp);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const components = [
|
|
43
|
+
'Button',
|
|
44
|
+
'DangerButton',
|
|
45
|
+
'PrimaryButton',
|
|
46
|
+
'SecondaryButton',
|
|
47
|
+
'Search',
|
|
48
|
+
];
|
|
49
|
+
for (const component of components) {
|
|
50
|
+
replacePropForComponent(component);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return root.toSource(printOptions);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
module.exports = transform;
|