@planningcenter/tapestry-migration-cli 2.4.0-rc.2 → 2.4.0-rc.21
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 +100 -6
- package/dist/tapestry-react-shim.cjs +1 -1
- package/package.json +2 -2
- package/src/components/button/index.ts +3 -3
- package/src/components/button/transforms/childrenToLabel.test.ts +5 -4
- package/src/components/button/transforms/childrenToLabel.ts +9 -39
- package/src/components/button/transforms/innerRefToRef.test.ts +170 -0
- package/src/components/button/transforms/innerRefToRef.ts +14 -0
- package/src/components/button/transforms/unsupportedProps.ts +8 -31
- package/src/components/link/index.ts +22 -2
- package/src/components/link/transforms/auditSpreadProps.test.ts +351 -0
- package/src/components/link/transforms/auditSpreadProps.ts +24 -0
- package/src/components/link/transforms/childrenToLabel.test.ts +331 -0
- package/src/components/link/transforms/childrenToLabel.ts +54 -0
- package/src/components/link/transforms/convertStyleProps.test.ts +391 -0
- package/src/components/link/transforms/convertStyleProps.ts +10 -0
- package/src/components/link/transforms/innerRefToRef.test.ts +170 -0
- package/src/components/link/transforms/innerRefToRef.ts +14 -0
- package/src/components/link/transforms/moveLinkImport.test.ts +295 -0
- package/src/components/{button/transforms/linkToButton.ts → link/transforms/moveLinkImport.ts} +4 -5
- package/src/components/link/transforms/removeAs.test.ts +192 -0
- package/src/components/link/transforms/removeAs.ts +17 -0
- package/src/components/link/transforms/{inlineToKind.test.ts → removeInlineMember.test.ts} +13 -28
- package/src/components/link/transforms/removeInlineMember.ts +11 -0
- package/src/components/link/transforms/removeInlineProp.test.ts +295 -0
- package/src/components/link/transforms/removeInlineProp.ts +15 -0
- package/src/components/link/transforms/reviewStyles.test.ts +172 -0
- package/src/components/link/transforms/reviewStyles.ts +17 -0
- package/src/components/link/transforms/targetBlankToExternal.test.ts +14 -0
- package/src/components/link/transforms/tooltipToWrapper.test.ts +392 -0
- package/src/components/link/transforms/tooltipToWrapper.ts +35 -0
- package/src/components/link/transforms/unsupportedProps.test.ts +265 -0
- package/src/components/link/transforms/unsupportedProps.ts +58 -0
- package/src/components/shared/conditions/hasAttributeValue.test.ts +22 -1
- package/src/components/shared/conditions/hasAttributeValue.ts +24 -6
- package/src/components/shared/helpers/childrenToLabelHelpers.ts +43 -0
- package/src/components/shared/helpers/unsupportedPropsHelpers.ts +35 -0
- package/src/components/shared/transformFactories/stylePropTransformFactory.ts +5 -1
- package/src/index.ts +18 -7
- package/src/stubs/textPlugin.ts +45 -0
- package/src/components/button/transforms/linkToButton.test.ts +0 -426
- package/src/components/link/transforms/inlineToKind.ts +0 -51
package/README.md
CHANGED
|
@@ -1,12 +1,106 @@
|
|
|
1
1
|
# tapestry-migration-cli
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A CLI tool to migrate Tapestry React components to Planning Center's Tapestry format.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
yarn add --dev @planningcenter/tapestry-migration-cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Recommended Migration Order
|
|
14
|
+
|
|
15
|
+
For optimal results, migrate components in this order:
|
|
16
|
+
|
|
17
|
+
1. **Button components first**: `npx @planningcenter/tapestry-migration-cli run button -p ./src/components --fix`
|
|
18
|
+
2. **Link components second**: `npx @planningcenter/tapestry-migration-cli run link -p ./src/components --fix`
|
|
19
|
+
|
|
20
|
+
This order ensures that Button components with navigation props are properly handled before Link components are migrated.
|
|
21
|
+
|
|
22
|
+
### Basic Commands
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Run a dry-run migration (preview changes)
|
|
26
|
+
npx @planningcenter/tapestry-migration-cli run button -p ./src/components
|
|
27
|
+
|
|
28
|
+
# Apply the migration changes
|
|
29
|
+
npx @planningcenter/tapestry-migration-cli run button -p ./src/components --fix
|
|
30
|
+
|
|
31
|
+
# Run with verbose output
|
|
32
|
+
npx @planningcenter/tapestry-migration-cli run button -p ./src/components --fix --verbose
|
|
33
|
+
|
|
34
|
+
# Generate a migration report
|
|
35
|
+
npx @planningcenter/tapestry-migration-cli run button -p ./src/components --fix --report-path ./migration-report.md
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Available Components
|
|
39
|
+
|
|
40
|
+
- `button` - Migrate Button components
|
|
41
|
+
- `link` - Migrate Link components
|
|
42
|
+
|
|
43
|
+
## Required Arguments
|
|
44
|
+
|
|
45
|
+
- `-p, --path <path>` - **REQUIRED**: Path to the folder or file to migrate
|
|
46
|
+
|
|
47
|
+
## Optional Arguments
|
|
48
|
+
|
|
49
|
+
- `-f, --fix` - Write changes to files (without this flag, it's a dry run)
|
|
50
|
+
- `-v, --verbose` - Show detailed output
|
|
51
|
+
- `-j, --js-theme <path>` - Path to JavaScript theme file
|
|
52
|
+
- `-r, --report-path <path>` - Path for migration report (default: MIGRATION_REPORT.md)
|
|
53
|
+
|
|
54
|
+
## How It Works
|
|
55
|
+
|
|
56
|
+
The migration tool automatically transforms your components to match Planning Center's current Tapestry specifications. Most property and usage changes are handled automatically, including:
|
|
57
|
+
|
|
58
|
+
- Converting deprecated props to their modern equivalents
|
|
59
|
+
- Updating import statements and component references
|
|
60
|
+
- Adjusting prop names and values to match current API
|
|
61
|
+
|
|
62
|
+
### Unsupported Props
|
|
63
|
+
|
|
64
|
+
For properties that cannot be automatically migrated, the tool will:
|
|
65
|
+
|
|
66
|
+
1. **Keep the prop as-is** - The prop remains in your code but will not work with the new Tapestry component
|
|
67
|
+
2. **Add a TODO comment** - Flagging the prop for manual migration
|
|
68
|
+
|
|
69
|
+
Example of an unsupported prop comment:
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
<Button
|
|
73
|
+
/* TODO: tapestry-migration (propName): 'mediaQueries' is not supported, please migrate as needed.
|
|
74
|
+
* It is recommended to use CSS media queries in a class that you apply to the component.
|
|
75
|
+
*/
|
|
76
|
+
mediaQueries={{ mobile: { fontSize: 14 } }}
|
|
77
|
+
>
|
|
78
|
+
Click me
|
|
79
|
+
</Button>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The comment includes guidance on how to handle the unsupported prop. Common recommendations include:
|
|
83
|
+
|
|
84
|
+
- Using CSS classes for styling instead of props
|
|
85
|
+
- Moving state-based styles (hover, focus, active) to CSS selectors
|
|
86
|
+
- Applying responsive styles through CSS media queries
|
|
87
|
+
|
|
88
|
+
## Alternative: Local Installation
|
|
89
|
+
|
|
90
|
+
If you prefer to install it locally and use a shorter command:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# Install locally
|
|
94
|
+
yarn add --dev @planningcenter/tapestry-migration-cli
|
|
95
|
+
|
|
96
|
+
# Add to package.json scripts
|
|
97
|
+
{
|
|
98
|
+
"scripts": {
|
|
99
|
+
"migrate": "tapestry-migration-cli"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
# Then run (following recommended order)
|
|
104
|
+
yarn migrate run button -p app/javascript/components --fix
|
|
105
|
+
yarn migrate run link -p app/javascript/components --fix
|
|
12
106
|
```
|
|
@@ -2681,7 +2681,7 @@ const PageHeaderActionsDropdownButton = reactExports.forwardRef(({ needsAttentio
|
|
|
2681
2681
|
});
|
|
2682
2682
|
PageHeaderActionsDropdownButton.displayName = "PageHeaderActionsDropdownButton";
|
|
2683
2683
|
const buildComponentClassName = (size, kind, className) => {
|
|
2684
|
-
return classNames(
|
|
2684
|
+
return classNames("tds-btn", size && size !== "md" && kind && COMPONENT_SIZE_CLASS_MAP[size], kind && COMPONENT_KIND_CLASS_MAP[kind], className);
|
|
2685
2685
|
};
|
|
2686
2686
|
const BaseLink = reactExports.forwardRef(({ size, prefix, suffix, kind, label, children, className, href, external = false, ...restProps }, ref) => {
|
|
2687
2687
|
const combinedClassName = buildComponentClassName(size, kind, className);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planningcenter/tapestry-migration-cli",
|
|
3
|
-
"version": "2.4.0-rc.
|
|
3
|
+
"version": "2.4.0-rc.21",
|
|
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": "ccf4df06966ffc1e520a3c78f613d98a4ef33c72"
|
|
55
55
|
}
|
|
@@ -8,7 +8,7 @@ import convertStyleProps from "./transforms/convertStyleProps"
|
|
|
8
8
|
import iconLeftToPrefix from "./transforms/iconLeftToPrefix"
|
|
9
9
|
import iconRightToSuffix from "./transforms/iconRightToSuffix"
|
|
10
10
|
import iconToIconButton from "./transforms/iconToIconButton"
|
|
11
|
-
import
|
|
11
|
+
import innerRefToRef from "./transforms/innerRefToRef"
|
|
12
12
|
import moveButtonImport from "./transforms/moveButtonImport"
|
|
13
13
|
import removeAsButton from "./transforms/removeAsButton"
|
|
14
14
|
import removeDuplicateKeys from "./transforms/removeDuplicateKeys"
|
|
@@ -47,7 +47,6 @@ const transform: Transform = async (fileInfo, api, options) => {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
const transforms = [
|
|
50
|
-
linkToButton,
|
|
51
50
|
tooltipToWrapper,
|
|
52
51
|
iconRightToSuffix,
|
|
53
52
|
iconLeftToPrefix,
|
|
@@ -55,16 +54,17 @@ const transform: Transform = async (fileInfo, api, options) => {
|
|
|
55
54
|
themeVariantToKind,
|
|
56
55
|
titleToLabel,
|
|
57
56
|
childrenToLabel,
|
|
57
|
+
innerRefToRef,
|
|
58
58
|
removeToTransform,
|
|
59
59
|
removeDuplicateKeys,
|
|
60
60
|
removeAsButton,
|
|
61
61
|
removeTypeButton,
|
|
62
62
|
auditSpreadProps,
|
|
63
63
|
reviewStyles,
|
|
64
|
+
spinnerToLoadingButton,
|
|
64
65
|
convertStyleProps,
|
|
65
66
|
unsupportedProps,
|
|
66
67
|
iconToIconButton,
|
|
67
|
-
spinnerToLoadingButton,
|
|
68
68
|
moveButtonImport,
|
|
69
69
|
]
|
|
70
70
|
|
|
@@ -105,10 +105,10 @@ function Test() {
|
|
|
105
105
|
"{/* TODO: tapestry-migration (children): complex children cannot be converted to label prop"
|
|
106
106
|
)
|
|
107
107
|
expect(result).toContain(
|
|
108
|
-
"take time to find the right text for the
|
|
108
|
+
"take time to find the right text for the component"
|
|
109
109
|
)
|
|
110
110
|
expect(result).toContain(
|
|
111
|
-
"prefix and suffix to correctly display those icons"
|
|
111
|
+
"If icons are used in the component, you can use prefix and suffix to correctly display those icons"
|
|
112
112
|
)
|
|
113
113
|
expect(result).toContain('<Icon name="save" />')
|
|
114
114
|
expect(result).toContain("Save")
|
|
@@ -177,8 +177,9 @@ function Test() {
|
|
|
177
177
|
"{/* TODO: tapestry-migration (label): Button has both label prop and children"
|
|
178
178
|
)
|
|
179
179
|
expect(result).toContain(
|
|
180
|
-
"take time to find the right text for the
|
|
180
|
+
"take time to find the right text for the component."
|
|
181
181
|
)
|
|
182
|
+
expect(result).not.toContain("If icons are used")
|
|
182
183
|
expect(result).toContain('label="Existing Label"')
|
|
183
184
|
expect(result).toContain("Child Content")
|
|
184
185
|
})
|
|
@@ -356,7 +357,7 @@ function Test() {
|
|
|
356
357
|
expect(result).toMatch(/\{\s*\/\*\s*TODO: tapestry-migration/)
|
|
357
358
|
expect(result).toMatch(/\*\/\s*\}/)
|
|
358
359
|
expect(result).toContain(
|
|
359
|
-
"take time to find the right text for the
|
|
360
|
+
"take time to find the right text for the component"
|
|
360
361
|
)
|
|
361
362
|
})
|
|
362
363
|
})
|
|
@@ -1,48 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Transform } from "jscodeshift"
|
|
2
2
|
|
|
3
3
|
import { addAttribute } from "../../shared/actions/addAttribute"
|
|
4
4
|
import { addComment } from "../../shared/actions/addComment"
|
|
5
5
|
import { removeChildren } from "../../shared/actions/removeChildren"
|
|
6
6
|
import { hasAttribute } from "../../shared/conditions/hasAttribute"
|
|
7
7
|
import { hasChildren } from "../../shared/conditions/hasChildren"
|
|
8
|
+
import {
|
|
9
|
+
buildComment,
|
|
10
|
+
extractTextContent,
|
|
11
|
+
} from "../../shared/helpers/childrenToLabelHelpers"
|
|
8
12
|
import { attributeTransformFactory } from "../../shared/transformFactories/attributeTransformFactory"
|
|
9
13
|
|
|
10
|
-
|
|
11
|
-
isSimpleText: boolean
|
|
12
|
-
textContent: string
|
|
13
|
-
} {
|
|
14
|
-
let textContent = ""
|
|
15
|
-
|
|
16
|
-
for (const child of children) {
|
|
17
|
-
if (child.type === "JSXText") {
|
|
18
|
-
const text = child.value.trim()
|
|
19
|
-
if (text) textContent += text
|
|
20
|
-
} else if (
|
|
21
|
-
child.type === "JSXExpressionContainer" &&
|
|
22
|
-
child.expression.type === "StringLiteral"
|
|
23
|
-
) {
|
|
24
|
-
textContent += child.expression.value
|
|
25
|
-
} else if (
|
|
26
|
-
child.type === "JSXExpressionContainer" &&
|
|
27
|
-
child.expression.type === "TemplateLiteral" &&
|
|
28
|
-
child.expression.expressions.length === 0
|
|
29
|
-
) {
|
|
30
|
-
// Simple template literal with no expressions like `hello`
|
|
31
|
-
textContent += child.expression.quasis[0].value.raw
|
|
32
|
-
} else {
|
|
33
|
-
// Complex content (JSX elements, expressions, etc.)
|
|
34
|
-
return { isSimpleText: false, textContent: "" }
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return { isSimpleText: true, textContent }
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function buildComment(message: string): string {
|
|
42
|
-
return `${message} - take time to find the right text for the button. If icons are used in the Button, you can use prefix and suffix to correctly display those icons.`
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const transform = attributeTransformFactory({
|
|
14
|
+
const transform: Transform = attributeTransformFactory({
|
|
46
15
|
condition: hasChildren,
|
|
47
16
|
targetComponent: "Button",
|
|
48
17
|
targetPackage: "@planningcenter/tapestry-react",
|
|
@@ -53,7 +22,7 @@ const transform = attributeTransformFactory({
|
|
|
53
22
|
j,
|
|
54
23
|
scope: "label",
|
|
55
24
|
source,
|
|
56
|
-
text: buildComment("Button has both label prop and children"),
|
|
25
|
+
text: buildComment("Button has both label prop and children", false),
|
|
57
26
|
})
|
|
58
27
|
return true
|
|
59
28
|
}
|
|
@@ -71,7 +40,8 @@ const transform = attributeTransformFactory({
|
|
|
71
40
|
scope: "children",
|
|
72
41
|
source,
|
|
73
42
|
text: buildComment(
|
|
74
|
-
"complex children cannot be converted to label prop"
|
|
43
|
+
"complex children cannot be converted to label prop",
|
|
44
|
+
true
|
|
75
45
|
),
|
|
76
46
|
})
|
|
77
47
|
return true
|
|
@@ -0,0 +1,170 @@
|
|
|
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 | 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("innerRefToRef transform", () => {
|
|
18
|
+
describe("basic transformations", () => {
|
|
19
|
+
it("should transform Button 'innerRef' prop to 'ref' prop", () => {
|
|
20
|
+
const input = `
|
|
21
|
+
import { Button } from "@planningcenter/tapestry-react"
|
|
22
|
+
|
|
23
|
+
export default function Test() {
|
|
24
|
+
return <Button innerRef={buttonRef}>Click me</Button>
|
|
25
|
+
}
|
|
26
|
+
`.trim()
|
|
27
|
+
|
|
28
|
+
const expected = `
|
|
29
|
+
import { Button } from "@planningcenter/tapestry-react"
|
|
30
|
+
|
|
31
|
+
export default function Test() {
|
|
32
|
+
return <Button ref={buttonRef}>Click me</Button>;
|
|
33
|
+
}
|
|
34
|
+
`.trim()
|
|
35
|
+
|
|
36
|
+
const result = applyTransform(input)
|
|
37
|
+
expect(result).toBe(expected)
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it("should transform Button 'innerRef' prop to 'ref' prop with function", () => {
|
|
41
|
+
const input = `
|
|
42
|
+
import { Button } from "@planningcenter/tapestry-react"
|
|
43
|
+
|
|
44
|
+
export default function Test() {
|
|
45
|
+
return <Button innerRef={(el) => setButtonRef(el)}>Click me</Button>
|
|
46
|
+
}
|
|
47
|
+
`.trim()
|
|
48
|
+
|
|
49
|
+
const expected = `
|
|
50
|
+
import { Button } from "@planningcenter/tapestry-react"
|
|
51
|
+
|
|
52
|
+
export default function Test() {
|
|
53
|
+
return <Button ref={(el) => setButtonRef(el)}>Click me</Button>;
|
|
54
|
+
}
|
|
55
|
+
`.trim()
|
|
56
|
+
|
|
57
|
+
const result = applyTransform(input)
|
|
58
|
+
expect(result).toBe(expected)
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
it("should transform Button 'innerRef' prop to 'ref' prop with useRef", () => {
|
|
62
|
+
const input = `
|
|
63
|
+
import { Button } from "@planningcenter/tapestry-react"
|
|
64
|
+
import { useRef } from "react"
|
|
65
|
+
|
|
66
|
+
export default function Test() {
|
|
67
|
+
const buttonRef = useRef(null)
|
|
68
|
+
return <Button innerRef={buttonRef}>Click me</Button>
|
|
69
|
+
}
|
|
70
|
+
`.trim()
|
|
71
|
+
|
|
72
|
+
const expected = `
|
|
73
|
+
import { Button } from "@planningcenter/tapestry-react"
|
|
74
|
+
import { useRef } from "react"
|
|
75
|
+
|
|
76
|
+
export default function Test() {
|
|
77
|
+
const buttonRef = useRef(null)
|
|
78
|
+
return <Button ref={buttonRef}>Click me</Button>;
|
|
79
|
+
}
|
|
80
|
+
`.trim()
|
|
81
|
+
|
|
82
|
+
const result = applyTransform(input)
|
|
83
|
+
expect(result).toBe(expected)
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
describe("multiple components", () => {
|
|
88
|
+
it("should transform multiple Button components with innerRef", () => {
|
|
89
|
+
const input = `
|
|
90
|
+
import { Button } from "@planningcenter/tapestry-react"
|
|
91
|
+
|
|
92
|
+
export default function Test() {
|
|
93
|
+
return (
|
|
94
|
+
<div>
|
|
95
|
+
<Button innerRef={buttonRef1}>First</Button>
|
|
96
|
+
<Button innerRef={buttonRef2}>Second</Button>
|
|
97
|
+
</div>
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
`.trim()
|
|
101
|
+
|
|
102
|
+
const expected = `
|
|
103
|
+
import { Button } from "@planningcenter/tapestry-react"
|
|
104
|
+
|
|
105
|
+
export default function Test() {
|
|
106
|
+
return (
|
|
107
|
+
<div>
|
|
108
|
+
<Button ref={buttonRef1}>First</Button>
|
|
109
|
+
<Button ref={buttonRef2}>Second</Button>
|
|
110
|
+
</div>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
`.trim()
|
|
114
|
+
|
|
115
|
+
const result = applyTransform(input)
|
|
116
|
+
expect(result).toBe(expected)
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
describe("edge cases", () => {
|
|
121
|
+
it("should not transform Button without innerRef", () => {
|
|
122
|
+
const input = `
|
|
123
|
+
import { Button } from "@planningcenter/tapestry-react"
|
|
124
|
+
|
|
125
|
+
export default function Test() {
|
|
126
|
+
return <Button onClick={handleClick}>Click me</Button>
|
|
127
|
+
}
|
|
128
|
+
`.trim()
|
|
129
|
+
|
|
130
|
+
const result = applyTransform(input)
|
|
131
|
+
expect(result).toBe(null)
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
it("should not transform other components with innerRef", () => {
|
|
135
|
+
const input = `
|
|
136
|
+
import { Link } from "@planningcenter/tapestry-react"
|
|
137
|
+
|
|
138
|
+
export default function Test() {
|
|
139
|
+
return <Link innerRef={linkRef}>Go somewhere</Link>
|
|
140
|
+
}
|
|
141
|
+
`.trim()
|
|
142
|
+
|
|
143
|
+
const result = applyTransform(input)
|
|
144
|
+
expect(result).toBe(null)
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
it("should preserve other props when transforming innerRef", () => {
|
|
148
|
+
const input = `
|
|
149
|
+
import { Button } from "@planningcenter/tapestry-react"
|
|
150
|
+
|
|
151
|
+
export default function Test() {
|
|
152
|
+
const buttonRef = null
|
|
153
|
+
return <Button innerRef={buttonRef} onClick={() => {}} disabled>Click me</Button>
|
|
154
|
+
}
|
|
155
|
+
`.trim()
|
|
156
|
+
|
|
157
|
+
const expected = `
|
|
158
|
+
import { Button } from "@planningcenter/tapestry-react"
|
|
159
|
+
|
|
160
|
+
export default function Test() {
|
|
161
|
+
const buttonRef = null
|
|
162
|
+
return <Button ref={buttonRef} onClick={() => {}} disabled>Click me</Button>;
|
|
163
|
+
}
|
|
164
|
+
`.trim()
|
|
165
|
+
|
|
166
|
+
const result = applyTransform(input)
|
|
167
|
+
expect(result).toBe(expected)
|
|
168
|
+
})
|
|
169
|
+
})
|
|
170
|
+
})
|
|
@@ -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: "Button",
|
|
8
|
+
targetPackage: "@planningcenter/tapestry-react",
|
|
9
|
+
transform: (element) => {
|
|
10
|
+
return transformAttributeName("innerRef", "ref", { element })
|
|
11
|
+
},
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
export default transform
|
|
@@ -1,44 +1,21 @@
|
|
|
1
1
|
import { JSXAttribute, Transform } from "jscodeshift"
|
|
2
2
|
|
|
3
|
-
import { stylePropNames } from "../../../../dist/tapestry-react-shim.cjs"
|
|
4
3
|
import { addCommentToUnsupportedProps } from "../../shared/actions/addCommentToUnsupportedProps"
|
|
4
|
+
import { SUPPORTED_PROPS_BASE } from "../../shared/helpers/unsupportedPropsHelpers"
|
|
5
5
|
import { attributeTransformFactory } from "../../shared/transformFactories/attributeTransformFactory"
|
|
6
6
|
|
|
7
|
-
const
|
|
8
|
-
...stylePropNames,
|
|
9
|
-
"children",
|
|
10
|
-
"className",
|
|
7
|
+
const BUTTON_SPECIFIC_PROPS = [
|
|
11
8
|
"disabled",
|
|
12
|
-
"kind",
|
|
13
|
-
"label",
|
|
14
|
-
"onClick",
|
|
15
|
-
"style",
|
|
16
|
-
"type",
|
|
17
|
-
"prefix",
|
|
18
|
-
"suffix",
|
|
19
|
-
"size",
|
|
20
9
|
"fullWidth",
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"external",
|
|
24
|
-
"id",
|
|
25
|
-
"onMouseOver",
|
|
26
|
-
"onMouseOut",
|
|
27
|
-
"onMouseDown",
|
|
28
|
-
"onMouseUp",
|
|
29
|
-
"onKeyUp",
|
|
30
|
-
"icon",
|
|
31
|
-
"weight",
|
|
32
|
-
"tabIndex",
|
|
33
|
-
"onKeyDown",
|
|
34
|
-
"onFocus",
|
|
35
|
-
"onBlur",
|
|
36
|
-
"role",
|
|
10
|
+
"loading",
|
|
11
|
+
"loadingAriaLabel",
|
|
37
12
|
"name",
|
|
38
|
-
"
|
|
39
|
-
"
|
|
13
|
+
"type",
|
|
14
|
+
"icon",
|
|
40
15
|
]
|
|
41
16
|
|
|
17
|
+
const SUPPORTED_PROPS = [...SUPPORTED_PROPS_BASE, ...BUTTON_SPECIFIC_PROPS]
|
|
18
|
+
|
|
42
19
|
const transform: Transform = attributeTransformFactory({
|
|
43
20
|
targetComponent: "Button",
|
|
44
21
|
targetPackage: "@planningcenter/tapestry-react",
|
|
@@ -1,17 +1,37 @@
|
|
|
1
1
|
import { Transform } from "jscodeshift"
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import auditSpreadProps from "./transforms/auditSpreadProps"
|
|
4
|
+
import childrenToLabel from "./transforms/childrenToLabel"
|
|
5
|
+
import convertStyleProps from "./transforms/convertStyleProps"
|
|
6
|
+
import innerRefToRef from "./transforms/innerRefToRef"
|
|
7
|
+
import moveLinkImport from "./transforms/moveLinkImport"
|
|
8
|
+
import removeAs from "./transforms/removeAs"
|
|
9
|
+
import removeInlineMember from "./transforms/removeInlineMember"
|
|
10
|
+
import removeInlineProp from "./transforms/removeInlineProp"
|
|
11
|
+
import reviewStyles from "./transforms/reviewStyles"
|
|
4
12
|
import targetBlankToExternal from "./transforms/targetBlankToExternal"
|
|
13
|
+
import tooltipToWrapper from "./transforms/tooltipToWrapper"
|
|
5
14
|
import toToHref from "./transforms/toToHref"
|
|
15
|
+
import unsupportedProps from "./transforms/unsupportedProps"
|
|
6
16
|
|
|
7
17
|
const transform: Transform = (fileInfo, api, options) => {
|
|
8
18
|
let currentSource = fileInfo.source
|
|
9
19
|
let hasAnyChanges = false
|
|
10
20
|
|
|
11
21
|
const transforms: Transform[] = [
|
|
12
|
-
|
|
22
|
+
removeInlineMember,
|
|
23
|
+
removeInlineProp,
|
|
24
|
+
tooltipToWrapper,
|
|
13
25
|
toToHref,
|
|
14
26
|
targetBlankToExternal,
|
|
27
|
+
innerRefToRef,
|
|
28
|
+
removeAs,
|
|
29
|
+
childrenToLabel,
|
|
30
|
+
auditSpreadProps,
|
|
31
|
+
reviewStyles,
|
|
32
|
+
convertStyleProps,
|
|
33
|
+
unsupportedProps,
|
|
34
|
+
moveLinkImport,
|
|
15
35
|
]
|
|
16
36
|
|
|
17
37
|
for (const individualTransform of transforms) {
|