@kaizen/components 1.80.1 → 1.80.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.
- package/codemods/README.md +12 -0
- package/codemods/renameV2ComponentImportsAndUsages/index.ts +19 -0
- package/codemods/renameV2ComponentImportsAndUsages/renameV2ComponentImportsAndUsages.spec.ts +390 -0
- package/codemods/renameV2ComponentImportsAndUsages/renameV2ComponentImportsAndUsages.ts +230 -0
- package/codemods/utils/index.ts +1 -0
- package/codemods/utils/updateJsxElementTagName.spec.ts +129 -0
- package/codemods/utils/updateJsxElementTagName.ts +56 -0
- package/codemods/utils/updateKaioImports.spec.ts +82 -0
- package/codemods/utils/updateKaioImports.ts +16 -7
- package/dist/cjs/src/__alpha__/SingleSelect/SingleSelect.cjs +69 -16
- package/dist/cjs/src/__alpha__/SingleSelect/context/SingleSelectContext.cjs +13 -0
- package/dist/cjs/src/__alpha__/SingleSelect/subcomponents/Popover/Popover.cjs +54 -0
- package/dist/cjs/src/__alpha__/SingleSelect/{SingleSelect.module.css.cjs → subcomponents/Popover/Popover.module.css.cjs} +1 -1
- package/dist/cjs/src/__alpha__/SingleSelect/subcomponents/Popover/utils/usePopoverPositioning.cjs +94 -0
- package/dist/cjs/src/__alpha__/SingleSelect/subcomponents/Popover/utils/usePositioningStyles.cjs +69 -0
- package/dist/cjs/src/__alpha__/SingleSelect/subcomponents/Popover/utils/useSupportsAnchorPositioning.cjs +12 -0
- package/dist/cjs/src/__alpha__/SingleSelect/subcomponents/Trigger/Trigger.cjs +41 -5
- package/dist/esm/src/__alpha__/SingleSelect/SingleSelect.mjs +60 -10
- package/dist/esm/src/__alpha__/SingleSelect/context/SingleSelectContext.mjs +10 -0
- package/dist/esm/src/__alpha__/SingleSelect/subcomponents/Popover/Popover.mjs +49 -0
- package/dist/esm/src/__alpha__/SingleSelect/subcomponents/Popover/Popover.module.css.mjs +4 -0
- package/dist/esm/src/__alpha__/SingleSelect/subcomponents/Popover/utils/usePopoverPositioning.mjs +92 -0
- package/dist/esm/src/__alpha__/SingleSelect/subcomponents/Popover/utils/usePositioningStyles.mjs +67 -0
- package/dist/esm/src/__alpha__/SingleSelect/subcomponents/Popover/utils/useSupportsAnchorPositioning.mjs +10 -0
- package/dist/esm/src/__alpha__/SingleSelect/subcomponents/Trigger/Trigger.mjs +43 -7
- package/dist/styles.css +8958 -8934
- package/dist/types/__alpha__/SingleSelect/SingleSelect.d.ts +7 -9
- package/dist/types/__alpha__/SingleSelect/context/SingleSelectContext.d.ts +12 -0
- package/dist/types/__alpha__/SingleSelect/context/index.d.ts +1 -0
- package/dist/types/__alpha__/SingleSelect/subcomponents/List/List.d.ts +2 -1
- package/dist/types/__alpha__/SingleSelect/subcomponents/ListItem/ListItem.d.ts +2 -1
- package/dist/types/__alpha__/SingleSelect/subcomponents/ListSection/ListSection.d.ts +2 -1
- package/dist/types/__alpha__/SingleSelect/subcomponents/Popover/Popover.d.ts +6 -0
- package/dist/types/__alpha__/SingleSelect/subcomponents/Popover/index.d.ts +1 -0
- package/dist/types/__alpha__/SingleSelect/subcomponents/Popover/utils/index.d.ts +2 -0
- package/dist/types/__alpha__/SingleSelect/subcomponents/Popover/utils/usePopoverPositioning.d.ts +4 -0
- package/dist/types/__alpha__/SingleSelect/subcomponents/Popover/utils/usePositioningStyles.d.ts +4 -0
- package/dist/types/__alpha__/SingleSelect/subcomponents/Popover/utils/useSupportsAnchorPositioning.d.ts +1 -0
- package/dist/types/__alpha__/SingleSelect/subcomponents/Trigger/Trigger.d.ts +2 -1
- package/dist/types/__alpha__/SingleSelect/subcomponents/index.d.ts +1 -0
- package/dist/types/__alpha__/SingleSelect/types.d.ts +45 -0
- package/package.json +4 -4
- package/src/Notification/GlobalNotification/_docs/GlobalNotification.stickersheet.stories.tsx +2 -1
- package/src/Notification/InlineNotification/_docs/InlineNotification.stickersheet.stories.tsx +4 -1
- package/src/Notification/ToastNotification/_docs/ToastNotification.stickersheet.stories.tsx +20 -6
- package/src/Notification/subcomponents/GenericNotification/_mixins.scss +5 -3
- package/src/__alpha__/SingleSelect/SingleSelect.tsx +79 -14
- package/src/__alpha__/SingleSelect/_docs/SingleSelect.mdx +5 -2
- package/src/__alpha__/SingleSelect/_docs/SingleSelect.spec.stories.tsx +100 -0
- package/src/__alpha__/SingleSelect/_docs/SingleSelect.stickersheet.stories.tsx +4 -4
- package/src/__alpha__/SingleSelect/_docs/SingleSelect.stories.tsx +21 -2
- package/src/__alpha__/SingleSelect/context/SingleSelectContext.tsx +21 -0
- package/src/__alpha__/SingleSelect/context/index.ts +1 -0
- package/src/__alpha__/SingleSelect/subcomponents/List/List.module.css +0 -1
- package/src/__alpha__/SingleSelect/subcomponents/List/List.tsx +2 -1
- package/src/__alpha__/SingleSelect/subcomponents/ListItem/ListItem.module.css +7 -0
- package/src/__alpha__/SingleSelect/subcomponents/ListItem/ListItem.tsx +2 -1
- package/src/__alpha__/SingleSelect/subcomponents/ListSection/ListSection.tsx +3 -1
- package/src/__alpha__/SingleSelect/subcomponents/Popover/Popover.module.css +24 -0
- package/src/__alpha__/SingleSelect/subcomponents/Popover/Popover.tsx +54 -0
- package/src/__alpha__/SingleSelect/subcomponents/Popover/index.ts +1 -0
- package/src/__alpha__/SingleSelect/subcomponents/Popover/utils/index.ts +2 -0
- package/src/__alpha__/SingleSelect/subcomponents/Popover/utils/usePopoverPositioning.ts +108 -0
- package/src/__alpha__/SingleSelect/subcomponents/Popover/utils/usePositioningStyles.ts +75 -0
- package/src/__alpha__/SingleSelect/subcomponents/Popover/utils/useSupportsAnchorPositioning.ts +13 -0
- package/src/__alpha__/SingleSelect/subcomponents/Trigger/Trigger.module.css +1 -0
- package/src/__alpha__/SingleSelect/subcomponents/Trigger/Trigger.tsx +29 -7
- package/src/__alpha__/SingleSelect/subcomponents/index.ts +1 -0
- package/src/__alpha__/SingleSelect/types.ts +58 -0
- package/dist/esm/src/__alpha__/SingleSelect/SingleSelect.module.css.mjs +0 -4
- package/src/__alpha__/SingleSelect/SingleSelect.module.css +0 -9
- package/src/__alpha__/SingleSelect/SingleSelect.spec.tsx +0 -26
package/codemods/README.md
CHANGED
|
@@ -25,6 +25,18 @@ pnpm kaizen-codemod src migrateWellVariantToColor
|
|
|
25
25
|
|
|
26
26
|
## Available codemods
|
|
27
27
|
|
|
28
|
+
### `renameV2ComponentImportsAndUsages`
|
|
29
|
+
|
|
30
|
+
Released in `1.80.3`
|
|
31
|
+
|
|
32
|
+
Renames component imports and usages for the v2 release:
|
|
33
|
+
|
|
34
|
+
- `Select` (from `@kaizen/components/next`) → `SingleSelect`
|
|
35
|
+
- `LikertScaleLegacy` → `LikertScale`
|
|
36
|
+
- `TitleBlockZen` → `TitleBlock`
|
|
37
|
+
|
|
38
|
+
Also renames corresponding Props types (e.g., `SelectProps` → `SingleSelectProps`).
|
|
39
|
+
|
|
28
40
|
### `migrateBrandMomentMoodToVariant`
|
|
29
41
|
|
|
30
42
|
Released in `1.58.0`
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { transformComponentsInDir } from '../utils'
|
|
2
|
+
import { renameV2ComponentImportsAndUsages } from './renameV2ComponentImportsAndUsages'
|
|
3
|
+
|
|
4
|
+
const run = (): void => {
|
|
5
|
+
console.log('~(-_- ~) Running V2 component renaming (~ -_-)~')
|
|
6
|
+
|
|
7
|
+
const targetDir = process.argv[2]
|
|
8
|
+
if (!targetDir) {
|
|
9
|
+
process.exit(1)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
transformComponentsInDir(
|
|
13
|
+
targetDir,
|
|
14
|
+
['Select', 'LikertScaleLegacy', 'TitleBlockZen'],
|
|
15
|
+
(tagNames) => [renameV2ComponentImportsAndUsages(tagNames)],
|
|
16
|
+
)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
run()
|
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
import { parseJsx } from '../__tests__/utils'
|
|
2
|
+
import {
|
|
3
|
+
getKaioTagNamesMapByComponentName,
|
|
4
|
+
printAst,
|
|
5
|
+
transformSource,
|
|
6
|
+
type TransformSourceArgs,
|
|
7
|
+
} from '../utils'
|
|
8
|
+
import { renameV2ComponentImportsAndUsages } from './renameV2ComponentImportsAndUsages'
|
|
9
|
+
|
|
10
|
+
const transformComponents = (sourceFile: TransformSourceArgs['sourceFile']): string => {
|
|
11
|
+
const kaioTagNamesMap = getKaioTagNamesMapByComponentName(sourceFile, [
|
|
12
|
+
'Select',
|
|
13
|
+
'LikertScaleLegacy',
|
|
14
|
+
'TitleBlockZen',
|
|
15
|
+
])
|
|
16
|
+
return transformSource({
|
|
17
|
+
sourceFile,
|
|
18
|
+
transformers: [renameV2ComponentImportsAndUsages(kaioTagNamesMap!)],
|
|
19
|
+
})
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
describe('renameV2ComponentImportsAndUsages', () => {
|
|
23
|
+
describe('Select -> SigleSelect', () => {
|
|
24
|
+
it('should rename Select import from next to SingleSelect', () => {
|
|
25
|
+
const inputAst = parseJsx(`import { Select } from "@kaizen/components/next"`)
|
|
26
|
+
const expectedAst = parseJsx(`import { SingleSelect } from "@kaizen/components"`)
|
|
27
|
+
|
|
28
|
+
const result = transformComponents(inputAst)
|
|
29
|
+
expect(result).toBe(printAst(expectedAst))
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('should rename Select import from future to SingleSelect', () => {
|
|
33
|
+
const inputAst = parseJsx(`import { Select } from "@kaizen/components/future"`)
|
|
34
|
+
const expectedAst = parseJsx(`import { SingleSelect } from "@kaizen/components"`)
|
|
35
|
+
|
|
36
|
+
const result = transformComponents(inputAst)
|
|
37
|
+
expect(result).toBe(printAst(expectedAst))
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it('should rename Select JSX element to SingleSelect', () => {
|
|
41
|
+
const inputAst = parseJsx(`
|
|
42
|
+
import { Select } from "@kaizen/components/next"
|
|
43
|
+
|
|
44
|
+
const MyComponent = () => <Select />
|
|
45
|
+
`)
|
|
46
|
+
const expectedAst = parseJsx(`
|
|
47
|
+
import { SingleSelect } from "@kaizen/components"
|
|
48
|
+
|
|
49
|
+
const MyComponent = () => <SingleSelect />
|
|
50
|
+
`)
|
|
51
|
+
|
|
52
|
+
const result = transformComponents(inputAst)
|
|
53
|
+
expect(result).toBe(printAst(expectedAst))
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('should rename Select[Type] to SingleSelect[Type] from future module', () => {
|
|
57
|
+
const inputAst = parseJsx(`
|
|
58
|
+
import type { SelectProps, SelectOption, SelectOptionGroup, SelectItem, SelectOptionNode, SelectOptionGroupNode, SelectItemNode } from "@kaizen/components/future"
|
|
59
|
+
`)
|
|
60
|
+
const expectedAst = parseJsx(`
|
|
61
|
+
import type { SingleSelectProps, SingleSelectOption, SingleSelectOptionGroup, SingleSelectItem, SingleSelectOptionNode, SingleSelectOptionGroupNode, SingleSelectItemNode } from "@kaizen/components"
|
|
62
|
+
`)
|
|
63
|
+
|
|
64
|
+
const result = transformComponents(inputAst)
|
|
65
|
+
expect(result).toBe(printAst(expectedAst))
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it('should rename Select[Type] to SingleSelect[Type] from next module', () => {
|
|
69
|
+
const inputAst = parseJsx(`
|
|
70
|
+
import type { SelectProps, SelectOption, SelectOptionGroup, SelectItem, SelectOptionNode, SelectOptionGroupNode, SelectItemNode } from "@kaizen/components/next"
|
|
71
|
+
`)
|
|
72
|
+
const expectedAst = parseJsx(`
|
|
73
|
+
import type { SingleSelectProps, SingleSelectOption, SingleSelectOptionGroup, SingleSelectItem, SingleSelectOptionNode, SingleSelectOptionGroupNode, SingleSelectItemNode } from "@kaizen/components"
|
|
74
|
+
`)
|
|
75
|
+
|
|
76
|
+
const result = transformComponents(inputAst)
|
|
77
|
+
expect(result).toBe(printAst(expectedAst))
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('should preserve type-only import declaration style', () => {
|
|
81
|
+
const inputAst = parseJsx(`
|
|
82
|
+
import type { SelectOption } from "@kaizen/components/next"
|
|
83
|
+
|
|
84
|
+
const option: SelectOption = { label: 'Test', value: 'test' }
|
|
85
|
+
`)
|
|
86
|
+
const expectedAst = parseJsx(`
|
|
87
|
+
import type { SingleSelectOption } from "@kaizen/components"
|
|
88
|
+
|
|
89
|
+
const option: SingleSelectOption = { label: 'Test', value: 'test' }
|
|
90
|
+
`)
|
|
91
|
+
|
|
92
|
+
const result = transformComponents(inputAst)
|
|
93
|
+
expect(result).toBe(printAst(expectedAst))
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
it('should preserve inline type import style', () => {
|
|
97
|
+
const inputAst = parseJsx(`
|
|
98
|
+
import { type SelectItem, Button } from "@kaizen/components/next"
|
|
99
|
+
|
|
100
|
+
const item: SelectItem = { label: 'Test', value: 'test' }
|
|
101
|
+
`)
|
|
102
|
+
const expectedAst = parseJsx(`
|
|
103
|
+
import { Button } from "@kaizen/components/next"
|
|
104
|
+
import type { SingleSelectItem } from "@kaizen/components"
|
|
105
|
+
|
|
106
|
+
const item: SingleSelectItem = { label: 'Test', value: 'test' }
|
|
107
|
+
`)
|
|
108
|
+
|
|
109
|
+
const result = transformComponents(inputAst)
|
|
110
|
+
expect(result).toBe(printAst(expectedAst))
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
it('should handle mixed imports with Select types and other components', () => {
|
|
114
|
+
const inputAst = parseJsx(`
|
|
115
|
+
import { Select, Button } from "@kaizen/components/next"
|
|
116
|
+
import type { SelectProps, SelectOption } from "@kaizen/components/future"
|
|
117
|
+
|
|
118
|
+
const MyComponent = (props: SelectProps) => (
|
|
119
|
+
<>
|
|
120
|
+
<Select />
|
|
121
|
+
<Button>Click me</Button>
|
|
122
|
+
</>
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
const option: SelectOption = { label: 'Test', value: 'test' }
|
|
126
|
+
`)
|
|
127
|
+
const expectedAst = parseJsx(`
|
|
128
|
+
import { Button } from "@kaizen/components/next"
|
|
129
|
+
import { SingleSelect, type SingleSelectProps, type SingleSelectOption } from "@kaizen/components"
|
|
130
|
+
|
|
131
|
+
const MyComponent = (props: SingleSelectProps) => (
|
|
132
|
+
<>
|
|
133
|
+
<SingleSelect />
|
|
134
|
+
<Button>Click me</Button>
|
|
135
|
+
</>
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
const option: SingleSelectOption = { label: 'Test', value: 'test' }
|
|
139
|
+
`)
|
|
140
|
+
|
|
141
|
+
const result = transformComponents(inputAst)
|
|
142
|
+
expect(result).toBe(printAst(expectedAst))
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
it('should handle Select with opening and closing tags', () => {
|
|
146
|
+
const inputAst = parseJsx(`
|
|
147
|
+
import { Select } from "@kaizen/components/next"
|
|
148
|
+
|
|
149
|
+
const MyComponent = () => (
|
|
150
|
+
<Select>
|
|
151
|
+
<option value="1">Option 1</option>
|
|
152
|
+
</Select>
|
|
153
|
+
)
|
|
154
|
+
`)
|
|
155
|
+
const expectedAst = parseJsx(`
|
|
156
|
+
import { SingleSelect } from "@kaizen/components"
|
|
157
|
+
|
|
158
|
+
const MyComponent = () => (
|
|
159
|
+
<SingleSelect>
|
|
160
|
+
<option value="1">Option 1</option>
|
|
161
|
+
</SingleSelect>
|
|
162
|
+
)
|
|
163
|
+
`)
|
|
164
|
+
|
|
165
|
+
const result = transformComponents(inputAst)
|
|
166
|
+
expect(result).toBe(printAst(expectedAst))
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
it('should handle aliased imports', () => {
|
|
170
|
+
const inputAst = parseJsx(`
|
|
171
|
+
import { Select as MySelect } from "@kaizen/components/next"
|
|
172
|
+
|
|
173
|
+
const MyComponent = () => <MySelect />
|
|
174
|
+
`)
|
|
175
|
+
const expectedAst = parseJsx(`
|
|
176
|
+
import { SingleSelect as MySelect } from "@kaizen/components"
|
|
177
|
+
|
|
178
|
+
const MyComponent = () => <MySelect />
|
|
179
|
+
`)
|
|
180
|
+
|
|
181
|
+
const result = transformComponents(inputAst)
|
|
182
|
+
expect(result).toBe(printAst(expectedAst))
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
it('should handle Component.SubComponent', () => {
|
|
186
|
+
const inputAst = parseJsx(`
|
|
187
|
+
import { Select } from "@kaizen/components/next"
|
|
188
|
+
|
|
189
|
+
const MyComponent = () => (
|
|
190
|
+
<Select>
|
|
191
|
+
{({ items }) =>
|
|
192
|
+
items.map((item) => {
|
|
193
|
+
return <Select.Option />;
|
|
194
|
+
})
|
|
195
|
+
}
|
|
196
|
+
</Select>
|
|
197
|
+
);
|
|
198
|
+
`)
|
|
199
|
+
const expectedAst = parseJsx(`
|
|
200
|
+
import { SingleSelect } from "@kaizen/components"
|
|
201
|
+
|
|
202
|
+
const MyComponent = () => (
|
|
203
|
+
<SingleSelect>
|
|
204
|
+
{({ items }) =>
|
|
205
|
+
items.map((item) => {
|
|
206
|
+
return <SingleSelect.Option />;
|
|
207
|
+
})
|
|
208
|
+
}
|
|
209
|
+
</SingleSelect>
|
|
210
|
+
);
|
|
211
|
+
`)
|
|
212
|
+
|
|
213
|
+
const result = transformComponents(inputAst)
|
|
214
|
+
expect(result).toBe(printAst(expectedAst))
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
it('should not override local types of same name', () => {
|
|
218
|
+
const inputAst = parseJsx(`
|
|
219
|
+
type SelectProps = {
|
|
220
|
+
thing: string
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const MyComponent = (props: SelectProps) => {
|
|
224
|
+
return <div>{props.customField}</div>
|
|
225
|
+
}
|
|
226
|
+
`)
|
|
227
|
+
|
|
228
|
+
const result = transformComponents(inputAst)
|
|
229
|
+
expect(result).toBe(printAst(inputAst))
|
|
230
|
+
})
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
describe('LikertScaleLegacy -> LikertScale', () => {
|
|
234
|
+
it('should rename LikertScaleLegacy import to LikertScale', () => {
|
|
235
|
+
const inputAst = parseJsx(`import { LikertScaleLegacy } from "@kaizen/components"`)
|
|
236
|
+
const expectedAst = parseJsx(`import { LikertScale } from "@kaizen/components"`)
|
|
237
|
+
|
|
238
|
+
const result = transformComponents(inputAst)
|
|
239
|
+
expect(result).toBe(printAst(expectedAst))
|
|
240
|
+
})
|
|
241
|
+
|
|
242
|
+
it('should rename LikertScaleLegacy JSX element to LikertScale', () => {
|
|
243
|
+
const inputAst = parseJsx(`
|
|
244
|
+
import { LikertScaleLegacy } from "@kaizen/components"
|
|
245
|
+
|
|
246
|
+
const MyComponent = () => <LikertScaleLegacy />
|
|
247
|
+
`)
|
|
248
|
+
const expectedAst = parseJsx(`
|
|
249
|
+
import { LikertScale } from "@kaizen/components"
|
|
250
|
+
|
|
251
|
+
const MyComponent = () => <LikertScale />
|
|
252
|
+
`)
|
|
253
|
+
|
|
254
|
+
const result = transformComponents(inputAst)
|
|
255
|
+
expect(result).toBe(printAst(expectedAst))
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
it('should leave LikertScaleProps type as is', () => {
|
|
259
|
+
const inputAst = parseJsx(`
|
|
260
|
+
import type { LikertScaleProps } from "@kaizen/components"
|
|
261
|
+
|
|
262
|
+
const MyComponent = (props: LikertScaleProps) => null
|
|
263
|
+
`)
|
|
264
|
+
const result = transformComponents(inputAst)
|
|
265
|
+
expect(result).toBe(printAst(inputAst))
|
|
266
|
+
})
|
|
267
|
+
})
|
|
268
|
+
|
|
269
|
+
describe('TitleBlockZen -> TitleBlock', () => {
|
|
270
|
+
it('should rename TitleBlockZen import to TitleBlock', () => {
|
|
271
|
+
const inputAst = parseJsx(`import { TitleBlockZen } from "@kaizen/components"`)
|
|
272
|
+
const expectedAst = parseJsx(`import { TitleBlock } from "@kaizen/components"`)
|
|
273
|
+
|
|
274
|
+
const result = transformComponents(inputAst)
|
|
275
|
+
expect(result).toBe(printAst(expectedAst))
|
|
276
|
+
})
|
|
277
|
+
|
|
278
|
+
it('should rename TitleBlockZen JSX element to TitleBlock', () => {
|
|
279
|
+
const inputAst = parseJsx(`
|
|
280
|
+
import { TitleBlockZen } from "@kaizen/components"
|
|
281
|
+
|
|
282
|
+
const MyComponent = () => <TitleBlockZen />
|
|
283
|
+
`)
|
|
284
|
+
const expectedAst = parseJsx(`
|
|
285
|
+
import { TitleBlock } from "@kaizen/components"
|
|
286
|
+
|
|
287
|
+
const MyComponent = () => <TitleBlock />
|
|
288
|
+
`)
|
|
289
|
+
|
|
290
|
+
const result = transformComponents(inputAst)
|
|
291
|
+
expect(result).toBe(printAst(expectedAst))
|
|
292
|
+
})
|
|
293
|
+
|
|
294
|
+
it('should leave TitleBlockProps type as is', () => {
|
|
295
|
+
const inputAst = parseJsx(`
|
|
296
|
+
import type { TitleBlockProps } from "@kaizen/components/next"
|
|
297
|
+
|
|
298
|
+
const MyComponent = (props: TitleBlockProps) => null
|
|
299
|
+
`)
|
|
300
|
+
const result = transformComponents(inputAst)
|
|
301
|
+
expect(result).toBe(printAst(inputAst))
|
|
302
|
+
})
|
|
303
|
+
|
|
304
|
+
it('should rename TitleBlockZen when it appears within a component prop', () => {
|
|
305
|
+
const inputAst = parseJsx(`
|
|
306
|
+
import { TitleBlockZen } from "@kaizen/components"
|
|
307
|
+
|
|
308
|
+
const MyComponent = () => {
|
|
309
|
+
return (
|
|
310
|
+
<Card
|
|
311
|
+
CardContent={
|
|
312
|
+
<Header>
|
|
313
|
+
<TitleBlockZen
|
|
314
|
+
navigationTabs={props.map(prop => <NavigationTab {...prop} />)}
|
|
315
|
+
/>
|
|
316
|
+
</Header>
|
|
317
|
+
}
|
|
318
|
+
/>
|
|
319
|
+
)
|
|
320
|
+
}
|
|
321
|
+
`)
|
|
322
|
+
const expectedAst = parseJsx(`
|
|
323
|
+
import { TitleBlock } from "@kaizen/components"
|
|
324
|
+
|
|
325
|
+
const MyComponent = () => {
|
|
326
|
+
return (
|
|
327
|
+
<Card
|
|
328
|
+
CardContent={
|
|
329
|
+
<Header>
|
|
330
|
+
<TitleBlock
|
|
331
|
+
navigationTabs={props.map(prop => <NavigationTab {...prop} />)}
|
|
332
|
+
/>
|
|
333
|
+
</Header>
|
|
334
|
+
}
|
|
335
|
+
/>
|
|
336
|
+
)
|
|
337
|
+
}
|
|
338
|
+
`)
|
|
339
|
+
|
|
340
|
+
const result = transformComponents(inputAst)
|
|
341
|
+
expect(result).toBe(printAst(expectedAst))
|
|
342
|
+
})
|
|
343
|
+
})
|
|
344
|
+
|
|
345
|
+
describe('Mixed scenarios', () => {
|
|
346
|
+
it('should handle multiple component imports in same file', () => {
|
|
347
|
+
const inputAst = parseJsx(`
|
|
348
|
+
import { Select } from "@kaizen/components/next"
|
|
349
|
+
import { LikertScaleLegacy, TitleBlockZen } from "@kaizen/components"
|
|
350
|
+
|
|
351
|
+
const MyComponent = () => (
|
|
352
|
+
<div>
|
|
353
|
+
<Select />
|
|
354
|
+
<LikertScaleLegacy />
|
|
355
|
+
<TitleBlockZen />
|
|
356
|
+
</div>
|
|
357
|
+
)
|
|
358
|
+
`)
|
|
359
|
+
const expectedAst = parseJsx(`
|
|
360
|
+
import { SingleSelect, LikertScale, TitleBlock } from "@kaizen/components"
|
|
361
|
+
|
|
362
|
+
const MyComponent = () => (
|
|
363
|
+
<div>
|
|
364
|
+
<SingleSelect />
|
|
365
|
+
<LikertScale />
|
|
366
|
+
<TitleBlock />
|
|
367
|
+
</div>
|
|
368
|
+
)
|
|
369
|
+
`)
|
|
370
|
+
|
|
371
|
+
const result = transformComponents(inputAst)
|
|
372
|
+
expect(result).toBe(printAst(expectedAst))
|
|
373
|
+
})
|
|
374
|
+
|
|
375
|
+
it('should not transform components not in the rename map', () => {
|
|
376
|
+
const inputAst = parseJsx(`
|
|
377
|
+
import { Button, Card } from "@kaizen/components"
|
|
378
|
+
|
|
379
|
+
const MyComponent = () => (
|
|
380
|
+
<Card>
|
|
381
|
+
<Button>Click me</Button>
|
|
382
|
+
</Card>
|
|
383
|
+
)
|
|
384
|
+
`)
|
|
385
|
+
|
|
386
|
+
const result = transformComponents(inputAst)
|
|
387
|
+
expect(result).toBe(printAst(inputAst))
|
|
388
|
+
})
|
|
389
|
+
})
|
|
390
|
+
})
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import ts from 'typescript'
|
|
2
|
+
import {
|
|
3
|
+
setImportToAdd,
|
|
4
|
+
setImportToRemove,
|
|
5
|
+
updateJsxElementTagName,
|
|
6
|
+
updateKaioImports,
|
|
7
|
+
type ComponentRenameConfig,
|
|
8
|
+
type TagImportAttributesMap,
|
|
9
|
+
type UpdateKaioImportsArgs,
|
|
10
|
+
} from '../utils'
|
|
11
|
+
|
|
12
|
+
type RenameConfig = {
|
|
13
|
+
newName: string
|
|
14
|
+
fromModules: string[]
|
|
15
|
+
toModule: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const renameMap = new Map<string, RenameConfig>([
|
|
19
|
+
[
|
|
20
|
+
'Select',
|
|
21
|
+
{
|
|
22
|
+
newName: 'SingleSelect',
|
|
23
|
+
fromModules: ['@kaizen/components/next', '@kaizen/components/future'],
|
|
24
|
+
toModule: '@kaizen/components',
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
[
|
|
28
|
+
'SelectProps',
|
|
29
|
+
{
|
|
30
|
+
newName: 'SingleSelectProps',
|
|
31
|
+
fromModules: ['@kaizen/components/next', '@kaizen/components/future'],
|
|
32
|
+
toModule: '@kaizen/components',
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
[
|
|
36
|
+
'SelectOption',
|
|
37
|
+
{
|
|
38
|
+
newName: 'SingleSelectOption',
|
|
39
|
+
fromModules: ['@kaizen/components/next', '@kaizen/components/future'],
|
|
40
|
+
toModule: '@kaizen/components',
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
[
|
|
44
|
+
'SelectOptionGroup',
|
|
45
|
+
{
|
|
46
|
+
newName: 'SingleSelectOptionGroup',
|
|
47
|
+
fromModules: ['@kaizen/components/next', '@kaizen/components/future'],
|
|
48
|
+
toModule: '@kaizen/components',
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
[
|
|
52
|
+
'SelectItem',
|
|
53
|
+
{
|
|
54
|
+
newName: 'SingleSelectItem',
|
|
55
|
+
fromModules: ['@kaizen/components/next', '@kaizen/components/future'],
|
|
56
|
+
toModule: '@kaizen/components',
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
[
|
|
60
|
+
'SelectOptionNode',
|
|
61
|
+
{
|
|
62
|
+
newName: 'SingleSelectOptionNode',
|
|
63
|
+
fromModules: ['@kaizen/components/next', '@kaizen/components/future'],
|
|
64
|
+
toModule: '@kaizen/components',
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
[
|
|
68
|
+
'SelectOptionGroupNode',
|
|
69
|
+
{
|
|
70
|
+
newName: 'SingleSelectOptionGroupNode',
|
|
71
|
+
fromModules: ['@kaizen/components/next', '@kaizen/components/future'],
|
|
72
|
+
toModule: '@kaizen/components',
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
[
|
|
76
|
+
'SelectItemNode',
|
|
77
|
+
{
|
|
78
|
+
newName: 'SingleSelectItemNode',
|
|
79
|
+
fromModules: ['@kaizen/components/next', '@kaizen/components/future'],
|
|
80
|
+
toModule: '@kaizen/components',
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
[
|
|
84
|
+
'LikertScaleLegacy',
|
|
85
|
+
{
|
|
86
|
+
newName: 'LikertScale',
|
|
87
|
+
fromModules: ['@kaizen/components'],
|
|
88
|
+
toModule: '@kaizen/components',
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
[
|
|
92
|
+
'TitleBlockZen',
|
|
93
|
+
{
|
|
94
|
+
newName: 'TitleBlock',
|
|
95
|
+
fromModules: ['@kaizen/components'],
|
|
96
|
+
toModule: '@kaizen/components',
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
])
|
|
100
|
+
|
|
101
|
+
const createComponentRenameConfig = (
|
|
102
|
+
config: RenameConfig,
|
|
103
|
+
fromModule: string,
|
|
104
|
+
): ComponentRenameConfig => ({
|
|
105
|
+
newName: config.newName,
|
|
106
|
+
fromModule,
|
|
107
|
+
toModule: config.toModule,
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
const componentRenameMap = new Map<string, ComponentRenameConfig>()
|
|
111
|
+
for (const [name, config] of Array.from(renameMap.entries())) {
|
|
112
|
+
if (
|
|
113
|
+
!name.endsWith('Props') &&
|
|
114
|
+
!name.includes('Option') &&
|
|
115
|
+
!name.includes('Item') &&
|
|
116
|
+
!name.includes('Node')
|
|
117
|
+
) {
|
|
118
|
+
componentRenameMap.set(name, createComponentRenameConfig(config, config.fromModules[0]))
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export const renameV2ComponentImportsAndUsages =
|
|
123
|
+
(tagsMap: TagImportAttributesMap | undefined): ts.TransformerFactory<ts.SourceFile> =>
|
|
124
|
+
(context) =>
|
|
125
|
+
(rootNode) => {
|
|
126
|
+
const importsToRemove: UpdateKaioImportsArgs['importsToRemove'] = new Map()
|
|
127
|
+
const importsToAdd: UpdateKaioImportsArgs['importsToAdd'] = new Map()
|
|
128
|
+
const validRenames = new Set<string>()
|
|
129
|
+
|
|
130
|
+
const visit = (node: ts.Node): ts.Node => {
|
|
131
|
+
if (ts.isImportDeclaration(node)) {
|
|
132
|
+
const moduleSpecifier = node.moduleSpecifier.getText().slice(1, -1)
|
|
133
|
+
|
|
134
|
+
const importClause = node.importClause
|
|
135
|
+
if (importClause?.namedBindings && ts.isNamedImports(importClause.namedBindings)) {
|
|
136
|
+
importClause.namedBindings.elements.forEach((importSpecifier) => {
|
|
137
|
+
const importName =
|
|
138
|
+
importSpecifier.propertyName?.getText() ?? importSpecifier.name?.getText()
|
|
139
|
+
|
|
140
|
+
const renameConfig = renameMap.get(importName)
|
|
141
|
+
if (renameConfig?.fromModules.includes(moduleSpecifier)) {
|
|
142
|
+
validRenames.add(importName)
|
|
143
|
+
setImportToRemove(importsToRemove, moduleSpecifier, importName)
|
|
144
|
+
setImportToAdd(importsToAdd, renameConfig.toModule, {
|
|
145
|
+
componentName: renameConfig.newName,
|
|
146
|
+
isTypeOnly: importSpecifier.isTypeOnly || importClause.isTypeOnly,
|
|
147
|
+
})
|
|
148
|
+
}
|
|
149
|
+
})
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (
|
|
154
|
+
ts.isJsxOpeningElement(node) ||
|
|
155
|
+
ts.isJsxSelfClosingElement(node) ||
|
|
156
|
+
ts.isJsxClosingElement(node)
|
|
157
|
+
) {
|
|
158
|
+
if (ts.isPropertyAccessExpression(node.tagName)) {
|
|
159
|
+
const left = node.tagName.expression.getText()
|
|
160
|
+
const rename = componentRenameMap.get(left)
|
|
161
|
+
|
|
162
|
+
if (rename) {
|
|
163
|
+
setImportToRemove(importsToRemove, rename.fromModule, left)
|
|
164
|
+
setImportToAdd(importsToAdd, rename.toModule, { componentName: rename.newName })
|
|
165
|
+
|
|
166
|
+
return updateJsxElementTagName(
|
|
167
|
+
context.factory,
|
|
168
|
+
node,
|
|
169
|
+
rename.newName,
|
|
170
|
+
componentRenameMap,
|
|
171
|
+
)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return ts.visitEachChild(node, visit, context)
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const tagName = node.tagName.getText()
|
|
178
|
+
const tagImportAttributes = tagsMap?.get(tagName)
|
|
179
|
+
if (!tagImportAttributes) return ts.visitEachChild(node, visit, context)
|
|
180
|
+
const kaioComponentName = tagImportAttributes.originalName
|
|
181
|
+
const oldImportSource = tagImportAttributes.importModuleName
|
|
182
|
+
const renameConfig = renameMap.get(kaioComponentName)
|
|
183
|
+
if (!renameConfig) return ts.visitEachChild(node, visit, context)
|
|
184
|
+
if (!renameConfig.fromModules.includes(oldImportSource)) {
|
|
185
|
+
console.warn(
|
|
186
|
+
`Expected ${kaioComponentName} to be imported from one of [${renameConfig.fromModules.join(', ')}], but found ${oldImportSource}`,
|
|
187
|
+
)
|
|
188
|
+
return ts.visitEachChild(node, visit, context)
|
|
189
|
+
}
|
|
190
|
+
setImportToRemove(importsToRemove, oldImportSource, kaioComponentName)
|
|
191
|
+
|
|
192
|
+
const alias =
|
|
193
|
+
tagImportAttributes?.tagName !== tagImportAttributes?.originalName
|
|
194
|
+
? tagImportAttributes?.tagName
|
|
195
|
+
: undefined
|
|
196
|
+
setImportToAdd(importsToAdd, renameConfig.toModule, {
|
|
197
|
+
componentName: renameConfig.newName,
|
|
198
|
+
alias,
|
|
199
|
+
})
|
|
200
|
+
const jsxElementName = alias ?? renameConfig.newName
|
|
201
|
+
const tempComponentMap = new Map([
|
|
202
|
+
[kaioComponentName, createComponentRenameConfig(renameConfig, oldImportSource)],
|
|
203
|
+
])
|
|
204
|
+
return updateJsxElementTagName(context.factory, node, jsxElementName, tempComponentMap)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (ts.isTypeReferenceNode(node)) {
|
|
208
|
+
const typeName = node.typeName.getText()
|
|
209
|
+
|
|
210
|
+
if (validRenames.has(typeName)) {
|
|
211
|
+
const renameConfig = renameMap.get(typeName)
|
|
212
|
+
if (renameConfig) {
|
|
213
|
+
return context.factory.updateTypeReferenceNode(
|
|
214
|
+
node,
|
|
215
|
+
context.factory.createIdentifier(renameConfig.newName),
|
|
216
|
+
node.typeArguments,
|
|
217
|
+
)
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return ts.visitEachChild(node, visit, context)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const transformedNode = ts.visitNode(rootNode, visit)
|
|
226
|
+
|
|
227
|
+
return updateKaioImports({ importsToRemove, importsToAdd })(context)(
|
|
228
|
+
transformedNode as ts.SourceFile,
|
|
229
|
+
)
|
|
230
|
+
}
|
package/codemods/utils/index.ts
CHANGED