Skip to content

Commit

Permalink
refactor(cssVars): use css vars work with vapor mode
Browse files Browse the repository at this point in the history
  • Loading branch information
edison1105 committed Dec 26, 2024
1 parent ef6986f commit 2895e1a
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 18 deletions.
5 changes: 3 additions & 2 deletions packages/compiler-sfc/src/compileScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import {
normalScriptDefaultVar,
processNormalScript,
} from './script/normalScript'
import { CSS_VARS_HELPER, genCssVarsCode } from './style/cssVars'
import { genCssVarsCode, getCssVarsHelper } from './style/cssVars'
import {
type SFCTemplateCompileOptions,
compileTemplate,
Expand Down Expand Up @@ -759,7 +759,7 @@ export function compileScript(
// no need to do this when targeting SSR
!options.templateOptions?.ssr
) {
ctx.helperImports.add(CSS_VARS_HELPER)
ctx.helperImports.add(getCssVarsHelper(vapor))
ctx.helperImports.add('unref')
ctx.s.prependLeft(
startOffset,
Expand All @@ -768,6 +768,7 @@ export function compileScript(
ctx.bindingMetadata,
scopeId,
!!options.isProd,
vapor,
)}\n`,
)
}
Expand Down
9 changes: 7 additions & 2 deletions packages/compiler-sfc/src/style/cssVars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@ import {
import type { SFCDescriptor } from '../parse'
import type { PluginCreator } from 'postcss'
import hash from 'hash-sum'
import { getEscapedCssVarName } from '@vue/shared'
import { capitalize, getEscapedCssVarName } from '@vue/shared'

export const CSS_VARS_HELPER = `useCssVars`

export function getCssVarsHelper(vapor: boolean | undefined): string {
return vapor ? `vapor${capitalize(CSS_VARS_HELPER)}` : CSS_VARS_HELPER
}

export function genCssVarsFromList(
vars: string[],
id: string,
Expand Down Expand Up @@ -162,6 +166,7 @@ export function genCssVarsCode(
bindings: BindingMetadata,
id: string,
isProd: boolean,
vapor?: boolean,
) {
const varsExp = genCssVarsFromList(vars, id, isProd)
const exp = createSimpleExpression(varsExp, false)
Expand All @@ -182,7 +187,7 @@ export function genCssVarsCode(
})
.join('')

return `_${CSS_VARS_HELPER}(_ctx => (${transformedString}))`
return `_${getCssVarsHelper(vapor)}(_ctx => (${transformedString}))`
}

// <script setup> already gets the calls injected as part of the transform
Expand Down
35 changes: 21 additions & 14 deletions packages/runtime-dom/src/helpers/useCssVars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,7 @@ export function useCssVars(getter: (ctx: any) => Record<string, string>): void {
updateTeleports(vars)
}

// handle cases where child component root is affected
// and triggers reflow in onMounted
onBeforeUpdate(() => {
queuePostFlushCb(setVars)
})

onMounted(() => {
// run setVars synchronously here, but run as post-effect on changes
watch(setVars, NOOP, { flush: 'post' })
const ob = new MutationObserver(setVars)
ob.observe(instance.subTree.el!.parentNode, { childList: true })
onUnmounted(() => ob.disconnect())
})
applyCssVars(() => instance.subTree.el!.parentNode!, setVars)
}

function setVarsOnVNode(vnode: VNode, vars: Record<string, string>) {
Expand Down Expand Up @@ -94,7 +82,26 @@ function setVarsOnVNode(vnode: VNode, vars: Record<string, string>) {
}
}

function setVarsOnNode(el: Node, vars: Record<string, string>) {
export function applyCssVars(
getParentNode: () => Node,
setVars: () => void,
): void {
// handle cases where child component root is affected
// and triggers reflow in onMounted
onBeforeUpdate(() => {
queuePostFlushCb(setVars)
})

onMounted(() => {
// run setVars synchronously here, but run as post-effect on changes
watch(setVars, NOOP, { flush: 'post' })
const ob = new MutationObserver(setVars)
ob.observe(getParentNode(), { childList: true })
onUnmounted(() => ob.disconnect())
})
}

export function setVarsOnNode(el: Node, vars: Record<string, string>): void {
if (el.nodeType === 1) {
const style = (el as HTMLElement).style
let cssText = ''
Expand Down
4 changes: 4 additions & 0 deletions packages/runtime-dom/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,3 +322,7 @@ export { patchStyle } from './modules/style'
* @internal
*/
export { shouldSetAsProp } from './patchProp'
/**
* @internal
*/
export { applyCssVars, setVarsOnNode } from './helpers/useCssVars'
1 change: 1 addition & 0 deletions packages/runtime-vapor/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ export { on, delegate, delegateEvents, setDynamicEvents } from './dom/event'
export { createIf } from './apiCreateIf'
export { createFor } from './apiCreateFor'
export { createTemplateRefSetter } from './apiTemplateRef'
export { vaporUseCssVars } from './useCssVars'
51 changes: 51 additions & 0 deletions packages/runtime-vapor/src/useCssVars.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import {
applyCssVars,
currentInstance,
setVarsOnNode,
warn,
} from '@vue/runtime-dom'
import { type VaporComponentInstance, isVaporComponent } from './component'
import { isArray } from '@vue/shared'
import type { Block } from './block'

export function vaporUseCssVars(getter: () => Record<string, string>): void {
if (!__BROWSER__ && !__TEST__) return

const instance = currentInstance as VaporComponentInstance
/* v8 ignore start */
if (!instance) {
__DEV__ &&
warn(`useCssVars is called without current active component instance.`)
return
}
/* v8 ignore stop */

applyCssVars(
() => resolveParentNode(instance.block),
() => setVarsOnBlock(instance.block, getter()),
)
}

function resolveParentNode(block: Block): Node {
if (block instanceof Node) {
return block.parentNode!
} else if (isVaporComponent(block)) {
return resolveParentNode(block.block!)
} else if (isArray(block)) {
return resolveParentNode(block[0])
} else {
return resolveParentNode(block.nodes)
}
}

function setVarsOnBlock(block: Block, vars: Record<string, string>): void {
if (block instanceof Node) {
setVarsOnNode(block, vars)
} else if (isArray(block)) {
block.forEach(child => setVarsOnBlock(child, vars))
} else if (isVaporComponent(block)) {
setVarsOnBlock(block.block!, vars)
} else {
setVarsOnBlock(block.nodes, vars)
}
}

0 comments on commit 2895e1a

Please sign in to comment.