unmount(vnode: VNode, doRemove?: boolean): void
move(vnode: VNode, container: any, anchor: any): void
slot(n1: VNode | null, n2: VNode, container: any, anchor: any): void
+ setTransitionHooks(
+ component: ComponentInternalInstance,
+ transition: TransitionHooks,
+ ): void
+ hydrate(node: Node, fn: () => void): void
- vdomMount: (component: ConcreteComponent, props?: any, slots?: any) => any
+ vdomMount: (
+ component: ConcreteComponent,
+ props?: any,
+ slots?: any,
+ scopeId?: string,
+ ) => any
vdomUnmount: UnmountComponentFn
vdomSlot: (
slots: any,
} from './component'
import { createComment, createTextNode } from './dom/node'
import { EffectScope, pauseTracking, resetTracking } from '@vue/reactivity'
- isHydrating,
+import {
+ currentHydrationNode,
+ isComment,
- import { queuePostFlushCb } from '@vue/runtime-dom'
+ locateHydrationNode,
+ locateVaporFragmentAnchor,
+} from './dom/hydration'
+import {
+ type TransitionHooks,
+ type TransitionProps,
+ type TransitionState,
+ performTransitionEnter,
+ performTransitionLeave,
+} from '@vue/runtime-dom'
+import {
+ applyTransitionHooks,
+ applyTransitionLeaveHooks,
+} from './components/Transition'
+
+export interface TransitionOptions {
+ $key?: any
+ $transition?: VaporTransitionHooks
+}
+ import { isHydrating } from './dom/hydration'
+ import { getInheritedScopeIds } from '@vue/runtime-dom'
-export type Block =
- | Node
- | VaporFragment
- | DynamicFragment
- | VaporComponentInstance
- | Block[]
+export interface VaporTransitionHooks extends TransitionHooks {
+ state: TransitionState
+ props: TransitionProps
+ instance: VaporComponentInstance
+ // mark transition hooks as disabled so that it skips during
+ // inserting
+ disabled?: boolean
+}
+
+export type TransitionBlock =
+ | (Node & TransitionOptions)
+ | (VaporFragment & TransitionOptions)
+ | (DynamicFragment & TransitionOptions)
+
+export type Block = TransitionBlock | VaporComponentInstance | Block[]
export type BlockFn = (...args: any[]) => Block
}
export class DynamicFragment extends VaporFragment {
- anchor: Node
+ anchor!: Node
scope: EffectScope | undefined
current?: BlockFn
+ fallback?: BlockFn
+ /**
+ * slot only
+ * indicates forwarded slot
+ */
+ forwarded?: boolean
constructor(anchorLabel?: string) {
super([])
component as any,
rawProps,
rawSlots,
+ scopeId,
)
- if (!isHydrating && _insertionParent) {
+
+ // `frag.insert` handles both hydration and mounting
+ if (_insertionParent) {
insert(frag, _insertionParent, _insertionAnchor)
}
return frag
rawProps?: LooseRawProps | null,
rawSlots?: LooseRawSlots | null,
isSingleRoot?: boolean,
+ once?: boolean,
+ scopeId?: string,
+ appContext?: GenericAppContext,
): HTMLElement | VaporComponentInstance {
if (!isString(comp)) {
- return createComponent(comp, rawProps, rawSlots, isSingleRoot, appContext)
+ return createComponent(
+ comp,
+ rawProps,
+ rawSlots,
+ isSingleRoot,
+ once,
+ scopeId,
++ appContext,
+ )
}
const _insertionParent = insertionParent
}
}
- if (!isHydrating && _insertionParent) {
+ if (i) fragment.forwarded = true
+ if (i || !hasForwardedSlot(fragment.nodes)) {
+ const scopeId = instance!.type.__scopeId
+ if (scopeId) setScopeId(fragment, `${scopeId}-s`)
+ }
+
+ if (
+ _insertionParent &&
+ (!isHydrating ||
+ // for vdom interop fragment, `fragment.insert` handles both hydration and mounting
+ fragment.insert)
+ ) {
insert(fragment, _insertionParent, _insertionAnchor)
}