@planningcenter/tapestry-migration-cli 3.0.0-rc.8 → 3.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.
Files changed (58) hide show
  1. package/README.md +5 -2
  2. package/dist/tapestry-react-shim.cjs +384 -318
  3. package/package.json +4 -3
  4. package/src/components/button/transforms/auditSpreadProps.ts +2 -16
  5. package/src/components/button/transforms/themeVariantToKind.test.ts +1 -1
  6. package/src/components/button/transforms/tooltipToWrapper.test.ts +5 -3
  7. package/src/components/button/transforms/unsupportedProps.test.ts +305 -0
  8. package/src/components/button/transforms/unsupportedProps.ts +5 -2
  9. package/src/components/checkbox/index.ts +2 -0
  10. package/src/components/checkbox/transforms/auditSpreadProps.test.ts +356 -0
  11. package/src/components/checkbox/transforms/auditSpreadProps.ts +10 -0
  12. package/src/components/checkbox/transforms/sizeMapping.test.ts +88 -9
  13. package/src/components/checkbox/transforms/sizeMapping.ts +7 -37
  14. package/src/components/checkbox/transforms/unsupportedProps.ts +6 -11
  15. package/src/components/link/transforms/auditSpreadProps.ts +2 -16
  16. package/src/components/link/transforms/tooltipToWrapper.test.ts +5 -3
  17. package/src/components/link/transforms/unsupportedProps.ts +2 -2
  18. package/src/components/radio/index.ts +38 -0
  19. package/src/components/radio/transforms/auditSpreadProps.test.ts +356 -0
  20. package/src/components/radio/transforms/auditSpreadProps.ts +10 -0
  21. package/src/components/radio/transforms/convertStyleProps.test.ts +161 -0
  22. package/src/components/radio/transforms/convertStyleProps.ts +10 -0
  23. package/src/components/radio/transforms/moveRadioImport.test.ts +152 -0
  24. package/src/components/radio/transforms/moveRadioImport.ts +13 -0
  25. package/src/components/radio/transforms/setDefaultSize.test.ts +287 -0
  26. package/src/components/radio/transforms/setDefaultSize.ts +29 -0
  27. package/src/components/radio/transforms/sizeMapping.test.ts +201 -0
  28. package/src/components/radio/transforms/sizeMapping.ts +15 -0
  29. package/src/components/radio/transforms/unsupportedProps.test.ts +241 -0
  30. package/src/components/radio/transforms/unsupportedProps.ts +35 -0
  31. package/src/components/shared/actions/getAttributeValue.test.ts +18 -0
  32. package/src/components/shared/actions/getAttributeValue.ts +18 -5
  33. package/src/components/shared/actions/getAttributeValueAsProps.ts +15 -0
  34. package/src/components/shared/conditions/notCondition.test.ts +35 -0
  35. package/src/components/shared/conditions/notCondition.ts +12 -0
  36. package/src/components/shared/helpers/unsupportedPropsHelpers.ts +26 -10
  37. package/src/components/shared/transformFactories/commentOnSpreadPropsFactory.test.ts +84 -0
  38. package/src/components/shared/transformFactories/commentOnSpreadPropsFactory.ts +26 -0
  39. package/src/components/shared/transformFactories/sizeMappingFactory.ts +56 -0
  40. package/src/components/toggle-switch/index.ts +40 -0
  41. package/src/components/toggle-switch/transforms/ariaLabelToLabel.test.ts +236 -0
  42. package/src/components/toggle-switch/transforms/ariaLabelToLabel.ts +35 -0
  43. package/src/components/toggle-switch/transforms/auditSpreadProps.test.ts +352 -0
  44. package/src/components/toggle-switch/transforms/auditSpreadProps.ts +10 -0
  45. package/src/components/toggle-switch/transforms/convertStyleProps.test.ts +161 -0
  46. package/src/components/toggle-switch/transforms/convertStyleProps.ts +10 -0
  47. package/src/components/toggle-switch/transforms/isCheckedToChecked.test.ts +175 -0
  48. package/src/components/toggle-switch/transforms/isCheckedToChecked.ts +18 -0
  49. package/src/components/toggle-switch/transforms/moveToggleSwitchImport.test.ts +192 -0
  50. package/src/components/toggle-switch/transforms/moveToggleSwitchImport.ts +13 -0
  51. package/src/components/toggle-switch/transforms/sizeMapping.test.ts +188 -0
  52. package/src/components/toggle-switch/transforms/sizeMapping.ts +13 -0
  53. package/src/components/toggle-switch/transforms/unsupportedProps.test.ts +241 -0
  54. package/src/components/toggle-switch/transforms/unsupportedProps.ts +42 -0
  55. package/src/index.ts +12 -5
  56. package/src/reportGenerator.ts +4 -0
  57. package/src/utils/componentNameNormalizer.test.ts +91 -0
  58. package/src/utils/componentNameNormalizer.ts +39 -0
@@ -0,0 +1,356 @@
1
+ import jscodeshift from "jscodeshift"
2
+ import { describe, expect, it } from "vitest"
3
+
4
+ import transform from "./auditSpreadProps"
5
+
6
+ const j = jscodeshift.withParser("tsx")
7
+
8
+ const AUDIT_COMMENT =
9
+ "TODO: tapestry-migration (spreadAttribute): Spread props can contain unsupported props, please explore usages and migrate as needed."
10
+
11
+ function applyTransform(source: string) {
12
+ const fileInfo = { path: "test.tsx", source }
13
+ return transform(
14
+ fileInfo,
15
+ { j, jscodeshift: j, report: () => {}, stats: () => {} },
16
+ {}
17
+ ) as string | null
18
+ }
19
+
20
+ describe("auditSpreadProps transform", () => {
21
+ describe("basic transformations", () => {
22
+ it("should add comment to Checkbox with single spread prop", () => {
23
+ const input = `
24
+ import { Checkbox } from "@planningcenter/tapestry-react"
25
+
26
+ export default function Test() {
27
+ const props = { onChange: handleChange }
28
+ return <Checkbox {...props} label="Save" name="choice" />
29
+ }
30
+ `.trim()
31
+
32
+ const result = applyTransform(input)
33
+ expect(result).toContain(AUDIT_COMMENT)
34
+ expect(result).toContain("{...props}")
35
+ })
36
+
37
+ it("should add comment to Checkbox with multiple spread props", () => {
38
+ const input = `
39
+ import { Checkbox } from "@planningcenter/tapestry-react"
40
+
41
+ export default function Test() {
42
+ const baseProps = { onChange: handleChange }
43
+ const styleProps = { className: "checkbox" }
44
+ return <Checkbox {...baseProps} {...styleProps} label="Save" name="choice" />
45
+ }
46
+ `.trim()
47
+
48
+ const result = applyTransform(input)
49
+ expect(result).toContain(AUDIT_COMMENT)
50
+ expect(result).toContain("{...baseProps}")
51
+ expect(result).toContain("{...styleProps}")
52
+ })
53
+
54
+ it("should handle Checkbox with spread props and regular attributes", () => {
55
+ const input = `
56
+ import { Checkbox } from "@planningcenter/tapestry-react"
57
+
58
+ export default function Test() {
59
+ const props = { onChange: handleChange }
60
+ return <Checkbox label="Save" name="choice" {...props} disabled />
61
+ }
62
+ `.trim()
63
+
64
+ const result = applyTransform(input)
65
+ expect(result).toContain(AUDIT_COMMENT)
66
+ expect(result).toContain('label="Save"')
67
+ expect(result).toContain('name="choice"')
68
+ expect(result).toContain("{...props}")
69
+ expect(result).toContain("disabled")
70
+ })
71
+
72
+ it("should handle multiple Checkbox components with spread props", () => {
73
+ const input = `
74
+ import { Checkbox } from "@planningcenter/tapestry-react"
75
+
76
+ export default function Test() {
77
+ const props1 = { onChange: handleChange1 }
78
+ const props2 = { onChange: handleChange2 }
79
+ return (
80
+ <div>
81
+ <Checkbox {...props1} label="Save" name="choice" />
82
+ <Checkbox {...props2} label="Cancel" name="choice" />
83
+ </div>
84
+ )
85
+ }
86
+ `.trim()
87
+
88
+ const result = applyTransform(input)
89
+ expect(result).toContain(AUDIT_COMMENT)
90
+ expect(result).toContain("{...props1}")
91
+ expect(result).toContain("{...props2}")
92
+ })
93
+ })
94
+
95
+ describe("edge cases", () => {
96
+ it("should not transform Checkbox without spread props", () => {
97
+ const input = `
98
+ import { Checkbox } from "@planningcenter/tapestry-react"
99
+
100
+ export default function Test() {
101
+ return <Checkbox onChange={handleChange} label="Save" name="choice" />
102
+ }
103
+ `.trim()
104
+
105
+ const result = applyTransform(input)
106
+ expect(result).toBe(null)
107
+ })
108
+
109
+ it("should not transform if Checkbox is not imported from @planningcenter/tapestry-react", () => {
110
+ const input = `
111
+ import { Checkbox } from "other-library"
112
+
113
+ export default function Test() {
114
+ const props = { onChange: handleChange }
115
+ return <Checkbox {...props} label="Save" name="choice" />
116
+ }
117
+ `.trim()
118
+
119
+ const result = applyTransform(input)
120
+ expect(result).toBe(null)
121
+ })
122
+
123
+ it("should handle Checkbox with alias import", () => {
124
+ const input = `
125
+ import { Checkbox as TapestryCheckbox } from "@planningcenter/tapestry-react"
126
+
127
+ export default function Test() {
128
+ const props = { onChange: handleChange }
129
+ return <TapestryCheckbox {...props} label="Save" name="choice" />
130
+ }
131
+ `.trim()
132
+
133
+ const result = applyTransform(input)
134
+ expect(result).toContain(AUDIT_COMMENT)
135
+ expect(result).toContain("{...props}")
136
+ })
137
+
138
+ it("should handle mixed Checkbox components (with and without spread props)", () => {
139
+ const input = `
140
+ import { Checkbox } from "@planningcenter/tapestry-react"
141
+
142
+ export default function Test() {
143
+ const props = { onChange: handleSave }
144
+ return (
145
+ <div>
146
+ <Checkbox {...props} label="Save" name="choice" />
147
+ <Checkbox label="Cancel" name="choice" />
148
+ <Checkbox onChange={handleDelete} label="Delete" name="choice" />
149
+ </div>
150
+ )
151
+ }
152
+ `.trim()
153
+
154
+ const result = applyTransform(input)
155
+ expect(result).toContain(AUDIT_COMMENT)
156
+ expect(result).toContain("{...props}")
157
+ expect(result).toContain('<Checkbox label="Cancel" name="choice" />')
158
+ expect(result).toContain("onChange={handleDelete}")
159
+ })
160
+ })
161
+
162
+ describe("complex spread prop scenarios", () => {
163
+ it("should handle Checkbox with complex spread expression", () => {
164
+ const input = `
165
+ import { Checkbox } from "@planningcenter/tapestry-react"
166
+
167
+ export default function Test() {
168
+ const baseProps = { className: "checkbox" }
169
+ const additionalProps = isDisabled ? { disabled: true } : {}
170
+ return <Checkbox {...baseProps} {...additionalProps} label="Save" name="choice" />
171
+ }
172
+ `.trim()
173
+
174
+ const result = applyTransform(input)
175
+ expect(result).toContain(AUDIT_COMMENT)
176
+ expect(result).toContain("{...baseProps}")
177
+ expect(result).toContain("{...additionalProps}")
178
+ })
179
+
180
+ it("should handle Checkbox with spread props in different positions", () => {
181
+ const input = `
182
+ import { Checkbox } from "@planningcenter/tapestry-react"
183
+
184
+ export default function Test() {
185
+ const props = { className: "checkbox" }
186
+ return (
187
+ <Checkbox
188
+ label="Save"
189
+ name="choice"
190
+ {...props}
191
+ disabled={false}
192
+ onChange={handleSave}
193
+ />
194
+ )
195
+ }
196
+ `.trim()
197
+
198
+ const result = applyTransform(input)
199
+ expect(result).toContain(AUDIT_COMMENT)
200
+ expect(result).toContain('label="Save"')
201
+ expect(result).toContain('name="choice"')
202
+ expect(result).toContain("{...props}")
203
+ expect(result).toContain("disabled={false}")
204
+ expect(result).toContain("onChange={handleSave}")
205
+ })
206
+
207
+ it("should handle spread props with object expressions", () => {
208
+ const input = `
209
+ import { Checkbox } from "@planningcenter/tapestry-react"
210
+
211
+ export default function Test() {
212
+ return <Checkbox {...{ onChange: handleChange, className: "checkbox" }} label="Save" name="choice" />
213
+ }
214
+ `.trim()
215
+
216
+ const result = applyTransform(input)
217
+ expect(result).toContain(AUDIT_COMMENT)
218
+ expect(result).toContain(
219
+ '{...{ onChange: handleChange, className: "checkbox" }}'
220
+ )
221
+ })
222
+
223
+ it("should handle spread props with function calls", () => {
224
+ const input = `
225
+ import { Checkbox } from "@planningcenter/tapestry-react"
226
+
227
+ export default function Test() {
228
+ return <Checkbox {...getCheckboxProps()} {...getStyleProps()} label="Save" name="choice" />
229
+ }
230
+ `.trim()
231
+
232
+ const result = applyTransform(input)
233
+ expect(result).toContain(AUDIT_COMMENT)
234
+ expect(result).toContain("{...getCheckboxProps()}")
235
+ expect(result).toContain("{...getStyleProps()}")
236
+ })
237
+ })
238
+
239
+ describe("self-closing Checkbox components", () => {
240
+ it("should handle self-closing Checkbox with spread props", () => {
241
+ const input = `
242
+ import { Checkbox } from "@planningcenter/tapestry-react"
243
+
244
+ export default function Test() {
245
+ const props = { label: "Close", name: "choice", onChange: handleClose }
246
+ return <Checkbox {...props} />
247
+ }
248
+ `.trim()
249
+
250
+ const result = applyTransform(input)
251
+ expect(result).toContain(AUDIT_COMMENT)
252
+ expect(result).toContain("{...props}")
253
+ })
254
+
255
+ it("should handle self-closing Checkbox with multiple spread props and attributes", () => {
256
+ const input = `
257
+ import { Checkbox } from "@planningcenter/tapestry-react"
258
+
259
+ export default function Test() {
260
+ const baseProps = { onChange: handleChange }
261
+ const styleProps = { className: "checkbox" }
262
+ return <Checkbox label="Action" name="choice" {...baseProps} {...styleProps} disabled />
263
+ }
264
+ `.trim()
265
+
266
+ const result = applyTransform(input)
267
+ expect(result).toContain(AUDIT_COMMENT)
268
+ expect(result).toContain('label="Action"')
269
+ expect(result).toContain('name="choice"')
270
+ expect(result).toContain("{...baseProps}")
271
+ expect(result).toContain("{...styleProps}")
272
+ expect(result).toContain("disabled")
273
+ })
274
+ })
275
+
276
+ describe("no changes scenarios", () => {
277
+ it("should return null when no Checkbox components have spread props", () => {
278
+ const input = `
279
+ import { Checkbox } from "@planningcenter/tapestry-react"
280
+
281
+ export default function Test() {
282
+ return (
283
+ <div>
284
+ <Checkbox label="Save" name="choice" />
285
+ <Checkbox label="Delete" name="choice" />
286
+ <Checkbox onChange={handleChange} label="Cancel" name="choice" />
287
+ </div>
288
+ )
289
+ }
290
+ `.trim()
291
+
292
+ const result = applyTransform(input)
293
+ expect(result).toBe(null)
294
+ })
295
+
296
+ it("should return null when no Checkbox imports exist", () => {
297
+ const input = `
298
+ import { Button } from "@planningcenter/tapestry-react"
299
+
300
+ export default function Test() {
301
+ const props = { onClick: handleClick }
302
+ return <Button {...props}>Save</Button>
303
+ }
304
+ `.trim()
305
+
306
+ const result = applyTransform(input)
307
+ expect(result).toBe(null)
308
+ })
309
+
310
+ it("should return null for empty file", () => {
311
+ const result = applyTransform("")
312
+ expect(result).toBe(null)
313
+ })
314
+
315
+ it("should return null when file has no JSX", () => {
316
+ const input = `
317
+ export function handleChange() {
318
+ console.log("changed")
319
+ }
320
+ `.trim()
321
+
322
+ const result = applyTransform(input)
323
+ expect(result).toBe(null)
324
+ })
325
+ })
326
+
327
+ describe("different import scenarios", () => {
328
+ it("should handle default import with spread props", () => {
329
+ const input = `
330
+ import Checkbox from "@planningcenter/tapestry-react"
331
+
332
+ export default function Test() {
333
+ const props = { onChange: handleChange }
334
+ return <Checkbox {...props} label="Save" name="choice" />
335
+ }
336
+ `.trim()
337
+
338
+ const result = applyTransform(input)
339
+ expect(result).toBe(null)
340
+ })
341
+
342
+ it("should handle namespace import", () => {
343
+ const input = `
344
+ import * as Tapestry from "@planningcenter/tapestry-react"
345
+
346
+ export default function Test() {
347
+ const props = { onChange: handleChange }
348
+ return <Tapestry.Checkbox {...props} label="Save" name="choice" />
349
+ }
350
+ `.trim()
351
+
352
+ const result = applyTransform(input)
353
+ expect(result).toBe(null)
354
+ })
355
+ })
356
+ })
@@ -0,0 +1,10 @@
1
+ import { Transform } from "jscodeshift"
2
+
3
+ import { commentOnSpreadPropsFactory } from "../../shared/transformFactories/commentOnSpreadPropsFactory"
4
+
5
+ const transform: Transform = commentOnSpreadPropsFactory({
6
+ targetComponent: "Checkbox",
7
+ targetPackage: "@planningcenter/tapestry-react",
8
+ })
9
+
10
+ export default transform
@@ -34,6 +34,23 @@ function Test() {
34
34
  )
35
35
  })
36
36
 
37
+ it('should transform size={"lg"} to md', () => {
38
+ const input = `
39
+ import { Checkbox } from "@planningcenter/tapestry-react"
40
+
41
+ function Test() {
42
+ return <Checkbox size={"lg"} label="Large checkbox" />
43
+ }
44
+ `.trim()
45
+
46
+ const result = applyTransform(input)
47
+ expect(result).toContain('size="md"')
48
+ expect(result).not.toContain('size={"lg"}')
49
+ expect(result).toContain(
50
+ 'TODO: tapestry-migration (size): Size "lg" was mapped to "md"'
51
+ )
52
+ })
53
+
37
54
  it("should transform xl to md", () => {
38
55
  const input = `
39
56
  import { Checkbox } from "@planningcenter/tapestry-react"
@@ -51,7 +68,24 @@ function Test() {
51
68
  )
52
69
  })
53
70
 
54
- it("should not transform xs size", () => {
71
+ it('should transform size={"xl"} to md', () => {
72
+ const input = `
73
+ import { Checkbox } from "@planningcenter/tapestry-react"
74
+
75
+ function Test() {
76
+ return <Checkbox size={"xl"} label="Extra large checkbox" />
77
+ }
78
+ `.trim()
79
+
80
+ const result = applyTransform(input)
81
+ expect(result).toContain('size="md"')
82
+ expect(result).not.toContain('size={"xl"}')
83
+ expect(result).toContain(
84
+ 'TODO: tapestry-migration (size): Size "xl" was mapped to "md"'
85
+ )
86
+ })
87
+
88
+ it("should transform xs to sm", () => {
55
89
  const input = `
56
90
  import { Checkbox } from "@planningcenter/tapestry-react"
57
91
 
@@ -61,8 +95,28 @@ function Test() {
61
95
  `.trim()
62
96
 
63
97
  const result = applyTransform(input)
64
- expect(result).toContain('size="xs"')
65
- expect(result).not.toContain("TODO: tapestry-migration")
98
+ expect(result).toContain('size="sm"')
99
+ expect(result).not.toContain('size="xs"')
100
+ expect(result).toContain(
101
+ 'TODO: tapestry-migration (size): Size "xs" was mapped to "sm"'
102
+ )
103
+ })
104
+
105
+ it('should transform size={"xs"} to sm', () => {
106
+ const input = `
107
+ import { Checkbox } from "@planningcenter/tapestry-react"
108
+
109
+ function Test() {
110
+ return <Checkbox size={"xs"} label="Extra small checkbox" />
111
+ }
112
+ `.trim()
113
+
114
+ const result = applyTransform(input)
115
+ expect(result).toContain('size="sm"')
116
+ expect(result).not.toContain('size={"xs"}')
117
+ expect(result).toContain(
118
+ 'TODO: tapestry-migration (size): Size "xs" was mapped to "sm"'
119
+ )
66
120
  })
67
121
 
68
122
  it("should not transform supported sizes", () => {
@@ -74,7 +128,6 @@ function Test() {
74
128
  <div>
75
129
  <Checkbox size="md" label="Medium checkbox" />
76
130
  <Checkbox size="sm" label="Small checkbox" />
77
- <Checkbox size="xs" label="Extra small checkbox" />
78
131
  </div>
79
132
  )
80
133
  }
@@ -83,7 +136,6 @@ function Test() {
83
136
  const result = applyTransform(input)
84
137
  expect(result).toContain('size="md"')
85
138
  expect(result).toContain('size="sm"')
86
- expect(result).toContain('size="xs"')
87
139
  expect(result).not.toContain("TODO: tapestry-migration")
88
140
  })
89
141
  })
@@ -139,12 +191,13 @@ function Test() {
139
191
 
140
192
  const result = applyTransform(input)
141
193
  expect(result).toContain('size="md"')
142
- expect(result).toContain('size="xs"')
194
+ expect(result).toContain('size="sm"')
143
195
  expect(result).not.toContain('size="lg"')
144
196
  expect(result).not.toContain('size="xl"')
145
- // Should have 2 TODO comments (one for lg->md, one for xl->md)
197
+ expect(result).not.toContain('size="xs"')
198
+ // Should have 3 TODO comments (one for lg->md, one for xl->md, one for xs->sm)
146
199
  const todoMatches = result.match(/TODO: tapestry-migration \(size\)/g)
147
- expect(todoMatches).toHaveLength(2)
200
+ expect(todoMatches).toHaveLength(3)
148
201
  })
149
202
 
150
203
  it("should preserve other props", () => {
@@ -175,7 +228,33 @@ function Test() {
175
228
  )
176
229
  })
177
230
 
178
- it("should not transform expression values", () => {
231
+ it("should handle mixed string literals and JSXExpressionContainers", () => {
232
+ const input = `
233
+ import { Checkbox } from "@planningcenter/tapestry-react"
234
+
235
+ function Test() {
236
+ return (
237
+ <div>
238
+ <Checkbox size="lg" label="String literal" />
239
+ <Checkbox size={"xl"} label="JSXExpressionContainer" />
240
+ <Checkbox size="xs" label="Another string literal" />
241
+ </div>
242
+ )
243
+ }
244
+ `.trim()
245
+
246
+ const result = applyTransform(input)
247
+ expect(result).toContain('size="md"')
248
+ expect(result).toContain('size="sm"')
249
+ expect(result).not.toContain('size="lg"')
250
+ expect(result).not.toContain('size={"xl"}')
251
+ expect(result).not.toContain('size="xs"')
252
+ // Should have 3 TODO comments (one for lg->md, one for xl->md, one for xs->sm)
253
+ const todoMatches = result.match(/TODO: tapestry-migration \(size\)/g)
254
+ expect(todoMatches).toHaveLength(3)
255
+ })
256
+
257
+ it("should not transform variable expression values", () => {
179
258
  const input = `
180
259
  import { Checkbox } from "@planningcenter/tapestry-react"
181
260
 
@@ -1,45 +1,15 @@
1
1
  import { Transform } from "jscodeshift"
2
2
 
3
- import { addCommentToAttribute } from "../../shared/actions/addCommentToAttribute"
4
- import { hasAttribute } from "../../shared/conditions/hasAttribute"
5
- import { attributeTransformFactory } from "../../shared/transformFactories/attributeTransformFactory"
3
+ import { sizeMappingFactory } from "../../shared/transformFactories/sizeMappingFactory"
6
4
 
7
- const SIZE_MAPPING = {
8
- lg: "md",
9
- xl: "md",
10
- }
11
-
12
- const transform: Transform = attributeTransformFactory({
13
- condition: hasAttribute("size"),
5
+ const transform: Transform = sizeMappingFactory({
6
+ sizeMapping: {
7
+ lg: "md",
8
+ xl: "md",
9
+ xs: "sm",
10
+ },
14
11
  targetComponent: "Checkbox",
15
12
  targetPackage: "@planningcenter/tapestry-react",
16
- transform: (element, { j }) => {
17
- let hasChanges = false
18
-
19
- const sizeAttr = element.openingElement.attributes?.find(
20
- (attr) => attr.type === "JSXAttribute" && attr.name.name === "size"
21
- )
22
-
23
- if (sizeAttr && sizeAttr.type === "JSXAttribute") {
24
- if (sizeAttr.value?.type === "StringLiteral") {
25
- const sizeValue = sizeAttr.value.value as string
26
- const mappedSize = SIZE_MAPPING[sizeValue as keyof typeof SIZE_MAPPING]
27
-
28
- if (mappedSize && mappedSize !== sizeValue) {
29
- sizeAttr.value.value = mappedSize
30
- hasChanges = true
31
-
32
- addCommentToAttribute({
33
- attribute: sizeAttr,
34
- j,
35
- text: `Size "${sizeValue}" was mapped to "${mappedSize}". Verify visual appearance as sizes may differ slightly.`,
36
- })
37
- }
38
- }
39
- }
40
-
41
- return hasChanges
42
- },
43
13
  })
44
14
 
45
15
  export default transform
@@ -1,20 +1,15 @@
1
1
  import { JSXAttribute, Transform } from "jscodeshift"
2
2
 
3
3
  import { addCommentToUnsupportedProps } from "../../shared/actions/addCommentToUnsupportedProps"
4
- import { SUPPORTED_PROPS_BASE } from "../../shared/helpers/unsupportedPropsHelpers"
4
+ import { CHECKBOX_RADIO_SUPPORTED_PROPS } from "../../shared/helpers/unsupportedPropsHelpers"
5
5
  import { attributeTransformFactory } from "../../shared/transformFactories/attributeTransformFactory"
6
6
 
7
- const CHECKBOX_SPECIFIC_PROPS = [
8
- "checked",
9
- "disabled",
10
- "indeterminate",
11
- "label",
12
- "name",
13
- "onChange",
14
- "value",
15
- ]
7
+ const CHECKBOX_SPECIFIC_PROPS = ["indeterminate"]
16
8
 
17
- const SUPPORTED_PROPS = [...SUPPORTED_PROPS_BASE, ...CHECKBOX_SPECIFIC_PROPS]
9
+ const SUPPORTED_PROPS = [
10
+ ...CHECKBOX_RADIO_SUPPORTED_PROPS,
11
+ ...CHECKBOX_SPECIFIC_PROPS,
12
+ ]
18
13
 
19
14
  const transform: Transform = attributeTransformFactory({
20
15
  targetComponent: "Checkbox",
@@ -1,24 +1,10 @@
1
1
  import { Transform } from "jscodeshift"
2
2
 
3
- import { addCommentToAttribute } from "../../shared/actions/addCommentToAttribute"
4
- import { getSpreadProps } from "../../shared/actions/getSpreadProps"
5
- import { hasSpreadProps } from "../../shared/actions/hasSpreadProps"
6
- import { attributeTransformFactory } from "../../shared/transformFactories/attributeTransformFactory"
3
+ import { commentOnSpreadPropsFactory } from "../../shared/transformFactories/commentOnSpreadPropsFactory"
7
4
 
8
- const COMMENT =
9
- "Spread props can contain unsupported props, please explore usages and migrate as needed."
10
-
11
- const transform: Transform = attributeTransformFactory({
12
- condition: hasSpreadProps,
5
+ const transform: Transform = commentOnSpreadPropsFactory({
13
6
  targetComponent: "Link",
14
7
  targetPackage: "@planningcenter/tapestry-react",
15
- transform: (element, { j }) => {
16
- const spreadProps = getSpreadProps(element)
17
- spreadProps.forEach((prop) =>
18
- addCommentToAttribute({ attribute: prop, j, text: COMMENT })
19
- )
20
- return spreadProps.length > 0
21
- },
22
8
  })
23
9
 
24
10
  export default transform
@@ -302,10 +302,12 @@ export default function Test({ items }) {
302
302
  }
303
303
  `.trim()
304
304
 
305
- const result = applyTransform(input)
305
+ const result = applyTransform(input)!
306
306
 
307
- expect(result).toContain(
308
- "<Tooltip key={item.id} {...`Save ${item.name}`}>"
307
+ expect(result).toContain("<Tooltip")
308
+ expect(result).toContain("key={item.id}")
309
+ expect(result.replace(/\s+/g, " ")).toContain(
310
+ "{...{ title: `Save ${item.name}` }}"
309
311
  )
310
312
  expect(result).toContain(
311
313
  "<Link href={item.url} onClick={() => save(item)}>"
@@ -1,7 +1,7 @@
1
1
  import { JSXAttribute, Transform } from "jscodeshift"
2
2
 
3
3
  import { addCommentToUnsupportedProps } from "../../shared/actions/addCommentToUnsupportedProps"
4
- import { SUPPORTED_PROPS_BASE } from "../../shared/helpers/unsupportedPropsHelpers"
4
+ import { BUTTON_LINK_SUPPORTED_PROPS } from "../../shared/helpers/unsupportedPropsHelpers"
5
5
  import { attributeTransformFactory } from "../../shared/transformFactories/attributeTransformFactory"
6
6
 
7
7
  // Note: 'target' and 'rel' are NOT included because they are handled by targetBlankToExternal transform
@@ -16,7 +16,7 @@ const LINK_SPECIFIC_PROPS = [
16
16
  "type",
17
17
  ]
18
18
 
19
- const SUPPORTED_PROPS = [...SUPPORTED_PROPS_BASE, ...LINK_SPECIFIC_PROPS]
19
+ const SUPPORTED_PROPS = [...BUTTON_LINK_SUPPORTED_PROPS, ...LINK_SPECIFIC_PROPS]
20
20
 
21
21
  const transform: Transform = attributeTransformFactory({
22
22
  targetComponent: "Link",