Skip to main content

Design system components

ToastStack

Docked stack of transient toasts: renders Toast children inline and owns the fixed placement, newest toast nearest the docked edge, so concurrent messages stay visible instead of replacing each other.

Status: stable. Group: feedback. Markdown version: /design-system/components/toast-stack.md

When to use

ToastStack is the multi-toast surface behind the app ToastProvider: showToast calls append items and each renders as an inline Toast laid out by the stack, newest nearest the docked edge. Use it (or the provider) whenever more than one transient message can be alive at once; a bare Toast stays correct for single, fully controlled cases.

When not to use

  • Avoid mounting more than one ToastStack per position; group toasts by position and render one stack per active position instead.
  • Do not use it for persistent or compliance-critical messaging; toasts auto-dismiss (use AlertBanner)

Look-alikes

  • AlertBanner: Do not use it for persistent or compliance-critical messaging; toasts auto-dismiss (use AlertBanner)
  • Toast: Do not mount two overlapping fixed <Toast /> instances yourself; use ToastStack (or the app ToastProvider) so concurrent messages stack instead of replacing each other.

Props

ToastStack props
PropTypeDefaultDescriptionRequired
toastsToastStackItem[]noneToasts to display, oldest first; new toasts are appended by the caller.Yes
position"top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right"bottom-centerScreen corner/edge the stack docks to. Defaults to bottom-center.No
onDismiss(id: string) => voidnoneCalled with the toast id when its auto-dismiss timer fires or its dismiss button is pressed. Timers pause while the pointer is over the stack or focus is inside it.No
dismissiblebooleanfalseGives every toast a dismiss button, so it can be closed by hand and keyboard users can reach it (focus inside the stack pauses the timers). Defaults to false: the toast is as wide as its message, for short confirmations that auto-dismiss.No
maxnumber5Maximum toasts rendered at once. Defaults to 5. The oldest render; newer ones wait unrendered (their timers only run while rendered), so a burst drains in arrival order.No
classNamestringnoneOptional classes on the stack wrapper.No

Variants

  • Available positions: top-left, top-center, top-right, bottom-left, bottom-center, bottom-right (default bottom-center).

Invalid combinations

The contract records no invalid combinations.

Keyboard

The contract records no keyboard interaction.

Rules

Every item under When not to use is a MUST NOT. MUST and SHOULD follow RFC 2119.

ToastStack rules
LevelRuleHow it is checked
MUSTARIA: Each stacked Toast keeps its own live region (role=status or role=alert per tone) so concurrent messages announce independently.Not yet verified: no evidence record. WCAG 4.1.2.
MUSTARIA: The stack wrapper is presentational: no role, pointer-events none with interactive children restored.Not yet verified: no evidence record. WCAG 4.1.2.
MUSTARIA: Toasts auto-dismiss (default 3000 ms); every timer pauses while the pointer is over the stack or focus is inside it and resumes with the time left. With dismissible, each toast has a translated dismiss button outside its live region, so keyboard users can focus a toast (pausing every timer) and close it; by default toasts have no button and are as wide as their message.Not yet verified: no evidence record. WCAG 4.1.2.
MUSTARIA: Each timer is owned by the stack and survives re-renders: appending a toast or a parent passing a fresh onDismiss function does not restart the toasts already showing.Not yet verified: no evidence record. WCAG 4.1.2.
MUSTRequired stories produce no axe violations at the configured severity.Automated by npm run test:stories:matrix:ci. WCAG 2.5.8.
MUSTThe accessibility tree (role, name, state) matches the committed snapshot for every required story.Automated by npm run test:stories:matrix:ci. WCAG 1.3.1, 4.1.2.
MUSTThe component remains legible and operable under a real browser forced-colors: active pass.Automated by npm run test:stories:hc.
MUSTA human completed an end-to-end accessibility review of this component.Manual review, last on 2026-11-04.

Install and import

  • Install: npm install @digitaltableteur/react (version 0.9.1, restricted access on npm).
  • Import: import { ToastStack } from "@digitaltableteur/react";
  • Entry point: @digitaltableteur/react/feedback exports it too.
  • Styles: import @digitaltableteur/react/style.css once at the app boundary.
  • Also available as the custom element <dt-toast-stack>; see the custom elements manifest.