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/core": "^7.22.17",
"@babel/parser": "^7.22.16", "@babel/parser": "^7.22.16",
"@babel/plugin-transform-typescript": "^7.22.15", "@babel/plugin-transform-typescript": "^7.22.15",
"@vue/compiler-sfc": "^3.3.6",
"chalk": "5.3.0", "chalk": "5.3.0",
"commander": "^11.0.0", "commander": "^11.0.0",
"cosmiconfig": "^8.3.6", "cosmiconfig": "^8.3.6",

View File

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

View File

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

View File

@ -17,6 +17,6 @@ exports[`transform css vars 2`] = `
exports[`transform css vars 3`] = ` exports[`transform css vars 3`] = `
"<script setup lang=\\"ts\\"></script> "<script setup lang=\\"ts\\"></script>
<template> <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>\\"" </template>\\""
`; `;

View File

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