@carbon/upgrade 11.24.0 → 11.25.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 +82 -1
- package/package.json +2 -2
- package/transforms/__testfixtures__/enable-v12-structured-list-visible-icons.input.js +275 -0
- package/transforms/__testfixtures__/enable-v12-structured-list-visible-icons.input.tsx +275 -0
- package/transforms/__testfixtures__/enable-v12-structured-list-visible-icons.output.js +275 -0
- package/transforms/__testfixtures__/enable-v12-structured-list-visible-icons.output.tsx +275 -0
- package/transforms/__tests__/enable-v12-structured-list-visible-icons-test.js +12 -0
- package/transforms/enable-v12-structured-list-visible-icons.js +166 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2025
|
|
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
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const STRUCTURED_LIST_WRAPPER = 'StructuredListWrapper';
|
|
10
|
+
const STRUCTURED_LIST_ROW = 'StructuredListRow';
|
|
11
|
+
const STRUCTURED_LIST_CELL = 'StructuredListCell';
|
|
12
|
+
const CHECKMARK_FILLED = 'CheckmarkFilled';
|
|
13
|
+
const ATTR_SELECTION = 'selection';
|
|
14
|
+
const ATTR_HEAD = 'head';
|
|
15
|
+
|
|
16
|
+
const defaultOptions = {
|
|
17
|
+
quote: 'single',
|
|
18
|
+
trailingComma: true,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
function transform(fileInfo, api, options) {
|
|
22
|
+
const j = api.jscodeshift;
|
|
23
|
+
const root = j(fileInfo.source);
|
|
24
|
+
const printOptions = options.printOptions || defaultOptions;
|
|
25
|
+
|
|
26
|
+
// Track function names used inside StructuredListWrapper
|
|
27
|
+
const functionsUsedInWrappers = new Set();
|
|
28
|
+
|
|
29
|
+
// First pass: Find all wrappers and identify functions used within them
|
|
30
|
+
findFunctionsUsedInWrappers(j, root, functionsUsedInWrappers);
|
|
31
|
+
|
|
32
|
+
// Second pass: Process identified functions and wrappers
|
|
33
|
+
transformSelectionWrappers(j, root, functionsUsedInWrappers);
|
|
34
|
+
|
|
35
|
+
return root.toSource(printOptions);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function findFunctionsUsedInWrappers(j, root, functionsUsedInWrappers) {
|
|
39
|
+
root
|
|
40
|
+
.find(j.JSXElement, {
|
|
41
|
+
openingElement: {
|
|
42
|
+
name: { name: STRUCTURED_LIST_WRAPPER },
|
|
43
|
+
attributes: (attrs) =>
|
|
44
|
+
attrs.some(
|
|
45
|
+
(attr) =>
|
|
46
|
+
attr.type === 'JSXAttribute' && attr.name.name === ATTR_SELECTION
|
|
47
|
+
),
|
|
48
|
+
},
|
|
49
|
+
})
|
|
50
|
+
.forEach((wrapper) => {
|
|
51
|
+
// Find all function calls within this wrapper
|
|
52
|
+
j(wrapper)
|
|
53
|
+
.find(j.JSXExpressionContainer)
|
|
54
|
+
.find(j.CallExpression)
|
|
55
|
+
.forEach((call) => {
|
|
56
|
+
// If it's a direct call to a function
|
|
57
|
+
if (call.node.callee.type === 'Identifier') {
|
|
58
|
+
const funcName = call.node.callee.name;
|
|
59
|
+
functionsUsedInWrappers.add(funcName);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function transformSelectionWrappers(j, root, functionsUsedInWrappers) {
|
|
66
|
+
transformIdentifiedFunctions(j, root, functionsUsedInWrappers);
|
|
67
|
+
|
|
68
|
+
// Then transform the wrappers themselves
|
|
69
|
+
root
|
|
70
|
+
.find(j.JSXElement, {
|
|
71
|
+
openingElement: {
|
|
72
|
+
name: { name: STRUCTURED_LIST_WRAPPER },
|
|
73
|
+
attributes: (attrs) =>
|
|
74
|
+
attrs.some(
|
|
75
|
+
(attr) =>
|
|
76
|
+
attr.type === 'JSXAttribute' && attr.name.name === ATTR_SELECTION
|
|
77
|
+
),
|
|
78
|
+
},
|
|
79
|
+
})
|
|
80
|
+
.forEach((wrapper) => {
|
|
81
|
+
// Transform direct rows in wrapper
|
|
82
|
+
j(wrapper)
|
|
83
|
+
.find(j.JSXElement, {
|
|
84
|
+
openingElement: { name: { name: STRUCTURED_LIST_ROW } },
|
|
85
|
+
})
|
|
86
|
+
.forEach((row) => transformRow(j, row));
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function transformIdentifiedFunctions(j, root, functionsUsedInWrappers) {
|
|
91
|
+
if (functionsUsedInWrappers.size === 0) return;
|
|
92
|
+
|
|
93
|
+
// Process regular function declarations
|
|
94
|
+
root
|
|
95
|
+
.find(j.FunctionDeclaration)
|
|
96
|
+
.filter(
|
|
97
|
+
(func) => func.node.id && functionsUsedInWrappers.has(func.node.id.name)
|
|
98
|
+
)
|
|
99
|
+
.forEach((func) => processNodeIfGeneratesRows(j, func));
|
|
100
|
+
|
|
101
|
+
// Process arrow functions in variable declarations
|
|
102
|
+
root
|
|
103
|
+
.find(j.VariableDeclarator)
|
|
104
|
+
.filter((decl) => {
|
|
105
|
+
// Must be named function in our set and be an arrow function
|
|
106
|
+
return (
|
|
107
|
+
decl.node.id &&
|
|
108
|
+
functionsUsedInWrappers.has(decl.node.id.name) &&
|
|
109
|
+
decl.node.init &&
|
|
110
|
+
decl.node.init.type === 'ArrowFunctionExpression'
|
|
111
|
+
);
|
|
112
|
+
})
|
|
113
|
+
.forEach((func) => processNodeIfGeneratesRows(j, func));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function processNodeIfGeneratesRows(j, func) {
|
|
117
|
+
// Find all StructuredListRow elements inside this function
|
|
118
|
+
j(func)
|
|
119
|
+
.find(j.JSXElement, {
|
|
120
|
+
openingElement: { name: { name: STRUCTURED_LIST_ROW } },
|
|
121
|
+
})
|
|
122
|
+
.forEach((row) => transformRow(j, row));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function transformRow(j, row) {
|
|
126
|
+
// Add selection prop to all rows if missing
|
|
127
|
+
const hasSelectionProp = row.node.openingElement.attributes.some(
|
|
128
|
+
(attr) => attr.type === 'JSXAttribute' && attr.name.name === ATTR_SELECTION
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
if (!hasSelectionProp) {
|
|
132
|
+
row.node.openingElement.attributes.push(
|
|
133
|
+
j.jsxAttribute(j.jsxIdentifier(ATTR_SELECTION))
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Only remove CheckmarkFilled cells from non-head rows
|
|
138
|
+
const hasHeadProp = row.node.openingElement.attributes.some(
|
|
139
|
+
(attr) => attr.type === 'JSXAttribute' && attr.name.name === ATTR_HEAD
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
if (!hasHeadProp) {
|
|
143
|
+
// Filter out cells with CheckmarkFilled
|
|
144
|
+
row.node.children = row.node.children.filter((child) => {
|
|
145
|
+
// Only check JSX elements that are StructuredListCell
|
|
146
|
+
if (
|
|
147
|
+
child.type !== 'JSXElement' ||
|
|
148
|
+
child.openingElement.name.name !== STRUCTURED_LIST_CELL
|
|
149
|
+
) {
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Check if cell contains CheckmarkFilled
|
|
154
|
+
return (
|
|
155
|
+
j(child)
|
|
156
|
+
.find(j.JSXElement, {
|
|
157
|
+
openingElement: { name: { name: CHECKMARK_FILLED } },
|
|
158
|
+
})
|
|
159
|
+
.size() === 0
|
|
160
|
+
);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
module.exports = transform;
|
|
166
|
+
module.exports.parser = 'tsx';
|