@sanity/ui-codemod 1.0.0-alpha.5 → 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.
Files changed (44) hide show
  1. package/dist/_chunks-es/addAttribute.js +1 -1
  2. package/dist/_chunks-es/box.mods.js +1 -1
  3. package/dist/_chunks-es/flex.mods.js +1 -150
  4. package/dist/_chunks-es/flex.mods.js.map +1 -1
  5. package/dist/_chunks-es/layout-mods.js +4 -0
  6. package/dist/_chunks-es/layout-mods.js.map +1 -1
  7. package/dist/_chunks-es/{transformComponent.js → transformStyledComponents.js} +150 -2
  8. package/dist/_chunks-es/transformStyledComponents.js.map +1 -0
  9. package/dist/transforms/latest/box/box.js +2 -2
  10. package/dist/transforms/latest/card/card.js +24 -9
  11. package/dist/transforms/latest/card/card.js.map +1 -1
  12. package/dist/transforms/latest/code/code.js +18 -7
  13. package/dist/transforms/latest/code/code.js.map +1 -1
  14. package/dist/transforms/latest/container/container.js +15 -7
  15. package/dist/transforms/latest/container/container.js.map +1 -1
  16. package/dist/transforms/latest/flex/flex.js +2 -2
  17. package/dist/transforms/latest/grid/grid.js +15 -7
  18. package/dist/transforms/latest/grid/grid.js.map +1 -1
  19. package/dist/transforms/latest/heading/heading.js +18 -7
  20. package/dist/transforms/latest/heading/heading.js.map +1 -1
  21. package/dist/transforms/latest/text/text.js +18 -7
  22. package/dist/transforms/latest/text/text.js.map +1 -1
  23. package/package.json +1 -1
  24. package/src/constants/latest/layout-mods.ts +4 -0
  25. package/src/transforms/latest/box/box.test.ts +3 -8
  26. package/src/transforms/latest/card/card.test.ts +100 -1
  27. package/src/transforms/latest/card/card.ts +42 -19
  28. package/src/transforms/latest/code/code.test.ts +84 -1
  29. package/src/transforms/latest/code/code.ts +47 -16
  30. package/src/transforms/latest/container/container.test.ts +78 -1
  31. package/src/transforms/latest/container/container.ts +29 -9
  32. package/src/transforms/latest/grid/grid.test.ts +78 -1
  33. package/src/transforms/latest/grid/grid.ts +29 -9
  34. package/src/transforms/latest/heading/heading.test.ts +84 -1
  35. package/src/transforms/latest/heading/heading.ts +47 -16
  36. package/src/transforms/latest/inline/inline.test.ts +78 -1
  37. package/src/transforms/latest/inline/inline.ts +29 -9
  38. package/src/transforms/latest/label/label.test.ts +84 -1
  39. package/src/transforms/latest/label/label.ts +36 -1
  40. package/src/transforms/latest/stack/stack.test.ts +100 -1
  41. package/src/transforms/latest/stack/stack.ts +29 -7
  42. package/src/transforms/latest/text/text.test.ts +84 -1
  43. package/src/transforms/latest/text/text.ts +58 -19
  44. package/dist/_chunks-es/transformComponent.js.map +0 -1
@@ -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 {GRID_MODS} from './grid.mods'
10
12
 
11
13
  const TODO_WARNING = 'Please double check the Grid 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, 'Grid', options)
25
+ const styledAliases = getStyledComponentAliases(
26
+ j,
27
+ root,
28
+ 'Grid',
29
+ fileInfo.path,
30
+ localNames,
31
+ options,
32
+ )
23
33
 
24
- if (!shouldTransformComponent(j, root, 'Grid', localNames, options)) {
34
+ if (!shouldTransformComponent(j, root, 'Grid', 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
- .find(j.JSXOpeningElement, {
34
- name: {type: 'JSXIdentifier', name: 'Grid'},
35
- })
36
- .forEach((path) => {
37
- if (transformAttributes(j, path, GRID_MODS, TODO_WARNING)) {
38
- markChanged()
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, GRID_MODS, TODO_WARNING)) {
50
+ markChanged()
51
+ }
52
+ })
53
+
54
+ if (
55
+ transformStyledComponents(j, root, styledAliases, () => true, {
56
+ callback: (path) => transformAttributes(j, path, GRID_MODS, TODO_WARNING),
40
57
  })
58
+ ) {
59
+ markChanged()
60
+ }
41
61
  })
42
62
  }
@@ -1,4 +1,6 @@
1
- import {defineInlineTest} from '../../../utils/testUtils'
1
+ import {expect} from 'vitest'
2
+
3
+ import {defineCrossFileTest, defineInlineTest} from '../../../utils/testUtils'
2
4
  import transform from './heading'
3
5
 
4
6
  defineInlineTest(
@@ -85,3 +87,84 @@ defineInlineTest(
85
87
  `,
86
88
  'warns if as props is missing',
87
89
  )
90
+
91
+ defineCrossFileTest(
92
+ transform,
93
+ {},
94
+ `
95
+ import {Heading} from '@sanity/ui'
96
+
97
+ export const RootHeading = styled(Heading)(({theme}) => ({}))
98
+ `,
99
+ `
100
+ import {RootHeading} from './Component.styled'
101
+
102
+ export function RootCode() {
103
+ return <RootHeading flex="auto" />
104
+ }
105
+ `,
106
+ (output) => {
107
+ expect(output.replace(/\s+/g, ' ')).toContain(
108
+ '<RootHeading style={{ flex: "1 1 auto" }} trim={true} />',
109
+ )
110
+ },
111
+ 'transforms attributes on imported styled Heading wrappers',
112
+ )
113
+
114
+ defineCrossFileTest(
115
+ transform,
116
+ {},
117
+ `
118
+ import {Heading} from '@sanity/ui'
119
+
120
+ export const RootHeading = styled(Heading)(({theme}) => ({}))
121
+ `,
122
+ `
123
+ import {Heading} from 'another-package'
124
+ import {RootHeading} from './Component.styled'
125
+
126
+ export function Component() {
127
+ return (
128
+ <>
129
+ <RootHeading flex="auto" />
130
+ <Heading flex="auto" />
131
+ </>
132
+ )
133
+ }
134
+ `,
135
+ (output) => {
136
+ expect(output.replace(/\s+/g, ' ')).toContain(
137
+ '<RootHeading style={{ flex: "1 1 auto" }} trim={true} />',
138
+ )
139
+ expect(output).toContain('<Heading flex="auto" />')
140
+ },
141
+ 'does not transform attributes on unrelated Heading from another package',
142
+ )
143
+
144
+ defineCrossFileTest(
145
+ transform,
146
+ {},
147
+ `
148
+ import {Heading} from '@sanity/ui'
149
+
150
+ export const RootHeading = styled(Heading)(({theme}) => ({}))
151
+ `,
152
+ `
153
+ import {RootHeading} from './index'
154
+
155
+ export function Component() {
156
+ return <RootHeading flex="auto" />
157
+ }
158
+ `,
159
+ (output) => {
160
+ expect(output.replace(/\s+/g, ' ')).toContain(
161
+ '<RootHeading style={{ flex: "1 1 auto" }} trim={true} />',
162
+ )
163
+ },
164
+ 'transforms styled Heading wrappers imported through barrel re-exports',
165
+ {
166
+ extraFiles: {
167
+ 'index.ts': `export {RootHeading} from './Component.styled'`,
168
+ },
169
+ },
170
+ )
@@ -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
- .find(j.JSXOpeningElement, {
35
- name: {type: 'JSXIdentifier', name: 'Heading'},
36
- })
37
- .forEach((path) => {
38
- let changed = false
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
- if (transformAttributes(j, path, HEADING_MODS, TODO_WARNING)) {
41
- changed = true
42
- }
59
+ if (changed) {
60
+ markChanged()
61
+ }
62
+ })
43
63
 
44
- if (addAttribute(j, path.node, 'trim', true)) {
45
- changed = true
46
- }
64
+ if (
65
+ transformStyledComponents(j, root, styledAliases, () => true, {
66
+ callback: (path) => {
67
+ let changed = false
47
68
 
48
- if (changed) {
49
- markChanged()
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 {defineInlineTest} from '../../../utils/testUtils'
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
- .find(j.JSXOpeningElement, {
34
- name: {type: 'JSXIdentifier', name: 'Inline'},
35
- })
36
- .forEach((path) => {
37
- if (transformAttributes(j, path, INLINE_MODS, TODO_WARNING)) {
38
- markChanged()
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 {defineInlineTest} from '../../../utils/testUtils'
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 {defineInlineTest} from '../../../utils/testUtils'
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
+ )