type App,
type ComponentInternalInstance,
type ConcreteComponent,
+ type HydrationRenderer,
MoveType,
type Plugin,
+ type RendererElement,
type RendererInternals,
+ type RendererNode,
type ShallowRef,
type Slots,
type VNode,
type VaporInteropInterface,
createVNode,
currentInstance,
+ ensureHydrationRenderer,
ensureRenderer,
+ ensureVaporSlotFallback,
+ isVNode,
onScopeDispose,
renderSlot,
+ shallowReactive,
shallowRef,
simpleSetCurrentInstance,
} from '@vue/runtime-dom'
frag.insert = (parentNode, anchor) => {
if (!isMounted) {
renderEffect(() => {
- const vnode = renderSlot(
- slotsRef.value,
- isFunction(name) ? name() : name,
- props,
- )
- if (isHydrating) {
- locateHydrationNode(true)
- ;(
- vdomHydrateNode ||
- (vdomHydrateNode = ensureHydrationRenderer().hydrateNode!)
- )(
- currentHydrationNode!,
- vnode,
+ let vnode: VNode | undefined
+ let isValidSlot = false
+ // only render slot if rawSlots is defined and slot nodes are not empty
+ // otherwise, render fallback
+ if (slotsRef.value) {
+ vnode = renderSlot(
+ slotsRef.value,
+ isFunction(name) ? name() : name,
+ props,
+ )
+
+ let children = vnode.children as any[]
+ // handle forwarded vapor slot without its own fallback
+ // use the fallback provided by the slot outlet
+ ensureVaporSlotFallback(children, fallback as any)
+ isValidSlot = children.length > 0
+ }
+
+ if (isValidSlot) {
- if (fallbackNodes) {
++ if (isHydrating) {
++ locateHydrationNode(true)
++ ;(
++ vdomHydrateNode ||
++ (vdomHydrateNode = ensureHydrationRenderer().hydrateNode!)
++ )(
++ currentHydrationNode!,
++ vnode!,
++ parentComponent as any,
++ null,
++ null,
++ false,
++ )
++ } else if (fallbackNodes) {
+ remove(fallbackNodes, parentNode)
+ fallbackNodes = undefined
+ }
+ internals.p(
+ oldVNode,
+ vnode!,
+ parentNode,
+ anchor,
parentComponent as any,
+ null,
++ undefined,
+ null,
+ false,
)
+ oldVNode = vnode!
} else {
- let isValidSlotContent
- let children = vnode.children as any[]
- /*
- * Handle forwarded vapor slot inside VDOM slot
- * Example: In a vapor component template:
- * <VDOMComp>
- * <template #header>
- * <slot name="header" /> <!-- This vapor slot gets forwarded -->
- * </template>
- * </VDOMComp>
- */
- let vaporSlot
- if (children.length === 1 && (vaporSlot = children[0].vs)) {
- const block = vaporSlot.slot(props)
- isValidSlotContent =
- isValidBlock(block) ||
- /*
- * If block is a vapor fragment with insert, it indicates a forwarded VDOM slot
- * Example: In a VDOM component template:
- * <VaporComp>
- * <template #header>
- * <slot name="header" /> <!-- This VDOM slot gets forwarded -->
- * </template>
- * </VaporComp>
- */
- (isFragment(block) && block.insert)
- } else {
- isValidSlotContent = children.length > 0
- }
- if (isValidSlotContent) {
- if (fallbackNodes) {
- remove(fallbackNodes, parentNode)
- fallbackNodes = undefined
+ // for forwarded slot without its own fallback, use the fallback
+ // provided by the slot outlet.
+ // re-fetch `frag.fallback` as it may have been updated at `createSlot`
+ fallback = frag.fallback
+ if (fallback && !fallbackNodes) {
+ // mount fallback
+ if (oldVNode) {
+ internals.um(oldVNode, parentComponent as any, null, true)
}
- internals.p(
- oldVNode,
- vnode,
+ insert(
+ (fallbackNodes = fallback(internals, parentComponent)),
parentNode,
anchor,
- parentComponent as any,
)
- oldVNode = vnode
- } else {
- if (fallback && !fallbackNodes) {
- // mount fallback
- if (oldVNode) {
- internals.um(oldVNode, parentComponent as any, null, true)
- }
- insert((fallbackNodes = fallback(props)), parentNode, anchor)
- }
- oldVNode = null
}
+ oldVNode = null
}
})
isMounted = true