Transition
Headless Transition; covers CSS transitions, CSS animations, computed motion duration.
| Package | @vizejs/ui/transition |
| Maturity | stable |
| Own the source | vize lib pull transition |
| Requires | presence |
| Aliases | css transition, enter leave, motion complete |
| Covers | CSS transitions, CSS animations, computed motion duration |
Minimal setup
Use a Vue 3.5+ project with Vue SFC compilation configured (see Vite+ integration).
vp install @vizejs/ui
Add the public import below to <script setup lang="ts">. Components provide behavior without styles; the preview uses optional Paper styles.
import { Transition } from "@vizejs/ui/transition";
Or copy the source into your project with vize lib pull transition (see Source Distribution).
Try it
This is the basic example maintained with the component source, using the public package imports. The preview adds the optional Paper styles.
Open the interactive example · Styling these components
Copy the example
<!-- Presence-driven fade transition toggled by a disclosure button. -->
<script setup lang="ts">
import { ref, useId } from "vue";
import { Transition as PresenceTransition } from "@vizejs/ui/transition";
const visible = ref(true);
const panelId = useId();
</script>
<template>
<div>
<button
type="button"
:aria-expanded="visible"
:aria-controls="panelId"
@click="() => (visible = !visible)"
>
{{ visible ? "Hide" : "Show" }} shipping details
</button>
<PresenceTransition :id="panelId" :present="visible" motion="fade">
<template #default="{ status }">
<p>Orders ship within two business days.</p>
<small>Transition status: {{ status }}</small>
</template>
</PresenceTransition>
</div>
</template>
API
Transition
Source: src/families/overlays/transition/transition.vue
Props
| Prop | Type | Default | Description |
|---|---|---|---|
present |
boolean |
false |
Whether the content should occupy the tree. |
forceMount |
boolean |
false |
Keep the slot mounted even while presence would otherwise unmount it. |
respectReducedMotion |
boolean |
true |
Skip enter and exit animation when prefers-reduced-motion: reduce matches. |
timeoutPadding |
number |
0 |
Extra milliseconds added to the computed motion duration before auto-complete. |
motion |
"fade" | "scale" | "slide" |
undefined |
Named enter/exit recipe published on data-vize-motion, pairing the host with the packaged motion stylesheet (@vizejs/ui/motion). |
Slots
| Slot | Slot props | Description |
|---|---|---|
default |
{ readonly present: boolean; readonly status: PresenceStatus } |
Transitioning contents. Receives status for styling hooks. |
Exposed
| Member | Type | Description |
|---|---|---|
completeAnimation |
— | |
element |
Readonly<ShallowRef<HTMLElement | null>> |
Template ref to the rendered root element. |
isPresent |
— | |
status |
— |
Behavior
Normative state × input → outcome table for transition.vue (@vizejs/ui/transition).
Every row is proven by the named test in
src/families/overlays/transition/transition.test.ts or
src/families/overlays/transition/transition-ssr.test.ts; compile-only assertions live in
src/families/overlays/transition/transition.types.test-d.ts.
| # | State | Input | Outcome | Proven by |
|---|---|---|---|---|
| T1 | unmounted | present=false render |
slot stays unmounted | keeps unmounted content out of the tree |
| T2 | unmounted | present becomes true |
host mounts in entering until completion |
enters through an explicit completion step |
| T3 | entering | computed motion duration elapses | status becomes present without a manual complete |
auto-completes when CSS motion duration is 0 |
| T4 | present | present becomes false |
status becomes exiting and the host stays mounted |
exits through an explicit completion step |
| T5 | any | reduced motion | enter and exit skip to the terminal phase | skips motion when the user prefers it |
| T6 | unmounted | forceMount |
slot stays mounted with unmounted status |
force-mounts hidden content |
| T7 | present | render | exposed element is the rendered node |
exposes the rendered element for composition |
| T8 | SSR | present=true |
byte-identical markup starts in present |
SSR test |
| T9 | public types | invalid padding or mutating readonly refs | compilation rejects misuse | src/families/overlays/transition/transition.types.test-d.ts |
| T10 | any | motion recipe prop |
data-vize-motion publishes the recipe; omitted prop renders no attribute |
publishes the named motion recipe for the packaged stylesheet |