Toast stack
Toasts that fan into a scaled pile at the bottom of the screen and settle on a shared spring.
API reference
Components
<Toast />
One animated card in the stack. Reads its index and the shared geometry from the ToastStack context and renders the motion.div that carries the fan-out choreography: the index-derived rise/scale/fade, the settle spring with a per-step stagger, the enter/exit throws, and the z-order. Toasts beyond maxVisible are kept mounted (so the stack keeps its depth) but faded out, aria-hidden, and pointer-inert.
children?
The toast's content - typically a NotificationCard carrying the icon, title, body and a dismiss button. The Toast never styles the face, only moves it.
className?
Merged onto the animated card element. Positioning (absolute bottom / full width / stacking transform) is owned by the mechanic; use this only for extra per-toast styling.
<ToastStack />
The stack viewport. Paints the fixed bottom-centred well, wraps the toasts in an AnimatePresence so enter and exit are layout-animated, and computes the shared geometry + reduced-motion mode every Toast reads. The well is pointer-events-none so the gaps around the toasts never swallow clicks; each visible toast re-enables pointer events for itself. Render Toast children inside; the stack positions them, they supply their own content.
children?
The Toast children, newest first (map useToastStack().toasts in order). More may be passed than are shown; the stack keeps maxVisible + 2 mounted (the extra two are the hidden exit tail) and drops the rest.
maxVisible?
How many toasts stay fully visible before the rest hide behind them. Defaults to 4.
stackOffsetY?
Vertical push, in px, applied per step back in the stack. Defaults to 10.
stackScale?
Scale shed per step back in the stack (0.06 = 6% smaller each). Defaults to 0.06.
stackOpacity?
Opacity shed per step back in the stack. Defaults to 0.2.
className?
Merged onto the fixed viewport element - reposition the well (e.g. top instead of bottom) or widen it here.
Hooks
useToastStack
The headless toast queue. Owns nothing visual: it hands back the ordered id list plus add/dismiss so a consumer wires their own trigger and their own event source, then renders the ids as Toast children of a ToastStack. Newest toasts are prepended, so the queue is naturally front-to-back.
useToastStack(): UseToastStackResultReturns
toasts
The live queue of toast ids, newest first - map it into Toast children inside a ToastStack.
add
Push a new toast onto the front of the queue, returning its id. Wire this to your own trigger.
dismiss
Remove the toast with id (typically from its dismiss button).
useToast
Reports whether the enclosing Toast is inside the visible window. Read it from a control the consumer drops into a toast (a dismiss button) so the control can set tabIndex={isVisible ? undefined : -1} and stay out of the tab order while its toast is hidden behind the stack. Returns isVisible: true outside a Toast, so a control reused elsewhere never breaks.
useToast(): ToastVisibility