/// Utilities
Transition
A mount/unmount transition primitive: keeps children mounted through an exit tween, then removes them.
import { Transition } from "@protocore/pds";Basics
Toggle mounted and the child fades in; toggle it off and the child stays mounted through the fade-out, then unmounts. The render-prop hands you a style object to spread onto your element.
Presets
Five named presets — fade, slide-up, slide-down, scale, and pop — each defining an enter/exit opacity and transform. Tune duration and timingFunction per instance.
Validator 0x8f…c2 rotated its signing key.
When to use it
Transition is the low-level primitive the library's own overlays are built on. Reach for it when you need to animate something *in and out* of the tree — the exit animation is the hard part, since a naive conditional render rips the element out before it can animate.
It is a headless render-prop: it computes an inline style (opacity + transform + the timing) and the current status, and you decide what element to put them on. That keeps it composable onto any node without an extra wrapper. For a ready-made loading scrim, use LoadingOverlay; for portalled surfaces with focus management, prefer Popover or Dialog, which handle transitions internally.
Usage
Do
- Spread the provided `style` onto exactly one element, and let Transition own its mounting.
- Use `duration`/`exitDuration` to give exits a slightly different pace when it feels right.
- Reach for it to animate conditional content out of the tree, not just in.
- Pick a preset that matches the surface's origin (slide for edges, scale/pop for anchored popovers).
Don't
- Don't also conditionally render the child yourself — Transition manages mount/unmount.
- Don't return multiple root elements from the render-prop; give it a single node.
- Don't hand-build entrance animations for Dialog/Popover/Toast — they already transition.
- Don't rely on the tween for critical information — reduced-motion users get an instant snap.
Accessibility
- `prefers-reduced-motion: reduce` collapses both the enter and exit durations to zero, so motion-sensitive users get an instant show/hide rather than no content.
- Transition renders no DOM of its own — accessibility (roles, focus, live regions) is the responsibility of the element you apply the style to.
- Because the child stays mounted during exit, any focus you moved into it should be moved out before you set `mounted={false}`.
- The `status` argument (`entering` / `entered` / `exiting`) lets you gate `aria-hidden` or `inert` if the exiting content should leave the a11y tree immediately.
Transition props
| Prop | Type | Default | Description |
|---|---|---|---|
children * | (style: CSSProperties, status: TransitionStatus) => ReactNode | — | Render-prop: receives the inline `style` to spread onto your own element, plus the current transition `status`. Return a single element. |
duration | number | 200 | Animation duration in ms (exit reuses it unless `exitDuration` is set). |
exitDuration | number | — | Optional distinct exit duration in ms. Falls back to `duration`. |
mounted * | boolean | — | When `true` the child is mounted and animated in; when `false` it animates out and unmounts. |
onEntered | (() => void) | — | Called after the enter animation completes. |
onExited | (() => void) | — | Called after the exit animation completes and the child has unmounted. |
timingFunction | string | var(--pds-ease) | CSS timing function for the tween. |
transition | enum | fade | Named enter/exit preset. |