| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- import {
- ref,
- render,
- useCssVars,
- createStaticVNode,
- h,
- reactive,
- nextTick,
- ComponentOptions,
- Suspense,
- Teleport,
- FunctionalComponent
- } from '@vue/runtime-dom'
- describe('useCssVars', () => {
- async function assertCssVars(getApp: (state: any) => ComponentOptions) {
- const state = reactive({ color: 'red' })
- const App = getApp(state)
- const root = document.createElement('div')
- render(h(App), root)
- await nextTick()
- for (const c of [].slice.call(root.children as any)) {
- expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe(`red`)
- }
- state.color = 'green'
- await nextTick()
- for (const c of [].slice.call(root.children as any)) {
- expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('green')
- }
- }
- test('basic', async () => {
- await assertCssVars(state => ({
- setup() {
- // test receiving render context
- useCssVars((ctx: any) => ({
- color: ctx.color
- }))
- return state
- },
- render() {
- return h('div')
- }
- }))
- })
- test('on fragment root', async () => {
- await assertCssVars(state => ({
- setup() {
- useCssVars(() => state)
- return () => [h('div'), h('div')]
- }
- }))
- })
- test('on HOCs', async () => {
- const Child = () => [h('div'), h('div')]
- await assertCssVars(state => ({
- setup() {
- useCssVars(() => state)
- return () => h(Child)
- }
- }))
- })
- test('on suspense root', async () => {
- const state = reactive({ color: 'red' })
- const root = document.createElement('div')
- let resolveAsync: any
- let asyncPromise: any
- const AsyncComp = {
- setup() {
- asyncPromise = new Promise(r => {
- resolveAsync = () => {
- r(() => h('p', 'default'))
- }
- })
- return asyncPromise
- }
- }
- const App = {
- setup() {
- useCssVars(() => state)
- return () =>
- h(Suspense, null, {
- default: h(AsyncComp),
- fallback: h('div', 'fallback')
- })
- }
- }
- render(h(App), root)
- await nextTick()
- // css vars use with fallback tree
- for (const c of [].slice.call(root.children as any)) {
- expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe(`red`)
- }
- // AsyncComp resolve
- resolveAsync()
- await asyncPromise.then(() => {})
- // Suspense effects flush
- await nextTick()
- // css vars use with default tree
- for (const c of [].slice.call(root.children as any)) {
- expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe(`red`)
- }
- state.color = 'green'
- await nextTick()
- for (const c of [].slice.call(root.children as any)) {
- expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('green')
- }
- })
- test('with subTree changed', async () => {
- const state = reactive({ color: 'red' })
- const value = ref(true)
- const root = document.createElement('div')
- const App = {
- setup() {
- useCssVars(() => state)
- return () => (value.value ? [h('div')] : [h('div'), h('div')])
- }
- }
- render(h(App), root)
- await nextTick()
- // css vars use with fallback tree
- for (const c of [].slice.call(root.children as any)) {
- expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe(`red`)
- }
- value.value = false
- await nextTick()
- for (const c of [].slice.call(root.children as any)) {
- expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('red')
- }
- })
- // #3894
- test('with subTree change inside HOC', async () => {
- const state = reactive({ color: 'red' })
- const value = ref(true)
- const root = document.createElement('div')
- const Child: FunctionalComponent = (_, { slots }) => slots.default!()
- const App = {
- setup() {
- useCssVars(() => state)
- return () =>
- h(Child, null, () =>
- value.value ? [h('div')] : [h('div'), h('div')]
- )
- }
- }
- render(h(App), root)
- await nextTick()
- // css vars use with fallback tree
- for (const c of [].slice.call(root.children as any)) {
- expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe(`red`)
- }
- value.value = false
- await nextTick()
- for (const c of [].slice.call(root.children as any)) {
- expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('red')
- }
- })
- test('with createStaticVNode', async () => {
- const state = reactive({ color: 'red' })
- const root = document.createElement('div')
- const App = {
- setup() {
- useCssVars(() => state)
- return () => [
- h('div'),
- createStaticVNode('<div>1</div><div><span>2</span></div>', 2),
- h('div')
- ]
- }
- }
- render(h(App), root)
- await nextTick()
- for (const c of [].slice.call(root.children as any)) {
- 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 in child slot', async () => {
- document.body.innerHTML = ''
- const state = reactive({ color: 'red' })
- const root = document.createElement('div')
- const target = document.body
- const Child: FunctionalComponent = (_, { slots }) => {
- return h('div', slots.default && slots.default())
- }
- const App = {
- setup() {
- useCssVars(() => state)
- return () => h(Child, () => [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')
- }
- })
- test('with teleport(disabled)', 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, disabled: true }, [h('div')])]
- }
- }
- expect(() => render(h(App), root)).not.toThrow(TypeError)
- await nextTick()
- expect(target.children.length).toBe(0)
- })
- test('with string style', async () => {
- document.body.innerHTML = ''
- const state = reactive({ color: 'red' })
- const root = document.createElement('div')
- const disabled = ref(false)
- const App = {
- setup() {
- useCssVars(() => state)
- return () => [
- h(
- 'div',
- { style: disabled.value ? 'pointer-events: none' : undefined },
- 'foo'
- )
- ]
- }
- }
- render(h(App), root)
- await nextTick()
- for (const c of [].slice.call(root.children as any)) {
- expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('red')
- }
- disabled.value = true
- await nextTick()
- for (const c of [].slice.call(root.children as any)) {
- expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('red')
- }
- })
- })
|