@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.
- package/dist/tapestry-react-shim.cjs +7 -1
- package/package.json +3 -3
- package/src/components/button/transforms/convertStyleProps.test.ts +97 -0
- package/src/components/button/transforms/removeTypeButton.test.ts +0 -1
- package/src/components/checkbox/transforms/moveCheckboxImport.test.ts +3 -0
- package/src/components/input/index.ts +66 -0
- package/src/components/input/transformableInput.ts +49 -0
- package/src/components/input/transforms/auditSpreadProps.test.ts +192 -0
- package/src/components/input/transforms/auditSpreadProps.ts +26 -0
- package/src/components/input/transforms/autoWidthTransform.test.ts +172 -0
- package/src/components/input/transforms/autoWidthTransform.ts +41 -0
- package/src/components/input/transforms/convertStyleProps.test.ts +128 -0
- package/src/components/input/transforms/convertStyleProps.ts +12 -0
- package/src/components/input/transforms/highlightOnInteractionToSelectTextOnFocus.test.ts +186 -0
- package/src/components/input/transforms/highlightOnInteractionToSelectTextOnFocus.ts +27 -0
- package/src/components/input/transforms/inputLabelToLabelProp.test.ts +319 -0
- package/src/components/input/transforms/inputLabelToLabelProp.ts +203 -0
- package/src/components/input/transforms/mergeFieldIntoInput.test.ts +469 -0
- package/src/components/input/transforms/mergeFieldIntoInput.ts +7 -0
- package/src/components/input/transforms/mergeInputLabel.test.ts +458 -0
- package/src/components/input/transforms/mergeInputLabel.ts +204 -0
- package/src/components/input/transforms/moveInputImport.test.ts +166 -0
- package/src/components/input/transforms/moveInputImport.ts +14 -0
- package/src/components/input/transforms/numberFieldAddTypeNumber.test.ts +92 -0
- package/src/components/input/transforms/numberFieldAddTypeNumber.ts +14 -0
- package/src/components/input/transforms/numberFieldRenameToInput.test.ts +126 -0
- package/src/components/input/transforms/numberFieldRenameToInput.ts +9 -0
- package/src/components/input/transforms/removeAsInput.test.ts +139 -0
- package/src/components/input/transforms/removeAsInput.ts +20 -0
- package/src/components/input/transforms/removeDuplicateKeys.test.ts +302 -0
- package/src/components/input/transforms/removeDuplicateKeys.ts +10 -0
- package/src/components/input/transforms/removeInputBox.test.ts +352 -0
- package/src/components/input/transforms/removeInputBox.ts +109 -0
- package/src/components/input/transforms/removeRedundantAriaLabel.test.ts +128 -0
- package/src/components/input/transforms/removeRedundantAriaLabel.ts +21 -0
- package/src/components/input/transforms/removeTypeInput.test.ts +212 -0
- package/src/components/input/transforms/removeTypeInput.ts +22 -0
- package/src/components/input/transforms/removeTypeText.test.ts +160 -0
- package/src/components/input/transforms/removeTypeText.ts +17 -0
- package/src/components/input/transforms/sizeMapping.test.ts +198 -0
- package/src/components/input/transforms/sizeMapping.ts +17 -0
- package/src/components/input/transforms/skipRenderSideProps.test.ts +236 -0
- package/src/components/input/transforms/skipRenderSideProps.ts +27 -0
- package/src/components/input/transforms/stateToInvalid.test.ts +208 -0
- package/src/components/input/transforms/stateToInvalid.ts +59 -0
- package/src/components/input/transforms/stateToInvalidTernary.test.ts +159 -0
- package/src/components/input/transforms/stateToInvalidTernary.ts +13 -0
- package/src/components/input/transforms/unsupportedProps.test.ts +566 -0
- package/src/components/input/transforms/unsupportedProps.ts +84 -0
- package/src/components/link/transforms/reviewStyles.test.ts +0 -1
- package/src/components/select/index.ts +58 -0
- package/src/components/select/transformableSelect.ts +7 -0
- package/src/components/select/transforms/auditSpreadProps.test.ts +103 -0
- package/src/components/select/transforms/auditSpreadProps.ts +26 -0
- package/src/components/select/transforms/childrenToOptions.test.ts +367 -0
- package/src/components/select/transforms/childrenToOptions.ts +295 -0
- package/src/components/select/transforms/convertLegacyOptions.test.ts +150 -0
- package/src/components/select/transforms/convertLegacyOptions.ts +105 -0
- package/src/components/select/transforms/convertStyleProps.test.ts +73 -0
- package/src/components/select/transforms/convertStyleProps.ts +12 -0
- package/src/components/select/transforms/emptyValueToPlaceholder.test.ts +122 -0
- package/src/components/select/transforms/emptyValueToPlaceholder.ts +22 -0
- package/src/components/select/transforms/innerRefToRef.test.ts +89 -0
- package/src/components/select/transforms/innerRefToRef.ts +18 -0
- package/src/components/select/transforms/mapChildrenToOptions.test.ts +521 -0
- package/src/components/select/transforms/mapChildrenToOptions.ts +312 -0
- package/src/components/select/transforms/mergeFieldIntoSelect.test.ts +506 -0
- package/src/components/select/transforms/mergeFieldIntoSelect.ts +7 -0
- package/src/components/select/transforms/mergeSelectLabel.test.ts +458 -0
- package/src/components/select/transforms/mergeSelectLabel.ts +225 -0
- package/src/components/select/transforms/moveSelectImport.test.ts +148 -0
- package/src/components/select/transforms/moveSelectImport.ts +14 -0
- package/src/components/select/transforms/removeDefaultProps.test.ts +249 -0
- package/src/components/select/transforms/removeDefaultProps.ts +112 -0
- package/src/components/select/transforms/sizeMapping.test.ts +188 -0
- package/src/components/select/transforms/sizeMapping.ts +17 -0
- package/src/components/select/transforms/skipMultipleSelect.test.ts +148 -0
- package/src/components/select/transforms/skipMultipleSelect.ts +23 -0
- package/src/components/select/transforms/stateToInvalid.test.ts +217 -0
- package/src/components/select/transforms/stateToInvalid.ts +59 -0
- package/src/components/select/transforms/stateToInvalidTernary.test.ts +146 -0
- package/src/components/select/transforms/stateToInvalidTernary.ts +13 -0
- package/src/components/select/transforms/unsupportedProps.test.ts +252 -0
- package/src/components/select/transforms/unsupportedProps.ts +44 -0
- package/src/components/shared/helpers/getAttributeExpression.ts +26 -0
- package/src/components/shared/helpers/unsupportedPropsHelpers.ts +102 -0
- package/src/components/shared/transformFactories/helpers/manageImports.ts +14 -12
- package/src/components/shared/transformFactories/mergeFieldFactory.ts +244 -0
- package/src/components/shared/transformFactories/sizeMappingFactory.ts +9 -2
- package/src/components/shared/transformFactories/stylePropTransformFactory.ts +56 -17
- package/src/components/shared/transformFactories/ternaryConditionalToPropFactory.ts +65 -0
- package/src/components/text-area/index.ts +48 -0
- package/src/components/text-area/transforms/auditSpreadProps.test.ts +139 -0
- package/src/components/text-area/transforms/auditSpreadProps.ts +10 -0
- package/src/components/text-area/transforms/convertStyleProps.test.ts +158 -0
- package/src/components/text-area/transforms/convertStyleProps.ts +10 -0
- package/src/components/text-area/transforms/innerRefToRef.test.ts +206 -0
- package/src/components/text-area/transforms/innerRefToRef.ts +14 -0
- package/src/components/text-area/transforms/mergeFieldIntoTextArea.test.ts +477 -0
- package/src/components/text-area/transforms/mergeFieldIntoTextArea.ts +5 -0
- package/src/components/text-area/transforms/moveTextAreaImport.test.ts +168 -0
- package/src/components/text-area/transforms/moveTextAreaImport.ts +13 -0
- package/src/components/text-area/transforms/removeDuplicateKeys.test.ts +129 -0
- package/src/components/text-area/transforms/removeDuplicateKeys.ts +8 -0
- package/src/components/text-area/transforms/removeRedundantAriaLabel.test.ts +183 -0
- package/src/components/text-area/transforms/removeRedundantAriaLabel.ts +59 -0
- package/src/components/text-area/transforms/sizeMapping.test.ts +199 -0
- package/src/components/text-area/transforms/sizeMapping.ts +15 -0
- package/src/components/text-area/transforms/stateToInvalid.test.ts +204 -0
- package/src/components/text-area/transforms/stateToInvalid.ts +57 -0
- package/src/components/text-area/transforms/stateToInvalidTernary.test.ts +133 -0
- package/src/components/text-area/transforms/stateToInvalidTernary.ts +11 -0
- package/src/components/text-area/transforms/unsupportedProps.test.ts +275 -0
- package/src/components/text-area/transforms/unsupportedProps.ts +35 -0
- package/src/index.ts +2 -1
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import jscodeshift from "jscodeshift"
|
|
2
|
+
import { describe, expect, it } from "vitest"
|
|
3
|
+
|
|
4
|
+
import transform from "./unsupportedProps"
|
|
5
|
+
|
|
6
|
+
const j = jscodeshift.withParser("tsx")
|
|
7
|
+
|
|
8
|
+
function applyTransform(source: string): string {
|
|
9
|
+
const fileInfo = { path: "test.tsx", source }
|
|
10
|
+
const result = transform(
|
|
11
|
+
fileInfo,
|
|
12
|
+
{ j, jscodeshift: j, report: () => {}, stats: () => {} },
|
|
13
|
+
{}
|
|
14
|
+
) as string | null
|
|
15
|
+
return result || source
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
describe("unsupportedProps transform", () => {
|
|
19
|
+
describe("unsupported prop detection", () => {
|
|
20
|
+
it("should add comment for css prop with specific message", () => {
|
|
21
|
+
const input = `
|
|
22
|
+
import { Select } from "@planningcenter/tapestry-react"
|
|
23
|
+
|
|
24
|
+
function Test() {
|
|
25
|
+
return <Select css={{ color: 'red' }} emptyValue="Pick" />
|
|
26
|
+
}
|
|
27
|
+
`.trim()
|
|
28
|
+
|
|
29
|
+
const result = applyTransform(input)
|
|
30
|
+
expect(result).toContain("TODO: tapestry-migration (css)")
|
|
31
|
+
expect(result).toContain(
|
|
32
|
+
"CSS prop is not supported. Use className or style prop instead."
|
|
33
|
+
)
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it("should add comment for tooltip prop with specific message", () => {
|
|
37
|
+
const input = `
|
|
38
|
+
import { Select } from "@planningcenter/tapestry-react"
|
|
39
|
+
|
|
40
|
+
function Test() {
|
|
41
|
+
return <Select tooltip={{ content: "Help" }} emptyValue="Pick" />
|
|
42
|
+
}
|
|
43
|
+
`.trim()
|
|
44
|
+
|
|
45
|
+
const result = applyTransform(input)
|
|
46
|
+
expect(result).toContain("TODO: tapestry-migration (tooltip)")
|
|
47
|
+
expect(result).toContain("unsupported anti-pattern")
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
it("should skip Select with multiple prop (handled by skipMultipleSelect)", () => {
|
|
51
|
+
const input = `
|
|
52
|
+
import { Select } from "@planningcenter/tapestry-react"
|
|
53
|
+
|
|
54
|
+
function Test() {
|
|
55
|
+
return <Select multiple emptyValue="Pick" />
|
|
56
|
+
}
|
|
57
|
+
`.trim()
|
|
58
|
+
|
|
59
|
+
const result = applyTransform(input)
|
|
60
|
+
expect(result).not.toContain("TODO: tapestry-migration")
|
|
61
|
+
expect(result).toContain("multiple")
|
|
62
|
+
expect(result).toContain('emptyValue="Pick"')
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it("should add comment for renderValue prop", () => {
|
|
66
|
+
const input = `
|
|
67
|
+
import { Select } from "@planningcenter/tapestry-react"
|
|
68
|
+
|
|
69
|
+
function Test() {
|
|
70
|
+
return <Select renderValue={(opts) => opts.map(o => o.label)} emptyValue="Pick" />
|
|
71
|
+
}
|
|
72
|
+
`.trim()
|
|
73
|
+
|
|
74
|
+
const result = applyTransform(input)
|
|
75
|
+
expect(result).toContain("TODO: tapestry-migration (renderValue)")
|
|
76
|
+
expect(result).toContain("renderValue is not supported")
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it("should add comments for removed props", () => {
|
|
80
|
+
const input = `
|
|
81
|
+
import { Select } from "@planningcenter/tapestry-react"
|
|
82
|
+
|
|
83
|
+
function Test() {
|
|
84
|
+
return (
|
|
85
|
+
<Select
|
|
86
|
+
keepInView
|
|
87
|
+
lockScrollWhileOpen
|
|
88
|
+
popoverProps={{ maxHeight: 300 }}
|
|
89
|
+
renderTo="body"
|
|
90
|
+
placeholder="Pick"
|
|
91
|
+
options={[]}
|
|
92
|
+
label="Test"
|
|
93
|
+
/>
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
`.trim()
|
|
97
|
+
|
|
98
|
+
const result = applyTransform(input)
|
|
99
|
+
expect(result).toContain("TODO: tapestry-migration (keepInView)")
|
|
100
|
+
expect(result).toContain("TODO: tapestry-migration (lockScrollWhileOpen)")
|
|
101
|
+
expect(result).toContain("TODO: tapestry-migration (popoverProps)")
|
|
102
|
+
expect(result).toContain("TODO: tapestry-migration (renderTo)")
|
|
103
|
+
})
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
describe("supported props", () => {
|
|
107
|
+
it("should not add comments for supported select props", () => {
|
|
108
|
+
const input = `
|
|
109
|
+
import { Select } from "@planningcenter/tapestry-react"
|
|
110
|
+
|
|
111
|
+
function Test() {
|
|
112
|
+
return (
|
|
113
|
+
<Select
|
|
114
|
+
disabled
|
|
115
|
+
name="select"
|
|
116
|
+
onChange={() => {}}
|
|
117
|
+
value="test"
|
|
118
|
+
placeholder="Pick one"
|
|
119
|
+
options={options}
|
|
120
|
+
/>
|
|
121
|
+
)
|
|
122
|
+
}
|
|
123
|
+
`.trim()
|
|
124
|
+
|
|
125
|
+
const result = applyTransform(input)
|
|
126
|
+
expect(result).not.toContain("TODO: tapestry-migration")
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
it("should not add comments for common props", () => {
|
|
130
|
+
const input = `
|
|
131
|
+
import { Select } from "@planningcenter/tapestry-react"
|
|
132
|
+
|
|
133
|
+
function Test() {
|
|
134
|
+
return (
|
|
135
|
+
<Select
|
|
136
|
+
className="test"
|
|
137
|
+
id="select"
|
|
138
|
+
style={{ color: 'red' }}
|
|
139
|
+
tabIndex={0}
|
|
140
|
+
label="Test"
|
|
141
|
+
placeholder="Pick"
|
|
142
|
+
options={[]}
|
|
143
|
+
/>
|
|
144
|
+
)
|
|
145
|
+
}
|
|
146
|
+
`.trim()
|
|
147
|
+
|
|
148
|
+
const result = applyTransform(input)
|
|
149
|
+
expect(result).not.toContain("TODO: tapestry-migration")
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
it("should not add comments for aria props", () => {
|
|
153
|
+
const input = `
|
|
154
|
+
import { Select } from "@planningcenter/tapestry-react"
|
|
155
|
+
|
|
156
|
+
function Test() {
|
|
157
|
+
return (
|
|
158
|
+
<Select
|
|
159
|
+
aria-label="Test select"
|
|
160
|
+
aria-describedby="description"
|
|
161
|
+
placeholder="Pick"
|
|
162
|
+
options={[]}
|
|
163
|
+
label="Test"
|
|
164
|
+
/>
|
|
165
|
+
)
|
|
166
|
+
}
|
|
167
|
+
`.trim()
|
|
168
|
+
|
|
169
|
+
const result = applyTransform(input)
|
|
170
|
+
expect(result).not.toContain("TODO: tapestry-migration")
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
it("should not add comments for data props", () => {
|
|
174
|
+
const input = `
|
|
175
|
+
import { Select } from "@planningcenter/tapestry-react"
|
|
176
|
+
|
|
177
|
+
function Test() {
|
|
178
|
+
return (
|
|
179
|
+
<Select
|
|
180
|
+
data-testid="select"
|
|
181
|
+
data-cy="test-select"
|
|
182
|
+
placeholder="Pick"
|
|
183
|
+
options={[]}
|
|
184
|
+
label="Test"
|
|
185
|
+
/>
|
|
186
|
+
)
|
|
187
|
+
}
|
|
188
|
+
`.trim()
|
|
189
|
+
|
|
190
|
+
const result = applyTransform(input)
|
|
191
|
+
expect(result).not.toContain("TODO: tapestry-migration")
|
|
192
|
+
})
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
describe("edge cases", () => {
|
|
196
|
+
it("should not affect Select without unsupported props", () => {
|
|
197
|
+
const input = `
|
|
198
|
+
import { Select } from "@planningcenter/tapestry-react"
|
|
199
|
+
|
|
200
|
+
function Test() {
|
|
201
|
+
return <Select label="Test" placeholder="Pick" options={[]} />
|
|
202
|
+
}
|
|
203
|
+
`.trim()
|
|
204
|
+
|
|
205
|
+
const result = applyTransform(input)
|
|
206
|
+
expect(result).toBe(input)
|
|
207
|
+
})
|
|
208
|
+
|
|
209
|
+
it("should not affect other components", () => {
|
|
210
|
+
const input = `
|
|
211
|
+
import { Button, Select } from "@planningcenter/tapestry-react"
|
|
212
|
+
|
|
213
|
+
function Test() {
|
|
214
|
+
return (
|
|
215
|
+
<div>
|
|
216
|
+
<Button css={{ color: 'red' }}>Click me</Button>
|
|
217
|
+
<Select label="Test" placeholder="Pick" options={[]} />
|
|
218
|
+
</div>
|
|
219
|
+
)
|
|
220
|
+
}
|
|
221
|
+
`.trim()
|
|
222
|
+
|
|
223
|
+
const result = applyTransform(input)
|
|
224
|
+
expect(result).not.toContain("TODO: tapestry-migration")
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
it("should handle mixed supported and unsupported props", () => {
|
|
228
|
+
const input = `
|
|
229
|
+
import { Select } from "@planningcenter/tapestry-react"
|
|
230
|
+
|
|
231
|
+
function Test() {
|
|
232
|
+
return (
|
|
233
|
+
<Select
|
|
234
|
+
disabled
|
|
235
|
+
css={{ color: 'red' }}
|
|
236
|
+
tooltip={{ content: "help" }}
|
|
237
|
+
label="Test"
|
|
238
|
+
placeholder="Pick"
|
|
239
|
+
options={[]}
|
|
240
|
+
/>
|
|
241
|
+
)
|
|
242
|
+
}
|
|
243
|
+
`.trim()
|
|
244
|
+
|
|
245
|
+
const result = applyTransform(input)
|
|
246
|
+
expect(result).toContain("TODO: tapestry-migration (css)")
|
|
247
|
+
expect(result).toContain("TODO: tapestry-migration (tooltip)")
|
|
248
|
+
expect(result).toContain("disabled")
|
|
249
|
+
expect(result).toContain('label="Test"')
|
|
250
|
+
})
|
|
251
|
+
})
|
|
252
|
+
})
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { JSXAttribute, Transform } from "jscodeshift"
|
|
2
|
+
|
|
3
|
+
import { addCommentToUnsupportedProps } from "../../shared/actions/addCommentToUnsupportedProps"
|
|
4
|
+
import { SELECT_SUPPORTED_PROPS } from "../../shared/helpers/unsupportedPropsHelpers"
|
|
5
|
+
import { attributeTransformFactory } from "../../shared/transformFactories/attributeTransformFactory"
|
|
6
|
+
import { transformableSelect } from "../transformableSelect"
|
|
7
|
+
|
|
8
|
+
const transform: Transform = attributeTransformFactory({
|
|
9
|
+
condition: transformableSelect,
|
|
10
|
+
targetComponent: "Select",
|
|
11
|
+
targetPackage: "@planningcenter/tapestry-react",
|
|
12
|
+
transform: (element, { j }) => {
|
|
13
|
+
const UNSUPPORTED_PROPS = (element.openingElement.attributes || [])
|
|
14
|
+
.filter(
|
|
15
|
+
(attr) =>
|
|
16
|
+
attr.type === "JSXAttribute" &&
|
|
17
|
+
attr.name.type === "JSXIdentifier" &&
|
|
18
|
+
!SELECT_SUPPORTED_PROPS.includes(attr.name.name as string) &&
|
|
19
|
+
!(attr.name.name as string).startsWith("aria-") &&
|
|
20
|
+
!(attr.name.name as string).startsWith("data-")
|
|
21
|
+
)
|
|
22
|
+
.map((attr) => (attr as JSXAttribute).name.name as string)
|
|
23
|
+
|
|
24
|
+
return addCommentToUnsupportedProps({
|
|
25
|
+
element,
|
|
26
|
+
j,
|
|
27
|
+
messageSuffix: (prop) => {
|
|
28
|
+
if (prop === "css") {
|
|
29
|
+
return "\n * CSS prop is not supported. Use className or style prop instead.\n"
|
|
30
|
+
}
|
|
31
|
+
if (prop === "tooltip") {
|
|
32
|
+
return "\n * Wrapping a select in a tooltip is an unsupported anti-pattern.\n"
|
|
33
|
+
}
|
|
34
|
+
if (prop === "renderValue") {
|
|
35
|
+
return "\n * renderValue is not supported. The select displays the selected option label.\n"
|
|
36
|
+
}
|
|
37
|
+
return ""
|
|
38
|
+
},
|
|
39
|
+
props: UNSUPPORTED_PROPS,
|
|
40
|
+
})
|
|
41
|
+
},
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
export default transform
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Expression, JSXElement } from "jscodeshift"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Gets the expression AST node for a JSX attribute value.
|
|
5
|
+
* Returns the expression node for dynamic values, or a StringLiteral for static ones.
|
|
6
|
+
*/
|
|
7
|
+
export function getAttributeExpression(
|
|
8
|
+
element: JSXElement,
|
|
9
|
+
attrName: string
|
|
10
|
+
): Expression | null {
|
|
11
|
+
const attrs = element.openingElement.attributes || []
|
|
12
|
+
for (const attr of attrs) {
|
|
13
|
+
if (attr.type !== "JSXAttribute") continue
|
|
14
|
+
if (attr.name.name !== attrName) continue
|
|
15
|
+
|
|
16
|
+
if (!attr.value) return null // boolean shorthand has no expression
|
|
17
|
+
if (attr.value.type === "StringLiteral") return attr.value
|
|
18
|
+
if (attr.value.type === "JSXExpressionContainer") {
|
|
19
|
+
const expr = attr.value.expression
|
|
20
|
+
if (expr.type === "JSXEmptyExpression") return null
|
|
21
|
+
return expr as Expression
|
|
22
|
+
}
|
|
23
|
+
return null
|
|
24
|
+
}
|
|
25
|
+
return null
|
|
26
|
+
}
|
|
@@ -49,3 +49,105 @@ export const CHECKBOX_RADIO_SUPPORTED_PROPS = [
|
|
|
49
49
|
...CHECKBOX_RADIO_SHARED_PROPS,
|
|
50
50
|
...STYLE_PROP_NAMES_WITHOUT_CSS,
|
|
51
51
|
]
|
|
52
|
+
|
|
53
|
+
export const INPUT_SPECIFIC_PROPS = [
|
|
54
|
+
"autoComplete",
|
|
55
|
+
"autoWidth",
|
|
56
|
+
"defaultValue",
|
|
57
|
+
"description",
|
|
58
|
+
"disabled",
|
|
59
|
+
"form",
|
|
60
|
+
"hideLabel",
|
|
61
|
+
"invalid",
|
|
62
|
+
"max",
|
|
63
|
+
"maxLength",
|
|
64
|
+
"min",
|
|
65
|
+
"minLength",
|
|
66
|
+
"name",
|
|
67
|
+
"onChange",
|
|
68
|
+
"placeholder",
|
|
69
|
+
"readOnly",
|
|
70
|
+
"required",
|
|
71
|
+
"selectTextOnFocus",
|
|
72
|
+
"spellCheck",
|
|
73
|
+
"type",
|
|
74
|
+
"value",
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
export const ACCEPTED_INPUT_TYPES = [
|
|
78
|
+
"email",
|
|
79
|
+
"number",
|
|
80
|
+
"password",
|
|
81
|
+
"search",
|
|
82
|
+
"tel",
|
|
83
|
+
"text",
|
|
84
|
+
"url",
|
|
85
|
+
] as const
|
|
86
|
+
|
|
87
|
+
// Per https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input#attributes
|
|
88
|
+
// Only covers the types accepted by the Tapestry Input component.
|
|
89
|
+
export const TYPE_SPECIFIC_PROPS: Record<string, string[]> = {
|
|
90
|
+
email: ["dirname", "list", "multiple", "pattern"],
|
|
91
|
+
number: ["inputMode", "list", "step"],
|
|
92
|
+
password: ["pattern"],
|
|
93
|
+
search: ["dirname", "inputMode", "list", "pattern"],
|
|
94
|
+
tel: ["dirname", "inputMode", "list", "pattern"],
|
|
95
|
+
text: ["dirname", "inputMode", "list", "pattern"],
|
|
96
|
+
url: ["dirname", "inputMode", "list", "pattern"],
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export const INPUT_SUPPORTED_PROPS = [...COMMON_PROPS, ...INPUT_SPECIFIC_PROPS]
|
|
100
|
+
|
|
101
|
+
export const SELECT_SPECIFIC_PROPS = [
|
|
102
|
+
"complex",
|
|
103
|
+
"defaultValue",
|
|
104
|
+
"description",
|
|
105
|
+
"disabled",
|
|
106
|
+
"form",
|
|
107
|
+
"invalid",
|
|
108
|
+
"name",
|
|
109
|
+
"onChange",
|
|
110
|
+
"options",
|
|
111
|
+
"placeholder",
|
|
112
|
+
"required",
|
|
113
|
+
"value",
|
|
114
|
+
]
|
|
115
|
+
|
|
116
|
+
export const SELECT_SUPPORTED_PROPS = [
|
|
117
|
+
...COMMON_PROPS,
|
|
118
|
+
...SELECT_SPECIFIC_PROPS,
|
|
119
|
+
...STYLE_PROP_NAMES_WITHOUT_CSS,
|
|
120
|
+
]
|
|
121
|
+
|
|
122
|
+
export const TEXTAREA_SPECIFIC_PROPS = [
|
|
123
|
+
"autoComplete",
|
|
124
|
+
"autoFocus",
|
|
125
|
+
"cols",
|
|
126
|
+
"defaultValue",
|
|
127
|
+
"description",
|
|
128
|
+
"disabled",
|
|
129
|
+
"dirname",
|
|
130
|
+
"form",
|
|
131
|
+
"hideLabel",
|
|
132
|
+
"invalid",
|
|
133
|
+
"maxLength",
|
|
134
|
+
"minLength",
|
|
135
|
+
"name",
|
|
136
|
+
"onChange",
|
|
137
|
+
"onInput",
|
|
138
|
+
"onSelect",
|
|
139
|
+
"placeholder",
|
|
140
|
+
"readOnly",
|
|
141
|
+
"required",
|
|
142
|
+
"resize",
|
|
143
|
+
"rows",
|
|
144
|
+
"spellCheck",
|
|
145
|
+
"value",
|
|
146
|
+
"wrap",
|
|
147
|
+
]
|
|
148
|
+
|
|
149
|
+
export const TEXTAREA_SUPPORTED_PROPS = [
|
|
150
|
+
...COMMON_PROPS,
|
|
151
|
+
...TEXTAREA_SPECIFIC_PROPS,
|
|
152
|
+
...STYLE_PROP_NAMES_WITHOUT_CSS,
|
|
153
|
+
]
|
|
@@ -136,7 +136,6 @@ export function removeImportFromDeclaration(
|
|
|
136
136
|
if (importIndex >= 0) {
|
|
137
137
|
specifiers.splice(importIndex, 1)
|
|
138
138
|
|
|
139
|
-
// Remove entire import if no specifiers left
|
|
140
139
|
if (specifiers.length === 0) {
|
|
141
140
|
importPath.get().prune()
|
|
142
141
|
}
|
|
@@ -162,19 +161,23 @@ export function addImport({
|
|
|
162
161
|
pkg: string
|
|
163
162
|
source: Collection
|
|
164
163
|
}): string {
|
|
165
|
-
// Check if component is already imported from the target package
|
|
166
164
|
const existingImportName = getImportName(component, pkg, { j, source })
|
|
167
165
|
if (existingImportName) {
|
|
168
166
|
return existingImportName
|
|
169
167
|
}
|
|
170
168
|
|
|
171
|
-
// Check for conflicts with imports from other packages
|
|
172
169
|
const hasConflict = hasConflictingImport(component, pkg, { j, source })
|
|
173
170
|
const finalComponentName = hasConflict ? conflictAlias : component
|
|
174
171
|
const alias =
|
|
175
172
|
finalComponentName !== component ? finalComponentName : undefined
|
|
176
173
|
|
|
177
|
-
//
|
|
174
|
+
// If there's a conflict but no meaningful alias (conflictAlias === component), skip
|
|
175
|
+
// adding the import to avoid duplicate identifiers. The conflicting import from another
|
|
176
|
+
// package will be migrated to the target package by another transform in the pipeline.
|
|
177
|
+
if (hasConflict && !alias) {
|
|
178
|
+
return finalComponentName
|
|
179
|
+
}
|
|
180
|
+
|
|
178
181
|
const targetImport = source
|
|
179
182
|
.find(j.ImportDeclaration, {
|
|
180
183
|
source: { value: pkg },
|
|
@@ -223,18 +226,17 @@ export function manageImports(
|
|
|
223
226
|
name: { name: sourceComponentName },
|
|
224
227
|
}).length > 0
|
|
225
228
|
|
|
226
|
-
// Handle source package import cleanup
|
|
227
|
-
|
|
228
|
-
|
|
229
|
+
// Handle source package import cleanup — search all declarations, not just the first,
|
|
230
|
+
// since a component may be in a separate import declaration from the same package.
|
|
231
|
+
if (!stillUsesSource) {
|
|
232
|
+
const sourceImports = source.find(j.ImportDeclaration, {
|
|
229
233
|
source: { value: config.fromPackage },
|
|
230
234
|
})
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
removeImportFromDeclaration(sourceImport, config.fromComponent)
|
|
235
|
+
for (let i = 0; i < sourceImports.length; i++) {
|
|
236
|
+
removeImportFromDeclaration(sourceImports.at(i), config.fromComponent)
|
|
237
|
+
}
|
|
235
238
|
}
|
|
236
239
|
|
|
237
|
-
// Handle target package import addition using addImport
|
|
238
240
|
addImport({
|
|
239
241
|
component: config.toComponent,
|
|
240
242
|
conflictAlias: config.conflictAlias || targetComponentName,
|