import { compileSFCScript, assertCode } from './utils'
describe('CSS vars injection', () => {
- describe('codegen', () => {
- test('<script> w/ no default export', () => {
- assertCode(
- compileSFCScript(
- `<script>const a = 1</script>\n` +
- `<style>div{ color: var(--v-bind:color); }</style>`
- ).content
- )
- })
-
- test('<script> w/ default export', () => {
- assertCode(
- compileSFCScript(
- `<script>export default { setup() {} }</script>\n` +
- `<style>div{ color: var(--:color); }</style>`
- ).content
- )
- })
-
- test('<script> w/ default export in strings/comments', () => {
- assertCode(
- compileSFCScript(
- `<script>
- // export default {}
- export default {}
- </script>\n` + `<style>div{ color: var(--:color); }</style>`
- ).content
- )
- })
-
- test('w/ <script setup>', () => {
- assertCode(
- compileSFCScript(
- `<script setup>const color = 'red'</script>\n` +
- `<style>div{ color: var(--:color); }</style>`
- ).content
- )
- })
- })
-
test('generating correct code for nested paths', () => {
const { content } = compileSFCScript(
`<script>const a = 1</script>\n` +
`<style>div{
- color: var(--v-bind:color);
- color: var(--v-bind:font.size);
+ color: v-bind(color);
+ font-size: v-bind('font.size');
}</style>`
)
expect(content).toMatch(`_useCssVars(_ctx => ({
</script>\n` +
`<style>
div {
- color: var(--:color);
- font-size: var(--:size);
- border: var(--:foo);
+ color: v-bind(color);
+ font-size: v-bind(size);
+ border: v-bind(foo);
}
</style>`
)
test('should rewrite CSS vars in scoped mode', () => {
const { code } = compileStyle({
source: `.foo {
- color: var(--v-bind:color);
- font-size: var(--:font.size);
+ color: v-bind(color);
+ font-size: v-bind('font.size');
}`,
filename: 'test.css',
id: 'data-v-test'
}"
`)
})
+
+ describe('codegen', () => {
+ test('<script> w/ no default export', () => {
+ assertCode(
+ compileSFCScript(
+ `<script>const a = 1</script>\n` +
+ `<style>div{ color: v-bind(color); }</style>`
+ ).content
+ )
+ })
+
+ test('<script> w/ default export', () => {
+ assertCode(
+ compileSFCScript(
+ `<script>export default { setup() {} }</script>\n` +
+ `<style>div{ color: v-bind(color); }</style>`
+ ).content
+ )
+ })
+
+ test('<script> w/ default export in strings/comments', () => {
+ assertCode(
+ compileSFCScript(
+ `<script>
+ // export default {}
+ export default {}
+ </script>\n` + `<style>div{ color: v-bind(color); }</style>`
+ ).content
+ )
+ })
+
+ test('w/ <script setup>', () => {
+ assertCode(
+ compileSFCScript(
+ `<script setup>const color = 'red'</script>\n` +
+ `<style>div{ color: v-bind(color); }</style>`
+ ).content
+ )
+ })
+ })
})
import postcss, { Root } from 'postcss'
export const CSS_VARS_HELPER = `useCssVars`
-export const cssVarRE = /\bvar\(--(?:v-bind)?:([^)]+)\)/g
+export const cssVarRE = /\bv-bind\(\s*(?:'([^']+)'|"([^"]+)"|([^'"][^)]*))\s*\)/g
export function convertCssVarCasing(raw: string): string {
return raw.replace(/([^\w-])/g, '_')
sfc.styles.forEach(style => {
let match
while ((match = cssVarRE.exec(style.content))) {
- vars.push(match[1])
+ vars.push(match[1] || match[2] || match[3])
}
})
return vars
root.walkDecls(decl => {
// rewrite CSS variables
if (cssVarRE.test(decl.value)) {
- decl.value = decl.value.replace(cssVarRE, (_, $1) => {
- return `var(--${shortId}-${convertCssVarCasing($1)})`
+ decl.value = decl.value.replace(cssVarRE, (_, $1, $2, $3) => {
+ return `var(--${shortId}-${convertCssVarCasing($1 || $2 || $3)})`
})
}
})