diff --git a/packages/runtime-vapor/__tests__/componentSlots.spec.ts b/packages/runtime-vapor/__tests__/componentSlots.spec.ts
index ea9c07dc0..16022d515 100644
--- a/packages/runtime-vapor/__tests__/componentSlots.spec.ts
+++ b/packages/runtime-vapor/__tests__/componentSlots.spec.ts
@@ -870,971 +870,137 @@ describe('component: slots', () => {
expect(host.innerHTML).toBe('barbar')
})
- describe('vdom interop', () => {
- const createVaporSlot = (fallbackText = 'fallback') => {
- return defineVaporComponent({
- setup() {
- const n0 = createSlot('foo', null, () => {
- const n2 = template(`
${fallbackText}
`)()
- return n2
- })
- return n0
- },
- })
- }
-
- const createVdomSlot = (fallbackText = 'fallback') => {
- return {
- render(this: any) {
- return renderSlot(this.$slots, 'foo', {}, () => [
- h('div', fallbackText),
- ])
- },
- }
- }
-
- const createVaporForwardedSlot = (
- targetComponent: any,
- fallbackText?: string,
- ) => {
- return defineVaporComponent({
- setup() {
- const createForwardedSlot = forwardedSlotCreator()
- const n2 = createComponent(
- targetComponent,
- null,
- {
- foo: () => {
- return fallbackText
- ? createForwardedSlot('foo', null, () => {
- const n2 = template(`${fallbackText}
`)()
- return n2
- })
- : createForwardedSlot('foo', null)
- },
- },
- true,
- )
- return n2
- },
- })
- }
-
- const createVdomForwardedSlot = (
- targetComponent: any,
- fallbackText?: string,
- ) => {
- return {
- render(this: any) {
- return h(targetComponent, null, {
- foo: () => [
- fallbackText
- ? renderSlot(this.$slots, 'foo', {}, () => [
- h('div', fallbackText),
- ])
- : renderSlot(this.$slots, 'foo'),
- ],
- _: 3 /* FORWARDED */,
- })
- },
- }
- }
-
- const createMultipleVaporForwardedSlots = (
- targetComponent: any,
- count: number,
- ) => {
- let current = targetComponent
- for (let i = 0; i < count; i++) {
- current = createVaporForwardedSlot(current)
- }
- return current
- }
-
- const createMultipleVdomForwardedSlots = (
- targetComponent: any,
- count: number,
- ) => {
- let current = targetComponent
- for (let i = 0; i < count; i++) {
- current = createVdomForwardedSlot(current)
- }
- return current
- }
-
- const createTestApp = (
- rootComponent: any,
- foo: Ref,
- show: Ref,
- ) => {
- return {
- setup() {
- return () =>
- h(
- rootComponent,
- null,
- createSlots({ _: 2 /* DYNAMIC */ } as any, [
- show.value
- ? {
- name: 'foo',
- fn: () => [h('span', foo.value)],
- key: '0',
- }
- : undefined,
- ]),
- )
- },
- }
- }
-
- const createEmptyTestApp = (rootComponent: any) => {
- return {
- setup() {
- return () => h(rootComponent)
- },
- }
- }
-
- test('vdom slot > vapor forwarded slot > vapor slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VaporSlot = createVaporSlot()
- const VaporForwardedSlot = createVaporForwardedSlot(VaporSlot)
- const App = createTestApp(VaporForwardedSlot, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe('fallback
')
- })
-
- test('vdom slot > vapor forwarded slot(with fallback) > vapor slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VaporSlot = createVaporSlot()
- const VaporForwardedSlotWithFallback = createVaporForwardedSlot(
- VaporSlot,
- 'forwarded fallback',
- )
- const App = createTestApp(VaporForwardedSlotWithFallback, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe('forwarded fallback
')
- })
-
- test('vdom slot > vapor forwarded slot > vdom slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VdomSlot = createVdomSlot()
- const VaporForwardedSlot = createVaporForwardedSlot(VdomSlot)
- const App = createTestApp(VaporForwardedSlot, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe('fallback
')
-
- show.value = true
- await nextTick()
- expect(root.innerHTML).toBe('bar')
- })
-
- test('vdom slot > vapor forwarded slot(with fallback) > vdom slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VdomSlot = createVdomSlot()
- const VaporForwardedSlotWithFallback = createVaporForwardedSlot(
- VdomSlot,
- 'forwarded fallback',
- )
- const App = createTestApp(VaporForwardedSlotWithFallback, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe('forwarded fallback
')
- })
-
- test('vdom slot > vapor forwarded slot > vdom forwarded slot > vapor slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VaporSlot = createVaporSlot()
- const VdomForwardedSlot = createVdomForwardedSlot(VaporSlot)
- const VaporForwardedSlot = createVaporForwardedSlot(VdomForwardedSlot)
- const App = createTestApp(VaporForwardedSlot, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe('fallback
')
-
- show.value = true
- await nextTick()
- expect(root.innerHTML).toBe('bar')
- })
-
- test('vdom slot > vapor forwarded slot(with fallback) > vdom forwarded slot > vapor slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VaporSlot = createVaporSlot()
- const VdomForwardedSlot = createVdomForwardedSlot(VaporSlot)
- const VaporForwardedSlotWithFallback = createVaporForwardedSlot(
- VdomForwardedSlot,
- 'forwarded fallback',
- )
- const App = createTestApp(VaporForwardedSlotWithFallback, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe('forwarded fallback
')
-
- show.value = true
- await nextTick()
- expect(root.innerHTML).toBe('bar')
- })
-
- test('vdom slot > vapor forwarded slot > vdom forwarded slot(with fallback) > vapor slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VaporSlot = createVaporSlot()
- const VdomForwardedSlotWithFallback = createVdomForwardedSlot(
- VaporSlot,
- 'vdom fallback',
- )
- const VaporForwardedSlot = createVaporForwardedSlot(
- VdomForwardedSlotWithFallback,
- )
- const App = createTestApp(VaporForwardedSlot, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe('vdom fallback
')
-
- show.value = true
- await nextTick()
- expect(root.innerHTML).toBe('bar')
- })
-
- test('vdom slot(empty) > vapor forwarded slot > vdom forwarded slot(with fallback) > vapor slot', async () => {
- const VaporSlot = createVaporSlot()
- const VdomForwardedSlotWithFallback = createVdomForwardedSlot(
- VaporSlot,
- 'vdom fallback',
- )
- const VaporForwardedSlot = createVaporForwardedSlot(
- VdomForwardedSlotWithFallback,
- )
- const App = createEmptyTestApp(VaporForwardedSlot)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('vdom fallback
')
- })
-
- test('vdom slot > vapor forwarded slot > vdom forwarded slot > vdom slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VdomSlot = createVdomSlot()
- const VdomForwardedSlot = createVdomForwardedSlot(VdomSlot)
- const VaporForwardedSlot = createVaporForwardedSlot(VdomForwardedSlot)
- const App = createTestApp(VaporForwardedSlot, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe('fallback
')
-
- show.value = true
- await nextTick()
- expect(root.innerHTML).toBe('bar')
- })
-
- test('vdom slot > vapor forwarded slot(with fallback) > vdom forwarded slot > vdom slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VdomSlot = createVdomSlot()
- const VdomForwardedSlot = createVdomForwardedSlot(VdomSlot)
- const VaporForwardedSlotWithFallback = createVaporForwardedSlot(
- VdomForwardedSlot,
- 'vapor fallback',
- )
- const App = createTestApp(VaporForwardedSlotWithFallback, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe('vapor fallback
')
-
- show.value = true
- await nextTick()
- expect(root.innerHTML).toBe('bar')
- })
-
- test('vdom slot > vapor forwarded slot > vdom forwarded slot(with fallback) > vdom slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VdomSlot = createVdomSlot()
-
- const VdomForwardedSlotWithFallback = createVdomForwardedSlot(
- VdomSlot,
- 'vdom fallback',
- )
- const VaporForwardedSlot = createVaporForwardedSlot(
- VdomForwardedSlotWithFallback,
- )
- const App = createTestApp(VaporForwardedSlot, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe('vdom fallback
')
-
- show.value = true
- await nextTick()
- expect(root.innerHTML).toBe('bar')
- })
-
- test('vdom slot > vapor forwarded slot (multiple) > vdom forwarded slot > vdom slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VdomSlot = createVdomSlot()
- const VdomForwardedSlot = createVdomForwardedSlot(VdomSlot)
- const VaporForwardedSlot = createMultipleVaporForwardedSlots(
- VdomForwardedSlot,
- 3,
- )
- const App = createTestApp(VaporForwardedSlot, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe('fallback
')
-
- show.value = true
- await nextTick()
- expect(root.innerHTML).toBe('bar')
- })
-
- test('vdom slot > vapor forwarded slot (multiple) > vdom forwarded slot(with fallback) > vdom slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VdomSlot = createVdomSlot()
- const VdomForwardedSlotWithFallback = createVdomForwardedSlot(
- VdomSlot,
- 'vdom fallback',
- )
- const VaporForwardedSlot = createMultipleVaporForwardedSlots(
- VdomForwardedSlotWithFallback,
- 3,
- )
- const App = createTestApp(VaporForwardedSlot, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe(
- 'vdom fallback
',
- )
-
- show.value = true
- await nextTick()
- expect(root.innerHTML).toBe('bar')
- })
-
- test('vdom slot > vdom forwarded slot > vapor slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VaporSlot = createVaporSlot()
- const VdomForwardedSlot = createVdomForwardedSlot(VaporSlot)
- const App = createTestApp(VdomForwardedSlot, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe('fallback
')
-
- show.value = true
- await nextTick()
- expect(root.innerHTML).toBe('bar')
- })
-
- test('vdom slot > vdom forwarded slot > vapor forwarded slot > vapor slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VaporSlot = createVaporSlot()
- const VaporForwardedSlot = createVaporForwardedSlot(VaporSlot)
- const VdomForwardedSlot = createVdomForwardedSlot(VaporForwardedSlot)
- const App = createTestApp(VdomForwardedSlot, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe('fallback
')
-
- show.value = true
- await nextTick()
- expect(root.innerHTML).toBe('bar')
- })
-
- test('vdom slot > vdom forwarded slot (multiple) > vapor forwarded slot > vdom slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VaporSlot = createVaporSlot()
- const VaporForwardedSlot = createVaporForwardedSlot(VaporSlot)
- const VdomForwardedSlot = createMultipleVdomForwardedSlots(
- VaporForwardedSlot,
- 3,
- )
- const App = createTestApp(VdomForwardedSlot, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe('fallback
')
-
- show.value = true
- await nextTick()
- expect(root.innerHTML).toBe('bar')
- })
-
- test('vdom slot > vdom forwarded slot (multiple) > vapor forwarded slot(with fallback) > vdom slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VaporSlot = createVaporSlot()
- const VaporForwardedSlot = createVaporForwardedSlot(
- VaporSlot,
- 'vapor fallback',
- )
- const VdomForwardedSlot = createMultipleVdomForwardedSlots(
- VaporForwardedSlot,
- 3,
- )
- const App = createTestApp(VdomForwardedSlot, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe('vapor fallback
')
-
- show.value = true
- await nextTick()
- expect(root.innerHTML).toBe('bar')
- })
-
- test('vdom slot > vapor forwarded slot > vapor forwarded slot > vdom slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VdomSlot = createVdomSlot()
- const VaporForwardedSlot1 = createMultipleVaporForwardedSlots(
- VdomSlot,
- 2,
- )
- const App = createTestApp(VaporForwardedSlot1, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe('fallback
')
-
- show.value = true
- await nextTick()
- expect(root.innerHTML).toBe('bar')
- })
-
- test('vdom slot > vapor forwarded slot(with fallback) > vapor forwarded slot > vdom slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VdomSlot = createVdomSlot()
- const VaporForwardedSlot2 = createVaporForwardedSlot(VdomSlot)
- const VaporForwardedSlot1WithFallback = createVaporForwardedSlot(
- VaporForwardedSlot2,
- 'vapor1 fallback',
- )
- const App = createTestApp(VaporForwardedSlot1WithFallback, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe('vapor1 fallback
')
-
- show.value = true
- await nextTick()
- expect(root.innerHTML).toBe('bar')
- })
-
- test('vdom slot > vapor forwarded slot > vapor forwarded slot(with fallback) > vdom slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VdomSlot = createVdomSlot()
- const VaporForwardedSlot2WithFallback = createVaporForwardedSlot(
- VdomSlot,
- 'vapor2 fallback',
- )
- const VaporForwardedSlot1 = createVaporForwardedSlot(
- VaporForwardedSlot2WithFallback,
- )
- const App = createTestApp(VaporForwardedSlot1, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe('vapor2 fallback
')
-
- show.value = true
- await nextTick()
- expect(root.innerHTML).toBe('bar')
- })
-
- test('vdom slot > vapor forwarded slot > vapor forwarded slot > vapor slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VaporSlot = createVaporSlot()
- const VaporForwardedSlot2 = createVaporForwardedSlot(VaporSlot)
- const VaporForwardedSlot1 =
- createVaporForwardedSlot(VaporForwardedSlot2)
- const App = createTestApp(VaporForwardedSlot1, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe('fallback
')
-
- show.value = true
- await nextTick()
- expect(root.innerHTML).toBe('bar')
- })
-
- test('vdom slot > vapor forwarded slot(with fallback) > vapor forwarded slot(with fallback) > vdom slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VdomSlot = createVdomSlot()
- const VaporForwardedSlot2WithFallback = createVaporForwardedSlot(
- VdomSlot,
- 'vapor2 fallback',
- )
- const VaporForwardedSlot1WithFallback = createVaporForwardedSlot(
- VaporForwardedSlot2WithFallback,
- 'vapor1 fallback',
- )
- const App = createTestApp(VaporForwardedSlot1WithFallback, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe('vapor1 fallback
')
-
- show.value = true
- await nextTick()
- expect(root.innerHTML).toBe('bar')
- })
-
- test('vdom slot > vapor forwarded slot(with fallback) > vapor forwarded slot(with fallback) > vapor slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VaporSlot = createVaporSlot()
- const VaporForwardedSlot2WithFallback = createVaporForwardedSlot(
- VaporSlot,
- 'vapor2 fallback',
- )
- const VaporForwardedSlot1WithFallback = createVaporForwardedSlot(
- VaporForwardedSlot2WithFallback,
- 'vapor1 fallback',
- )
- const App = createTestApp(VaporForwardedSlot1WithFallback, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe(
- 'vapor1 fallback
',
- )
-
- show.value = true
- await nextTick()
- expect(root.innerHTML).toBe('bar')
- })
-
- test('vdom slot > vdom forwarded slot(with fallback) > vdom forwarded slot(with fallback) > vapor slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VaporSlot = createVaporSlot()
- const VdomForwardedSlot2WithFallback = createVdomForwardedSlot(
- VaporSlot,
- 'vdom2 fallback',
- )
- const VdomForwardedSlot1WithFallback = createVdomForwardedSlot(
- VdomForwardedSlot2WithFallback,
- 'vdom1 fallback',
- )
- const App = createTestApp(VdomForwardedSlot1WithFallback, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe('vdom1 fallback
')
-
- show.value = true
- await nextTick()
- expect(root.innerHTML).toBe('bar')
- })
-
- test('vdom slot > vdom forwarded slot(with fallback) > vdom forwarded slot(with fallback) > vdom slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VdomSlot = createVdomSlot()
- const VdomForwardedSlot2WithFallback = createVdomForwardedSlot(
- VdomSlot,
- 'vdom2 fallback',
- )
- const VdomForwardedSlot1WithFallback = createVdomForwardedSlot(
- VdomForwardedSlot2WithFallback,
- 'vdom1 fallback',
- )
- const App = createTestApp(VdomForwardedSlot1WithFallback, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe('vdom1 fallback
')
-
- show.value = true
- await nextTick()
- expect(root.innerHTML).toBe('bar')
- })
-
- test('vdom slot > vdom forwarded slot(with fallback) > vdom forwarded slot(with fallback) (multiple) > vapor slot', async () => {
- const foo = ref('foo')
- const show = ref(true)
-
- const VaporSlot = createVaporSlot()
- const VdomForwardedSlot3WithFallback = createVdomForwardedSlot(
- VaporSlot,
- 'vdom3 fallback',
- )
- const VdomForwardedSlot2WithFallback = createVdomForwardedSlot(
- VdomForwardedSlot3WithFallback,
- 'vdom2 fallback',
- )
- const VdomForwardedSlot1WithFallback = createVdomForwardedSlot(
- VdomForwardedSlot2WithFallback,
- 'vdom1 fallback',
- )
- const App = createTestApp(VdomForwardedSlot1WithFallback, foo, show)
-
- const root = document.createElement('div')
- createApp(App).use(vaporInteropPlugin).mount(root)
- expect(root.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(root.innerHTML).toBe('bar')
-
- show.value = false
- await nextTick()
- expect(root.innerHTML).toBe('vdom1 fallback
')
-
- show.value = true
- await nextTick()
- expect(root.innerHTML).toBe('bar')
- })
- })
- })
-
- describe('forwarded slot', () => {
- test('should work', async () => {
+ test('forwarded slot with fallback', async () => {
const Child = defineVaporComponent({
setup() {
- return createSlot('foo', null)
- },
- })
- const Parent = defineVaporComponent({
- setup() {
- const createForwardedSlot = forwardedSlotCreator()
- const n2 = createComponent(
- Child,
- null,
- {
- foo: () => {
- return createForwardedSlot('foo', null)
- },
- },
- true,
- )
- return n2
+ return createSlot('default', null, () => template('child fallback')())
},
})
- const foo = ref('foo')
- const { host } = define({
- setup() {
- const n2 = createComponent(
- Parent,
- null,
- {
- foo: () => {
- const n0 = template(' ')() as any
- renderEffect(() => setText(n0, foo.value))
- return n0
- },
- },
- true,
- )
- return n2
- },
- }).render()
-
- expect(host.innerHTML).toBe('foo')
-
- foo.value = 'bar'
- await nextTick()
- expect(host.innerHTML).toBe('bar')
- })
-
- test('mixed with non-forwarded slot', async () => {
- const Child = defineVaporComponent({
- setup() {
- return [createSlot('foo', null)]
- },
- })
const Parent = defineVaporComponent({
setup() {
const createForwardedSlot = forwardedSlotCreator()
const n2 = createComponent(Child, null, {
- foo: () => {
- const n0 = createForwardedSlot('foo', null)
+ default: () => {
+ const n0 = createForwardedSlot('default', null, () => {
+ return template('')()
+ })
return n0
},
})
- const n3 = createSlot('default', null)
- return [n2, n3]
+ return n2
},
})
- const foo = ref('foo')
- const { host } = define({
+ const { html } = define({
setup() {
- const n2 = createComponent(
- Parent,
- null,
- {
- foo: () => {
- const n0 = template(' ')() as any
- renderEffect(() => setText(n0, foo.value))
- return n0
- },
- default: () => {
- const n3 = template(' ')() as any
- renderEffect(() => setText(n3, foo.value))
- return n3
- },
- },
- true,
- )
- return n2
+ return createComponent(Parent, null, {
+ default: () => template('')(),
+ })
},
}).render()
- expect(host.innerHTML).toBe('foofoo')
+ expect(html()).toBe('child fallback')
+ })
- foo.value = 'bar'
+ test('forwarded slot with fallback (v-if)', async () => {
+ const Child = defineVaporComponent({
+ setup() {
+ return createSlot('default', null, () => template('child fallback')())
+ },
+ })
+
+ const show = ref(false)
+ const Parent = defineVaporComponent({
+ setup() {
+ const createForwardedSlot = forwardedSlotCreator()
+ const n2 = createComponent(Child, null, {
+ default: () => {
+ const n0 = createForwardedSlot('default', null, () => {
+ const n2 = createIf(
+ () => show.value,
+ () => {
+ const n4 = template('if content
')()
+ return n4
+ },
+ )
+ return n2
+ })
+ return n0
+ },
+ })
+ return n2
+ },
+ })
+
+ const { html } = define({
+ setup() {
+ return createComponent(Parent, null, {
+ default: () => template('')(),
+ })
+ },
+ }).render()
+
+ expect(html()).toBe('child fallback')
+
+ show.value = true
await nextTick()
- expect(host.innerHTML).toBe('barbar')
+ expect(html()).toBe(
+ 'if content
',
+ )
+ })
+
+ test('forwarded slot with fallback (v-for)', async () => {
+ const Child = defineVaporComponent({
+ setup() {
+ return createSlot('default', null, () => template('child fallback')())
+ },
+ })
+
+ const items = ref([])
+ const Parent = defineVaporComponent({
+ setup() {
+ const createForwardedSlot = forwardedSlotCreator()
+ const n2 = createComponent(Child, null, {
+ default: () => {
+ const n0 = createForwardedSlot('default', null, () => {
+ const n2 = createFor(
+ () => items.value,
+ for_item0 => {
+ const n4 = template(' ')() as any
+ const x4 = child(n4) as any
+ renderEffect(() =>
+ setText(x4, toDisplayString(for_item0.value)),
+ )
+ return n4
+ },
+ )
+ return n2
+ })
+ return n0
+ },
+ })
+ return n2
+ },
+ })
+
+ const { html } = define({
+ setup() {
+ return createComponent(Parent, null, {
+ default: () => template('')(),
+ })
+ },
+ }).render()
+
+ expect(html()).toBe('child fallback')
+
+ items.value.push(1)
+ await nextTick()
+ expect(html()).toBe('1')
+
+ items.value.pop()
+ await nextTick()
+ expect(html()).toBe('child fallback')
})
describe('vdom interop', () => {
diff --git a/packages/runtime-vapor/src/block.ts b/packages/runtime-vapor/src/block.ts
index 9ccb0fb26..87ba58527 100644
--- a/packages/runtime-vapor/src/block.ts
+++ b/packages/runtime-vapor/src/block.ts
@@ -102,12 +102,23 @@ export function setFragmentFallback(
fragment: VaporFragment,
fallback: BlockFn,
): void {
- // stop recursion if fragment has its own fallback
- if (fragment.fallback) return
+ if (fragment.fallback) {
+ const originalFallback = fragment.fallback
+ // if the original fallback also renders invalid blocks,
+ // this ensures proper fallback chaining
+ fragment.fallback = () => {
+ const fallbackNodes = originalFallback()
+ if (isValidBlock(fallbackNodes)) {
+ return fallbackNodes
+ }
+ return fallback()
+ }
+ } else {
+ fragment.fallback = fallback
+ }
- fragment.fallback = fallback
if (isFragment(fragment.nodes)) {
- setFragmentFallback(fragment.nodes, fallback)
+ setFragmentFallback(fragment.nodes, fragment.fallback)
}
}