@planningcenter/tapestry-migration-cli 3.5.0 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -0
- package/package.json +3 -3
- package/src/availableComponents.ts +1 -0
- package/src/components/button/transforms/tooltipToWrapper.test.ts +50 -3
- package/src/components/button/transforms/tooltipToWrapper.ts +18 -0
- package/src/components/flex/index.test.ts +140 -0
- package/src/components/flex/index.ts +40 -0
- package/src/components/flex/transforms/alignmentToAlign.test.ts +185 -0
- package/src/components/flex/transforms/alignmentToAlign.ts +73 -0
- package/src/components/flex/transforms/axisToDirection.test.ts +140 -0
- package/src/components/flex/transforms/axisToDirection.ts +51 -0
- package/src/components/flex/transforms/distributionToJustify.test.ts +214 -0
- package/src/components/flex/transforms/distributionToJustify.ts +76 -0
- package/src/components/flex/transforms/innerRefToRef.test.ts +100 -0
- package/src/components/flex/transforms/innerRefToRef.ts +14 -0
- package/src/components/flex/transforms/moveFlexImport.test.ts +202 -0
- package/src/components/flex/transforms/moveFlexImport.ts +14 -0
- package/src/components/flex/transforms/setDefaultAxis.test.ts +114 -0
- package/src/components/flex/transforms/setDefaultAxis.ts +29 -0
- package/src/components/flex/transforms/spacingToGap.test.ts +176 -0
- package/src/components/flex/transforms/spacingToGap.ts +49 -0
- package/src/components/select/index.ts +2 -0
- package/src/components/select/transforms/onChangeSignature.test.ts +224 -0
- package/src/components/select/transforms/onChangeSignature.ts +172 -0
- package/src/components/shared/actions/resolveConstantAttributeValue.test.ts +122 -0
- package/src/components/shared/actions/resolveConstantAttributeValue.ts +31 -0
- package/src/components/toggle-switch/index.ts +2 -0
- package/src/components/toggle-switch/transforms/onClickToOnChange.test.ts +210 -0
- package/src/components/toggle-switch/transforms/onClickToOnChange.ts +71 -0
- package/src/index.test.ts +79 -0
- package/src/index.ts +29 -0
- package/src/migrationList.ts +22 -0
- package/src/utils/componentLabel.test.ts +61 -0
- package/src/utils/componentLabel.ts +15 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import jscodeshift from "jscodeshift"
|
|
2
|
+
import { describe, expect, it } from "vitest"
|
|
3
|
+
|
|
4
|
+
import transform from "./axisToDirection"
|
|
5
|
+
|
|
6
|
+
const j = jscodeshift.withParser("tsx")
|
|
7
|
+
|
|
8
|
+
function applyTransform(source: string): string | null {
|
|
9
|
+
const fileInfo = { path: "test.tsx", source }
|
|
10
|
+
return transform(
|
|
11
|
+
fileInfo,
|
|
12
|
+
{ j, jscodeshift: j, report: () => {}, stats: () => {} },
|
|
13
|
+
{}
|
|
14
|
+
) as string | null
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
describe("axisToDirection transform", () => {
|
|
18
|
+
it('maps axis="horizontal" to direction="row"', () => {
|
|
19
|
+
const input = `
|
|
20
|
+
import { StackView } from "@planningcenter/tapestry-react"
|
|
21
|
+
|
|
22
|
+
export default function Test() {
|
|
23
|
+
return <StackView axis="horizontal">Test</StackView>
|
|
24
|
+
}
|
|
25
|
+
`.trim()
|
|
26
|
+
|
|
27
|
+
const result = applyTransform(input)
|
|
28
|
+
expect(result).toContain('direction="row"')
|
|
29
|
+
expect(result).not.toContain("axis")
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('maps axis="vertical" to direction="column"', () => {
|
|
33
|
+
const input = `
|
|
34
|
+
import { StackView } from "@planningcenter/tapestry-react"
|
|
35
|
+
|
|
36
|
+
export default function Test() {
|
|
37
|
+
return <StackView axis="vertical">Test</StackView>
|
|
38
|
+
}
|
|
39
|
+
`.trim()
|
|
40
|
+
|
|
41
|
+
const result = applyTransform(input)
|
|
42
|
+
expect(result).toContain('direction="column"')
|
|
43
|
+
expect(result).not.toContain("axis")
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
it("maps an expression-wrapped string literal", () => {
|
|
47
|
+
const input = `
|
|
48
|
+
import { StackView } from "@planningcenter/tapestry-react"
|
|
49
|
+
|
|
50
|
+
export default function Test() {
|
|
51
|
+
return <StackView axis={"horizontal"}>Test</StackView>
|
|
52
|
+
}
|
|
53
|
+
`.trim()
|
|
54
|
+
|
|
55
|
+
const result = applyTransform(input)
|
|
56
|
+
expect(result).toContain('direction="row"')
|
|
57
|
+
expect(result).not.toContain("axis")
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it("maps the StackView.HORIZONTAL constant", () => {
|
|
61
|
+
const input = `
|
|
62
|
+
import { StackView } from "@planningcenter/tapestry-react"
|
|
63
|
+
|
|
64
|
+
export default function Test() {
|
|
65
|
+
return <StackView axis={StackView.HORIZONTAL}>Test</StackView>
|
|
66
|
+
}
|
|
67
|
+
`.trim()
|
|
68
|
+
|
|
69
|
+
const result = applyTransform(input)
|
|
70
|
+
expect(result).toContain('direction="row"')
|
|
71
|
+
expect(result).not.toContain("axis")
|
|
72
|
+
expect(result).not.toContain("StackView.HORIZONTAL")
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
it("maps the StackView.VERTICAL constant", () => {
|
|
76
|
+
const input = `
|
|
77
|
+
import { StackView } from "@planningcenter/tapestry-react"
|
|
78
|
+
|
|
79
|
+
export default function Test() {
|
|
80
|
+
return <StackView axis={StackView.VERTICAL}>Test</StackView>
|
|
81
|
+
}
|
|
82
|
+
`.trim()
|
|
83
|
+
|
|
84
|
+
const result = applyTransform(input)
|
|
85
|
+
expect(result).toContain('direction="column"')
|
|
86
|
+
expect(result).not.toContain("StackView.VERTICAL")
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it("flags a dynamic axis value and leaves it in place", () => {
|
|
90
|
+
const input = `
|
|
91
|
+
import { StackView } from "@planningcenter/tapestry-react"
|
|
92
|
+
|
|
93
|
+
export default function Test({ orientation }) {
|
|
94
|
+
return <StackView axis={orientation}>Test</StackView>
|
|
95
|
+
}
|
|
96
|
+
`.trim()
|
|
97
|
+
|
|
98
|
+
const result = applyTransform(input)
|
|
99
|
+
expect(result).toContain("axis={orientation}")
|
|
100
|
+
expect(result).toContain("TODO: tapestry-migration (axis)")
|
|
101
|
+
expect(result).not.toContain('direction="')
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
it("maps an aliased StackView import", () => {
|
|
105
|
+
const input = `
|
|
106
|
+
import { StackView as Stack } from "@planningcenter/tapestry-react"
|
|
107
|
+
|
|
108
|
+
export default function Test() {
|
|
109
|
+
return <Stack axis="horizontal">Test</Stack>
|
|
110
|
+
}
|
|
111
|
+
`.trim()
|
|
112
|
+
|
|
113
|
+
const result = applyTransform(input)
|
|
114
|
+
expect(result).toContain('direction="row"')
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
it("returns null when there is no axis to map", () => {
|
|
118
|
+
const input = `
|
|
119
|
+
import { StackView } from "@planningcenter/tapestry-react"
|
|
120
|
+
|
|
121
|
+
export default function Test() {
|
|
122
|
+
return <StackView>Test</StackView>
|
|
123
|
+
}
|
|
124
|
+
`.trim()
|
|
125
|
+
|
|
126
|
+
expect(applyTransform(input)).toBe(null)
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
it("returns null when StackView is not imported from tapestry-react", () => {
|
|
130
|
+
const input = `
|
|
131
|
+
import { StackView } from "some-other-package"
|
|
132
|
+
|
|
133
|
+
export default function Test() {
|
|
134
|
+
return <StackView axis="horizontal">Test</StackView>
|
|
135
|
+
}
|
|
136
|
+
`.trim()
|
|
137
|
+
|
|
138
|
+
expect(applyTransform(input)).toBe(null)
|
|
139
|
+
})
|
|
140
|
+
})
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Transform } from "jscodeshift"
|
|
2
|
+
|
|
3
|
+
import { addComment } from "../../shared/actions/addComment"
|
|
4
|
+
import { getAttribute } from "../../shared/actions/getAttribute"
|
|
5
|
+
import { resolveConstantAttributeValue } from "../../shared/actions/resolveConstantAttributeValue"
|
|
6
|
+
import { hasAttribute } from "../../shared/conditions/hasAttribute"
|
|
7
|
+
import { attributeTransformFactory } from "../../shared/transformFactories/attributeTransformFactory"
|
|
8
|
+
|
|
9
|
+
const CONSTANT_AXIS_MAP: Record<string, string> = {
|
|
10
|
+
HORIZONTAL: "horizontal",
|
|
11
|
+
VERTICAL: "vertical",
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const AXIS_DIRECTION_MAP: Record<string, string> = {
|
|
15
|
+
horizontal: "row",
|
|
16
|
+
vertical: "column",
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const transform: Transform = attributeTransformFactory({
|
|
20
|
+
condition: hasAttribute("axis"),
|
|
21
|
+
targetComponent: "StackView",
|
|
22
|
+
targetPackage: "@planningcenter/tapestry-react",
|
|
23
|
+
transform: (element, { j, source }) => {
|
|
24
|
+
const axisAttribute = getAttribute({ element, name: "axis" })
|
|
25
|
+
if (!axisAttribute) return false
|
|
26
|
+
|
|
27
|
+
const resolved = resolveConstantAttributeValue({
|
|
28
|
+
attribute: axisAttribute,
|
|
29
|
+
constantMap: CONSTANT_AXIS_MAP,
|
|
30
|
+
})
|
|
31
|
+
const direction = resolved ? AXIS_DIRECTION_MAP[resolved] : undefined
|
|
32
|
+
|
|
33
|
+
if (!direction) {
|
|
34
|
+
addComment({
|
|
35
|
+
element,
|
|
36
|
+
j,
|
|
37
|
+
scope: "axis",
|
|
38
|
+
source,
|
|
39
|
+
text: "could not migrate axis to direction automatically; convert this value to row or column manually",
|
|
40
|
+
})
|
|
41
|
+
return true
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
axisAttribute.name.name = "direction"
|
|
45
|
+
axisAttribute.value = j.stringLiteral(direction)
|
|
46
|
+
|
|
47
|
+
return true
|
|
48
|
+
},
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
export default transform
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import jscodeshift from "jscodeshift"
|
|
2
|
+
import { describe, expect, it } from "vitest"
|
|
3
|
+
|
|
4
|
+
import transform from "./distributionToJustify"
|
|
5
|
+
|
|
6
|
+
const j = jscodeshift.withParser("tsx")
|
|
7
|
+
|
|
8
|
+
function applyTransform(source: string): string | null {
|
|
9
|
+
const fileInfo = { path: "test.tsx", source }
|
|
10
|
+
return transform(
|
|
11
|
+
fileInfo,
|
|
12
|
+
{ j, jscodeshift: j, report: () => {}, stats: () => {} },
|
|
13
|
+
{}
|
|
14
|
+
) as string | null
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
describe("distributionToJustify transform", () => {
|
|
18
|
+
it("renames distribution to justify", () => {
|
|
19
|
+
const input = `
|
|
20
|
+
import { StackView } from "@planningcenter/tapestry-react"
|
|
21
|
+
|
|
22
|
+
export default function Test() {
|
|
23
|
+
return (
|
|
24
|
+
<StackView distribution="start">
|
|
25
|
+
<StackView distribution="center">
|
|
26
|
+
<StackView distribution="end">
|
|
27
|
+
<StackView distribution="space-between">
|
|
28
|
+
<StackView distribution="space-evenly">Test</StackView>
|
|
29
|
+
</StackView>
|
|
30
|
+
</StackView>
|
|
31
|
+
</StackView>
|
|
32
|
+
</StackView>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
`.trim()
|
|
36
|
+
|
|
37
|
+
const result = applyTransform(input)
|
|
38
|
+
expect(result).toContain('justify="start"')
|
|
39
|
+
expect(result).toContain('justify="center"')
|
|
40
|
+
expect(result).toContain('justify="end"')
|
|
41
|
+
expect(result).toContain('justify="space-between"')
|
|
42
|
+
expect(result).toContain('justify="space-evenly"')
|
|
43
|
+
expect(result).not.toContain("distribution")
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
it("resolves StackView.CENTER constant to justify", () => {
|
|
47
|
+
const input = `
|
|
48
|
+
import { StackView } from "@planningcenter/tapestry-react"
|
|
49
|
+
|
|
50
|
+
export default function Test() {
|
|
51
|
+
return <StackView distribution={StackView.CENTER}>Test</StackView>
|
|
52
|
+
}
|
|
53
|
+
`.trim()
|
|
54
|
+
|
|
55
|
+
const result = applyTransform(input)
|
|
56
|
+
expect(result).toContain('justify="center"')
|
|
57
|
+
expect(result).not.toContain("distribution")
|
|
58
|
+
expect(result).not.toContain("StackView.CENTER")
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
it("resolves StackView.START constant to justify", () => {
|
|
62
|
+
const input = `
|
|
63
|
+
import { StackView } from "@planningcenter/tapestry-react"
|
|
64
|
+
|
|
65
|
+
export default function Test() {
|
|
66
|
+
return <StackView distribution={StackView.START}>Test</StackView>
|
|
67
|
+
}
|
|
68
|
+
`.trim()
|
|
69
|
+
|
|
70
|
+
const result = applyTransform(input)
|
|
71
|
+
expect(result).toContain('justify="start"')
|
|
72
|
+
expect(result).not.toContain("StackView.START")
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
it("resolves StackView.END constant to justify", () => {
|
|
76
|
+
const input = `
|
|
77
|
+
import { StackView } from "@planningcenter/tapestry-react"
|
|
78
|
+
|
|
79
|
+
export default function Test() {
|
|
80
|
+
return <StackView distribution={StackView.END}>Test</StackView>
|
|
81
|
+
}
|
|
82
|
+
`.trim()
|
|
83
|
+
|
|
84
|
+
const result = applyTransform(input)
|
|
85
|
+
expect(result).toContain('justify="end"')
|
|
86
|
+
expect(result).not.toContain("StackView.END")
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it("resolves StackView.SPACE_BETWEEN constant to justify", () => {
|
|
90
|
+
const input = `
|
|
91
|
+
import { StackView } from "@planningcenter/tapestry-react"
|
|
92
|
+
|
|
93
|
+
export default function Test() {
|
|
94
|
+
return <StackView distribution={StackView.SPACE_BETWEEN}>Test</StackView>
|
|
95
|
+
}
|
|
96
|
+
`.trim()
|
|
97
|
+
|
|
98
|
+
const result = applyTransform(input)
|
|
99
|
+
expect(result).toContain('justify="space-between"')
|
|
100
|
+
expect(result).not.toContain("StackView.SPACE_BETWEEN")
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
it("resolves StackView.SPACE_EVENLY constant to justify", () => {
|
|
104
|
+
const input = `
|
|
105
|
+
import { StackView } from "@planningcenter/tapestry-react"
|
|
106
|
+
|
|
107
|
+
export default function Test() {
|
|
108
|
+
return <StackView distribution={StackView.SPACE_EVENLY}>Test</StackView>
|
|
109
|
+
}
|
|
110
|
+
`.trim()
|
|
111
|
+
|
|
112
|
+
const result = applyTransform(input)
|
|
113
|
+
expect(result).toContain('justify="space-evenly"')
|
|
114
|
+
expect(result).not.toContain("StackView.SPACE_EVENLY")
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
it("flags distribution={StackView.FILL} with a TODO and leaves it in place", () => {
|
|
118
|
+
const input = `
|
|
119
|
+
import { StackView } from "@planningcenter/tapestry-react"
|
|
120
|
+
|
|
121
|
+
export default function Test() {
|
|
122
|
+
return <StackView distribution={StackView.FILL}>Test</StackView>
|
|
123
|
+
}
|
|
124
|
+
`.trim()
|
|
125
|
+
|
|
126
|
+
const result = applyTransform(input)
|
|
127
|
+
expect(result).toContain("distribution={StackView.FILL}")
|
|
128
|
+
expect(result).toContain("TODO: tapestry-migration (distribution)")
|
|
129
|
+
expect(result).not.toContain('justify="')
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
it('flags distribution="fill" with a TODO and leaves it in place', () => {
|
|
133
|
+
const input = `
|
|
134
|
+
import { StackView } from "@planningcenter/tapestry-react"
|
|
135
|
+
|
|
136
|
+
export default function Test() {
|
|
137
|
+
return <StackView distribution="fill">Test</StackView>
|
|
138
|
+
}
|
|
139
|
+
`.trim()
|
|
140
|
+
|
|
141
|
+
const result = applyTransform(input)
|
|
142
|
+
expect(result).toContain('distribution="fill"')
|
|
143
|
+
expect(result).toContain("TODO: tapestry-migration (distribution)")
|
|
144
|
+
expect(result).not.toContain('justify="')
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
it("flags an unrecognized string literal with a TODO", () => {
|
|
148
|
+
const input = `
|
|
149
|
+
import { StackView } from "@planningcenter/tapestry-react"
|
|
150
|
+
|
|
151
|
+
export default function Test() {
|
|
152
|
+
return <StackView distribution="space-around">Test</StackView>
|
|
153
|
+
}
|
|
154
|
+
`.trim()
|
|
155
|
+
|
|
156
|
+
const result = applyTransform(input)
|
|
157
|
+
expect(result).toContain('distribution="space-around"')
|
|
158
|
+
expect(result).toContain("TODO: tapestry-migration (distribution)")
|
|
159
|
+
expect(result).not.toContain('justify="')
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
it("flags a dynamic distribution value with a TODO", () => {
|
|
163
|
+
const input = `
|
|
164
|
+
import { StackView } from "@planningcenter/tapestry-react"
|
|
165
|
+
|
|
166
|
+
export default function Test({ distributionProp }) {
|
|
167
|
+
return <StackView distribution={distributionProp}>Test</StackView>
|
|
168
|
+
}
|
|
169
|
+
`.trim()
|
|
170
|
+
|
|
171
|
+
const result = applyTransform(input)
|
|
172
|
+
expect(result).toContain("distribution={distributionProp}")
|
|
173
|
+
expect(result).toContain("TODO: tapestry-migration (distribution)")
|
|
174
|
+
expect(result).not.toContain('justify="')
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
it("respects an aliased StackView import", () => {
|
|
178
|
+
const input = `
|
|
179
|
+
import { StackView as Stack } from "@planningcenter/tapestry-react"
|
|
180
|
+
|
|
181
|
+
export default function Test() {
|
|
182
|
+
return <Stack distribution="center">Test</Stack>
|
|
183
|
+
}
|
|
184
|
+
`.trim()
|
|
185
|
+
|
|
186
|
+
const result = applyTransform(input)
|
|
187
|
+
expect(result).toContain('justify="center"')
|
|
188
|
+
expect(result).not.toContain("distribution")
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
it("returns null when there is no distribution to migrate", () => {
|
|
192
|
+
const input = `
|
|
193
|
+
import { StackView } from "@planningcenter/tapestry-react"
|
|
194
|
+
|
|
195
|
+
export default function Test() {
|
|
196
|
+
return <StackView>Test</StackView>
|
|
197
|
+
}
|
|
198
|
+
`.trim()
|
|
199
|
+
|
|
200
|
+
expect(applyTransform(input)).toBe(null)
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
it("returns null when StackView is not imported from tapestry-react", () => {
|
|
204
|
+
const input = `
|
|
205
|
+
import { StackView } from "some-other-package"
|
|
206
|
+
|
|
207
|
+
export default function Test() {
|
|
208
|
+
return <StackView distribution="center">Test</StackView>
|
|
209
|
+
}
|
|
210
|
+
`.trim()
|
|
211
|
+
|
|
212
|
+
expect(applyTransform(input)).toBe(null)
|
|
213
|
+
})
|
|
214
|
+
})
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Transform } from "jscodeshift"
|
|
2
|
+
|
|
3
|
+
import { addComment } from "../../shared/actions/addComment"
|
|
4
|
+
import { getAttribute } from "../../shared/actions/getAttribute"
|
|
5
|
+
import { resolveConstantAttributeValue } from "../../shared/actions/resolveConstantAttributeValue"
|
|
6
|
+
import { hasAttribute } from "../../shared/conditions/hasAttribute"
|
|
7
|
+
import { attributeTransformFactory } from "../../shared/transformFactories/attributeTransformFactory"
|
|
8
|
+
|
|
9
|
+
const VALID_JUSTIFY_VALUES = new Set([
|
|
10
|
+
"start",
|
|
11
|
+
"center",
|
|
12
|
+
"end",
|
|
13
|
+
"space-between",
|
|
14
|
+
"space-evenly",
|
|
15
|
+
])
|
|
16
|
+
|
|
17
|
+
const CONSTANT_DISTRIBUTION_MAP: Record<string, string> = {
|
|
18
|
+
CENTER: "center",
|
|
19
|
+
END: "end",
|
|
20
|
+
FILL: "fill",
|
|
21
|
+
SPACE_BETWEEN: "space-between",
|
|
22
|
+
SPACE_EVENLY: "space-evenly",
|
|
23
|
+
START: "start",
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const transform: Transform = attributeTransformFactory({
|
|
27
|
+
condition: hasAttribute("distribution"),
|
|
28
|
+
targetComponent: "StackView",
|
|
29
|
+
targetPackage: "@planningcenter/tapestry-react",
|
|
30
|
+
transform: (element, { j, source }) => {
|
|
31
|
+
const distributionAttribute = getAttribute({
|
|
32
|
+
element,
|
|
33
|
+
name: "distribution",
|
|
34
|
+
})
|
|
35
|
+
if (!distributionAttribute) return false
|
|
36
|
+
|
|
37
|
+
const resolved = resolveConstantAttributeValue({
|
|
38
|
+
attribute: distributionAttribute,
|
|
39
|
+
constantMap: CONSTANT_DISTRIBUTION_MAP,
|
|
40
|
+
})
|
|
41
|
+
const distributionValue =
|
|
42
|
+
resolved !== null &&
|
|
43
|
+
(VALID_JUSTIFY_VALUES.has(resolved) || resolved === "fill")
|
|
44
|
+
? resolved
|
|
45
|
+
: null
|
|
46
|
+
|
|
47
|
+
if (distributionValue === null) {
|
|
48
|
+
addComment({
|
|
49
|
+
element,
|
|
50
|
+
j,
|
|
51
|
+
scope: "distribution",
|
|
52
|
+
source,
|
|
53
|
+
text: "could not migrate distribution to justify automatically; convert this value to start, center, end, space-between, or space-evenly manually",
|
|
54
|
+
})
|
|
55
|
+
return true
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (distributionValue === "fill") {
|
|
59
|
+
addComment({
|
|
60
|
+
element,
|
|
61
|
+
j,
|
|
62
|
+
scope: "distribution",
|
|
63
|
+
source,
|
|
64
|
+
text: 'distribution="fill" has no Flex equivalent; remove this prop and use expand on the child elements instead',
|
|
65
|
+
})
|
|
66
|
+
return true
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
distributionAttribute.name.name = "justify"
|
|
70
|
+
distributionAttribute.value = j.stringLiteral(distributionValue)
|
|
71
|
+
|
|
72
|
+
return true
|
|
73
|
+
},
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
export default transform
|
|
@@ -0,0 +1,100 @@
|
|
|
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 | null {
|
|
9
|
+
const fileInfo = { path: "test.tsx", source }
|
|
10
|
+
return transform(
|
|
11
|
+
fileInfo,
|
|
12
|
+
{ j, jscodeshift: j, report: () => {}, stats: () => {} },
|
|
13
|
+
{ verbose }
|
|
14
|
+
) as string | null
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
describe("innerRefToRef transform", () => {
|
|
18
|
+
it("renames innerRef to ref", () => {
|
|
19
|
+
const input = `
|
|
20
|
+
import { StackView } from "@planningcenter/tapestry-react"
|
|
21
|
+
|
|
22
|
+
export default function Test() {
|
|
23
|
+
const ref = React.useRef()
|
|
24
|
+
return <StackView innerRef={ref}>Test</StackView>
|
|
25
|
+
}
|
|
26
|
+
`.trim()
|
|
27
|
+
|
|
28
|
+
const result = applyTransform(input)
|
|
29
|
+
expect(result).toContain("ref={ref}")
|
|
30
|
+
expect(result).not.toContain("innerRef=")
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
it("renames innerRef with a callback ref", () => {
|
|
34
|
+
const input = `
|
|
35
|
+
import { StackView } from "@planningcenter/tapestry-react"
|
|
36
|
+
|
|
37
|
+
export default function Test() {
|
|
38
|
+
return <StackView innerRef={(el) => console.log(el)}>Test</StackView>
|
|
39
|
+
}
|
|
40
|
+
`.trim()
|
|
41
|
+
|
|
42
|
+
const result = applyTransform(input)
|
|
43
|
+
expect(result).toContain("ref={(el) => console.log(el)}")
|
|
44
|
+
expect(result).not.toContain("innerRef=")
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it("respects an aliased StackView import", () => {
|
|
48
|
+
const input = `
|
|
49
|
+
import { StackView as Stack } from "@planningcenter/tapestry-react"
|
|
50
|
+
|
|
51
|
+
export default function Test() {
|
|
52
|
+
return <Stack innerRef={myRef}>Test</Stack>
|
|
53
|
+
}
|
|
54
|
+
`.trim()
|
|
55
|
+
|
|
56
|
+
const result = applyTransform(input)
|
|
57
|
+
expect(result).toContain("ref={myRef}")
|
|
58
|
+
expect(result).not.toContain("innerRef=")
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
it("adds a CHANGED comment when verbose is enabled", () => {
|
|
62
|
+
const input = `
|
|
63
|
+
import { StackView } from "@planningcenter/tapestry-react"
|
|
64
|
+
|
|
65
|
+
export default function Test() {
|
|
66
|
+
return <StackView innerRef={myRef}>Test</StackView>
|
|
67
|
+
}
|
|
68
|
+
`.trim()
|
|
69
|
+
|
|
70
|
+
const result = applyTransform(input, true)
|
|
71
|
+
expect(result).toContain("ref={myRef}")
|
|
72
|
+
expect(result).toContain(
|
|
73
|
+
"CHANGED: tapestry-migration (ref): renamed from innerRef"
|
|
74
|
+
)
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
it("returns null when there is no innerRef to migrate", () => {
|
|
78
|
+
const input = `
|
|
79
|
+
import { StackView } from "@planningcenter/tapestry-react"
|
|
80
|
+
|
|
81
|
+
export default function Test() {
|
|
82
|
+
return <StackView>Test</StackView>
|
|
83
|
+
}
|
|
84
|
+
`.trim()
|
|
85
|
+
|
|
86
|
+
expect(applyTransform(input)).toBe(null)
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it("returns null when StackView is not imported from tapestry-react", () => {
|
|
90
|
+
const input = `
|
|
91
|
+
import { StackView } from "some-other-package"
|
|
92
|
+
|
|
93
|
+
export default function Test() {
|
|
94
|
+
return <StackView innerRef={myRef}>Test</StackView>
|
|
95
|
+
}
|
|
96
|
+
`.trim()
|
|
97
|
+
|
|
98
|
+
expect(applyTransform(input)).toBe(null)
|
|
99
|
+
})
|
|
100
|
+
})
|
|
@@ -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: "StackView",
|
|
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
|