From ecef92b1dc098c4c247ab0295d34933f15fec6f0 Mon Sep 17 00:00:00 2001 From: daiwei Date: Thu, 13 Mar 2025 21:46:40 +0800 Subject: [PATCH] wip: handle fallthrough attrs --- .../src/components/Transition.ts | 48 +++++++++++++------ .../src/components/TransitionGroup.ts | 12 +++-- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/packages/runtime-vapor/src/components/Transition.ts b/packages/runtime-vapor/src/components/Transition.ts index 03f8a003e6..7f6179a3a7 100644 --- a/packages/runtime-vapor/src/components/Transition.ts +++ b/packages/runtime-vapor/src/components/Transition.ts @@ -22,7 +22,7 @@ import { isFragment, } from '../block' import { type VaporComponentInstance, isVaporComponent } from '../component' -import { isArray } from '@vue/shared' +import { extend, isArray } from '@vue/shared' import { renderEffect } from '../renderEffect' import { setDynamicProps } from '../dom/prop' @@ -34,10 +34,11 @@ const decorate = (t: typeof VaporTransition) => { } export const VaporTransition: FunctionalComponent = - /*@__PURE__*/ decorate((props, { slots }) => { + /*@__PURE__*/ decorate((props, { slots, attrs }) => { const children = (slots.default && slots.default()) as any as Block if (!children) return + const instance = currentInstance! as VaporComponentInstance const { mode } = props checkTransitionMode(mode) @@ -48,15 +49,13 @@ 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 - } + children.$transition!.props = resolvedProps } else { - // replace existing transition hooks const child = findTransitionBlock(children) - if (child && child.$transition) { - child.$transition.props = resolvedProps - applyTransitionHooks(child, child.$transition) + if (child) { + // replace existing transition hooks + child.$transition!.props = resolvedProps + applyTransitionHooks(child, child.$transition!) } } } else { @@ -64,11 +63,31 @@ export const VaporTransition: FunctionalComponent = } }) - applyTransitionHooks(children, { - state: useTransitionState(), - props: resolvedProps!, - instance: currentInstance!, - } as VaporTransitionHooks) + // fallthrough attrs + let fallthroughAttrs = true + if (instance.hasFallthrough) { + renderEffect(() => { + // attrs are accessed in advance + const resolvedAttrs = extend({}, attrs) + const child = findTransitionBlock(children) + if (child) { + setDynamicProps(child, [resolvedAttrs]) + // ensure fallthrough attrs are not happened again in + // applyTransitionHooks + fallthroughAttrs = false + } + }) + } + + applyTransitionHooks( + children, + { + state: useTransitionState(), + props: resolvedProps!, + instance: instance, + } as VaporTransitionHooks, + fallthroughAttrs, + ) return children }) @@ -164,7 +183,6 @@ export function applyTransitionHooks( setTransitionHooks(child, resolvedHooks) if (isFrag) setTransitionHooksToFragment(block, resolvedHooks) - // TODO handle attrs update // fallthrough attrs if (fallthroughAttrs && instance.hasFallthrough) { setDynamicProps(child, [instance.attrs]) diff --git a/packages/runtime-vapor/src/components/TransitionGroup.ts b/packages/runtime-vapor/src/components/TransitionGroup.ts index a811505f56..c12260bf37 100644 --- a/packages/runtime-vapor/src/components/TransitionGroup.ts +++ b/packages/runtime-vapor/src/components/TransitionGroup.ts @@ -28,7 +28,11 @@ import { setTransitionHooks, setTransitionHooksToFragment, } from './Transition' -import { type ObjectVaporComponent, isVaporComponent } from '../component' +import { + type ObjectVaporComponent, + type VaporComponentInstance, + isVaporComponent, +} from '../component' import { isForBlock } from '../apiCreateFor' import { renderEffect, setDynamicProps } from '@vue/runtime-vapor' @@ -50,7 +54,7 @@ export const VaporTransitionGroup: ObjectVaporComponent = decorate({ }), setup(props: TransitionGroupProps, { slots }) { - const instance = currentInstance + const instance = currentInstance as VaporComponentInstance const state = useTransitionState() const cssTransitionProps = resolveTransitionProps(props) @@ -144,7 +148,9 @@ export const VaporTransitionGroup: ObjectVaporComponent = decorate({ const container = document.createElement(tag) insert(slottedBlock, container) // fallthrough attrs - renderEffect(() => setDynamicProps(container, [instance!.attrs])) + if (instance!.hasFallthrough) { + renderEffect(() => setDynamicProps(container, [instance!.attrs])) + } return container } else { const frag = __DEV__ -- 2.47.2