@sanity/ui-codemod 1.0.0-alpha.4 → 1.0.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks-es/addAttribute.js +1 -1
- package/dist/_chunks-es/box.mods.js +1 -1
- package/dist/_chunks-es/layout-mods.js +4 -0
- package/dist/_chunks-es/layout-mods.js.map +1 -1
- package/dist/_chunks-es/{transformComponent.js → transformStyledComponents.js} +150 -2
- package/dist/_chunks-es/transformStyledComponents.js.map +1 -0
- package/dist/transforms/latest/box/box.js +1 -147
- package/dist/transforms/latest/box/box.js.map +1 -1
- package/dist/transforms/latest/card/card.js +24 -9
- package/dist/transforms/latest/card/card.js.map +1 -1
- package/dist/transforms/latest/code/code.js +18 -7
- package/dist/transforms/latest/code/code.js.map +1 -1
- package/dist/transforms/latest/container/container.js +15 -7
- package/dist/transforms/latest/container/container.js.map +1 -1
- package/dist/transforms/latest/flex/flex.js +15 -7
- package/dist/transforms/latest/flex/flex.js.map +1 -1
- package/dist/transforms/latest/grid/grid.js +15 -7
- package/dist/transforms/latest/grid/grid.js.map +1 -1
- package/dist/transforms/latest/heading/heading.js +18 -7
- package/dist/transforms/latest/heading/heading.js.map +1 -1
- package/dist/transforms/latest/text/text.js +18 -7
- package/dist/transforms/latest/text/text.js.map +1 -1
- package/package.json +1 -1
- package/src/constants/latest/layout-mods.ts +4 -0
- package/src/transforms/latest/box/box.test.ts +86 -151
- package/src/transforms/latest/card/card.test.ts +100 -1
- package/src/transforms/latest/card/card.ts +42 -19
- package/src/transforms/latest/code/code.test.ts +84 -1
- package/src/transforms/latest/code/code.ts +47 -16
- package/src/transforms/latest/container/container.test.ts +78 -1
- package/src/transforms/latest/container/container.ts +29 -9
- package/src/transforms/latest/flex/flex.test.ts +78 -1
- package/src/transforms/latest/flex/flex.ts +29 -9
- package/src/transforms/latest/grid/grid.test.ts +78 -1
- package/src/transforms/latest/grid/grid.ts +29 -9
- package/src/transforms/latest/heading/heading.test.ts +84 -1
- package/src/transforms/latest/heading/heading.ts +47 -16
- package/src/transforms/latest/inline/inline.test.ts +78 -1
- package/src/transforms/latest/inline/inline.ts +29 -9
- package/src/transforms/latest/label/label.test.ts +84 -1
- package/src/transforms/latest/label/label.ts +36 -1
- package/src/transforms/latest/stack/stack.test.ts +100 -1
- package/src/transforms/latest/stack/stack.ts +29 -7
- package/src/transforms/latest/text/text.test.ts +84 -1
- package/src/transforms/latest/text/text.ts +58 -19
- package/src/utils/testUtils.ts +45 -0
- package/dist/_chunks-es/transformComponent.js.map +0 -1
|
@@ -3,10 +3,12 @@ import {type API, type FileInfo} from 'jscodeshift'
|
|
|
3
3
|
import type {BaseOptions} from '../../../types/BaseOptions'
|
|
4
4
|
import {addAttribute} from '../../../utils/addAttribute'
|
|
5
5
|
import {getComponentLocalNames} from '../../../utils/getComponentLocalNames'
|
|
6
|
+
import {getStyledComponentAliases} from '../../../utils/getStyledComponentAliases'
|
|
6
7
|
import {shouldTransformComponent} from '../../../utils/shouldTransformComponent'
|
|
7
8
|
import {transformAttributes} from '../../../utils/transformAttributes'
|
|
8
9
|
import {transformComponent} from '../../../utils/transformComponent'
|
|
9
10
|
import {transformImport} from '../../../utils/transformImport'
|
|
11
|
+
import {transformStyledComponents} from '../../../utils/transformStyledComponents'
|
|
10
12
|
import {HEADING_MODS} from './heading.mods'
|
|
11
13
|
|
|
12
14
|
const TODO_WARNING = 'Please double check the Heading migration below'
|
|
@@ -21,8 +23,16 @@ export default function transform(
|
|
|
21
23
|
|
|
22
24
|
return transformComponent(fileInfo, api, ({j, root, markChanged}) => {
|
|
23
25
|
const localNames = getComponentLocalNames(j, root, 'Heading', options)
|
|
26
|
+
const styledAliases = getStyledComponentAliases(
|
|
27
|
+
j,
|
|
28
|
+
root,
|
|
29
|
+
'Heading',
|
|
30
|
+
fileInfo.path,
|
|
31
|
+
localNames,
|
|
32
|
+
options,
|
|
33
|
+
)
|
|
24
34
|
|
|
25
|
-
if (!shouldTransformComponent(j, root, 'Heading', localNames, options)) {
|
|
35
|
+
if (!shouldTransformComponent(j, root, 'Heading', localNames, options, styledAliases)) {
|
|
26
36
|
return
|
|
27
37
|
}
|
|
28
38
|
|
|
@@ -30,24 +40,45 @@ export default function transform(
|
|
|
30
40
|
markChanged()
|
|
31
41
|
}
|
|
32
42
|
|
|
33
|
-
root
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
.
|
|
38
|
-
|
|
43
|
+
root.find(j.JSXOpeningElement).forEach((path) => {
|
|
44
|
+
let changed = false
|
|
45
|
+
const name = path.node.name
|
|
46
|
+
|
|
47
|
+
if (name.type !== 'JSXIdentifier' || !localNames.has(name.name)) {
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (transformAttributes(j, path, HEADING_MODS, TODO_WARNING)) {
|
|
52
|
+
changed = true
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (addAttribute(j, path.node, 'trim', true)) {
|
|
56
|
+
changed = true
|
|
57
|
+
}
|
|
39
58
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
59
|
+
if (changed) {
|
|
60
|
+
markChanged()
|
|
61
|
+
}
|
|
62
|
+
})
|
|
43
63
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
64
|
+
if (
|
|
65
|
+
transformStyledComponents(j, root, styledAliases, () => true, {
|
|
66
|
+
callback: (path) => {
|
|
67
|
+
let changed = false
|
|
47
68
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
69
|
+
if (transformAttributes(j, path, HEADING_MODS, TODO_WARNING)) {
|
|
70
|
+
changed = true
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (addAttribute(j, path.node, 'trim', true)) {
|
|
74
|
+
changed = true
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return changed
|
|
78
|
+
},
|
|
51
79
|
})
|
|
80
|
+
) {
|
|
81
|
+
markChanged()
|
|
82
|
+
}
|
|
52
83
|
})
|
|
53
84
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {expect} from 'vitest'
|
|
2
|
+
|
|
3
|
+
import {defineCrossFileTest, defineInlineTest} from '../../../utils/testUtils'
|
|
2
4
|
import transform from './inline'
|
|
3
5
|
|
|
4
6
|
defineInlineTest(
|
|
@@ -55,3 +57,78 @@ defineInlineTest(
|
|
|
55
57
|
`,
|
|
56
58
|
'warns if margin prop is present',
|
|
57
59
|
)
|
|
60
|
+
|
|
61
|
+
defineCrossFileTest(
|
|
62
|
+
transform,
|
|
63
|
+
{},
|
|
64
|
+
`
|
|
65
|
+
import {Inline} from '@sanity/ui'
|
|
66
|
+
|
|
67
|
+
export const RootInline = styled(Inline)(({theme}) => ({}))
|
|
68
|
+
`,
|
|
69
|
+
`
|
|
70
|
+
import {RootInline} from './Component.styled'
|
|
71
|
+
|
|
72
|
+
export function Component() {
|
|
73
|
+
return <RootInline space={2} />
|
|
74
|
+
}
|
|
75
|
+
`,
|
|
76
|
+
(output) => {
|
|
77
|
+
expect(output).toContain('<RootInline gap={2} />')
|
|
78
|
+
},
|
|
79
|
+
'transforms attributes on imported styled Inline wrappers',
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
defineCrossFileTest(
|
|
83
|
+
transform,
|
|
84
|
+
{},
|
|
85
|
+
`
|
|
86
|
+
import {Inline} from '@sanity/ui'
|
|
87
|
+
|
|
88
|
+
export const RootInline = styled(Inline)(({theme}) => ({}))
|
|
89
|
+
`,
|
|
90
|
+
`
|
|
91
|
+
import {Inline} from 'another-package'
|
|
92
|
+
import {RootInline} from './Component.styled'
|
|
93
|
+
|
|
94
|
+
export function Component() {
|
|
95
|
+
return (
|
|
96
|
+
<>
|
|
97
|
+
<RootInline space={2} />
|
|
98
|
+
<Inline space={2} />
|
|
99
|
+
</>
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
`,
|
|
103
|
+
(output) => {
|
|
104
|
+
expect(output).toContain('<RootInline gap={2} />')
|
|
105
|
+
expect(output).toContain('<Inline space={2} />')
|
|
106
|
+
},
|
|
107
|
+
'does not transform attributes on unrelated Inline from another package',
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
defineCrossFileTest(
|
|
111
|
+
transform,
|
|
112
|
+
{},
|
|
113
|
+
`
|
|
114
|
+
import {Inline} from '@sanity/ui'
|
|
115
|
+
|
|
116
|
+
export const RootInline = styled(Inline)(({theme}) => ({}))
|
|
117
|
+
`,
|
|
118
|
+
`
|
|
119
|
+
import {RootInline} from './index'
|
|
120
|
+
|
|
121
|
+
export function Component() {
|
|
122
|
+
return <RootInline space={2} />
|
|
123
|
+
}
|
|
124
|
+
`,
|
|
125
|
+
(output) => {
|
|
126
|
+
expect(output).toContain('<RootInline gap={2} />')
|
|
127
|
+
},
|
|
128
|
+
'transforms styled Inline wrappers imported through barrel re-exports',
|
|
129
|
+
{
|
|
130
|
+
extraFiles: {
|
|
131
|
+
'index.ts': `export {RootInline} from './Component.styled'`,
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
)
|
|
@@ -2,10 +2,12 @@ import {type API, type FileInfo} from 'jscodeshift'
|
|
|
2
2
|
|
|
3
3
|
import type {BaseOptions} from '../../../types/BaseOptions'
|
|
4
4
|
import {getComponentLocalNames} from '../../../utils/getComponentLocalNames'
|
|
5
|
+
import {getStyledComponentAliases} from '../../../utils/getStyledComponentAliases'
|
|
5
6
|
import {shouldTransformComponent} from '../../../utils/shouldTransformComponent'
|
|
6
7
|
import {transformAttributes} from '../../../utils/transformAttributes'
|
|
7
8
|
import {transformComponent} from '../../../utils/transformComponent'
|
|
8
9
|
import {transformImport} from '../../../utils/transformImport'
|
|
10
|
+
import {transformStyledComponents} from '../../../utils/transformStyledComponents'
|
|
9
11
|
import {INLINE_MODS} from './inline.mods'
|
|
10
12
|
|
|
11
13
|
const TODO_WARNING = 'Please double check the Inline migration below'
|
|
@@ -20,8 +22,16 @@ export default function transform(
|
|
|
20
22
|
|
|
21
23
|
return transformComponent(fileInfo, api, ({j, root, markChanged}) => {
|
|
22
24
|
const localNames = getComponentLocalNames(j, root, 'Inline', options)
|
|
25
|
+
const styledAliases = getStyledComponentAliases(
|
|
26
|
+
j,
|
|
27
|
+
root,
|
|
28
|
+
'Inline',
|
|
29
|
+
fileInfo.path,
|
|
30
|
+
localNames,
|
|
31
|
+
options,
|
|
32
|
+
)
|
|
23
33
|
|
|
24
|
-
if (!shouldTransformComponent(j, root, 'Inline', localNames, options)) {
|
|
34
|
+
if (!shouldTransformComponent(j, root, 'Inline', localNames, options, styledAliases)) {
|
|
25
35
|
return
|
|
26
36
|
}
|
|
27
37
|
|
|
@@ -29,14 +39,24 @@ export default function transform(
|
|
|
29
39
|
markChanged()
|
|
30
40
|
}
|
|
31
41
|
|
|
32
|
-
root
|
|
33
|
-
.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
42
|
+
root.find(j.JSXOpeningElement).forEach((path) => {
|
|
43
|
+
const name = path.node.name
|
|
44
|
+
|
|
45
|
+
if (name.type !== 'JSXIdentifier' || !localNames.has(name.name)) {
|
|
46
|
+
return
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (transformAttributes(j, path, INLINE_MODS, TODO_WARNING)) {
|
|
50
|
+
markChanged()
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
if (
|
|
55
|
+
transformStyledComponents(j, root, styledAliases, () => true, {
|
|
56
|
+
callback: (path) => transformAttributes(j, path, INLINE_MODS, TODO_WARNING),
|
|
40
57
|
})
|
|
58
|
+
) {
|
|
59
|
+
markChanged()
|
|
60
|
+
}
|
|
41
61
|
})
|
|
42
62
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {expect} from 'vitest'
|
|
2
|
+
|
|
3
|
+
import {defineCrossFileTest, defineInlineTest} from '../../../utils/testUtils'
|
|
2
4
|
import transform from './label'
|
|
3
5
|
|
|
4
6
|
defineInlineTest(
|
|
@@ -111,3 +113,84 @@ defineInlineTest(
|
|
|
111
113
|
`,
|
|
112
114
|
'moves width props to style and updates mapped value',
|
|
113
115
|
)
|
|
116
|
+
|
|
117
|
+
defineCrossFileTest(
|
|
118
|
+
transform,
|
|
119
|
+
{},
|
|
120
|
+
`
|
|
121
|
+
import {Label} from '@sanity/ui'
|
|
122
|
+
|
|
123
|
+
export const RootLabel = styled(Label)(({theme}) => ({}))
|
|
124
|
+
`,
|
|
125
|
+
`
|
|
126
|
+
import {RootLabel} from './Component.styled'
|
|
127
|
+
|
|
128
|
+
export function RootCode() {
|
|
129
|
+
return <RootLabel flex="auto" />
|
|
130
|
+
}
|
|
131
|
+
`,
|
|
132
|
+
(output) => {
|
|
133
|
+
expect(output.replace(/\s+/g, ' ')).toContain(
|
|
134
|
+
'<RootLabel style={{ flex: "1 1 auto" }} as="div" trim={true} />',
|
|
135
|
+
)
|
|
136
|
+
},
|
|
137
|
+
'transforms attributes on imported styled Label wrappers',
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
defineCrossFileTest(
|
|
141
|
+
transform,
|
|
142
|
+
{},
|
|
143
|
+
`
|
|
144
|
+
import {Label} from '@sanity/ui'
|
|
145
|
+
|
|
146
|
+
export const RootLabel = styled(Label)(({theme}) => ({}))
|
|
147
|
+
`,
|
|
148
|
+
`
|
|
149
|
+
import {Label} from 'another-package'
|
|
150
|
+
import {RootLabel} from './Component.styled'
|
|
151
|
+
|
|
152
|
+
export function Component() {
|
|
153
|
+
return (
|
|
154
|
+
<>
|
|
155
|
+
<RootLabel flex="auto" />
|
|
156
|
+
<Label flex="auto" />
|
|
157
|
+
</>
|
|
158
|
+
)
|
|
159
|
+
}
|
|
160
|
+
`,
|
|
161
|
+
(output) => {
|
|
162
|
+
expect(output.replace(/\s+/g, ' ')).toContain(
|
|
163
|
+
'<RootLabel style={{ flex: "1 1 auto" }} as="div" trim={true} />',
|
|
164
|
+
)
|
|
165
|
+
expect(output).toContain('<Label flex="auto" />')
|
|
166
|
+
},
|
|
167
|
+
'does not transform attributes on unrelated Label from another package',
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
defineCrossFileTest(
|
|
171
|
+
transform,
|
|
172
|
+
{},
|
|
173
|
+
`
|
|
174
|
+
import {Label} from '@sanity/ui'
|
|
175
|
+
|
|
176
|
+
export const RootLabel = styled(Label)(({theme}) => ({}))
|
|
177
|
+
`,
|
|
178
|
+
`
|
|
179
|
+
import {RootLabel} from './index'
|
|
180
|
+
|
|
181
|
+
export function Component() {
|
|
182
|
+
return <RootLabel flex="auto" />
|
|
183
|
+
}
|
|
184
|
+
`,
|
|
185
|
+
(output) => {
|
|
186
|
+
expect(output.replace(/\s+/g, ' ')).toContain(
|
|
187
|
+
'<RootLabel style={{ flex: "1 1 auto" }} as="div" trim={true} />',
|
|
188
|
+
)
|
|
189
|
+
},
|
|
190
|
+
'transforms styled Label wrappers imported through barrel re-exports',
|
|
191
|
+
{
|
|
192
|
+
extraFiles: {
|
|
193
|
+
'index.ts': `export {RootLabel} from './Component.styled'`,
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
)
|
|
@@ -3,11 +3,13 @@ import {type API, type FileInfo} from 'jscodeshift'
|
|
|
3
3
|
import type {BaseOptions} from '../../../types/BaseOptions'
|
|
4
4
|
import {addAttribute} from '../../../utils/addAttribute'
|
|
5
5
|
import {getComponentLocalNames} from '../../../utils/getComponentLocalNames'
|
|
6
|
+
import {getStyledComponentAliases} from '../../../utils/getStyledComponentAliases'
|
|
6
7
|
import {replaceElement} from '../../../utils/replaceElement'
|
|
7
8
|
import {shouldTransformComponent} from '../../../utils/shouldTransformComponent'
|
|
8
9
|
import {transformAttributes} from '../../../utils/transformAttributes'
|
|
9
10
|
import {transformComponent} from '../../../utils/transformComponent'
|
|
10
11
|
import {transformImport} from '../../../utils/transformImport'
|
|
12
|
+
import {transformStyledComponents} from '../../../utils/transformStyledComponents'
|
|
11
13
|
import {LABEL_MODS} from './label.mods'
|
|
12
14
|
|
|
13
15
|
const TODO_WARNING = 'Please double check the Label migration below'
|
|
@@ -22,8 +24,16 @@ export default function transform(
|
|
|
22
24
|
|
|
23
25
|
return transformComponent(fileInfo, api, ({j, root, markChanged}) => {
|
|
24
26
|
const localNames = getComponentLocalNames(j, root, 'Label', options)
|
|
27
|
+
const styledAliases = getStyledComponentAliases(
|
|
28
|
+
j,
|
|
29
|
+
root,
|
|
30
|
+
'Label',
|
|
31
|
+
fileInfo.path,
|
|
32
|
+
localNames,
|
|
33
|
+
options,
|
|
34
|
+
)
|
|
25
35
|
|
|
26
|
-
if (!shouldTransformComponent(j, root, 'Label', localNames, options)) {
|
|
36
|
+
if (!shouldTransformComponent(j, root, 'Label', localNames, options, styledAliases)) {
|
|
27
37
|
return
|
|
28
38
|
}
|
|
29
39
|
|
|
@@ -38,6 +48,7 @@ export default function transform(
|
|
|
38
48
|
() => true,
|
|
39
49
|
{
|
|
40
50
|
element: 'Label',
|
|
51
|
+
localNames,
|
|
41
52
|
},
|
|
42
53
|
{
|
|
43
54
|
element: 'Eyebrow',
|
|
@@ -63,5 +74,29 @@ export default function transform(
|
|
|
63
74
|
) {
|
|
64
75
|
markChanged()
|
|
65
76
|
}
|
|
77
|
+
|
|
78
|
+
if (
|
|
79
|
+
transformStyledComponents(j, root, styledAliases, () => true, {
|
|
80
|
+
callback: (path) => {
|
|
81
|
+
let changed = false
|
|
82
|
+
|
|
83
|
+
if (transformAttributes(j, path, LABEL_MODS, TODO_WARNING)) {
|
|
84
|
+
changed = true
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (addAttribute(j, path.node, 'as', 'div')) {
|
|
88
|
+
changed = true
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (addAttribute(j, path.node, 'trim', true)) {
|
|
92
|
+
changed = true
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return changed
|
|
96
|
+
},
|
|
97
|
+
})
|
|
98
|
+
) {
|
|
99
|
+
markChanged()
|
|
100
|
+
}
|
|
66
101
|
})
|
|
67
102
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {expect} from 'vitest'
|
|
2
|
+
|
|
3
|
+
import {defineCrossFileTest, defineInlineTest} from '../../../utils/testUtils'
|
|
2
4
|
import transform from './stack'
|
|
3
5
|
|
|
4
6
|
defineInlineTest(
|
|
@@ -158,3 +160,100 @@ defineInlineTest(
|
|
|
158
160
|
`,
|
|
159
161
|
'replaces Stack with Flex and transforms attributes',
|
|
160
162
|
)
|
|
163
|
+
|
|
164
|
+
defineCrossFileTest(
|
|
165
|
+
transform,
|
|
166
|
+
{},
|
|
167
|
+
`
|
|
168
|
+
import {Stack} from '@sanity/ui'
|
|
169
|
+
|
|
170
|
+
export const RootStack = styled(Stack)(({theme}) => ({}))
|
|
171
|
+
`,
|
|
172
|
+
`
|
|
173
|
+
import {RootStack} from './Component.styled'
|
|
174
|
+
|
|
175
|
+
export function Component() {
|
|
176
|
+
return <RootStack space={2} />
|
|
177
|
+
}
|
|
178
|
+
`,
|
|
179
|
+
(output) => {
|
|
180
|
+
expect(output).toContain('<RootStack gap={2} />')
|
|
181
|
+
},
|
|
182
|
+
'transforms attributes on imported styled Stack wrappers',
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
defineCrossFileTest(
|
|
186
|
+
transform,
|
|
187
|
+
{},
|
|
188
|
+
`
|
|
189
|
+
import {Stack} from '@sanity/ui'
|
|
190
|
+
|
|
191
|
+
export const RootStack = styled(Stack)(({theme}) => ({}))
|
|
192
|
+
`,
|
|
193
|
+
`
|
|
194
|
+
import {RootStack} from './Component.styled'
|
|
195
|
+
|
|
196
|
+
export function Component() {
|
|
197
|
+
return <RootStack padding={2} />
|
|
198
|
+
}
|
|
199
|
+
`,
|
|
200
|
+
(output) => {
|
|
201
|
+
expect(output).toContain('UI-CODEMOD TODO: Please double check styled(Stack) migration below')
|
|
202
|
+
expect(output).toContain('<RootStack padding={2} />')
|
|
203
|
+
},
|
|
204
|
+
'adds todo warning when imported styled Stack wrapper should be replaced',
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
defineCrossFileTest(
|
|
208
|
+
transform,
|
|
209
|
+
{},
|
|
210
|
+
`
|
|
211
|
+
import {Stack} from '@sanity/ui'
|
|
212
|
+
|
|
213
|
+
export const RootStack = styled(Stack)(({theme}) => ({}))
|
|
214
|
+
`,
|
|
215
|
+
`
|
|
216
|
+
import {Stack} from 'another-package'
|
|
217
|
+
import {RootStack} from './Component.styled'
|
|
218
|
+
|
|
219
|
+
export function Component() {
|
|
220
|
+
return (
|
|
221
|
+
<>
|
|
222
|
+
<RootStack space={2} />
|
|
223
|
+
<Stack space={2} />
|
|
224
|
+
</>
|
|
225
|
+
)
|
|
226
|
+
}
|
|
227
|
+
`,
|
|
228
|
+
(output) => {
|
|
229
|
+
expect(output).toContain('<RootStack gap={2} />')
|
|
230
|
+
expect(output).toContain('<Stack space={2} />')
|
|
231
|
+
},
|
|
232
|
+
'does not rewrite unrelated Stack from another package',
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
defineCrossFileTest(
|
|
236
|
+
transform,
|
|
237
|
+
{},
|
|
238
|
+
`
|
|
239
|
+
import {Stack} from '@sanity/ui'
|
|
240
|
+
|
|
241
|
+
export const RootStack = styled(Stack)(({theme}) => ({}))
|
|
242
|
+
`,
|
|
243
|
+
`
|
|
244
|
+
import {RootStack} from './index'
|
|
245
|
+
|
|
246
|
+
export function Component() {
|
|
247
|
+
return <RootStack space={2} />
|
|
248
|
+
}
|
|
249
|
+
`,
|
|
250
|
+
(output) => {
|
|
251
|
+
expect(output).toContain('<RootStack gap={2} />')
|
|
252
|
+
},
|
|
253
|
+
'transforms styled Stack wrappers imported through barrel re-exports',
|
|
254
|
+
{
|
|
255
|
+
extraFiles: {
|
|
256
|
+
'index.ts': `export {RootStack} from './Component.styled'`,
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
)
|
|
@@ -3,18 +3,21 @@ import {type API, type FileInfo, type JSXElement} from 'jscodeshift'
|
|
|
3
3
|
import type {BaseOptions} from '../../../types/BaseOptions'
|
|
4
4
|
import {addAttribute} from '../../../utils/addAttribute'
|
|
5
5
|
import {getComponentLocalNames} from '../../../utils/getComponentLocalNames'
|
|
6
|
+
import {getStyledComponentAliases} from '../../../utils/getStyledComponentAliases'
|
|
6
7
|
import {replaceElement} from '../../../utils/replaceElement'
|
|
7
8
|
import {shouldTransformComponent} from '../../../utils/shouldTransformComponent'
|
|
8
9
|
import {transformAttributes} from '../../../utils/transformAttributes'
|
|
9
10
|
import {transformComponent} from '../../../utils/transformComponent'
|
|
10
11
|
import {transformImport} from '../../../utils/transformImport'
|
|
12
|
+
import {transformStyledComponents} from '../../../utils/transformStyledComponents'
|
|
11
13
|
import {FLEX_MODS} from '../flex/flex.mods'
|
|
12
14
|
import {STACK_MODS} from './stack.mods'
|
|
13
15
|
|
|
14
16
|
const STACK_TODO_WARNING = 'Please double check the Stack migration below'
|
|
15
17
|
const FLEX_TODO_WARNING = 'Please double check the Flex migration below'
|
|
18
|
+
const STYLED_TODO_WARNING = 'Please double check styled(Stack) migration below'
|
|
16
19
|
|
|
17
|
-
function
|
|
20
|
+
function replaceWithFlex(attrs: JSXElement['openingElement']['attributes']) {
|
|
18
21
|
if (!attrs) {
|
|
19
22
|
return false
|
|
20
23
|
}
|
|
@@ -26,7 +29,9 @@ function hasFlexAttrs(attrs: JSXElement['openingElement']['attributes']) {
|
|
|
26
29
|
(attr.name.name.startsWith('padding') ||
|
|
27
30
|
attr.name.name.startsWith('margin') ||
|
|
28
31
|
attr.name.name.startsWith('overflow') ||
|
|
29
|
-
attr.name.name.startsWith('flex')
|
|
32
|
+
attr.name.name.startsWith('flex') ||
|
|
33
|
+
attr.name.name.endsWith('height') ||
|
|
34
|
+
attr.name.name.endsWith('width')),
|
|
30
35
|
)
|
|
31
36
|
}
|
|
32
37
|
|
|
@@ -40,8 +45,16 @@ export default function transform(
|
|
|
40
45
|
|
|
41
46
|
return transformComponent(fileInfo, api, ({j, root, markChanged}) => {
|
|
42
47
|
const localNames = getComponentLocalNames(j, root, 'Stack', options)
|
|
48
|
+
const styledAliases = getStyledComponentAliases(
|
|
49
|
+
j,
|
|
50
|
+
root,
|
|
51
|
+
'Stack',
|
|
52
|
+
fileInfo.path,
|
|
53
|
+
localNames,
|
|
54
|
+
options,
|
|
55
|
+
)
|
|
43
56
|
|
|
44
|
-
if (!shouldTransformComponent(j, root, 'Stack', localNames, options)) {
|
|
57
|
+
if (!shouldTransformComponent(j, root, 'Stack', localNames, options, styledAliases)) {
|
|
45
58
|
return
|
|
46
59
|
}
|
|
47
60
|
|
|
@@ -53,11 +66,10 @@ export default function transform(
|
|
|
53
66
|
replaceElement(
|
|
54
67
|
j,
|
|
55
68
|
root,
|
|
56
|
-
(attrs) =>
|
|
57
|
-
return hasFlexAttrs(attrs)
|
|
58
|
-
},
|
|
69
|
+
(attrs) => replaceWithFlex(attrs),
|
|
59
70
|
{
|
|
60
71
|
element: 'Stack',
|
|
72
|
+
localNames,
|
|
61
73
|
},
|
|
62
74
|
{
|
|
63
75
|
element: 'Flex',
|
|
@@ -85,10 +97,11 @@ export default function transform(
|
|
|
85
97
|
j,
|
|
86
98
|
root,
|
|
87
99
|
(attrs) => {
|
|
88
|
-
return !
|
|
100
|
+
return !replaceWithFlex(attrs)
|
|
89
101
|
},
|
|
90
102
|
{
|
|
91
103
|
element: 'Stack',
|
|
104
|
+
localNames,
|
|
92
105
|
},
|
|
93
106
|
{
|
|
94
107
|
element: 'VStack',
|
|
@@ -98,5 +111,14 @@ export default function transform(
|
|
|
98
111
|
) {
|
|
99
112
|
markChanged()
|
|
100
113
|
}
|
|
114
|
+
|
|
115
|
+
if (
|
|
116
|
+
transformStyledComponents(j, root, styledAliases, (attrs) => !replaceWithFlex(attrs), {
|
|
117
|
+
warning: STYLED_TODO_WARNING,
|
|
118
|
+
callback: (path) => transformAttributes(j, path, STACK_MODS, STACK_TODO_WARNING),
|
|
119
|
+
})
|
|
120
|
+
) {
|
|
121
|
+
markChanged()
|
|
122
|
+
}
|
|
101
123
|
})
|
|
102
124
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {expect} from 'vitest'
|
|
2
|
+
|
|
3
|
+
import {defineCrossFileTest, defineInlineTest} from '../../../utils/testUtils'
|
|
2
4
|
import transform from './text'
|
|
3
5
|
|
|
4
6
|
defineInlineTest(
|
|
@@ -111,3 +113,84 @@ defineInlineTest(
|
|
|
111
113
|
`,
|
|
112
114
|
'moves width props to style and updates mapped value',
|
|
113
115
|
)
|
|
116
|
+
|
|
117
|
+
defineCrossFileTest(
|
|
118
|
+
transform,
|
|
119
|
+
{},
|
|
120
|
+
`
|
|
121
|
+
import {Text} from '@sanity/ui'
|
|
122
|
+
|
|
123
|
+
export const RootText = styled(Text)(({theme}) => ({}))
|
|
124
|
+
`,
|
|
125
|
+
`
|
|
126
|
+
import {RootText} from './Component.styled'
|
|
127
|
+
|
|
128
|
+
export function RootCode() {
|
|
129
|
+
return <RootText flex="auto" />
|
|
130
|
+
}
|
|
131
|
+
`,
|
|
132
|
+
(output) => {
|
|
133
|
+
expect(output.replace(/\s+/g, ' ')).toContain(
|
|
134
|
+
'<RootText style={{ flex: "1 1 auto" }} as="div" trim={true} />',
|
|
135
|
+
)
|
|
136
|
+
},
|
|
137
|
+
'transforms attributes on imported styled Text wrappers',
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
defineCrossFileTest(
|
|
141
|
+
transform,
|
|
142
|
+
{},
|
|
143
|
+
`
|
|
144
|
+
import {Text} from '@sanity/ui'
|
|
145
|
+
|
|
146
|
+
export const RootText = styled(Text)(({theme}) => ({}))
|
|
147
|
+
`,
|
|
148
|
+
`
|
|
149
|
+
import {Text} from 'another-package'
|
|
150
|
+
import {RootText} from './Component.styled'
|
|
151
|
+
|
|
152
|
+
export function Component() {
|
|
153
|
+
return (
|
|
154
|
+
<>
|
|
155
|
+
<RootText flex="auto" />
|
|
156
|
+
<Text flex="auto" />
|
|
157
|
+
</>
|
|
158
|
+
)
|
|
159
|
+
}
|
|
160
|
+
`,
|
|
161
|
+
(output) => {
|
|
162
|
+
expect(output.replace(/\s+/g, ' ')).toContain(
|
|
163
|
+
'<RootText style={{ flex: "1 1 auto" }} as="div" trim={true} />',
|
|
164
|
+
)
|
|
165
|
+
expect(output).toContain('<Text flex="auto" />')
|
|
166
|
+
},
|
|
167
|
+
'does not transform attributes on unrelated Text from another package',
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
defineCrossFileTest(
|
|
171
|
+
transform,
|
|
172
|
+
{},
|
|
173
|
+
`
|
|
174
|
+
import {Text} from '@sanity/ui'
|
|
175
|
+
|
|
176
|
+
export const RootText = styled(Text)(({theme}) => ({}))
|
|
177
|
+
`,
|
|
178
|
+
`
|
|
179
|
+
import {RootText} from './index'
|
|
180
|
+
|
|
181
|
+
export function Component() {
|
|
182
|
+
return <RootText flex="auto" />
|
|
183
|
+
}
|
|
184
|
+
`,
|
|
185
|
+
(output) => {
|
|
186
|
+
expect(output.replace(/\s+/g, ' ')).toContain(
|
|
187
|
+
'<RootText style={{ flex: "1 1 auto" }} as="div" trim={true} />',
|
|
188
|
+
)
|
|
189
|
+
},
|
|
190
|
+
'transforms styled Text wrappers imported through barrel re-exports',
|
|
191
|
+
{
|
|
192
|
+
extraFiles: {
|
|
193
|
+
'index.ts': `export {RootText} from './Component.styled'`,
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
)
|