@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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "jscodeshift";
|
|
2
2
|
import { addAttribute } from "../../../_chunks-es/addAttribute.js";
|
|
3
|
-
import { transformComponent, getComponentLocalNames, shouldTransformComponent, transformImport, transformAttributes } from "../../../_chunks-es/
|
|
3
|
+
import { transformComponent, getComponentLocalNames, getStyledComponentAliases, shouldTransformComponent, transformImport, transformAttributes, transformStyledComponents } from "../../../_chunks-es/transformStyledComponents.js";
|
|
4
4
|
const TEXT_MODS = {
|
|
5
5
|
accent: {
|
|
6
6
|
type: "rename-mapped",
|
|
@@ -73,13 +73,24 @@ const TEXT_MODS = {
|
|
|
73
73
|
function transform(fileInfo, api, options) {
|
|
74
74
|
const { fromPackage, toPackage } = options || {};
|
|
75
75
|
return transformComponent(fileInfo, api, ({ j, root, markChanged }) => {
|
|
76
|
-
const localNames = getComponentLocalNames(j, root, "Text", options)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
const localNames = getComponentLocalNames(j, root, "Text", options), styledAliases = getStyledComponentAliases(
|
|
77
|
+
j,
|
|
78
|
+
root,
|
|
79
|
+
"Text",
|
|
80
|
+
fileInfo.path,
|
|
81
|
+
localNames,
|
|
82
|
+
options
|
|
83
|
+
);
|
|
84
|
+
shouldTransformComponent(j, root, "Text", localNames, options, styledAliases) && (transformImport(j, root, "Text", fromPackage, toPackage) && markChanged(), root.find(j.JSXOpeningElement).forEach((path) => {
|
|
80
85
|
let changed = !1;
|
|
81
|
-
|
|
82
|
-
|
|
86
|
+
const name = path.node.name;
|
|
87
|
+
name.type !== "JSXIdentifier" || !localNames.has(name.name) || (transformAttributes(j, path, TEXT_MODS, TODO_WARNING) && (changed = !0), addAttribute(j, path.node, "as", "div") && (changed = !0), addAttribute(j, path.node, "trim", !0) && (changed = !0), changed && markChanged());
|
|
88
|
+
}), transformStyledComponents(j, root, styledAliases, () => !0, {
|
|
89
|
+
callback: (path) => {
|
|
90
|
+
let changed = !1;
|
|
91
|
+
return transformAttributes(j, path, TEXT_MODS, TODO_WARNING) && (changed = !0), addAttribute(j, path.node, "as", "div") && (changed = !0), addAttribute(j, path.node, "trim", !0) && (changed = !0), changed && markChanged(), changed;
|
|
92
|
+
}
|
|
93
|
+
}) && markChanged());
|
|
83
94
|
});
|
|
84
95
|
}
|
|
85
96
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.js","sources":["../../../../src/transforms/latest/text/text.mods.ts","../../../../src/transforms/latest/text/text.ts"],"sourcesContent":["import type {AttributeMods} from '../../../types/AttributeMods'\n\n/** @internal */\nexport const TEXT_MODS: AttributeMods = {\n accent: {\n type: 'rename-mapped',\n name: 'tone',\n mapping: {\n true: 'suggest',\n },\n },\n flex: {\n type: 'style-mapped',\n style: 'flex',\n mapping: {\n none: '0 0 auto',\n auto: '1 1 auto',\n initial: '0 1 auto',\n 1: '1',\n 2: '2',\n 3: '3',\n 4: '4',\n 5: '5',\n 6: '6',\n 7: '7',\n 8: '8',\n 9: '9',\n 10: '10',\n 11: '11',\n 12: '12',\n },\n },\n maxWidth: {\n type: 'style-mapped',\n style: 'maxWidth',\n mapping: {\n auto: 'none',\n fill: '100%',\n 0: '20rem',\n 1: '40rem',\n 2: '60rem',\n 3: '80rem',\n 4: '100rem',\n 5: '120rem',\n },\n },\n textOverflow: {\n type: 'rename-mapped',\n name: 'truncate',\n mapping: {\n ellipsis: 1,\n clip: 1,\n },\n },\n width: {\n type: 'style-mapped',\n style: 'width',\n mapping: {\n auto: 'auto',\n fill: '100%',\n stretch: 'stretch',\n min: 'min-content',\n max: 'max-content',\n 0: '20rem',\n 1: '40rem',\n 2: '60rem',\n 3: '80rem',\n 4: '100rem',\n 5: '120rem',\n },\n },\n}\n","import {type API, type FileInfo} from 'jscodeshift'\n\nimport type {BaseOptions} from '../../../types/BaseOptions'\nimport {addAttribute} from '../../../utils/addAttribute'\nimport {getComponentLocalNames} from '../../../utils/getComponentLocalNames'\nimport {shouldTransformComponent} from '../../../utils/shouldTransformComponent'\nimport {transformAttributes} from '../../../utils/transformAttributes'\nimport {transformComponent} from '../../../utils/transformComponent'\nimport {transformImport} from '../../../utils/transformImport'\nimport {TEXT_MODS} from './text.mods'\n\nconst TODO_WARNING = 'Please double check the Text migration below'\n\n/** @internal */\nexport default function transform(\n fileInfo: FileInfo,\n api: API,\n options: BaseOptions,\n): string | undefined {\n const {fromPackage, toPackage} = options || {}\n\n return transformComponent(fileInfo, api, ({j, root, markChanged}) => {\n const localNames = getComponentLocalNames(j, root, 'Text', options)\n\n if (!shouldTransformComponent(j, root, 'Text', localNames, options)) {\n return\n }\n\n if (transformImport(j, root, 'Text', fromPackage, toPackage)) {\n markChanged()\n }\n\n root
|
|
1
|
+
{"version":3,"file":"text.js","sources":["../../../../src/transforms/latest/text/text.mods.ts","../../../../src/transforms/latest/text/text.ts"],"sourcesContent":["import type {AttributeMods} from '../../../types/AttributeMods'\n\n/** @internal */\nexport const TEXT_MODS: AttributeMods = {\n accent: {\n type: 'rename-mapped',\n name: 'tone',\n mapping: {\n true: 'suggest',\n },\n },\n flex: {\n type: 'style-mapped',\n style: 'flex',\n mapping: {\n none: '0 0 auto',\n auto: '1 1 auto',\n initial: '0 1 auto',\n 1: '1',\n 2: '2',\n 3: '3',\n 4: '4',\n 5: '5',\n 6: '6',\n 7: '7',\n 8: '8',\n 9: '9',\n 10: '10',\n 11: '11',\n 12: '12',\n },\n },\n maxWidth: {\n type: 'style-mapped',\n style: 'maxWidth',\n mapping: {\n auto: 'none',\n fill: '100%',\n 0: '20rem',\n 1: '40rem',\n 2: '60rem',\n 3: '80rem',\n 4: '100rem',\n 5: '120rem',\n },\n },\n textOverflow: {\n type: 'rename-mapped',\n name: 'truncate',\n mapping: {\n ellipsis: 1,\n clip: 1,\n },\n },\n width: {\n type: 'style-mapped',\n style: 'width',\n mapping: {\n auto: 'auto',\n fill: '100%',\n stretch: 'stretch',\n min: 'min-content',\n max: 'max-content',\n 0: '20rem',\n 1: '40rem',\n 2: '60rem',\n 3: '80rem',\n 4: '100rem',\n 5: '120rem',\n },\n },\n}\n","import {type API, type FileInfo} from 'jscodeshift'\n\nimport type {BaseOptions} from '../../../types/BaseOptions'\nimport {addAttribute} from '../../../utils/addAttribute'\nimport {getComponentLocalNames} from '../../../utils/getComponentLocalNames'\nimport {getStyledComponentAliases} from '../../../utils/getStyledComponentAliases'\nimport {shouldTransformComponent} from '../../../utils/shouldTransformComponent'\nimport {transformAttributes} from '../../../utils/transformAttributes'\nimport {transformComponent} from '../../../utils/transformComponent'\nimport {transformImport} from '../../../utils/transformImport'\nimport {transformStyledComponents} from '../../../utils/transformStyledComponents'\nimport {TEXT_MODS} from './text.mods'\n\nconst TODO_WARNING = 'Please double check the Text migration below'\n\n/** @internal */\nexport default function transform(\n fileInfo: FileInfo,\n api: API,\n options: BaseOptions,\n): string | undefined {\n const {fromPackage, toPackage} = options || {}\n\n return transformComponent(fileInfo, api, ({j, root, markChanged}) => {\n const localNames = getComponentLocalNames(j, root, 'Text', options)\n const styledAliases = getStyledComponentAliases(\n j,\n root,\n 'Text',\n fileInfo.path,\n localNames,\n options,\n )\n\n if (!shouldTransformComponent(j, root, 'Text', localNames, options, styledAliases)) {\n return\n }\n\n if (transformImport(j, root, 'Text', fromPackage, toPackage)) {\n markChanged()\n }\n\n root.find(j.JSXOpeningElement).forEach((path) => {\n let changed = false\n const name = path.node.name\n\n if (name.type !== 'JSXIdentifier' || !localNames.has(name.name)) {\n return\n }\n\n if (transformAttributes(j, path, TEXT_MODS, TODO_WARNING)) {\n changed = true\n }\n\n if (addAttribute(j, path.node, 'as', 'div')) {\n changed = true\n }\n\n if (addAttribute(j, path.node, 'trim', true)) {\n changed = true\n }\n\n if (changed) {\n markChanged()\n }\n })\n\n if (\n transformStyledComponents(j, root, styledAliases, () => true, {\n callback: (path) => {\n let changed = false\n\n if (transformAttributes(j, path, TEXT_MODS, TODO_WARNING)) {\n changed = true\n }\n\n if (addAttribute(j, path.node, 'as', 'div')) {\n changed = true\n }\n\n if (addAttribute(j, path.node, 'trim', true)) {\n changed = true\n }\n\n if (changed) {\n markChanged()\n }\n\n return changed\n },\n })\n ) {\n markChanged()\n }\n })\n}\n"],"names":[],"mappings":";;;AAGO,MAAM,YAA2B;AAAA,EACtC,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,MACP,MAAM;AAAA,IAAA;AAAA,EACR;AAAA,EAEF,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SAAS;AAAA,MACP,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,IAAA;AAAA,EACN;AAAA,EAEF,UAAU;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SAAS;AAAA,MACP,MAAM;AAAA,MACN,MAAM;AAAA,MACN,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,IAAA;AAAA,EACL;AAAA,EAEF,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,MACP,UAAU;AAAA,MACV,MAAM;AAAA,IAAA;AAAA,EACR;AAAA,EAEF,OAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SAAS;AAAA,MACP,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,KAAK;AAAA,MACL,KAAK;AAAA,MACL,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,IAAA;AAAA,EACL;AAEJ,GC1DM,eAAe;AAGrB,SAAwB,UACtB,UACA,KACA,SACoB;AACpB,QAAM,EAAC,aAAa,UAAA,IAAa,WAAW,CAAA;AAE5C,SAAO,mBAAmB,UAAU,KAAK,CAAC,EAAC,GAAG,MAAM,kBAAiB;AACnE,UAAM,aAAa,uBAAuB,GAAG,MAAM,QAAQ,OAAO,GAC5D,gBAAgB;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS;AAAA,MACT;AAAA,MACA;AAAA,IAAA;AAGG,6BAAyB,GAAG,MAAM,QAAQ,YAAY,SAAS,aAAa,MAI7E,gBAAgB,GAAG,MAAM,QAAQ,aAAa,SAAS,KACzD,YAAA,GAGF,KAAK,KAAK,EAAE,iBAAiB,EAAE,QAAQ,CAAC,SAAS;AAC/C,UAAI,UAAU;AACd,YAAM,OAAO,KAAK,KAAK;AAEnB,WAAK,SAAS,mBAAmB,CAAC,WAAW,IAAI,KAAK,IAAI,MAI1D,oBAAoB,GAAG,MAAM,WAAW,YAAY,MACtD,UAAU,KAGR,aAAa,GAAG,KAAK,MAAM,MAAM,KAAK,MACxC,UAAU,KAGR,aAAa,GAAG,KAAK,MAAM,QAAQ,EAAI,MACzC,UAAU,KAGR,WACF;IAEJ,CAAC,GAGC,0BAA0B,GAAG,MAAM,eAAe,MAAM,IAAM;AAAA,MAC5D,UAAU,CAAC,SAAS;AAClB,YAAI,UAAU;AAEd,eAAI,oBAAoB,GAAG,MAAM,WAAW,YAAY,MACtD,UAAU,KAGR,aAAa,GAAG,KAAK,MAAM,MAAM,KAAK,MACxC,UAAU,KAGR,aAAa,GAAG,KAAK,MAAM,QAAQ,EAAI,MACzC,UAAU,KAGR,WACF,YAAA,GAGK;AAAA,MACT;AAAA,IAAA,CACD,KAED,YAAA;AAAA,EAEJ,CAAC;AACH;"}
|
package/package.json
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {tmpdir} from 'node:os'
|
|
3
|
-
import {join} from 'node:path'
|
|
1
|
+
import {expect} from 'vitest'
|
|
4
2
|
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
const applyTransform = require('jscodeshift/dist/testUtils').applyTransform
|
|
8
|
-
|
|
9
|
-
import {clearModuleParseCache} from '../../../utils/parseModule'
|
|
10
|
-
import {defineInlineTest} from '../../../utils/testUtils'
|
|
3
|
+
import {defineCrossFileTest, defineInlineTest} from '../../../utils/testUtils'
|
|
11
4
|
import transform from './box'
|
|
12
5
|
|
|
13
6
|
defineInlineTest(
|
|
@@ -246,157 +239,99 @@ defineInlineTest(
|
|
|
246
239
|
'warns and does not transform attributes if styled Box should be replaced',
|
|
247
240
|
)
|
|
248
241
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
for (const dir of tempDirs.splice(0)) {
|
|
255
|
-
rmSync(dir, {recursive: true, force: true})
|
|
256
|
-
}
|
|
257
|
-
})
|
|
258
|
-
|
|
259
|
-
describe('cross-file styled aliases', () => {
|
|
260
|
-
it('transforms attributes on imported styled Box wrappers', () => {
|
|
261
|
-
const dir = mkdtempSync(join(tmpdir(), 'ui-codemod-box-crossfile-'))
|
|
262
|
-
|
|
263
|
-
tempDirs.push(dir)
|
|
264
|
-
|
|
265
|
-
writeFileSync(
|
|
266
|
-
join(dir, 'Component.styled.tsx'),
|
|
267
|
-
`
|
|
268
|
-
import {Box} from '@sanity/ui'
|
|
269
|
-
|
|
270
|
-
export const RootBox = styled(Box)(({theme}) => ({}))
|
|
271
|
-
`,
|
|
272
|
-
)
|
|
273
|
-
|
|
274
|
-
writeFileSync(
|
|
275
|
-
join(dir, 'Component.tsx'),
|
|
276
|
-
`
|
|
277
|
-
import {RootBox} from './Component.styled'
|
|
278
|
-
|
|
279
|
-
export function Component() {
|
|
280
|
-
return <RootBox alignItems="center" />
|
|
281
|
-
}
|
|
282
|
-
`,
|
|
283
|
-
)
|
|
284
|
-
|
|
285
|
-
const importerPath = join(dir, 'Component.tsx')
|
|
286
|
-
const source = readFileSync(importerPath, 'utf8')
|
|
287
|
-
const output = applyTransform(transform, {}, {source, path: importerPath}, {parser: 'tsx'})
|
|
288
|
-
|
|
289
|
-
expect(output).toContain('alignItems: "center"')
|
|
290
|
-
expect(output).not.toContain('<RootBox alignItems="center" />')
|
|
291
|
-
})
|
|
292
|
-
|
|
293
|
-
it('adds todo warning when imported styled Box wrapper should be replaced', () => {
|
|
294
|
-
const dir = mkdtempSync(join(tmpdir(), 'ui-codemod-box-crossfile-todo-'))
|
|
295
|
-
|
|
296
|
-
tempDirs.push(dir)
|
|
297
|
-
|
|
298
|
-
writeFileSync(
|
|
299
|
-
join(dir, 'Component.styled.tsx'),
|
|
300
|
-
`
|
|
301
|
-
import {Box} from '@sanity/ui'
|
|
242
|
+
defineCrossFileTest(
|
|
243
|
+
transform,
|
|
244
|
+
{},
|
|
245
|
+
`
|
|
246
|
+
import {Box} from '@sanity/ui'
|
|
302
247
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
248
|
+
export const RootBox = styled(Box)(({theme}) => ({}))
|
|
249
|
+
`,
|
|
250
|
+
`
|
|
251
|
+
import {RootBox} from './Component.styled'
|
|
306
252
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
253
|
+
export function Component() {
|
|
254
|
+
return <RootBox alignItems="center" />
|
|
255
|
+
}
|
|
256
|
+
`,
|
|
257
|
+
(output) => {
|
|
258
|
+
expect(output.replace(/\s+/g, ' ')).toContain('<RootBox style={{ alignItems: "center" }} />')
|
|
259
|
+
},
|
|
260
|
+
'transforms attributes on imported styled Box wrappers',
|
|
261
|
+
)
|
|
311
262
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
263
|
+
defineCrossFileTest(
|
|
264
|
+
transform,
|
|
265
|
+
{},
|
|
266
|
+
`
|
|
267
|
+
import {Box} from '@sanity/ui'
|
|
317
268
|
|
|
318
|
-
const
|
|
319
|
-
|
|
320
|
-
|
|
269
|
+
export const RootBox = styled(Box)(({theme}) => ({}))
|
|
270
|
+
`,
|
|
271
|
+
`
|
|
272
|
+
import {RootBox} from './Component.styled'
|
|
321
273
|
|
|
274
|
+
export function Component() {
|
|
275
|
+
return <RootBox display="flex" alignItems="center" />
|
|
276
|
+
}
|
|
277
|
+
`,
|
|
278
|
+
(output) => {
|
|
322
279
|
expect(output).toContain('UI-CODEMOD TODO: Please double check styled(Box) migration below')
|
|
323
280
|
expect(output).toContain('<RootBox display="flex" alignItems="center" />')
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
it('does not rewrite unrelated Box from another package', () => {
|
|
328
|
-
const dir = mkdtempSync(join(tmpdir(), 'ui-codemod-box-crossfile-unrelated-'))
|
|
329
|
-
|
|
330
|
-
tempDirs.push(dir)
|
|
331
|
-
|
|
332
|
-
writeFileSync(
|
|
333
|
-
join(dir, 'Component.styled.tsx'),
|
|
334
|
-
`
|
|
335
|
-
import {Box} from '@sanity/ui'
|
|
336
|
-
|
|
337
|
-
export const RootBox = styled(Box)(({theme}) => ({}))
|
|
338
|
-
`,
|
|
339
|
-
)
|
|
340
|
-
|
|
341
|
-
writeFileSync(
|
|
342
|
-
join(dir, 'Component.tsx'),
|
|
343
|
-
`
|
|
344
|
-
import {Box} from 'another-package'
|
|
345
|
-
import {RootBox} from './Component.styled'
|
|
346
|
-
|
|
347
|
-
export function Component() {
|
|
348
|
-
return (
|
|
349
|
-
<>
|
|
350
|
-
<RootBox alignItems="center" />
|
|
351
|
-
<Box display="flex" />
|
|
352
|
-
</>
|
|
353
|
-
)
|
|
354
|
-
}
|
|
355
|
-
`,
|
|
356
|
-
)
|
|
357
|
-
|
|
358
|
-
const importerPath = join(dir, 'Component.tsx')
|
|
359
|
-
const source = readFileSync(importerPath, 'utf8')
|
|
360
|
-
const output = applyTransform(transform, {}, {source, path: importerPath}, {parser: 'tsx'})
|
|
361
|
-
|
|
362
|
-
expect(output).toContain('alignItems: "center"')
|
|
363
|
-
expect(output).not.toContain('<RootBox alignItems="center" />')
|
|
364
|
-
expect(output).toContain('<Box display="flex" />')
|
|
365
|
-
expect(output).not.toContain('<Flex')
|
|
366
|
-
})
|
|
367
|
-
|
|
368
|
-
it('transforms styled Box wrappers imported through barrel re-exports', () => {
|
|
369
|
-
const dir = mkdtempSync(join(tmpdir(), 'ui-codemod-box-crossfile-barrel-'))
|
|
370
|
-
|
|
371
|
-
tempDirs.push(dir)
|
|
372
|
-
|
|
373
|
-
writeFileSync(
|
|
374
|
-
join(dir, 'Component.styled.tsx'),
|
|
375
|
-
`
|
|
376
|
-
import {Box} from '@sanity/ui'
|
|
377
|
-
|
|
378
|
-
export const RootBox = styled(Box)(({theme}) => ({}))
|
|
379
|
-
`,
|
|
380
|
-
)
|
|
281
|
+
},
|
|
282
|
+
'adds todo warning when imported styled Box wrapper should be replaced',
|
|
283
|
+
)
|
|
381
284
|
|
|
382
|
-
|
|
285
|
+
defineCrossFileTest(
|
|
286
|
+
transform,
|
|
287
|
+
{},
|
|
288
|
+
`
|
|
289
|
+
import {Box} from '@sanity/ui'
|
|
383
290
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
291
|
+
export const RootBox = styled(Box)(({theme}) => ({}))
|
|
292
|
+
`,
|
|
293
|
+
`
|
|
294
|
+
import {Box} from 'another-package'
|
|
295
|
+
import {RootBox} from './Component.styled'
|
|
296
|
+
|
|
297
|
+
export function Component() {
|
|
298
|
+
return (
|
|
299
|
+
<>
|
|
300
|
+
<RootBox alignItems="center" />
|
|
301
|
+
<Box display="flex" />
|
|
302
|
+
</>
|
|
303
|
+
)
|
|
304
|
+
}
|
|
305
|
+
`,
|
|
306
|
+
(output) => {
|
|
307
|
+
expect(output.replace(/\s+/g, ' ')).toContain('<RootBox style={{ alignItems: "center" }} />')
|
|
308
|
+
expect(output).toContain('<Box display="flex" />')
|
|
309
|
+
},
|
|
310
|
+
'does not rewrite unrelated Box from another package',
|
|
311
|
+
)
|
|
388
312
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
313
|
+
defineCrossFileTest(
|
|
314
|
+
transform,
|
|
315
|
+
{},
|
|
316
|
+
`
|
|
317
|
+
import {Box} from '@sanity/ui'
|
|
394
318
|
|
|
395
|
-
const
|
|
396
|
-
|
|
397
|
-
|
|
319
|
+
export const RootBox = styled(Box)(({theme}) => ({}))
|
|
320
|
+
`,
|
|
321
|
+
`
|
|
322
|
+
import {RootBox} from './index'
|
|
398
323
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
324
|
+
export function Component() {
|
|
325
|
+
return <RootBox alignItems="center" />
|
|
326
|
+
}
|
|
327
|
+
`,
|
|
328
|
+
(output) => {
|
|
329
|
+
expect(output.replace(/\s+/g, ' ')).toContain('<RootBox style={{ alignItems: "center" }} />')
|
|
330
|
+
},
|
|
331
|
+
'transforms styled Box wrappers imported through barrel re-exports',
|
|
332
|
+
{
|
|
333
|
+
extraFiles: {
|
|
334
|
+
'index.ts': `export {RootBox} from './Component.styled'`,
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
)
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {expect} from 'vitest'
|
|
2
|
+
|
|
3
|
+
import {defineCrossFileTest, defineInlineTest} from '../../../utils/testUtils'
|
|
2
4
|
import transform from './card'
|
|
3
5
|
|
|
4
6
|
defineInlineTest(
|
|
@@ -205,3 +207,100 @@ defineInlineTest(
|
|
|
205
207
|
`,
|
|
206
208
|
'warns if Card includes muted prop',
|
|
207
209
|
)
|
|
210
|
+
|
|
211
|
+
defineCrossFileTest(
|
|
212
|
+
transform,
|
|
213
|
+
{},
|
|
214
|
+
`
|
|
215
|
+
import {Card} from '@sanity/ui'
|
|
216
|
+
|
|
217
|
+
export const RootCard = styled(Card)(({theme}) => ({}))
|
|
218
|
+
`,
|
|
219
|
+
`
|
|
220
|
+
import {RootCard} from './Component.styled'
|
|
221
|
+
|
|
222
|
+
export function Component() {
|
|
223
|
+
return <RootCard padding={4} radius={3} border />
|
|
224
|
+
}
|
|
225
|
+
`,
|
|
226
|
+
(output) => {
|
|
227
|
+
expect(output).toContain('<RootCard density="regular" />')
|
|
228
|
+
},
|
|
229
|
+
'transforms attributes on imported styled Card wrappers',
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
defineCrossFileTest(
|
|
233
|
+
transform,
|
|
234
|
+
{},
|
|
235
|
+
`
|
|
236
|
+
import {Card} from '@sanity/ui'
|
|
237
|
+
|
|
238
|
+
export const RootCard = styled(Card)(({theme}) => ({}))
|
|
239
|
+
`,
|
|
240
|
+
`
|
|
241
|
+
import {RootCard} from './Component.styled'
|
|
242
|
+
|
|
243
|
+
export function Component() {
|
|
244
|
+
return <RootCard padding={1} />
|
|
245
|
+
}
|
|
246
|
+
`,
|
|
247
|
+
(output) => {
|
|
248
|
+
expect(output).toContain('UI-CODEMOD TODO: Please double check styled(Card) migration below')
|
|
249
|
+
expect(output).toContain('<RootCard padding={1} />')
|
|
250
|
+
},
|
|
251
|
+
'adds todo warning when imported styled Card wrapper should be replaced',
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
defineCrossFileTest(
|
|
255
|
+
transform,
|
|
256
|
+
{},
|
|
257
|
+
`
|
|
258
|
+
import {Card} from '@sanity/ui'
|
|
259
|
+
|
|
260
|
+
export const RootCard = styled(Card)(({theme}) => ({}))
|
|
261
|
+
`,
|
|
262
|
+
`
|
|
263
|
+
import {Card} from 'another-package'
|
|
264
|
+
import {RootCard} from './Component.styled'
|
|
265
|
+
|
|
266
|
+
export function Component() {
|
|
267
|
+
return (
|
|
268
|
+
<>
|
|
269
|
+
<RootCard padding={4} radius={3} border />
|
|
270
|
+
<Card padding={4} radius={3} border />
|
|
271
|
+
</>
|
|
272
|
+
)
|
|
273
|
+
}
|
|
274
|
+
`,
|
|
275
|
+
(output) => {
|
|
276
|
+
expect(output).toContain('<RootCard density="regular" />')
|
|
277
|
+
expect(output).toContain('<Card padding={4} radius={3} border />')
|
|
278
|
+
},
|
|
279
|
+
'does not rewrite unrelated Card from another package',
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
defineCrossFileTest(
|
|
283
|
+
transform,
|
|
284
|
+
{},
|
|
285
|
+
`
|
|
286
|
+
import {Card} from '@sanity/ui'
|
|
287
|
+
|
|
288
|
+
export const RootCard = styled(Card)(({theme}) => ({}))
|
|
289
|
+
`,
|
|
290
|
+
`
|
|
291
|
+
import {RootCard} from './index'
|
|
292
|
+
|
|
293
|
+
export function Component() {
|
|
294
|
+
return <RootCard padding={4} radius={3} border />
|
|
295
|
+
}
|
|
296
|
+
`,
|
|
297
|
+
(output) => {
|
|
298
|
+
expect(output).toContain('<RootCard density="regular" />')
|
|
299
|
+
},
|
|
300
|
+
'transforms styled Card wrappers imported through barrel re-exports',
|
|
301
|
+
{
|
|
302
|
+
extraFiles: {
|
|
303
|
+
'index.ts': `export {RootCard} from './Component.styled'`,
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
)
|
|
@@ -1,19 +1,22 @@
|
|
|
1
|
-
import {type API, type FileInfo} from 'jscodeshift'
|
|
1
|
+
import {type API, type FileInfo, type JSXAttribute, type JSXSpreadAttribute} from 'jscodeshift'
|
|
2
2
|
|
|
3
3
|
import type {BaseOptions} from '../../../types/BaseOptions'
|
|
4
4
|
import {getAttribute} from '../../../utils/getAttribute'
|
|
5
5
|
import {getComponentLocalNames} from '../../../utils/getComponentLocalNames'
|
|
6
6
|
import {getStaticAttributeExpression} from '../../../utils/getStaticAttributeExpression'
|
|
7
|
+
import {getStyledComponentAliases} from '../../../utils/getStyledComponentAliases'
|
|
7
8
|
import {replaceElement} from '../../../utils/replaceElement'
|
|
8
9
|
import {shouldTransformComponent} from '../../../utils/shouldTransformComponent'
|
|
9
10
|
import {transformAttributes} from '../../../utils/transformAttributes'
|
|
10
11
|
import {transformComponent} from '../../../utils/transformComponent'
|
|
11
12
|
import {transformImport} from '../../../utils/transformImport'
|
|
13
|
+
import {transformStyledComponents} from '../../../utils/transformStyledComponents'
|
|
12
14
|
import {BOX_MODS} from '../box/box.mods'
|
|
13
15
|
import {CARD_MODS} from './card.mods'
|
|
14
16
|
|
|
15
17
|
const CARD_TODO_WARNING = 'Please double check the Card migration below'
|
|
16
18
|
const BOX_TODO_WARNING = 'Please double check the Box migration below'
|
|
19
|
+
const STYLED_TODO_WARNING = 'Please double check styled(Card) migration below'
|
|
17
20
|
|
|
18
21
|
/** @internal */
|
|
19
22
|
export default function transform(
|
|
@@ -25,8 +28,16 @@ export default function transform(
|
|
|
25
28
|
|
|
26
29
|
return transformComponent(fileInfo, api, ({j, root, markChanged}) => {
|
|
27
30
|
const localNames = getComponentLocalNames(j, root, 'Card', options)
|
|
31
|
+
const styledAliases = getStyledComponentAliases(
|
|
32
|
+
j,
|
|
33
|
+
root,
|
|
34
|
+
'Card',
|
|
35
|
+
fileInfo.path,
|
|
36
|
+
localNames,
|
|
37
|
+
options,
|
|
38
|
+
)
|
|
28
39
|
|
|
29
|
-
if (!shouldTransformComponent(j, root, 'Card', localNames, options)) {
|
|
40
|
+
if (!shouldTransformComponent(j, root, 'Card', localNames, options, styledAliases)) {
|
|
30
41
|
return
|
|
31
42
|
}
|
|
32
43
|
|
|
@@ -34,29 +45,32 @@ export default function transform(
|
|
|
34
45
|
markChanged()
|
|
35
46
|
}
|
|
36
47
|
|
|
48
|
+
const replaceWithBox = (attrs: (JSXAttribute | JSXSpreadAttribute)[]) => {
|
|
49
|
+
const density = getAttribute(attrs, 'density')
|
|
50
|
+
const muted = getAttribute(attrs, 'muted')
|
|
51
|
+
const scheme = getAttribute(attrs, 'scheme')
|
|
52
|
+
const border = getAttribute(attrs, 'border')
|
|
53
|
+
const padding = getStaticAttributeExpression(j, attrs, 'padding')
|
|
54
|
+
const radius = getStaticAttributeExpression(j, attrs, 'radius')
|
|
55
|
+
|
|
56
|
+
return !(
|
|
57
|
+
density ||
|
|
58
|
+
muted ||
|
|
59
|
+
scheme ||
|
|
60
|
+
(border && padding === 3 && radius == 2) ||
|
|
61
|
+
(border && padding === 4 && radius == 3) ||
|
|
62
|
+
(border && padding === 5 && radius == 4)
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
|
|
37
66
|
if (
|
|
38
67
|
replaceElement(
|
|
39
68
|
j,
|
|
40
69
|
root,
|
|
41
|
-
(attrs) =>
|
|
42
|
-
const density = getAttribute(attrs, 'density')
|
|
43
|
-
const muted = getAttribute(attrs, 'muted')
|
|
44
|
-
const scheme = getAttribute(attrs, 'scheme')
|
|
45
|
-
const border = getAttribute(attrs, 'border')
|
|
46
|
-
const padding = getStaticAttributeExpression(j, attrs, 'padding')
|
|
47
|
-
const radius = getStaticAttributeExpression(j, attrs, 'radius')
|
|
48
|
-
|
|
49
|
-
return !(
|
|
50
|
-
density ||
|
|
51
|
-
muted ||
|
|
52
|
-
scheme ||
|
|
53
|
-
(border && padding === 3 && radius == 2) ||
|
|
54
|
-
(border && padding === 4 && radius == 3) ||
|
|
55
|
-
(border && padding === 5 && radius == 4)
|
|
56
|
-
)
|
|
57
|
-
},
|
|
70
|
+
(attrs) => replaceWithBox(attrs),
|
|
58
71
|
{
|
|
59
72
|
element: 'Card',
|
|
73
|
+
localNames,
|
|
60
74
|
callback: (path) => transformAttributes(j, path, CARD_MODS, CARD_TODO_WARNING),
|
|
61
75
|
},
|
|
62
76
|
{
|
|
@@ -67,5 +81,14 @@ export default function transform(
|
|
|
67
81
|
) {
|
|
68
82
|
markChanged()
|
|
69
83
|
}
|
|
84
|
+
|
|
85
|
+
if (
|
|
86
|
+
transformStyledComponents(j, root, styledAliases, (attrs) => !replaceWithBox(attrs), {
|
|
87
|
+
warning: STYLED_TODO_WARNING,
|
|
88
|
+
callback: (path) => transformAttributes(j, path, CARD_MODS, CARD_TODO_WARNING),
|
|
89
|
+
})
|
|
90
|
+
) {
|
|
91
|
+
markChanged()
|
|
92
|
+
}
|
|
70
93
|
})
|
|
71
94
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {expect} from 'vitest'
|
|
2
|
+
|
|
3
|
+
import {defineCrossFileTest, defineInlineTest} from '../../../utils/testUtils'
|
|
2
4
|
import transform from './code'
|
|
3
5
|
|
|
4
6
|
defineInlineTest(
|
|
@@ -59,3 +61,84 @@ defineInlineTest(
|
|
|
59
61
|
`,
|
|
60
62
|
'moves width props to style and uppdates mapped values',
|
|
61
63
|
)
|
|
64
|
+
|
|
65
|
+
defineCrossFileTest(
|
|
66
|
+
transform,
|
|
67
|
+
{},
|
|
68
|
+
`
|
|
69
|
+
import {Code} from '@sanity/ui'
|
|
70
|
+
|
|
71
|
+
export const RootCode = styled(Code)(({theme}) => ({}))
|
|
72
|
+
`,
|
|
73
|
+
`
|
|
74
|
+
import {RootCode} from './Component.styled'
|
|
75
|
+
|
|
76
|
+
export function RootCode() {
|
|
77
|
+
return <RootCode flex="auto" />
|
|
78
|
+
}
|
|
79
|
+
`,
|
|
80
|
+
(output) => {
|
|
81
|
+
expect(output.replace(/\s+/g, ' ')).toContain(
|
|
82
|
+
'<RootCode style={{ flex: "1 1 auto" }} trim={true} />',
|
|
83
|
+
)
|
|
84
|
+
},
|
|
85
|
+
'transforms attributes on imported styled Code wrappers',
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
defineCrossFileTest(
|
|
89
|
+
transform,
|
|
90
|
+
{},
|
|
91
|
+
`
|
|
92
|
+
import {Code} from '@sanity/ui'
|
|
93
|
+
|
|
94
|
+
export const RootCode = styled(Code)(({theme}) => ({}))
|
|
95
|
+
`,
|
|
96
|
+
`
|
|
97
|
+
import {Code} from 'another-package'
|
|
98
|
+
import {RootCode} from './Component.styled'
|
|
99
|
+
|
|
100
|
+
export function Component() {
|
|
101
|
+
return (
|
|
102
|
+
<>
|
|
103
|
+
<RootCode flex="auto" />
|
|
104
|
+
<Code flex="auto" />
|
|
105
|
+
</>
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
`,
|
|
109
|
+
(output) => {
|
|
110
|
+
expect(output.replace(/\s+/g, ' ')).toContain(
|
|
111
|
+
'<RootCode style={{ flex: "1 1 auto" }} trim={true} />',
|
|
112
|
+
)
|
|
113
|
+
expect(output).toContain('<Code flex="auto" />')
|
|
114
|
+
},
|
|
115
|
+
'does not transform attributes on unrelated Code from another package',
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
defineCrossFileTest(
|
|
119
|
+
transform,
|
|
120
|
+
{},
|
|
121
|
+
`
|
|
122
|
+
import {Code} from '@sanity/ui'
|
|
123
|
+
|
|
124
|
+
export const RootCode = styled(Code)(({theme}) => ({}))
|
|
125
|
+
`,
|
|
126
|
+
`
|
|
127
|
+
import {RootCode} from './index'
|
|
128
|
+
|
|
129
|
+
export function Component() {
|
|
130
|
+
return <RootCode flex="auto" />
|
|
131
|
+
}
|
|
132
|
+
`,
|
|
133
|
+
(output) => {
|
|
134
|
+
expect(output.replace(/\s+/g, ' ')).toContain(
|
|
135
|
+
'<RootCode style={{ flex: "1 1 auto" }} trim={true} />',
|
|
136
|
+
)
|
|
137
|
+
},
|
|
138
|
+
'transforms styled Code wrappers imported through barrel re-exports',
|
|
139
|
+
{
|
|
140
|
+
extraFiles: {
|
|
141
|
+
'index.ts': `export {RootCode} from './Component.styled'`,
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
)
|