From c9ee8d1eac43bb8f3a5b968e27ffde6470980bec Mon Sep 17 00:00:00 2001 From: daiwei Date: Thu, 13 Mar 2025 21:46:40 +0800 Subject: [PATCH] wip: handle fallthrough attrs --- .../__tests__/transition.spec.ts | 2 +- packages/runtime-vapor/src/apiCreateFor.ts | 2 +- packages/runtime-vapor/src/block.ts | 1 + .../src/components/Transition.ts | 36 +++++++++++++------ 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/packages-private/vapor-e2e-test/__tests__/transition.spec.ts b/packages-private/vapor-e2e-test/__tests__/transition.spec.ts index 196f37e889..41d9010476 100644 --- a/packages-private/vapor-e2e-test/__tests__/transition.spec.ts +++ b/packages-private/vapor-e2e-test/__tests__/transition.spec.ts @@ -824,7 +824,7 @@ describe('vapor transition', () => { E2E_TIMEOUT, ) - test.todo( + test( 'wrapping transition + fallthrough attrs', async () => { const btnSelector = '.if-fallthrough-attr > button' diff --git a/packages/runtime-vapor/src/apiCreateFor.ts b/packages/runtime-vapor/src/apiCreateFor.ts index a49c635e2e..92bfe56258 100644 --- a/packages/runtime-vapor/src/apiCreateFor.ts +++ b/packages/runtime-vapor/src/apiCreateFor.ts @@ -318,7 +318,7 @@ export const createFor = ( // apply transition for new nodes if (frag.$transition) { - applyTransitionHooks(block.nodes, frag.$transition) + applyTransitionHooks(block.nodes, frag.$transition, false) } if (parent) insert(block.nodes, parent, anchor) diff --git a/packages/runtime-vapor/src/block.ts b/packages/runtime-vapor/src/block.ts index edd9bade61..6c882badcd 100644 --- a/packages/runtime-vapor/src/block.ts +++ b/packages/runtime-vapor/src/block.ts @@ -28,6 +28,7 @@ export interface TransitionOptions { export interface VaporTransitionHooks extends TransitionHooks { state: TransitionState props: TransitionProps + instance: VaporComponentInstance // mark transition hooks as disabled so that it skips during // inserting disabled?: boolean diff --git a/packages/runtime-vapor/src/components/Transition.ts b/packages/runtime-vapor/src/components/Transition.ts index ced53428cc..03f8a003e6 100644 --- a/packages/runtime-vapor/src/components/Transition.ts +++ b/packages/runtime-vapor/src/components/Transition.ts @@ -24,6 +24,7 @@ import { import { type VaporComponentInstance, isVaporComponent } from '../component' import { isArray } from '@vue/shared' import { renderEffect } from '../renderEffect' +import { setDynamicProps } from '../dom/prop' const decorate = (t: typeof VaporTransition) => { t.displayName = 'VaporTransition' @@ -47,7 +48,9 @@ export const VaporTransition: FunctionalComponent = if (isMounted) { // only update props for Fragment block, for later reusing if (isFragment(children)) { - if (children.$transition) children.$transition.props = resolvedProps + if (children.$transition) { + children.$transition.props = resolvedProps + } } else { // replace existing transition hooks const child = findTransitionBlock(children) @@ -64,6 +67,7 @@ export const VaporTransition: FunctionalComponent = applyTransitionHooks(children, { state: useTransitionState(), props: resolvedProps!, + instance: currentInstance!, } as VaporTransitionHooks) return children @@ -131,32 +135,41 @@ export function resolveTransitionHooks( ) as VaporTransitionHooks hooks.state = state hooks.props = props + hooks.instance = instance as VaporComponentInstance return hooks } export function applyTransitionHooks( block: Block, hooks: VaporTransitionHooks, + fallthroughAttrs: boolean = true, ): VaporTransitionHooks { - const inFragment = isFragment(block) - const child = findTransitionBlock(block, inFragment) + const isFrag = isFragment(block) + const child = findTransitionBlock(block) if (!child) { // set transition hooks on fragment for reusing during it's updating - if (inFragment) setTransitionHooksToFragment(block, hooks) + if (isFrag) setTransitionHooksToFragment(block, hooks) return hooks } - const { props, state, delayedLeave } = hooks + const { props, instance, state, delayedLeave } = hooks let resolvedHooks = resolveTransitionHooks( child, props, state, - currentInstance!, + instance, hooks => (resolvedHooks = hooks as VaporTransitionHooks), ) resolvedHooks.delayedLeave = delayedLeave setTransitionHooks(child, resolvedHooks) - if (inFragment) setTransitionHooksToFragment(block, resolvedHooks) + if (isFrag) setTransitionHooksToFragment(block, resolvedHooks) + + // TODO handle attrs update + // fallthrough attrs + if (fallthroughAttrs && instance.hasFallthrough) { + setDynamicProps(child, [instance.attrs]) + } + return resolvedHooks } @@ -168,12 +181,12 @@ export function applyTransitionLeaveHooks( const leavingBlock = findTransitionBlock(block) if (!leavingBlock) return undefined - const { props, state } = enterHooks + const { props, state, instance } = enterHooks const leavingHooks = resolveTransitionHooks( leavingBlock, props, state, - currentInstance!, + instance, ) setTransitionHooks(leavingBlock, leavingHooks) @@ -218,6 +231,7 @@ export function findTransitionBlock( return transitionBlockCache.get(block) } + let isFrag = false let child: TransitionBlock | undefined if (block instanceof Node) { // transition can only be applied on Element child @@ -244,7 +258,7 @@ export function findTransitionBlock( if (!__DEV__) break } } - } else if (isFragment(block)) { + } else if ((isFrag = isFragment(block))) { if (block.insert) { child = block } else { @@ -252,7 +266,7 @@ export function findTransitionBlock( } } - if (__DEV__ && !child && !inFragment) { + if (__DEV__ && !child && !inFragment && !isFrag) { warn('Transition component has no valid child element') } -- 2.47.2