refactor: transform css variables for components (#129)

* refactor: transform css only in component

* refactor: more concise

* fix: pipeline
This commit is contained in:
zernonia 2023-10-21 18:02:19 +08:00 committed by GitHub
parent f96d00ec6f
commit ccfe4a891d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 105 additions and 25 deletions

View File

@ -49,6 +49,7 @@
"@babel/core": "^7.22.17",
"@babel/parser": "^7.22.16",
"@babel/plugin-transform-typescript": "^7.22.15",
"@vue/compiler-sfc": "^3.3.6",
"chalk": "5.3.0",
"commander": "^11.0.0",
"cosmiconfig": "^8.3.6",

View File

@ -1,5 +1,7 @@
import { SyntaxKind } from 'ts-morph'
import type * as z from 'zod'
import MagicString from 'magic-string'
import { parse, walk } from '@vue/compiler-sfc'
import { SyntaxKind } from 'ts-morph'
import type { registryBaseColorSchema } from '@/src/utils/registry/schema'
import type { Transformer } from '@/src/utils/transformers'
@ -9,22 +11,32 @@ export const transformCssVars: Transformer = async ({
baseColor,
}) => {
// No transform if using css variables.
if (config.tailwind?.cssVariables || !baseColor?.inlineColors)
if (config.tailwind?.cssVariables || !baseColor?.inlineColors || sourceFile.getFilePath().endsWith('ts'))
return sourceFile
const parsed = parse(sourceFile.getText())
const template = parsed.descriptor.template
if (!template)
return sourceFile
sourceFile.getDescendantsOfKind(SyntaxKind.StringLiteral).forEach((node) => {
if (template.loc.start.offset >= node.getPos())
return sourceFile
const value = node.getText()
if (value.includes('cn(')) {
const splitted = value.split('\'').map(i => applyColorMapping(i, baseColor.inlineColors))
node.replaceWithText(`${splitted.join('\'')}`)
const hasClosingDoubleQuote = value.match(/"/g)?.length === 2
if (value.search('\'') === -1 && hasClosingDoubleQuote) {
const mapped = applyColorMapping(value.replace(/"/g, ''), baseColor.inlineColors)
node.replaceWithText(`"${mapped}"`)
}
else if (value) {
const valueWithColorMapping = applyColorMapping(
value.replace(/"/g, ''),
baseColor.inlineColors,
)
node.replaceWithText(`"${valueWithColorMapping.trim()}"`)
else {
const s = new MagicString(value)
s.replace(/'(.*?)'/g, (substring) => {
return `'${applyColorMapping(substring.replace(/\'/g, ''), baseColor.inlineColors)}'`
})
node.replaceWithText(s.toString())
}
})
@ -103,6 +115,6 @@ export function applyColorMapping(
if (!lightMode.includes(className))
lightMode.push(className)
}
return `${lightMode.join(' ')} ${darkMode.join(' ').trim()}`
const combined = `${lightMode.join(' ').replace(/\'/g, '')} ${darkMode.join(' ').trim()}`.trim()
return `${combined}`
}

View File

@ -1,8 +1,7 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`handle tailwind config template correctly 1`] = `
"
import animate from \\"tailwindcss-animate\\"
"import animate from \\"tailwindcss-animate\\"
/** @type {import('tailwindcss').Config} */
export default {
@ -43,9 +42,7 @@ export default {
`;
exports[`handle tailwind config template correctly 2`] = `
"
import animate from \\"tailwindcss-animate\\"
"import animate from \\"tailwindcss-animate\\"
/** @type {import('tailwindcss').Config} */
export default {

View File

@ -17,6 +17,6 @@ exports[`transform css vars 2`] = `
exports[`transform css vars 3`] = `
"<script setup lang=\\"ts\\"></script>
<template>
<div :class=\\"cn( 'bg-white hover:bg-stone-100 dark:bg-stone-950 dark:hover:bg-stone-800', true && 'text-stone-50 sm:focus:text-stone-900 dark:text-stone-900 dark:sm:focus:text-stone-50')\\" >foo</div>
<div :class=\\"cn('bg-white hover:bg-stone-100 dark:bg-stone-950 dark:hover:bg-stone-800', true && 'text-stone-50 sm:focus:text-stone-900 dark:text-stone-900 dark:sm:focus:text-stone-50')\\">foo</div>
</template>\\""
`;

View File

@ -137,7 +137,7 @@ importers:
version: 3.3.4
autoprefixer:
specifier: ^10.4.16
version: 10.4.16(postcss@8.4.30)
version: 10.4.16(postcss@8.4.31)
lodash.template:
specifier: ^4.5.0
version: 4.5.0
@ -167,7 +167,7 @@ importers:
version: 4.4.11(@types/node@20.7.0)
vitepress:
specifier: ^1.0.0-rc.20
version: 1.0.0-rc.20(@algolia/client-search@4.20.0)(@types/node@20.7.0)(postcss@8.4.30)(search-insights@2.8.3)
version: 1.0.0-rc.20(@algolia/client-search@4.20.0)(@types/node@20.7.0)(postcss@8.4.31)(search-insights@2.8.3)
vue-tsc:
specifier: ^1.8.15
version: 1.8.15(typescript@5.2.2)
@ -186,6 +186,9 @@ importers:
'@babel/plugin-transform-typescript':
specifier: ^7.22.15
version: 7.22.15(@babel/core@7.23.0)
'@vue/compiler-sfc':
specifier: ^3.3.6
version: 3.3.6
chalk:
specifier: 5.3.0
version: 5.3.0
@ -2709,12 +2712,28 @@ packages:
estree-walker: 2.0.2
source-map-js: 1.0.2
/@vue/compiler-core@3.3.6:
resolution: {integrity: sha512-2JNjemwaNwf+MkkatATVZi7oAH1Hx0B04DdPH3ZoZ8vKC1xZVP7nl4HIsk8XYd3r+/52sqqoz9TWzYc3yE9dqA==}
dependencies:
'@babel/parser': 7.23.0
'@vue/shared': 3.3.6
estree-walker: 2.0.2
source-map-js: 1.0.2
dev: false
/@vue/compiler-dom@3.3.4:
resolution: {integrity: sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==}
dependencies:
'@vue/compiler-core': 3.3.4
'@vue/shared': 3.3.4
/@vue/compiler-dom@3.3.6:
resolution: {integrity: sha512-1MxXcJYMHiTPexjLAJUkNs/Tw2eDf2tY3a0rL+LfuWyiKN2s6jvSwywH3PWD8bKICjfebX3GWx2Os8jkRDq3Ng==}
dependencies:
'@vue/compiler-core': 3.3.6
'@vue/shared': 3.3.6
dev: false
/@vue/compiler-sfc@3.3.4:
resolution: {integrity: sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==}
dependencies:
@ -2729,12 +2748,34 @@ packages:
postcss: 8.4.30
source-map-js: 1.0.2
/@vue/compiler-sfc@3.3.6:
resolution: {integrity: sha512-/Kms6du2h1VrXFreuZmlvQej8B1zenBqIohP0690IUBkJjsFvJxY0crcvVRJ0UhMgSR9dewB+khdR1DfbpArJA==}
dependencies:
'@babel/parser': 7.23.0
'@vue/compiler-core': 3.3.6
'@vue/compiler-dom': 3.3.6
'@vue/compiler-ssr': 3.3.6
'@vue/reactivity-transform': 3.3.6
'@vue/shared': 3.3.6
estree-walker: 2.0.2
magic-string: 0.30.5
postcss: 8.4.31
source-map-js: 1.0.2
dev: false
/@vue/compiler-ssr@3.3.4:
resolution: {integrity: sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==}
dependencies:
'@vue/compiler-dom': 3.3.4
'@vue/shared': 3.3.4
/@vue/compiler-ssr@3.3.6:
resolution: {integrity: sha512-QTIHAfDCHhjXlYGkUg5KH7YwYtdUM1vcFl/FxFDlD6d0nXAmnjizka3HITp8DGudzHndv2PjKVS44vqqy0vP4w==}
dependencies:
'@vue/compiler-dom': 3.3.6
'@vue/shared': 3.3.6
dev: false
/@vue/devtools-api@6.5.0:
resolution: {integrity: sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==}
@ -2766,6 +2807,16 @@ packages:
estree-walker: 2.0.2
magic-string: 0.30.3
/@vue/reactivity-transform@3.3.6:
resolution: {integrity: sha512-RlJl4dHfeO7EuzU1iJOsrlqWyJfHTkJbvYz/IOJWqu8dlCNWtxWX377WI0VsbAgBizjwD+3ZjdnvSyyFW1YVng==}
dependencies:
'@babel/parser': 7.23.0
'@vue/compiler-core': 3.3.6
'@vue/shared': 3.3.6
estree-walker: 2.0.2
magic-string: 0.30.5
dev: false
/@vue/reactivity@3.3.4:
resolution: {integrity: sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==}
dependencies:
@ -2796,6 +2847,10 @@ packages:
/@vue/shared@3.3.4:
resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==}
/@vue/shared@3.3.6:
resolution: {integrity: sha512-Xno5pEqg8SVhomD0kTSmfh30ZEmV/+jZtyh39q6QflrjdJCXah5lrnOLi9KB6a5k5aAHXMXjoMnxlzUkCNfWLQ==}
dev: false
/@vue/typescript@1.8.15(typescript@5.2.2):
resolution: {integrity: sha512-qWyanQKXOsK84S8rP7QBrqsvUdQ0nZABZmTjXMpb3ox4Bp5IbkscREA3OPUrkgl64mAxwwCzIWcOc3BPTCPjQw==}
dependencies:
@ -3124,7 +3179,7 @@ packages:
tslib: 2.6.2
dev: false
/autoprefixer@10.4.16(postcss@8.4.30):
/autoprefixer@10.4.16(postcss@8.4.31):
resolution: {integrity: sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==}
engines: {node: ^10 || ^12 || >=14}
hasBin: true
@ -3136,7 +3191,7 @@ packages:
fraction.js: 4.3.6
normalize-range: 0.1.2
picocolors: 1.0.0
postcss: 8.4.30
postcss: 8.4.31
postcss-value-parser: 4.2.0
dev: true
@ -5974,6 +6029,13 @@ packages:
dependencies:
'@jridgewell/sourcemap-codec': 1.4.15
/magic-string@0.30.5:
resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==}
engines: {node: '>=12'}
dependencies:
'@jridgewell/sourcemap-codec': 1.4.15
dev: false
/make-error@1.3.6:
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
@ -6842,6 +6904,14 @@ packages:
picocolors: 1.0.0
source-map-js: 1.0.2
/postcss@8.4.31:
resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
engines: {node: ^10 || ^12 || >=14}
dependencies:
nanoid: 3.3.6
picocolors: 1.0.0
source-map-js: 1.0.2
/potpack@1.0.2:
resolution: {integrity: sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==}
dev: false
@ -8311,7 +8381,7 @@ packages:
fsevents: 2.3.3
dev: true
/vitepress@1.0.0-rc.20(@algolia/client-search@4.20.0)(@types/node@20.7.0)(postcss@8.4.30)(search-insights@2.8.3):
/vitepress@1.0.0-rc.20(@algolia/client-search@4.20.0)(@types/node@20.7.0)(postcss@8.4.31)(search-insights@2.8.3):
resolution: {integrity: sha512-CykMUJ8JLxLcGWek0ew3wln4RYbsOd1+0YzXITTpajggpynm2S331TNkJVOkHrMRc6GYe3y4pS40GfgcW0ZwAw==}
hasBin: true
peerDependencies:
@ -8332,7 +8402,7 @@ packages:
focus-trap: 7.5.3
mark.js: 8.11.1
minisearch: 6.1.0
postcss: 8.4.30
postcss: 8.4.31
shiki: 0.14.4
vite: 4.4.11(@types/node@20.7.0)
vue: 3.3.4