@planningcenter/tapestry-migration-cli 2.4.0 → 2.4.1-rc.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/package.json +2 -2
- package/src/components/checkbox/index.ts +38 -0
- package/src/components/checkbox/transforms/childrenToLabel.test.ts +146 -0
- package/src/components/checkbox/transforms/childrenToLabel.ts +54 -0
- package/src/components/checkbox/transforms/convertStyleProps.test.ts +161 -0
- package/src/components/checkbox/transforms/convertStyleProps.ts +10 -0
- package/src/components/checkbox/transforms/innerRefToRef.test.ts +161 -0
- package/src/components/checkbox/transforms/innerRefToRef.ts +14 -0
- package/src/components/checkbox/transforms/moveCheckboxImport.test.ts +182 -0
- package/src/components/checkbox/transforms/moveCheckboxImport.ts +13 -0
- package/src/components/checkbox/transforms/sizeMapping.test.ts +193 -0
- package/src/components/checkbox/transforms/sizeMapping.ts +45 -0
- package/src/components/checkbox/transforms/unsupportedProps.test.ts +243 -0
- package/src/components/checkbox/transforms/unsupportedProps.ts +47 -0
- package/src/jscodeshiftRunner.ts +9 -1
- package/src/reportGenerator.ts +23 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planningcenter/tapestry-migration-cli",
|
|
3
|
-
"version": "2.4.0",
|
|
3
|
+
"version": "2.4.1-rc.0",
|
|
4
4
|
"description": "CLI tool for Tapestry migrations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -51,5 +51,5 @@
|
|
|
51
51
|
"publishConfig": {
|
|
52
52
|
"access": "public"
|
|
53
53
|
},
|
|
54
|
-
"gitHead": "
|
|
54
|
+
"gitHead": "c643ce32f1e79ee51403daeaaeac4940729ab69d"
|
|
55
55
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Transform } from "jscodeshift"
|
|
2
|
+
|
|
3
|
+
import childrenToLabel from "./transforms/childrenToLabel"
|
|
4
|
+
import convertStyleProps from "./transforms/convertStyleProps"
|
|
5
|
+
import innerRefToRef from "./transforms/innerRefToRef"
|
|
6
|
+
import moveCheckboxImport from "./transforms/moveCheckboxImport"
|
|
7
|
+
import sizeMapping from "./transforms/sizeMapping"
|
|
8
|
+
import unsupportedProps from "./transforms/unsupportedProps"
|
|
9
|
+
|
|
10
|
+
const transform: Transform = (fileInfo, api, options) => {
|
|
11
|
+
let currentSource = fileInfo.source
|
|
12
|
+
let hasAnyChanges = false
|
|
13
|
+
|
|
14
|
+
const transforms = [
|
|
15
|
+
childrenToLabel,
|
|
16
|
+
sizeMapping,
|
|
17
|
+
innerRefToRef,
|
|
18
|
+
convertStyleProps,
|
|
19
|
+
unsupportedProps,
|
|
20
|
+
moveCheckboxImport,
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
for (const individualTransform of transforms) {
|
|
24
|
+
const result = individualTransform(
|
|
25
|
+
{ ...fileInfo, source: currentSource },
|
|
26
|
+
api,
|
|
27
|
+
options
|
|
28
|
+
)
|
|
29
|
+
if (result && result !== currentSource) {
|
|
30
|
+
currentSource = result as string
|
|
31
|
+
hasAnyChanges = true
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return hasAnyChanges ? currentSource : null
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export default transform
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import jscodeshift from "jscodeshift"
|
|
2
|
+
import { describe, expect, it } from "vitest"
|
|
3
|
+
|
|
4
|
+
import transform from "./childrenToLabel"
|
|
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("childrenToLabel transform for Checkbox", () => {
|
|
19
|
+
describe("simple text conversion", () => {
|
|
20
|
+
it("should convert simple text children to label prop", () => {
|
|
21
|
+
const input = `
|
|
22
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
23
|
+
|
|
24
|
+
function Test() {
|
|
25
|
+
return <Checkbox>Accept terms</Checkbox>
|
|
26
|
+
}
|
|
27
|
+
`.trim()
|
|
28
|
+
|
|
29
|
+
const result = applyTransform(input)
|
|
30
|
+
expect(result).toContain('<Checkbox label="Accept terms" />')
|
|
31
|
+
expect(result).not.toContain("Accept terms</Checkbox>")
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it("should not convert when label prop already exists", () => {
|
|
35
|
+
const input = `
|
|
36
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
37
|
+
|
|
38
|
+
function Test() {
|
|
39
|
+
return <Checkbox label="Already has label">Accept terms</Checkbox>
|
|
40
|
+
}
|
|
41
|
+
`.trim()
|
|
42
|
+
|
|
43
|
+
const result = applyTransform(input)
|
|
44
|
+
expect(result).toContain('label="Already has label"')
|
|
45
|
+
expect(result).toContain("Accept terms</Checkbox>")
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it("should handle whitespace in text content", () => {
|
|
49
|
+
const input = `
|
|
50
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
51
|
+
|
|
52
|
+
function Test() {
|
|
53
|
+
return <Checkbox> Accept terms </Checkbox>
|
|
54
|
+
}
|
|
55
|
+
`.trim()
|
|
56
|
+
|
|
57
|
+
const result = applyTransform(input)
|
|
58
|
+
expect(result).toContain('<Checkbox label="Accept terms" />')
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
it("should not convert complex children", () => {
|
|
62
|
+
const input = `
|
|
63
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
64
|
+
|
|
65
|
+
function Test() {
|
|
66
|
+
return (
|
|
67
|
+
<Checkbox>
|
|
68
|
+
<span>Accept</span> terms
|
|
69
|
+
</Checkbox>
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
`.trim()
|
|
73
|
+
|
|
74
|
+
const result = applyTransform(input)
|
|
75
|
+
expect(result).not.toContain("label=")
|
|
76
|
+
expect(result).toContain("<span>Accept</span>terms")
|
|
77
|
+
expect(result).toContain(
|
|
78
|
+
"TODO: tapestry-migration (children): complex children cannot be converted to label prop"
|
|
79
|
+
)
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it("should not convert when children contain JSX elements", () => {
|
|
83
|
+
const input = `
|
|
84
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
85
|
+
|
|
86
|
+
function Test() {
|
|
87
|
+
return (
|
|
88
|
+
<Checkbox>
|
|
89
|
+
Accept <strong>terms</strong>
|
|
90
|
+
</Checkbox>
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
`.trim()
|
|
94
|
+
|
|
95
|
+
const result = applyTransform(input)
|
|
96
|
+
expect(result).not.toContain("label=")
|
|
97
|
+
expect(result).toContain("Accept <strong>terms</strong>")
|
|
98
|
+
expect(result).toContain(
|
|
99
|
+
"TODO: tapestry-migration (children): complex children cannot be converted to label prop"
|
|
100
|
+
)
|
|
101
|
+
})
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
describe("edge cases", () => {
|
|
105
|
+
it("should handle empty children", () => {
|
|
106
|
+
const input = `
|
|
107
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
108
|
+
|
|
109
|
+
function Test() {
|
|
110
|
+
return <Checkbox></Checkbox>
|
|
111
|
+
}
|
|
112
|
+
`.trim()
|
|
113
|
+
|
|
114
|
+
const result = applyTransform(input)
|
|
115
|
+
expect(result).toContain("<Checkbox></Checkbox>")
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
it("should handle self-closing checkbox", () => {
|
|
119
|
+
const input = `
|
|
120
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
121
|
+
|
|
122
|
+
function Test() {
|
|
123
|
+
return <Checkbox />
|
|
124
|
+
}
|
|
125
|
+
`.trim()
|
|
126
|
+
|
|
127
|
+
const result = applyTransform(input)
|
|
128
|
+
expect(result).toContain("<Checkbox />")
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
it("should handle checkbox with other props", () => {
|
|
132
|
+
const input = `
|
|
133
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
134
|
+
|
|
135
|
+
function Test() {
|
|
136
|
+
return <Checkbox checked disabled>Accept terms</Checkbox>
|
|
137
|
+
}
|
|
138
|
+
`.trim()
|
|
139
|
+
|
|
140
|
+
const result = applyTransform(input)
|
|
141
|
+
expect(result).toContain(
|
|
142
|
+
'<Checkbox checked disabled label="Accept terms" />'
|
|
143
|
+
)
|
|
144
|
+
})
|
|
145
|
+
})
|
|
146
|
+
})
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Transform } from "jscodeshift"
|
|
2
|
+
|
|
3
|
+
import { addAttribute } from "../../shared/actions/addAttribute"
|
|
4
|
+
import { addComment } from "../../shared/actions/addComment"
|
|
5
|
+
import { removeChildren } from "../../shared/actions/removeChildren"
|
|
6
|
+
import { hasAttribute } from "../../shared/conditions/hasAttribute"
|
|
7
|
+
import { hasChildren } from "../../shared/conditions/hasChildren"
|
|
8
|
+
import {
|
|
9
|
+
buildComment,
|
|
10
|
+
extractTextContent,
|
|
11
|
+
} from "../../shared/helpers/childrenToLabelHelpers"
|
|
12
|
+
import { attributeTransformFactory } from "../../shared/transformFactories/attributeTransformFactory"
|
|
13
|
+
|
|
14
|
+
const transform: Transform = attributeTransformFactory({
|
|
15
|
+
condition: hasChildren,
|
|
16
|
+
targetComponent: "Checkbox",
|
|
17
|
+
targetPackage: "@planningcenter/tapestry-react",
|
|
18
|
+
transform: (element, { j, source }) => {
|
|
19
|
+
if (hasAttribute("label")(element)) {
|
|
20
|
+
addComment({
|
|
21
|
+
element,
|
|
22
|
+
j,
|
|
23
|
+
scope: "label",
|
|
24
|
+
source,
|
|
25
|
+
text: buildComment("Checkbox has both label prop and children", false),
|
|
26
|
+
})
|
|
27
|
+
return true
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const { isSimpleText, textContent } = extractTextContent(element.children!)
|
|
31
|
+
|
|
32
|
+
if (isSimpleText && textContent) {
|
|
33
|
+
addAttribute({ element, j, name: "label", value: textContent })
|
|
34
|
+
removeChildren(element)
|
|
35
|
+
return true
|
|
36
|
+
} else if (!isSimpleText) {
|
|
37
|
+
addComment({
|
|
38
|
+
element,
|
|
39
|
+
j,
|
|
40
|
+
scope: "children",
|
|
41
|
+
source,
|
|
42
|
+
text: buildComment(
|
|
43
|
+
"complex children cannot be converted to label prop",
|
|
44
|
+
true
|
|
45
|
+
),
|
|
46
|
+
})
|
|
47
|
+
return true
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return false
|
|
51
|
+
},
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
export default transform
|
|
@@ -0,0 +1,161 @@
|
|
|
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 { Checkbox } from "@planningcenter/tapestry-react"
|
|
23
|
+
|
|
24
|
+
export function TestComponent() {
|
|
25
|
+
return <Checkbox visible={false} label="Hidden Checkbox" />
|
|
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 { Checkbox } from "@planningcenter/tapestry-react"
|
|
39
|
+
|
|
40
|
+
export function TestComponent() {
|
|
41
|
+
return <Checkbox visible={true} label="Visible Checkbox" />
|
|
42
|
+
}
|
|
43
|
+
`
|
|
44
|
+
|
|
45
|
+
const result = applyTransform(source)
|
|
46
|
+
|
|
47
|
+
// visible={true} is default behavior, so it should be removed with no style added
|
|
48
|
+
expect(result).not.toContain("visible={true}")
|
|
49
|
+
expect(result).not.toContain("style={{") // No style should be added
|
|
50
|
+
expect(result).toContain('<Checkbox label="Visible Checkbox" />')
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it("should handle visible expressions", () => {
|
|
54
|
+
const source = `
|
|
55
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
56
|
+
|
|
57
|
+
export function TestComponent() {
|
|
58
|
+
const isVisible = true
|
|
59
|
+
return <Checkbox visible={isVisible} label="Variable Checkbox" />
|
|
60
|
+
}
|
|
61
|
+
`
|
|
62
|
+
|
|
63
|
+
const result = applyTransform(source)
|
|
64
|
+
|
|
65
|
+
// Note: visible expressions are handled by handleVisibleExpressions transform,
|
|
66
|
+
// not convertStyleProps, so the visible prop should remain
|
|
67
|
+
expect(result).toContain("visible: isVisible")
|
|
68
|
+
expect(result).toContain("style={{") // Style should be added for expressions
|
|
69
|
+
})
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
describe("style prop removal", () => {
|
|
73
|
+
it("should remove alignItems prop", () => {
|
|
74
|
+
const source = `
|
|
75
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
76
|
+
|
|
77
|
+
export function TestComponent() {
|
|
78
|
+
return <Checkbox alignItems="center" label="Test" />
|
|
79
|
+
}
|
|
80
|
+
`
|
|
81
|
+
|
|
82
|
+
const result = applyTransform(source)
|
|
83
|
+
|
|
84
|
+
expect(result).not.toContain("alignItems=")
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
it("should remove marginTop prop", () => {
|
|
88
|
+
const source = `
|
|
89
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
90
|
+
|
|
91
|
+
export function TestComponent() {
|
|
92
|
+
return <Checkbox marginTop={16} label="Test" />
|
|
93
|
+
}
|
|
94
|
+
`
|
|
95
|
+
|
|
96
|
+
const result = applyTransform(source)
|
|
97
|
+
|
|
98
|
+
expect(result).not.toContain("marginTop=")
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it("should remove multiple style props", () => {
|
|
102
|
+
const source = `
|
|
103
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
104
|
+
|
|
105
|
+
export function TestComponent() {
|
|
106
|
+
return <Checkbox alignItems="center" marginTop={16} label="Test" />
|
|
107
|
+
}
|
|
108
|
+
`
|
|
109
|
+
|
|
110
|
+
const result = applyTransform(source)
|
|
111
|
+
|
|
112
|
+
expect(result).not.toContain("alignItems=")
|
|
113
|
+
expect(result).not.toContain("marginTop=")
|
|
114
|
+
})
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
describe("combination of style props", () => {
|
|
118
|
+
it("should handle combination of visible and style props", () => {
|
|
119
|
+
const source = `
|
|
120
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
121
|
+
|
|
122
|
+
export function TestComponent() {
|
|
123
|
+
return (
|
|
124
|
+
<Checkbox
|
|
125
|
+
visible={false}
|
|
126
|
+
alignItems="center"
|
|
127
|
+
marginTop={16}
|
|
128
|
+
label="Combined Checkbox"
|
|
129
|
+
/>
|
|
130
|
+
)
|
|
131
|
+
}
|
|
132
|
+
`
|
|
133
|
+
|
|
134
|
+
const result = applyTransform(source)
|
|
135
|
+
|
|
136
|
+
expect(result).toContain("style={{")
|
|
137
|
+
expect(result).toContain('display: "none"') // from visible={false}
|
|
138
|
+
expect(result).not.toContain("visible={false}")
|
|
139
|
+
expect(result).not.toContain("alignItems=")
|
|
140
|
+
expect(result).not.toContain("marginTop=")
|
|
141
|
+
})
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
describe("import handling", () => {
|
|
145
|
+
it("should not affect imports", () => {
|
|
146
|
+
const source = `
|
|
147
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
148
|
+
|
|
149
|
+
export function TestComponent() {
|
|
150
|
+
return <Checkbox visible={false} label="Test" />
|
|
151
|
+
}
|
|
152
|
+
`
|
|
153
|
+
|
|
154
|
+
const result = applyTransform(source)
|
|
155
|
+
|
|
156
|
+
expect(result).toContain(
|
|
157
|
+
'import { Checkbox } from "@planningcenter/tapestry-react"'
|
|
158
|
+
)
|
|
159
|
+
})
|
|
160
|
+
})
|
|
161
|
+
})
|
|
@@ -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: "Checkbox",
|
|
9
|
+
targetPackage: "@planningcenter/tapestry-react",
|
|
10
|
+
})
|
|
@@ -0,0 +1,161 @@
|
|
|
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): 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("innerRefToRef transform", () => {
|
|
19
|
+
describe("innerRef to ref conversion", () => {
|
|
20
|
+
it("should convert innerRef to ref", () => {
|
|
21
|
+
const input = `
|
|
22
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
23
|
+
|
|
24
|
+
function Test() {
|
|
25
|
+
const checkboxRef = React.useRef()
|
|
26
|
+
return <Checkbox innerRef={checkboxRef} label="Test" />
|
|
27
|
+
}
|
|
28
|
+
`.trim()
|
|
29
|
+
|
|
30
|
+
const result = applyTransform(input)
|
|
31
|
+
expect(result).toContain("ref={checkboxRef}")
|
|
32
|
+
expect(result).not.toContain("innerRef=")
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it("should convert innerRef with expression", () => {
|
|
36
|
+
const input = `
|
|
37
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
38
|
+
|
|
39
|
+
function Test() {
|
|
40
|
+
return <Checkbox innerRef={myRef} label="Test" />
|
|
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 { Checkbox } from "@planningcenter/tapestry-react"
|
|
52
|
+
|
|
53
|
+
function Test() {
|
|
54
|
+
return <Checkbox innerRef={(el) => console.log(el)} label="Test" />
|
|
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 { Checkbox } from "@planningcenter/tapestry-react"
|
|
66
|
+
|
|
67
|
+
function Test() {
|
|
68
|
+
const checkboxRef = React.useRef()
|
|
69
|
+
return <Checkbox ref={checkboxRef} label="Test" />
|
|
70
|
+
}
|
|
71
|
+
`.trim()
|
|
72
|
+
|
|
73
|
+
const result = applyTransform(input)
|
|
74
|
+
expect(result).toContain("ref={checkboxRef}")
|
|
75
|
+
expect(result).not.toContain("innerRef=")
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
it("should handle multiple checkboxes", () => {
|
|
79
|
+
const input = `
|
|
80
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
81
|
+
|
|
82
|
+
function Test() {
|
|
83
|
+
const ref1 = React.useRef()
|
|
84
|
+
const ref2 = React.useRef()
|
|
85
|
+
return (
|
|
86
|
+
<div>
|
|
87
|
+
<Checkbox innerRef={ref1} label="First" />
|
|
88
|
+
<Checkbox 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, Checkbox } from "@planningcenter/tapestry-react"
|
|
105
|
+
|
|
106
|
+
function Test() {
|
|
107
|
+
const buttonRef = React.useRef()
|
|
108
|
+
const checkboxRef = React.useRef()
|
|
109
|
+
return (
|
|
110
|
+
<div>
|
|
111
|
+
<Button innerRef={buttonRef}>Click me</Button>
|
|
112
|
+
<Checkbox innerRef={checkboxRef} label="Test" />
|
|
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={checkboxRef}")
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
it("should handle checkbox without innerRef", () => {
|
|
124
|
+
const input = `
|
|
125
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
126
|
+
|
|
127
|
+
function Test() {
|
|
128
|
+
return <Checkbox label="Test" />
|
|
129
|
+
}
|
|
130
|
+
`.trim()
|
|
131
|
+
|
|
132
|
+
const result = applyTransform(input)
|
|
133
|
+
expect(result).toContain('<Checkbox label="Test" />')
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
it("should preserve other props", () => {
|
|
137
|
+
const input = `
|
|
138
|
+
import { Checkbox } from "@planningcenter/tapestry-react"
|
|
139
|
+
|
|
140
|
+
function Test() {
|
|
141
|
+
const checkboxRef = React.useRef()
|
|
142
|
+
return (
|
|
143
|
+
<Checkbox
|
|
144
|
+
innerRef={checkboxRef}
|
|
145
|
+
label="Test"
|
|
146
|
+
checked
|
|
147
|
+
disabled
|
|
148
|
+
/>
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
`.trim()
|
|
152
|
+
|
|
153
|
+
const result = applyTransform(input)
|
|
154
|
+
expect(result).toContain("ref={checkboxRef}")
|
|
155
|
+
expect(result).toContain('label="Test"')
|
|
156
|
+
expect(result).toContain("checked")
|
|
157
|
+
expect(result).toContain("disabled")
|
|
158
|
+
expect(result).not.toContain("innerRef=")
|
|
159
|
+
})
|
|
160
|
+
})
|
|
161
|
+
})
|
|
@@ -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: "Checkbox",
|
|
8
|
+
targetPackage: "@planningcenter/tapestry-react",
|
|
9
|
+
transform: (element) => {
|
|
10
|
+
return transformAttributeName("innerRef", "ref", { element })
|
|
11
|
+
},
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
export default transform
|