normalScriptDefaultVar,
processNormalScript,
} from './script/normalScript'
-import { CSS_VARS_HELPER, genCssVarsCode } from './style/cssVars'
+import { genCssVarsCode, getCssVarsHelper } from './style/cssVars'
import {
type SFCTemplateCompileOptions,
compileTemplate,
// 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,
ctx.bindingMetadata,
scopeId,
!!options.isProd,
+ vapor,
)}\n`,
)
}
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,
bindings: BindingMetadata,
id: string,
isProd: boolean,
+ vapor?: boolean,
) {
const varsExp = genCssVarsFromList(vars, id, isProd)
const exp = createSimpleExpression(varsExp, false)
})
.join('')
- return `_${CSS_VARS_HELPER}(_ctx => (${transformedString}))`
+ return `_${getCssVarsHelper(vapor)}(_ctx => (${transformedString}))`
}
// <script setup> already gets the calls injected as part of the transform
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>) {
}
}
-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 = ''
* @internal
*/
export { shouldSetAsProp } from './patchProp'
+/**
+ * @internal
+ */
+export { applyCssVars, setVarsOnNode } from './helpers/useCssVars'
export { createIf } from './apiCreateIf'
export { createFor } from './apiCreateFor'
export { createTemplateRefSetter } from './apiTemplateRef'
+export { vaporUseCssVars } from './useCssVars'
--- /dev/null
+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)
+ }
+}