refactor: transform tw prefix by specific case

This commit is contained in:
zernonia 2024-06-19 08:53:16 +08:00
parent 20c38b35e9
commit b2f2981377
3 changed files with 36 additions and 8 deletions

View File

@ -1,14 +1,13 @@
import type { CodemodPlugin } from 'vue-metamorph' import type { CodemodPlugin } from 'vue-metamorph'
import { splitClassName } from './transform-css-vars' import { splitClassName } from './transform-css-vars'
import type { TransformOpts } from '.' import type { TransformOpts } from '.'
import type { Config } from '@/src/utils/get-config'
export function transformTwPrefix(opts: TransformOpts): CodemodPlugin { export function transformTwPrefix(opts: TransformOpts): CodemodPlugin {
return { return {
type: 'codemod', type: 'codemod',
name: 'add prefix to tailwind classes', name: 'add prefix to tailwind classes',
transform({ scriptASTs, sfcAST, utils: { traverseScriptAST, traverseTemplateAST } }) { transform({ scriptASTs, sfcAST, utils: { traverseScriptAST, traverseTemplateAST, astHelpers } }) {
let transformCount = 0 let transformCount = 0
const { config } = opts const { config } = opts
@ -17,13 +16,32 @@ export function transformTwPrefix(opts: TransformOpts): CodemodPlugin {
for (const scriptAST of scriptASTs) { for (const scriptAST of scriptASTs) {
traverseScriptAST(scriptAST, { traverseScriptAST(scriptAST, {
visitLiteral(path) { visitCallExpression(path) {
if (path.parent.value.type !== 'ImportDeclaration' && typeof path.node.value === 'string') { if (path.node.callee.type === 'Identifier' && path.node.callee.name === 'cva') {
// mutate the node const nodes = path.node.arguments
path.node.value = applyPrefix(path.node.value, config.tailwind.prefix) nodes.forEach((node) => {
transformCount++ // cva(base, ...)
} if (node.type === 'Literal' && typeof node.value === 'string') {
node.value = applyPrefix(node.value, config.tailwind.prefix)
transformCount++
}
else if (node.type === 'ObjectExpression') {
node.properties.forEach((node) => {
// cva(..., { variants: { ... } })
if (node.type === 'Property' && node.key.type === 'Identifier' && node.key.name === 'variants') {
const nodes = astHelpers.findAll(node, { type: 'Literal' })
nodes.forEach((node) => {
if (typeof node.value === 'string') {
node.value = applyPrefix(node.value, config.tailwind.prefix)
transformCount++
}
})
}
})
}
})
}
return this.traverse(path) return this.traverse(path)
}, },
}) })

View File

@ -2,6 +2,8 @@
exports[`transform tailwind prefix 1`] = ` exports[`transform tailwind prefix 1`] = `
"import { cva } from 'class-variance-authority' "import { cva } from 'class-variance-authority'
export { default as Button } from './Button.vue'
export type { ButtonType } from './Button.vue'
export const testVariants = cva( export const testVariants = cva(
'tw-bg-background hover:tw-bg-muted tw-text-primary-foreground sm:focus:tw-text-accent-foreground', 'tw-bg-background hover:tw-bg-muted tw-text-primary-foreground sm:focus:tw-text-accent-foreground',
@ -14,6 +16,9 @@ export const testVariants = cva(
default: 'tw-h-10 tw-px-4 tw-py-2', default: 'tw-h-10 tw-px-4 tw-py-2',
}, },
}, },
defaultVariants: {
variant: 'default',
},
}, },
) )
" "

View File

@ -7,6 +7,8 @@ it('transform tailwind prefix', async () => {
await transform({ await transform({
filename: 'test.ts', filename: 'test.ts',
raw: `import { cva } from "class-variance-authority" raw: `import { cva } from "class-variance-authority"
export { default as Button } from "./Button.vue"
export type { ButtonType } from "./Button.vue"
export const testVariants = cva( export const testVariants = cva(
'bg-background hover:bg-muted text-primary-foreground sm:focus:text-accent-foreground', 'bg-background hover:bg-muted text-primary-foreground sm:focus:text-accent-foreground',
@ -19,6 +21,9 @@ it('transform tailwind prefix', async () => {
default: 'h-10 px-4 py-2', default: 'h-10 px-4 py-2',
}, },
}, },
defaultVariants: {
variant: 'default',
},
}, },
)`, )`,
config: { config: {