}
}
}
+
+ updateCssVars(parentComponent, n2)
},
remove(
)
}
}
+ updateCssVars(parentComponent, vnode)
}
return vnode.anchor && nextSibling(vnode.anchor as Node)
}
__isTeleport: true
new (): { $props: VNodeProps & TeleportProps }
}
+
+function updateCssVars(
+ parentComponent: ComponentInternalInstance | null,
+ vnode: VNode
+) {
+ // presence of .ut method indicates owner component uses css vars.
+ // code path here can assume browser environment.
+ if (parentComponent && parentComponent.ut) {
+ let node = (vnode.children as VNode[])[0].el!
+ while (node !== vnode.targetAnchor) {
+ if (node.nodeType === 1)
+ node.setAttribute('data-v-owner', parentComponent.uid)
+ node = node.nextSibling
+ }
+ parentComponent.ut()
+ }
+}
nextTick,
ComponentOptions,
Suspense,
+ Teleport,
FunctionalComponent
} from '@vue/runtime-dom'
expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('red')
}
})
+
+ test('with teleport', async () => {
+ document.body.innerHTML = ''
+ const state = reactive({ color: 'red' })
+ const root = document.createElement('div')
+ const target = document.body
+
+ const App = {
+ setup() {
+ useCssVars(() => state)
+ return () => [h(Teleport, { to: target }, [h('div')])]
+ }
+ }
+
+ render(h(App), root)
+ await nextTick()
+ for (const c of [].slice.call(target.children as any)) {
+ expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('red')
+ }
+ })
+
+ test('with teleport(change subTree)', async () => {
+ document.body.innerHTML = ''
+ const state = reactive({ color: 'red' })
+ const root = document.createElement('div')
+ const target = document.body
+ const toggle = ref(false)
+
+ const App = {
+ setup() {
+ useCssVars(() => state)
+ return () => [
+ h(Teleport, { to: target }, [
+ h('div'),
+ toggle.value ? h('div') : null
+ ])
+ ]
+ }
+ }
+
+ render(h(App), root)
+ await nextTick()
+ expect(target.children.length).toBe(1)
+ for (const c of [].slice.call(target.children as any)) {
+ expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('red')
+ }
+
+ toggle.value = true
+ await nextTick()
+ expect(target.children.length).toBe(2)
+ for (const c of [].slice.call(target.children as any)) {
+ expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('red')
+ }
+ })
})
return
}
- const setVars = () =>
- setVarsOnVNode(instance.subTree, getter(instance.proxy!))
+ const updateTeleports = (instance.ut = (vars = getter(instance.proxy)) => {
+ Array.from(
+ document.querySelectorAll(`[data-v-owner="${instance.uid}"]`)
+ ).forEach(node => setVarsOnNode(node, vars))
+ })
+
+ const setVars = () => {
+ const vars = getter(instance.proxy)
+ setVarsOnVNode(instance.subTree, vars)
+ updateTeleports(vars)
+ }
+
watchPostEffect(setVars)
+
onMounted(() => {
const ob = new MutationObserver(setVars)
ob.observe(instance.subTree.el!.parentNode, { childList: true })