import { createApp, h, nextTick, ref } from '@vue/runtime-dom' import { createComponent, createDynamicComponent, createFor, createSlot, defineVaporComponent, setInsertionState, template, vaporInteropPlugin, withVaporCtx, } from '../src' import { makeRender } from './_utils' const define = makeRender() describe('scopeId', () => { test('should attach scopeId to child component', () => { const Child = defineVaporComponent({ __scopeId: 'child', setup() { return template('
', true)() }, }) const { html } = define({ __scopeId: 'parent', setup() { return createComponent(Child) }, }).render() expect(html()).toBe(`
`) }) test('should attach scopeId to child component with insertion state', () => { const Child = defineVaporComponent({ __scopeId: 'child', setup() { return template('
', true)() }, }) const { html } = define({ __scopeId: 'parent', setup() { const t0 = template('
', true) const n1 = t0() as any setInsertionState(n1) createComponent(Child) return n1 }, }).render() expect(html()).toBe(`
`) }) test('should attach scopeId to nested child component', () => { const Child = defineVaporComponent({ __scopeId: 'child', setup() { return template('
', true)() }, }) const Parent = defineVaporComponent({ __scopeId: 'parent', setup() { return createComponent(Child) }, }) const { html } = define({ __scopeId: 'app', setup() { return createComponent(Parent) }, }).render() expect(html()).toBe(`
`) }) test('should not attach scopeId to nested multiple root components', () => { const Child = defineVaporComponent({ __scopeId: 'child', setup() { return template('
', true)() }, }) const Parent = defineVaporComponent({ __scopeId: 'parent', setup() { const n0 = template('
')() const n1 = createComponent(Child) return [n0, n1] }, }) const { html } = define({ __scopeId: 'app', setup() { return createComponent(Parent) }, }).render() expect(html()).toBe(`
`) }) test('should attach scopeId to nested child component with insertion state', () => { const Child = defineVaporComponent({ __scopeId: 'child', setup() { return template('
', true)() }, }) const Parent = defineVaporComponent({ __scopeId: 'parent', setup() { return createComponent(Child) }, }) const { html } = define({ __scopeId: 'app', setup() { const t0 = template('
', true) const n1 = t0() as any setInsertionState(n1) createComponent(Parent) return n1 }, }).render() expect(html()).toBe( `
`, ) }) test('should attach scopeId to dynamic component', () => { const { html } = define({ __scopeId: 'parent', setup() { return createDynamicComponent(() => 'button') }, }).render() expect(html()).toBe(``) }) test('should attach scopeId to dynamic component with insertion state', () => { const { html } = define({ __scopeId: 'parent', setup() { const t0 = template('
', true) const n1 = t0() as any setInsertionState(n1) createDynamicComponent(() => 'button') return n1 }, }).render() expect(html()).toBe( `
`, ) }) test('should attach scopeId to nested dynamic component', () => { const Comp = defineVaporComponent({ __scopeId: 'child', setup() { return createDynamicComponent(() => 'button', null, null, true) }, }) const { html } = define({ __scopeId: 'parent', setup() { return createComponent(Comp, null, null, true) }, }).render() expect(html()).toBe( ``, ) }) test('should attach scopeId to nested dynamic component with insertion state', () => { const Comp = defineVaporComponent({ __scopeId: 'child', setup() { return createDynamicComponent(() => 'button', null, null, true) }, }) const { html } = define({ __scopeId: 'parent', setup() { const t0 = template('
', true) const n1 = t0() as any setInsertionState(n1) createComponent(Comp, null, null, true) return n1 }, }).render() expect(html()).toBe( `
`, ) }) test.todo('should attach scopeId to suspense content', async () => {}) // :slotted basic test('should work on slots', () => { const Child = defineVaporComponent({ __scopeId: 'child', setup() { const n1 = template('
', true)() as any setInsertionState(n1) createSlot('default', null) return n1 }, }) const Child2 = defineVaporComponent({ __scopeId: 'child2', setup() { return template('', true)() }, }) const { html } = define({ __scopeId: 'parent', setup() { const n2 = createComponent( Child, null, { default: withVaporCtx(() => { const n0 = template('
')() const n1 = createComponent(Child2) return [n0, n1] }), }, true, ) return n2 }, }).render() // slot content should have: // - scopeId from parent // - slotted scopeId (with `-s` postfix) from child (the tree owner) expect(html()).toBe( `
` + `
` + // component inside slot should have: // - scopeId from template context // - slotted scopeId from slot owner // - its own scopeId `` + `` + `
`, ) }) test(':slotted on forwarded slots', async () => { const Wrapper = defineVaporComponent({ __scopeId: 'wrapper', setup() { //
const n1 = template('
', true)() as any setInsertionState(n1) createSlot('default', null, undefined, true /* noSlotted */) return n1 }, }) const Slotted = defineVaporComponent({ __scopeId: 'slotted', setup() { // const n1 = createComponent( Wrapper, null, { default: withVaporCtx(() => { const n0 = createSlot('default', null) return n0 }), }, true, ) return n1 }, }) const { html } = define({ __scopeId: 'root', setup() { //
const n2 = createComponent( Slotted, null, { default: () => { return template('
')() }, }, true, ) return n2 }, }).render() expect(html()).toBe( `
` + `
` + `` + `
`, ) }) test('nested components with slots', async () => { const Child = defineVaporComponent({ setup() { const n0 = template('
')() as any setInsertionState(n0, null, 0, true) createSlot('default') return n0 }, }) const Parent = defineVaporComponent({ __scopeId: 'data-v-parent', setup() { const n3 = createComponent( Child, null, { default: withVaporCtx(() => { const n2 = createComponent( Child, null, { default: withVaporCtx(() => { const n1 = createComponent( Child, null, { default: () => { const t0 = template('test')() as any return t0 }, }, true, ) return n1 }), }, true, ) return n2 }), }, true, ) return n3 }, }) const { host } = define({ __scopeId: 'app', setup() { return createComponent(Parent) }, }).render() expect(host.innerHTML).toBe( `
` + `
` + `
test` + `
` + `
` + `
`, ) }) test('nested components in vFor with slots', async () => { const Parent = defineVaporComponent({ setup() { const n1 = template('
', true)() as any setInsertionState(n1, null, 0, true) createSlot('default', null) return n1 }, }) const Child = defineVaporComponent({ setup() { const n1 = template('
', true)() as any setInsertionState(n1, null, 0, true) createSlot('default', null) return n1 }, }) const count = ref(0) const { html } = define({ __scopeId: 'app', setup() { const n4 = createComponent( Parent, null, { default: withVaporCtx(() => { const n0 = createFor( () => count.value, _for_item0 => { const n3 = createComponent( Child, { class: () => 'test' }, { default: () => { const n2 = template('
red ')() return n2 }, }, ) return n3 }, item => item, 2, ) return n0 }), }, true, ) return n4 }, }).render() expect(html()).toBe(`
`) count.value++ await nextTick() expect(html()).toBe( `
` + `
` + // should have app scopeId `
red
` + `
` + `
`, ) }) }) describe('vdom interop', () => { test('vdom parent > vapor child', () => { const VaporChild = defineVaporComponent({ __scopeId: 'vapor-child', setup() { return template('', true)() }, }) const VdomParent = { __scopeId: 'vdom-parent', setup() { return () => h(VaporChild as any) }, } const App = { setup() { return () => h(VdomParent) }, } const root = document.createElement('div') createApp(App).use(vaporInteropPlugin).mount(root) expect(root.innerHTML).toBe( ``, ) }) test('vdom parent > vapor child > vdom child', () => { const VdomChild = { __scopeId: 'vdom-child', setup() { return () => h('button') }, } const VaporChild = defineVaporComponent({ __scopeId: 'vapor-child', setup() { return createComponent(VdomChild as any, null, null, true) }, }) const VdomParent = { __scopeId: 'vdom-parent', setup() { return () => h(VaporChild as any) }, } const App = { setup() { return () => h(VdomParent) }, } const root = document.createElement('div') createApp(App).use(vaporInteropPlugin).mount(root) expect(root.innerHTML).toBe( ``, ) }) test('vdom parent > vapor child > vapor child > vdom child', () => { const VdomChild = { __scopeId: 'vdom-child', setup() { return () => h('button') }, } const NestedVaporChild = defineVaporComponent({ __scopeId: 'nested-vapor-child', setup() { return createComponent(VdomChild as any, null, null, true) }, }) const VaporChild = defineVaporComponent({ __scopeId: 'vapor-child', setup() { return createComponent(NestedVaporChild as any, null, null, true) }, }) const VdomParent = { __scopeId: 'vdom-parent', setup() { return () => h(VaporChild as any) }, } const App = { setup() { return () => h(VdomParent) }, } const root = document.createElement('div') createApp(App).use(vaporInteropPlugin).mount(root) expect(root.innerHTML).toBe( ``, ) }) test('vdom parent > vapor dynamic child', () => { const VaporChild = defineVaporComponent({ __scopeId: 'vapor-child', setup() { return createDynamicComponent(() => 'button', null, null, true) }, }) const VdomParent = { __scopeId: 'vdom-parent', setup() { return () => h(VaporChild as any) }, } const App = { setup() { return () => h(VdomParent) }, } const root = document.createElement('div') createApp(App).use(vaporInteropPlugin).mount(root) expect(root.innerHTML).toBe( ``, ) }) test('vapor parent > vdom child', () => { const VdomChild = { __scopeId: 'vdom-child', setup() { return () => h('button') }, } const VaporParent = defineVaporComponent({ __scopeId: 'vapor-parent', setup() { return createComponent(VdomChild as any, null, null, true) }, }) const App = { setup() { return () => h(VaporParent as any) }, } const root = document.createElement('div') createApp(App).use(vaporInteropPlugin).mount(root) expect(root.innerHTML).toBe( ``, ) }) test('vapor parent > vdom child > vapor child', () => { const VaporChild = defineVaporComponent({ __scopeId: 'vapor-child', setup() { return template('', true)() }, }) const VdomChild = { __scopeId: 'vdom-child', setup() { return () => h(VaporChild as any) }, } const VaporParent = defineVaporComponent({ __scopeId: 'vapor-parent', setup() { return createComponent(VdomChild as any, null, null, true) }, }) const App = { setup() { return () => h(VaporParent as any) }, } const root = document.createElement('div') createApp(App).use(vaporInteropPlugin).mount(root) expect(root.innerHTML).toBe( ``, ) }) test('vapor parent > vdom child > vdom child > vapor child', () => { const VaporChild = defineVaporComponent({ __scopeId: 'vapor-child', setup() { return template('', true)() }, }) const VdomChild = { __scopeId: 'vdom-child', setup() { return () => h(VaporChild as any) }, } const VdomParent = { __scopeId: 'vdom-parent', setup() { return () => h(VdomChild as any) }, } const VaporParent = defineVaporComponent({ __scopeId: 'vapor-parent', setup() { return createComponent(VdomParent as any, null, null, true) }, }) const App = { setup() { return () => h(VaporParent as any) }, } const root = document.createElement('div') createApp(App).use(vaporInteropPlugin).mount(root) expect(root.innerHTML).toBe( ``, ) }) test('vapor parent > vapor slot > vdom child', () => { const VaporSlot = defineVaporComponent({ __scopeId: 'vapor-slot', setup() { const n1 = template('
', true)() as any setInsertionState(n1) createSlot('default', null) return n1 }, }) const VdomChild = { __scopeId: 'vdom-child', setup() { return () => h('span') }, } const VaporParent = defineVaporComponent({ __scopeId: 'vapor-parent', setup() { const n2 = createComponent( VaporSlot, null, { default: withVaporCtx(() => { const n0 = template('
')() const n1 = createComponent(VdomChild) return [n0, n1] }), }, true, ) return n2 }, }) const App = { setup() { return () => h(VaporParent as any) }, } const root = document.createElement('div') createApp(App).use(vaporInteropPlugin).mount(root) expect(root.innerHTML).toBe( `
` + `
` + `` + `` + `
`, ) }) })