@planningcenter/tapestry-migration-cli 3.1.0-rc.6 → 3.1.0-rc.7
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 +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 +8 -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 +391 -0
- package/src/components/input/transforms/mergeFieldIntoInput.ts +213 -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/removeTypeText.test.ts +160 -0
- package/src/components/input/transforms/removeTypeText.ts +18 -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/shared/helpers/unsupportedPropsHelpers.ts +52 -0
- package/src/components/shared/transformFactories/helpers/manageImports.ts +14 -12
- package/src/components/shared/transformFactories/sizeMappingFactory.ts +9 -2
- package/src/components/shared/transformFactories/stylePropTransformFactory.ts +54 -16
- package/src/components/shared/transformFactories/ternaryConditionalToPropFactory.ts +65 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import jscodeshift from "jscodeshift"
|
|
2
|
+
import { describe, expect, it } from "vitest"
|
|
3
|
+
|
|
4
|
+
import transform from "./stateToInvalid"
|
|
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("stateToInvalid transform", () => {
|
|
19
|
+
describe("state='error' conversion", () => {
|
|
20
|
+
it("should convert state='error' to invalid", () => {
|
|
21
|
+
const input = `
|
|
22
|
+
import { Input } from "@planningcenter/tapestry-react"
|
|
23
|
+
|
|
24
|
+
function Test() {
|
|
25
|
+
return <Input state="error" label="Name" />
|
|
26
|
+
}
|
|
27
|
+
`.trim()
|
|
28
|
+
|
|
29
|
+
const result = applyTransform(input)
|
|
30
|
+
expect(result).toContain("invalid")
|
|
31
|
+
expect(result).not.toContain('state="error"')
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('should convert state={"error"} expression to invalid', () => {
|
|
35
|
+
const input = `
|
|
36
|
+
import { Input } from "@planningcenter/tapestry-react"
|
|
37
|
+
|
|
38
|
+
function Test() {
|
|
39
|
+
return <Input state={"error"} label="Name" />
|
|
40
|
+
}
|
|
41
|
+
`.trim()
|
|
42
|
+
|
|
43
|
+
const result = applyTransform(input)
|
|
44
|
+
expect(result).toContain("invalid")
|
|
45
|
+
expect(result).not.toContain("state=")
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it("should preserve other props when converting state='error'", () => {
|
|
49
|
+
const input = `
|
|
50
|
+
import { Input } from "@planningcenter/tapestry-react"
|
|
51
|
+
|
|
52
|
+
function Test() {
|
|
53
|
+
return (
|
|
54
|
+
<Input
|
|
55
|
+
state="error"
|
|
56
|
+
label="Name"
|
|
57
|
+
placeholder="Enter name"
|
|
58
|
+
onChange={handleChange}
|
|
59
|
+
/>
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
`.trim()
|
|
63
|
+
|
|
64
|
+
const result = applyTransform(input)
|
|
65
|
+
expect(result).toContain("invalid")
|
|
66
|
+
expect(result).not.toContain("state=")
|
|
67
|
+
expect(result).toContain('label="Name"')
|
|
68
|
+
expect(result).toContain('placeholder="Enter name"')
|
|
69
|
+
expect(result).toContain("onChange={handleChange}")
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
describe("state='success' conversion", () => {
|
|
74
|
+
it("should remove state='success' and add comment", () => {
|
|
75
|
+
const input = `
|
|
76
|
+
import { Input } from "@planningcenter/tapestry-react"
|
|
77
|
+
|
|
78
|
+
function Test() {
|
|
79
|
+
return <Input state="success" label="Name" />
|
|
80
|
+
}
|
|
81
|
+
`.trim()
|
|
82
|
+
|
|
83
|
+
const result = applyTransform(input)
|
|
84
|
+
// The prop is removed from the element (comment text may still contain the string)
|
|
85
|
+
expect(result).not.toContain('<Input state="success"')
|
|
86
|
+
expect(result).toContain("TODO: tapestry-migration (state)")
|
|
87
|
+
expect(result).toContain("no equivalent")
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
it('should remove state={"success"} and add comment', () => {
|
|
91
|
+
const input = `
|
|
92
|
+
import { Input } from "@planningcenter/tapestry-react"
|
|
93
|
+
|
|
94
|
+
function Test() {
|
|
95
|
+
return <Input state={"success"} label="Name" />
|
|
96
|
+
}
|
|
97
|
+
`.trim()
|
|
98
|
+
|
|
99
|
+
const result = applyTransform(input)
|
|
100
|
+
// The prop is removed from the element
|
|
101
|
+
expect(result).not.toContain("state={")
|
|
102
|
+
expect(result).toContain("TODO: tapestry-migration (state)")
|
|
103
|
+
})
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
describe("dynamic state value", () => {
|
|
107
|
+
it("should add comment for variable state value", () => {
|
|
108
|
+
const input = `
|
|
109
|
+
import { Input } from "@planningcenter/tapestry-react"
|
|
110
|
+
|
|
111
|
+
function Test() {
|
|
112
|
+
const inputState = isError ? "error" : undefined
|
|
113
|
+
return <Input state={inputState} label="Name" />
|
|
114
|
+
}
|
|
115
|
+
`.trim()
|
|
116
|
+
|
|
117
|
+
const result = applyTransform(input)
|
|
118
|
+
expect(result).toContain("TODO: tapestry-migration (state)")
|
|
119
|
+
expect(result).toContain("'state' has been replaced by 'invalid'")
|
|
120
|
+
expect(result).toContain("state={inputState}")
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
it("should add comment for string variable", () => {
|
|
124
|
+
const input = `
|
|
125
|
+
import { Input } from "@planningcenter/tapestry-react"
|
|
126
|
+
|
|
127
|
+
function Test() {
|
|
128
|
+
return <Input state={currentState} label="Name" />
|
|
129
|
+
}
|
|
130
|
+
`.trim()
|
|
131
|
+
|
|
132
|
+
const result = applyTransform(input)
|
|
133
|
+
expect(result).toContain("TODO: tapestry-migration (state)")
|
|
134
|
+
})
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
describe("edge cases", () => {
|
|
138
|
+
it("should not affect Input without state prop", () => {
|
|
139
|
+
const input = `
|
|
140
|
+
import { Input } from "@planningcenter/tapestry-react"
|
|
141
|
+
|
|
142
|
+
function Test() {
|
|
143
|
+
return <Input label="Name" />
|
|
144
|
+
}
|
|
145
|
+
`.trim()
|
|
146
|
+
|
|
147
|
+
const result = applyTransform(input)
|
|
148
|
+
expect(result).toBe(input)
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
it("should not affect other components", () => {
|
|
152
|
+
const input = `
|
|
153
|
+
import { Input, Button } from "@planningcenter/tapestry-react"
|
|
154
|
+
|
|
155
|
+
function Test() {
|
|
156
|
+
return (
|
|
157
|
+
<div>
|
|
158
|
+
<Button state="error">Error</Button>
|
|
159
|
+
<Input state="error" label="Name" />
|
|
160
|
+
</div>
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
`.trim()
|
|
164
|
+
|
|
165
|
+
const result = applyTransform(input)
|
|
166
|
+
// Button state should be unchanged
|
|
167
|
+
expect(result).toContain('<Button state="error">Error</Button>')
|
|
168
|
+
// Input state should be transformed
|
|
169
|
+
expect(result).not.toContain('<Input state="error"')
|
|
170
|
+
expect(result).toContain("invalid")
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
it("should not transform if not imported from @planningcenter/tapestry-react", () => {
|
|
174
|
+
const input = `
|
|
175
|
+
import { Input } from "other-library"
|
|
176
|
+
|
|
177
|
+
function Test() {
|
|
178
|
+
return <Input state="error" label="Name" />
|
|
179
|
+
}
|
|
180
|
+
`.trim()
|
|
181
|
+
|
|
182
|
+
const result = applyTransform(input)
|
|
183
|
+
expect(result).toBe(input)
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
it("should handle multiple inputs with different states", () => {
|
|
187
|
+
const input = `
|
|
188
|
+
import { Input } from "@planningcenter/tapestry-react"
|
|
189
|
+
|
|
190
|
+
function Test() {
|
|
191
|
+
return (
|
|
192
|
+
<div>
|
|
193
|
+
<Input state="error" label="Error field" />
|
|
194
|
+
<Input state="success" label="Success field" />
|
|
195
|
+
<Input label="Normal field" />
|
|
196
|
+
</div>
|
|
197
|
+
)
|
|
198
|
+
}
|
|
199
|
+
`.trim()
|
|
200
|
+
|
|
201
|
+
const result = applyTransform(input)
|
|
202
|
+
expect(result).toContain("invalid")
|
|
203
|
+
expect(result).toContain("TODO: tapestry-migration (state)")
|
|
204
|
+
expect(result).not.toContain('<Input state="error"')
|
|
205
|
+
expect(result).not.toContain('<Input state="success"')
|
|
206
|
+
})
|
|
207
|
+
})
|
|
208
|
+
})
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Transform } from "jscodeshift"
|
|
2
|
+
|
|
3
|
+
import { addAttribute } from "../../shared/actions/addAttribute"
|
|
4
|
+
import { addComment } from "../../shared/actions/addComment"
|
|
5
|
+
import { getAttribute } from "../../shared/actions/getAttribute"
|
|
6
|
+
import { getAttributeValue } from "../../shared/actions/getAttributeValue"
|
|
7
|
+
import { removeAttribute } from "../../shared/actions/removeAttribute"
|
|
8
|
+
import { andConditions } from "../../shared/conditions/andConditions"
|
|
9
|
+
import { hasAttribute } from "../../shared/conditions/hasAttribute"
|
|
10
|
+
import { attributeTransformFactory } from "../../shared/transformFactories/attributeTransformFactory"
|
|
11
|
+
import { transformableInput } from "../transformableInput"
|
|
12
|
+
|
|
13
|
+
const transform: Transform = attributeTransformFactory({
|
|
14
|
+
condition: andConditions(hasAttribute("state"), transformableInput),
|
|
15
|
+
targetComponent: "Input",
|
|
16
|
+
targetPackage: "@planningcenter/tapestry-react",
|
|
17
|
+
transform: (element, { j, source }) => {
|
|
18
|
+
const attr = getAttribute({ element, name: "state" })
|
|
19
|
+
if (!attr) return false
|
|
20
|
+
|
|
21
|
+
const value = getAttributeValue({ attribute: attr, j })
|
|
22
|
+
|
|
23
|
+
if (value === "error") {
|
|
24
|
+
removeAttribute("state", { element, j, source })
|
|
25
|
+
addAttribute({
|
|
26
|
+
booleanAsShorthand: true,
|
|
27
|
+
element,
|
|
28
|
+
j,
|
|
29
|
+
name: "invalid",
|
|
30
|
+
value: true,
|
|
31
|
+
})
|
|
32
|
+
return true
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (value === "success") {
|
|
36
|
+
removeAttribute("state", { element, j, source })
|
|
37
|
+
addComment({
|
|
38
|
+
element,
|
|
39
|
+
j,
|
|
40
|
+
scope: "state",
|
|
41
|
+
source,
|
|
42
|
+
text: "'state=\"success\"' has no equivalent in the new Input API. Remove this prop and implement success feedback separately.",
|
|
43
|
+
})
|
|
44
|
+
return true
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Dynamic value — can't determine at compile time
|
|
48
|
+
addComment({
|
|
49
|
+
element,
|
|
50
|
+
j,
|
|
51
|
+
scope: "state",
|
|
52
|
+
source,
|
|
53
|
+
text: "'state' has been replaced by 'invalid' (boolean). For error state, use invalid={true}. 'success' has no equivalent. Migrate this prop manually.",
|
|
54
|
+
})
|
|
55
|
+
return true
|
|
56
|
+
},
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
export default transform
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import jscodeshift from "jscodeshift"
|
|
2
|
+
import { describe, expect, it } from "vitest"
|
|
3
|
+
|
|
4
|
+
import transform from "./stateToInvalidTernary"
|
|
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("stateToInvalidTernary transform", () => {
|
|
18
|
+
describe("successful conversions", () => {
|
|
19
|
+
it("converts state={hasError ? 'error' : null} → invalid={hasError}", () => {
|
|
20
|
+
const input = `
|
|
21
|
+
import { Input } from "@planningcenter/tapestry-react"
|
|
22
|
+
|
|
23
|
+
function Test() {
|
|
24
|
+
return <Input state={hasError ? "error" : null} label="Name" />
|
|
25
|
+
}
|
|
26
|
+
`.trim()
|
|
27
|
+
|
|
28
|
+
const result = applyTransform(input)
|
|
29
|
+
expect(result).not.toBeNull()
|
|
30
|
+
expect(result).toContain("invalid={hasError}")
|
|
31
|
+
expect(result).not.toContain("state=")
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it("converts member expression: state={form.hasError ? 'error' : null} → invalid={form.hasError}", () => {
|
|
35
|
+
const input = `
|
|
36
|
+
import { Input } from "@planningcenter/tapestry-react"
|
|
37
|
+
|
|
38
|
+
function Test() {
|
|
39
|
+
return <Input state={form.hasError ? "error" : null} label="Name" />
|
|
40
|
+
}
|
|
41
|
+
`.trim()
|
|
42
|
+
|
|
43
|
+
const result = applyTransform(input)
|
|
44
|
+
expect(result).not.toBeNull()
|
|
45
|
+
expect(result).toContain("invalid={form.hasError}")
|
|
46
|
+
expect(result).not.toContain("state=")
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it("converts binary expression: state={errors.length > 0 ? 'error' : null} → invalid={errors.length > 0}", () => {
|
|
50
|
+
const input = `
|
|
51
|
+
import { Input } from "@planningcenter/tapestry-react"
|
|
52
|
+
|
|
53
|
+
function Test() {
|
|
54
|
+
return <Input state={errors.length > 0 ? "error" : null} label="Name" />
|
|
55
|
+
}
|
|
56
|
+
`.trim()
|
|
57
|
+
|
|
58
|
+
const result = applyTransform(input)
|
|
59
|
+
expect(result).not.toBeNull()
|
|
60
|
+
expect(result).toContain("invalid={errors.length > 0}")
|
|
61
|
+
expect(result).not.toContain("state=")
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it("converts state={hasError ? 'error' : undefined} → invalid={hasError}", () => {
|
|
65
|
+
const input = `
|
|
66
|
+
import { Input } from "@planningcenter/tapestry-react"
|
|
67
|
+
|
|
68
|
+
function Test() {
|
|
69
|
+
return <Input state={hasError ? "error" : undefined} label="Name" />
|
|
70
|
+
}
|
|
71
|
+
`.trim()
|
|
72
|
+
|
|
73
|
+
const result = applyTransform(input)
|
|
74
|
+
expect(result).not.toBeNull()
|
|
75
|
+
expect(result).toContain("invalid={hasError}")
|
|
76
|
+
expect(result).not.toContain("state=")
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
describe("no-op cases", () => {
|
|
81
|
+
it("returns null when consequent is not 'error'", () => {
|
|
82
|
+
const input = `
|
|
83
|
+
import { Input } from "@planningcenter/tapestry-react"
|
|
84
|
+
|
|
85
|
+
function Test() {
|
|
86
|
+
return <Input state={hasWarning ? "warning" : null} label="Name" />
|
|
87
|
+
}
|
|
88
|
+
`.trim()
|
|
89
|
+
|
|
90
|
+
const result = applyTransform(input)
|
|
91
|
+
expect(result).toBeNull()
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
it("returns null when alternate is not null/undefined", () => {
|
|
95
|
+
const input = `
|
|
96
|
+
import { Input } from "@planningcenter/tapestry-react"
|
|
97
|
+
|
|
98
|
+
function Test() {
|
|
99
|
+
return <Input state={hasError ? "error" : "success"} label="Name" />
|
|
100
|
+
}
|
|
101
|
+
`.trim()
|
|
102
|
+
|
|
103
|
+
const result = applyTransform(input)
|
|
104
|
+
expect(result).toBeNull()
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it("returns null when Input is from a different package", () => {
|
|
108
|
+
const input = `
|
|
109
|
+
import { Input } from "other-library"
|
|
110
|
+
|
|
111
|
+
function Test() {
|
|
112
|
+
return <Input state={hasError ? "error" : null} label="Name" />
|
|
113
|
+
}
|
|
114
|
+
`.trim()
|
|
115
|
+
|
|
116
|
+
const result = applyTransform(input)
|
|
117
|
+
expect(result).toBeNull()
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
it("returns null when Input has renderLeft prop", () => {
|
|
121
|
+
const input = `
|
|
122
|
+
import { Input } from "@planningcenter/tapestry-react"
|
|
123
|
+
|
|
124
|
+
function Test() {
|
|
125
|
+
return <Input state={hasError ? "error" : null} renderLeft={() => <span />} label="Name" />
|
|
126
|
+
}
|
|
127
|
+
`.trim()
|
|
128
|
+
|
|
129
|
+
const result = applyTransform(input)
|
|
130
|
+
expect(result).toBeNull()
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
it("returns null when Input has renderRight prop", () => {
|
|
134
|
+
const input = `
|
|
135
|
+
import { Input } from "@planningcenter/tapestry-react"
|
|
136
|
+
|
|
137
|
+
function Test() {
|
|
138
|
+
return <Input state={hasError ? "error" : null} renderRight={() => <span />} label="Name" />
|
|
139
|
+
}
|
|
140
|
+
`.trim()
|
|
141
|
+
|
|
142
|
+
const result = applyTransform(input)
|
|
143
|
+
expect(result).toBeNull()
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
it("returns null when Input has no state prop", () => {
|
|
147
|
+
const input = `
|
|
148
|
+
import { Input } from "@planningcenter/tapestry-react"
|
|
149
|
+
|
|
150
|
+
function Test() {
|
|
151
|
+
return <Input label="Name" />
|
|
152
|
+
}
|
|
153
|
+
`.trim()
|
|
154
|
+
|
|
155
|
+
const result = applyTransform(input)
|
|
156
|
+
expect(result).toBeNull()
|
|
157
|
+
})
|
|
158
|
+
})
|
|
159
|
+
})
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { andConditions } from "../../shared/conditions/andConditions"
|
|
2
|
+
import { hasAttribute } from "../../shared/conditions/hasAttribute"
|
|
3
|
+
import { ternaryConditionalToPropFactory } from "../../shared/transformFactories/ternaryConditionalToPropFactory"
|
|
4
|
+
import { transformableInput } from "../transformableInput"
|
|
5
|
+
|
|
6
|
+
export default ternaryConditionalToPropFactory({
|
|
7
|
+
condition: andConditions(hasAttribute("state"), transformableInput),
|
|
8
|
+
fromProp: "state",
|
|
9
|
+
matchValue: "error",
|
|
10
|
+
targetComponent: "Input",
|
|
11
|
+
targetPackage: "@planningcenter/tapestry-react",
|
|
12
|
+
toProp: "invalid",
|
|
13
|
+
})
|