Skip to content

Commit b527cc4

Browse files
committed
fix(runtime-vapor): delegate async root slot wrappers to TransitionGroup
1 parent ec70485 commit b527cc4

3 files changed

Lines changed: 75 additions & 2 deletions

File tree

packages-private/vapor-e2e-test/__tests__/transition-group.spec.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,50 @@ describe('vapor transition-group', () => {
10221022
E2E_TIMEOUT,
10231023
)
10241024

1025+
test(
1026+
'async root slot component move',
1027+
async () => {
1028+
const btnSelector = '.async-root-slot-component-move > button'
1029+
const containerSelector = '.async-root-slot-component-move > div'
1030+
1031+
await waitForInnerHTML(
1032+
containerSelector,
1033+
`<div class="test">a</div>` +
1034+
`<div class="test">b</div>` +
1035+
`<div class="test">c</div>`,
1036+
)
1037+
await expect
1038+
.element(css(containerSelector))
1039+
.toContainHTML(
1040+
`<div class="test">a</div>` +
1041+
`<div class="test">b</div>` +
1042+
`<div class="test">c</div>` +
1043+
`<!--for--><!--slot--><!--async component--><!--transition-group-->`,
1044+
)
1045+
1046+
click(btnSelector)
1047+
await nextTick()
1048+
await nextFrame()
1049+
expect(html(containerSelector)).toContain(
1050+
`<div class="test group-enter-from group-enter-active">d</div>` +
1051+
`<div class="test">b</div>` +
1052+
`<div class="test group-move" style="">a</div>` +
1053+
`<div class="test group-leave-from group-leave-active group-move" style="">c</div>` +
1054+
`<!--for--><!--slot--><!--async component--><!--transition-group-->`,
1055+
)
1056+
1057+
await transitionFinish()
1058+
await expect
1059+
.element(css(containerSelector))
1060+
.toContainHTML(
1061+
`<div class="test">d</div>` +
1062+
`<div class="test">b</div>` +
1063+
`<div class="test" style="">a</div>`,
1064+
)
1065+
},
1066+
E2E_TIMEOUT,
1067+
)
1068+
10251069
describe('interop', () => {
10261070
test(
10271071
'avoid set transition hooks for comment node',
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<script setup vapor>
2+
import { defineVaporAsyncComponent, ref } from 'vue'
3+
import RootSlot from '../../components/RootSlot.vue'
4+
5+
const AsyncRootSlot = defineVaporAsyncComponent(() => Promise.resolve(RootSlot))
6+
const items = ref(['a', 'b', 'c'])
7+
const moveClick = () => (items.value = ['d', 'b', 'a'])
8+
</script>
9+
10+
<template>
11+
<div class="async-root-slot-component-move">
12+
<button @click="moveClick">async root slot button</button>
13+
<div>
14+
<transition-group name="group">
15+
<AsyncRootSlot key="async-root-slot">
16+
<div v-for="item in items" :key="item" class="test">{{ item }}</div>
17+
</AsyncRootSlot>
18+
</transition-group>
19+
</div>
20+
</div>
21+
</template>

packages/runtime-vapor/src/components/Transition.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import { renderEffect } from '../renderEffect'
4040
import {
4141
DynamicFragment,
4242
ForFragment,
43+
SlotFragment,
4344
type VaporFragment,
4445
isFragment,
4546
} from '../fragment'
@@ -326,8 +327,15 @@ function applyResolvedTransitionHooks(
326327
}
327328
}
328329

329-
// delegate to TransitionGroup's apply logic for list children
330-
if (hooks.applyGroup && block instanceof ForFragment) {
330+
// Delegate list/root-slot wrappers back to TransitionGroup's apply logic.
331+
// Other fragment shapes, such as keyed v-if branches, still need normal
332+
// enter/leave hooks for their resolved single child.
333+
if (
334+
hooks.applyGroup &&
335+
(block instanceof ForFragment ||
336+
block instanceof SlotFragment ||
337+
(isVaporComponent(block) && block.block instanceof SlotFragment))
338+
) {
331339
hooks.applyGroup(block, hooks.props, hooks.state, hooks.instance)
332340
return { hooks }
333341
}

0 commit comments

Comments
 (0)