import { computed, nextTick, onMounted, onUnmounted, ref, shallowRef, watch } from 'vue' import type { ComputedRef, CSSProperties, Ref } from 'vue' import { SlideUpDownState } from '@/enums' /** * Subset of CSS properties used to animate the height transition. */ export type SlideUpDownStyle = Pick< CSSProperties, 'overflow' | 'transition-property' | 'transition-duration' | 'height' > /** * Reactive options driving the slide animation. They mirror the `active` and * `duration` props of the `SlideUpDown` component. */ export interface UseSlideUpDownOptions { /** * Whether the content is expanded. Toggling it triggers the slide. */ active: Ref /** * Duration of the height transition, in milliseconds. */ duration: Ref } /** * Reactive API returned by {@link useSlideUpDown}. */ export interface UseSlideUpDown { /** * Template ref to attach to the animated container element. */ container: Ref /** * Current phase of the slide animation. */ state: Ref /** * Whether the host component has mounted, gating the measured height so the * initial render can rely on `height: auto` instead of a pixel value. */ mounted: Ref /** * Inline style applied to the container for the current animation phase. */ style: ComputedRef /** * Start the slide: snapshot the height, render once, then enter the active * phase so the CSS transition can run. */ triggerSlide: () => Promise /** * Settle the animation back to its resting phase, unless the transition was * bubbled up from an animated child element. */ cleanLayout: (event: Event | null) => Promise | undefined } /** * Owns the height-based open/close animation of the `SlideUpDown` component: * measures the container `scrollHeight`, derives the inline transition style for * each animation phase, and drives the phase lifecycle when `active` toggles. * * The animation runs in three phases (see {@link SlideUpDownState}): `pre` * locks the height to the measured value, `active` transitions it towards the * target height, and `post` releases the height once the transition ends. * * @param options - Reactive slide options (see {@link UseSlideUpDownOptions}). * @returns The {@link UseSlideUpDown} API: the `container` ref to attach to the * host element, the `state`/`mounted` refs, the `style` computed for the * template, and the `triggerSlide`/`cleanLayout` lifecycle handlers. * @example * // Internal building block of the `SlideUpDown` component; not exported from * // the package root. Inside a `