@planningcenter/tapestry-migration-cli 3.1.0-rc.2 → 3.1.0-rc.20

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 (115) hide show
  1. package/dist/tapestry-react-shim.cjs +7 -1
  2. package/package.json +3 -3
  3. package/src/components/button/transforms/convertStyleProps.test.ts +97 -0
  4. package/src/components/button/transforms/removeTypeButton.test.ts +0 -1
  5. package/src/components/checkbox/transforms/moveCheckboxImport.test.ts +3 -0
  6. package/src/components/input/index.ts +66 -0
  7. package/src/components/input/transformableInput.ts +49 -0
  8. package/src/components/input/transforms/auditSpreadProps.test.ts +192 -0
  9. package/src/components/input/transforms/auditSpreadProps.ts +26 -0
  10. package/src/components/input/transforms/autoWidthTransform.test.ts +172 -0
  11. package/src/components/input/transforms/autoWidthTransform.ts +41 -0
  12. package/src/components/input/transforms/convertStyleProps.test.ts +128 -0
  13. package/src/components/input/transforms/convertStyleProps.ts +12 -0
  14. package/src/components/input/transforms/highlightOnInteractionToSelectTextOnFocus.test.ts +186 -0
  15. package/src/components/input/transforms/highlightOnInteractionToSelectTextOnFocus.ts +27 -0
  16. package/src/components/input/transforms/inputLabelToLabelProp.test.ts +319 -0
  17. package/src/components/input/transforms/inputLabelToLabelProp.ts +203 -0
  18. package/src/components/input/transforms/mergeFieldIntoInput.test.ts +469 -0
  19. package/src/components/input/transforms/mergeFieldIntoInput.ts +7 -0
  20. package/src/components/input/transforms/mergeInputLabel.test.ts +458 -0
  21. package/src/components/input/transforms/mergeInputLabel.ts +204 -0
  22. package/src/components/input/transforms/moveInputImport.test.ts +166 -0
  23. package/src/components/input/transforms/moveInputImport.ts +14 -0
  24. package/src/components/input/transforms/numberFieldAddTypeNumber.test.ts +92 -0
  25. package/src/components/input/transforms/numberFieldAddTypeNumber.ts +14 -0
  26. package/src/components/input/transforms/numberFieldRenameToInput.test.ts +126 -0
  27. package/src/components/input/transforms/numberFieldRenameToInput.ts +9 -0
  28. package/src/components/input/transforms/removeAsInput.test.ts +139 -0
  29. package/src/components/input/transforms/removeAsInput.ts +20 -0
  30. package/src/components/input/transforms/removeDuplicateKeys.test.ts +302 -0
  31. package/src/components/input/transforms/removeDuplicateKeys.ts +10 -0
  32. package/src/components/input/transforms/removeInputBox.test.ts +352 -0
  33. package/src/components/input/transforms/removeInputBox.ts +109 -0
  34. package/src/components/input/transforms/removeRedundantAriaLabel.test.ts +128 -0
  35. package/src/components/input/transforms/removeRedundantAriaLabel.ts +21 -0
  36. package/src/components/input/transforms/removeTypeInput.test.ts +212 -0
  37. package/src/components/input/transforms/removeTypeInput.ts +22 -0
  38. package/src/components/input/transforms/removeTypeText.test.ts +160 -0
  39. package/src/components/input/transforms/removeTypeText.ts +17 -0
  40. package/src/components/input/transforms/sizeMapping.test.ts +198 -0
  41. package/src/components/input/transforms/sizeMapping.ts +17 -0
  42. package/src/components/input/transforms/skipRenderSideProps.test.ts +236 -0
  43. package/src/components/input/transforms/skipRenderSideProps.ts +27 -0
  44. package/src/components/input/transforms/stateToInvalid.test.ts +208 -0
  45. package/src/components/input/transforms/stateToInvalid.ts +59 -0
  46. package/src/components/input/transforms/stateToInvalidTernary.test.ts +159 -0
  47. package/src/components/input/transforms/stateToInvalidTernary.ts +13 -0
  48. package/src/components/input/transforms/unsupportedProps.test.ts +566 -0
  49. package/src/components/input/transforms/unsupportedProps.ts +84 -0
  50. package/src/components/link/transforms/reviewStyles.test.ts +0 -1
  51. package/src/components/select/index.ts +58 -0
  52. package/src/components/select/transformableSelect.ts +7 -0
  53. package/src/components/select/transforms/auditSpreadProps.test.ts +103 -0
  54. package/src/components/select/transforms/auditSpreadProps.ts +26 -0
  55. package/src/components/select/transforms/childrenToOptions.test.ts +367 -0
  56. package/src/components/select/transforms/childrenToOptions.ts +295 -0
  57. package/src/components/select/transforms/convertLegacyOptions.test.ts +150 -0
  58. package/src/components/select/transforms/convertLegacyOptions.ts +105 -0
  59. package/src/components/select/transforms/convertStyleProps.test.ts +73 -0
  60. package/src/components/select/transforms/convertStyleProps.ts +12 -0
  61. package/src/components/select/transforms/emptyValueToPlaceholder.test.ts +122 -0
  62. package/src/components/select/transforms/emptyValueToPlaceholder.ts +22 -0
  63. package/src/components/select/transforms/innerRefToRef.test.ts +89 -0
  64. package/src/components/select/transforms/innerRefToRef.ts +18 -0
  65. package/src/components/select/transforms/mapChildrenToOptions.test.ts +521 -0
  66. package/src/components/select/transforms/mapChildrenToOptions.ts +312 -0
  67. package/src/components/select/transforms/mergeFieldIntoSelect.test.ts +506 -0
  68. package/src/components/select/transforms/mergeFieldIntoSelect.ts +7 -0
  69. package/src/components/select/transforms/mergeSelectLabel.test.ts +458 -0
  70. package/src/components/select/transforms/mergeSelectLabel.ts +225 -0
  71. package/src/components/select/transforms/moveSelectImport.test.ts +148 -0
  72. package/src/components/select/transforms/moveSelectImport.ts +14 -0
  73. package/src/components/select/transforms/removeDefaultProps.test.ts +249 -0
  74. package/src/components/select/transforms/removeDefaultProps.ts +112 -0
  75. package/src/components/select/transforms/sizeMapping.test.ts +188 -0
  76. package/src/components/select/transforms/sizeMapping.ts +17 -0
  77. package/src/components/select/transforms/skipMultipleSelect.test.ts +148 -0
  78. package/src/components/select/transforms/skipMultipleSelect.ts +23 -0
  79. package/src/components/select/transforms/stateToInvalid.test.ts +217 -0
  80. package/src/components/select/transforms/stateToInvalid.ts +59 -0
  81. package/src/components/select/transforms/stateToInvalidTernary.test.ts +146 -0
  82. package/src/components/select/transforms/stateToInvalidTernary.ts +13 -0
  83. package/src/components/select/transforms/unsupportedProps.test.ts +252 -0
  84. package/src/components/select/transforms/unsupportedProps.ts +44 -0
  85. package/src/components/shared/helpers/getAttributeExpression.ts +26 -0
  86. package/src/components/shared/helpers/unsupportedPropsHelpers.ts +102 -0
  87. package/src/components/shared/transformFactories/helpers/manageImports.ts +14 -12
  88. package/src/components/shared/transformFactories/mergeFieldFactory.ts +244 -0
  89. package/src/components/shared/transformFactories/sizeMappingFactory.ts +9 -2
  90. package/src/components/shared/transformFactories/stylePropTransformFactory.ts +56 -17
  91. package/src/components/shared/transformFactories/ternaryConditionalToPropFactory.ts +65 -0
  92. package/src/components/text-area/index.ts +48 -0
  93. package/src/components/text-area/transforms/auditSpreadProps.test.ts +139 -0
  94. package/src/components/text-area/transforms/auditSpreadProps.ts +10 -0
  95. package/src/components/text-area/transforms/convertStyleProps.test.ts +158 -0
  96. package/src/components/text-area/transforms/convertStyleProps.ts +10 -0
  97. package/src/components/text-area/transforms/innerRefToRef.test.ts +206 -0
  98. package/src/components/text-area/transforms/innerRefToRef.ts +14 -0
  99. package/src/components/text-area/transforms/mergeFieldIntoTextArea.test.ts +477 -0
  100. package/src/components/text-area/transforms/mergeFieldIntoTextArea.ts +5 -0
  101. package/src/components/text-area/transforms/moveTextAreaImport.test.ts +168 -0
  102. package/src/components/text-area/transforms/moveTextAreaImport.ts +13 -0
  103. package/src/components/text-area/transforms/removeDuplicateKeys.test.ts +129 -0
  104. package/src/components/text-area/transforms/removeDuplicateKeys.ts +8 -0
  105. package/src/components/text-area/transforms/removeRedundantAriaLabel.test.ts +183 -0
  106. package/src/components/text-area/transforms/removeRedundantAriaLabel.ts +59 -0
  107. package/src/components/text-area/transforms/sizeMapping.test.ts +199 -0
  108. package/src/components/text-area/transforms/sizeMapping.ts +15 -0
  109. package/src/components/text-area/transforms/stateToInvalid.test.ts +204 -0
  110. package/src/components/text-area/transforms/stateToInvalid.ts +57 -0
  111. package/src/components/text-area/transforms/stateToInvalidTernary.test.ts +133 -0
  112. package/src/components/text-area/transforms/stateToInvalidTernary.ts +11 -0
  113. package/src/components/text-area/transforms/unsupportedProps.test.ts +275 -0
  114. package/src/components/text-area/transforms/unsupportedProps.ts +35 -0
  115. package/src/index.ts +2 -1
@@ -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: "TextArea",
7
+ targetPackage: "@planningcenter/tapestry-react",
8
+ })
9
+
10
+ export default transform
@@ -0,0 +1,158 @@
1
+ import jscodeshift from "jscodeshift"
2
+ import { describe, expect, it } from "vitest"
3
+
4
+ import transform from "./convertStyleProps"
5
+
6
+ const j = jscodeshift.withParser("tsx")
7
+
8
+ function applyTransform(source: string, options = {}) {
9
+ const fileInfo = { path: "test.tsx", source }
10
+ const result = transform(
11
+ fileInfo,
12
+ { j, jscodeshift: j, report: () => {}, stats: () => {} },
13
+ options
14
+ ) as string | null
15
+ return result || source
16
+ }
17
+
18
+ describe("convertStyleProps transform", () => {
19
+ describe("visible prop - handled by theme system", () => {
20
+ it("should convert visible={false} to display: none", () => {
21
+ const source = `
22
+ import { TextArea } from "@planningcenter/tapestry-react"
23
+
24
+ export function TestComponent() {
25
+ return <TextArea visible={false} label="Hidden TextArea" />
26
+ }
27
+ `
28
+
29
+ const result = applyTransform(source)
30
+
31
+ expect(result).toContain("style={{")
32
+ expect(result).toContain('display: "none"')
33
+ expect(result).not.toContain("visible={false}")
34
+ })
35
+
36
+ it("should remove visible={true} with no style changes (true is default)", () => {
37
+ const source = `
38
+ import { TextArea } from "@planningcenter/tapestry-react"
39
+
40
+ export function TestComponent() {
41
+ return <TextArea visible={true} label="Visible TextArea" />
42
+ }
43
+ `
44
+
45
+ const result = applyTransform(source)
46
+
47
+ expect(result).not.toContain("visible={true}")
48
+ expect(result).not.toContain("style={{")
49
+ expect(result).toContain('<TextArea label="Visible TextArea" />')
50
+ })
51
+
52
+ it("should handle visible expressions", () => {
53
+ const source = `
54
+ import { TextArea } from "@planningcenter/tapestry-react"
55
+
56
+ export function TestComponent() {
57
+ const isVisible = true
58
+ return <TextArea visible={isVisible} label="Variable TextArea" />
59
+ }
60
+ `
61
+
62
+ const result = applyTransform(source)
63
+
64
+ expect(result).toContain("visible: isVisible")
65
+ expect(result).toContain("style={{")
66
+ })
67
+ })
68
+
69
+ describe("style prop removal", () => {
70
+ it("should remove alignItems prop", () => {
71
+ const source = `
72
+ import { TextArea } from "@planningcenter/tapestry-react"
73
+
74
+ export function TestComponent() {
75
+ return <TextArea alignItems="center" label="Test" />
76
+ }
77
+ `
78
+
79
+ const result = applyTransform(source)
80
+
81
+ expect(result).not.toContain("alignItems=")
82
+ })
83
+
84
+ it("should remove marginTop prop", () => {
85
+ const source = `
86
+ import { TextArea } from "@planningcenter/tapestry-react"
87
+
88
+ export function TestComponent() {
89
+ return <TextArea marginTop={16} label="Test" />
90
+ }
91
+ `
92
+
93
+ const result = applyTransform(source)
94
+
95
+ expect(result).not.toContain("marginTop=")
96
+ })
97
+
98
+ it("should remove multiple style props", () => {
99
+ const source = `
100
+ import { TextArea } from "@planningcenter/tapestry-react"
101
+
102
+ export function TestComponent() {
103
+ return <TextArea alignItems="center" marginTop={16} label="Test" />
104
+ }
105
+ `
106
+
107
+ const result = applyTransform(source)
108
+
109
+ expect(result).not.toContain("alignItems=")
110
+ expect(result).not.toContain("marginTop=")
111
+ })
112
+ })
113
+
114
+ describe("combination of style props", () => {
115
+ it("should handle combination of visible and style props", () => {
116
+ const source = `
117
+ import { TextArea } from "@planningcenter/tapestry-react"
118
+
119
+ export function TestComponent() {
120
+ return (
121
+ <TextArea
122
+ visible={false}
123
+ alignItems="center"
124
+ marginTop={16}
125
+ label="Combined TextArea"
126
+ />
127
+ )
128
+ }
129
+ `
130
+
131
+ const result = applyTransform(source)
132
+
133
+ expect(result).toContain("style={{")
134
+ expect(result).toContain('display: "none"')
135
+ expect(result).not.toContain("visible={false}")
136
+ expect(result).not.toContain("alignItems=")
137
+ expect(result).not.toContain("marginTop=")
138
+ })
139
+ })
140
+
141
+ describe("import handling", () => {
142
+ it("should not affect imports", () => {
143
+ const source = `
144
+ import { TextArea } from "@planningcenter/tapestry-react"
145
+
146
+ export function TestComponent() {
147
+ return <TextArea visible={false} label="Test" />
148
+ }
149
+ `
150
+
151
+ const result = applyTransform(source)
152
+
153
+ expect(result).toContain(
154
+ 'import { TextArea } from "@planningcenter/tapestry-react"'
155
+ )
156
+ })
157
+ })
158
+ })
@@ -0,0 +1,10 @@
1
+ import { stackViewPlugin } from "../../../stubs/stackViewPlugin"
2
+ import { stylePropTransformFactory } from "../../shared/transformFactories/stylePropTransformFactory"
3
+
4
+ export default stylePropTransformFactory({
5
+ plugin: stackViewPlugin,
6
+ stylesToKeep: ["visible"],
7
+ stylesToRemove: [],
8
+ targetComponent: "TextArea",
9
+ targetPackage: "@planningcenter/tapestry-react",
10
+ })
@@ -0,0 +1,206 @@
1
+ import jscodeshift from "jscodeshift"
2
+ import { describe, expect, it } from "vitest"
3
+
4
+ import transform from "./innerRefToRef"
5
+
6
+ const j = jscodeshift.withParser("tsx")
7
+
8
+ function applyTransform(source: string, verbose = false): string {
9
+ const fileInfo = { path: "test.tsx", source }
10
+ const result = transform(
11
+ fileInfo,
12
+ { j, jscodeshift: j, report: () => {}, stats: () => {} },
13
+ { verbose }
14
+ ) as string | null
15
+ return result || source
16
+ }
17
+
18
+ describe("innerRefToRef transform", () => {
19
+ describe("innerRef to ref conversion", () => {
20
+ it("should convert innerRef to ref", () => {
21
+ const input = `
22
+ import { TextArea } from "@planningcenter/tapestry-react"
23
+
24
+ function Test() {
25
+ const textareaRef = React.useRef()
26
+ return <TextArea innerRef={textareaRef} label="Notes" />
27
+ }
28
+ `.trim()
29
+
30
+ const result = applyTransform(input)
31
+ expect(result).toContain("ref={textareaRef}")
32
+ expect(result).not.toContain("innerRef=")
33
+ })
34
+
35
+ it("should convert innerRef with expression", () => {
36
+ const input = `
37
+ import { TextArea } from "@planningcenter/tapestry-react"
38
+
39
+ function Test() {
40
+ return <TextArea innerRef={myRef} label="Notes" />
41
+ }
42
+ `.trim()
43
+
44
+ const result = applyTransform(input)
45
+ expect(result).toContain("ref={myRef}")
46
+ expect(result).not.toContain("innerRef=")
47
+ })
48
+
49
+ it("should convert innerRef with callback", () => {
50
+ const input = `
51
+ import { TextArea } from "@planningcenter/tapestry-react"
52
+
53
+ function Test() {
54
+ return <TextArea innerRef={(el) => console.log(el)} label="Notes" />
55
+ }
56
+ `.trim()
57
+
58
+ const result = applyTransform(input)
59
+ expect(result).toContain("ref={(el) => console.log(el)}")
60
+ expect(result).not.toContain("innerRef=")
61
+ })
62
+
63
+ it("should not affect existing ref props", () => {
64
+ const input = `
65
+ import { TextArea } from "@planningcenter/tapestry-react"
66
+
67
+ function Test() {
68
+ const textareaRef = React.useRef()
69
+ return <TextArea ref={textareaRef} label="Notes" />
70
+ }
71
+ `.trim()
72
+
73
+ const result = applyTransform(input)
74
+ expect(result).toContain("ref={textareaRef}")
75
+ expect(result).not.toContain("innerRef=")
76
+ })
77
+
78
+ it("should handle multiple TextAreas", () => {
79
+ const input = `
80
+ import { TextArea } from "@planningcenter/tapestry-react"
81
+
82
+ function Test() {
83
+ const ref1 = React.useRef()
84
+ const ref2 = React.useRef()
85
+ return (
86
+ <div>
87
+ <TextArea innerRef={ref1} label="First" />
88
+ <TextArea innerRef={ref2} label="Second" />
89
+ </div>
90
+ )
91
+ }
92
+ `.trim()
93
+
94
+ const result = applyTransform(input)
95
+ expect(result).toContain("ref={ref1}")
96
+ expect(result).toContain("ref={ref2}")
97
+ expect(result).not.toContain("innerRef=")
98
+ })
99
+ })
100
+
101
+ describe("edge cases", () => {
102
+ it("should not affect other components", () => {
103
+ const input = `
104
+ import { Button, TextArea } from "@planningcenter/tapestry-react"
105
+
106
+ function Test() {
107
+ const buttonRef = React.useRef()
108
+ const textareaRef = React.useRef()
109
+ return (
110
+ <div>
111
+ <Button innerRef={buttonRef}>Click me</Button>
112
+ <TextArea innerRef={textareaRef} label="Notes" />
113
+ </div>
114
+ )
115
+ }
116
+ `.trim()
117
+
118
+ const result = applyTransform(input)
119
+ expect(result).toContain("<Button innerRef={buttonRef}>Click me</Button>")
120
+ expect(result).toContain("ref={textareaRef}")
121
+ })
122
+
123
+ it("should handle TextArea without innerRef", () => {
124
+ const input = `
125
+ import { TextArea } from "@planningcenter/tapestry-react"
126
+
127
+ function Test() {
128
+ return <TextArea label="Notes" />
129
+ }
130
+ `.trim()
131
+
132
+ const result = applyTransform(input)
133
+ expect(result).toContain('<TextArea label="Notes" />')
134
+ })
135
+
136
+ it("should preserve other props", () => {
137
+ const input = `
138
+ import { TextArea } from "@planningcenter/tapestry-react"
139
+
140
+ function Test() {
141
+ const textareaRef = React.useRef()
142
+ return (
143
+ <TextArea
144
+ innerRef={textareaRef}
145
+ label="Notes"
146
+ rows={5}
147
+ disabled
148
+ />
149
+ )
150
+ }
151
+ `.trim()
152
+
153
+ const result = applyTransform(input)
154
+ expect(result).toContain("ref={textareaRef}")
155
+ expect(result).toContain('label="Notes"')
156
+ expect(result).toContain("rows={5}")
157
+ expect(result).toContain("disabled")
158
+ expect(result).not.toContain("innerRef=")
159
+ })
160
+
161
+ it("should not transform if not imported from @planningcenter/tapestry-react", () => {
162
+ const input = `
163
+ import { TextArea } from "other-library"
164
+
165
+ function Test() {
166
+ return <TextArea innerRef={myRef} label="Notes" />
167
+ }
168
+ `.trim()
169
+
170
+ const result = applyTransform(input)
171
+ expect(result).toContain("innerRef={myRef}")
172
+ })
173
+
174
+ it("should handle alias import", () => {
175
+ const input = `
176
+ import { TextArea as MyTextArea } from "@planningcenter/tapestry-react"
177
+
178
+ function Test() {
179
+ return <MyTextArea innerRef={myRef} label="Notes" />
180
+ }
181
+ `.trim()
182
+
183
+ const result = applyTransform(input)
184
+ expect(result).toContain("ref={myRef}")
185
+ expect(result).not.toContain("innerRef=")
186
+ })
187
+
188
+ it("should add CHANGED comment when verbose is enabled", () => {
189
+ const input = `
190
+ import { TextArea } from "@planningcenter/tapestry-react"
191
+
192
+ function Test() {
193
+ const textareaRef = React.useRef()
194
+ return <TextArea innerRef={textareaRef} label="Notes" />
195
+ }
196
+ `.trim()
197
+
198
+ const result = applyTransform(input, true)
199
+ expect(result).toContain("ref={textareaRef}")
200
+ expect(result).not.toContain("innerRef=")
201
+ expect(result).toContain(
202
+ "CHANGED: tapestry-migration (ref): renamed from innerRef"
203
+ )
204
+ })
205
+ })
206
+ })
@@ -0,0 +1,14 @@
1
+ import { transformAttributeName } from "../../shared/actions/transformAttributeName"
2
+ import { hasAttribute } from "../../shared/conditions/hasAttribute"
3
+ import { attributeTransformFactory } from "../../shared/transformFactories/attributeTransformFactory"
4
+
5
+ const transform = attributeTransformFactory({
6
+ condition: hasAttribute("innerRef"),
7
+ targetComponent: "TextArea",
8
+ targetPackage: "@planningcenter/tapestry-react",
9
+ transform: (element, { j, options }) => {
10
+ return transformAttributeName("innerRef", "ref", { element, j, options })
11
+ },
12
+ })
13
+
14
+ export default transform