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
| Prop | Type | Default | Description | Required |
|---|---|---|---|---|
toasts | ToastStackItem[] | none | Toasts 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-center | Screen corner/edge the stack docks to. Defaults to bottom-center. | No |
onDismiss | (id: string) => void | none | Called 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 |
dismissible | boolean | false | Gives 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 |
max | number | 5 | Maximum 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 |
className | string | none | Optional classes on the stack wrapper. | No |
Variants
- Available positions:
top-left,top-center,top-right,bottom-left,bottom-center,bottom-right(defaultbottom-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.
| Level | Rule | How it is checked |
|---|---|---|
| MUST | ARIA: 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. |
| MUST | ARIA: The stack wrapper is presentational: no role, pointer-events none with interactive children restored. | Not yet verified: no evidence record. WCAG 4.1.2. |
| MUST | ARIA: 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. |
| MUST | ARIA: 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. |
| MUST | Required stories produce no axe violations at the configured severity. | Automated by npm run test:stories:matrix:ci. WCAG 2.5.8. |
| MUST | The 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. |
| MUST | The component remains legible and operable under a real browser forced-colors: active pass. | Automated by npm run test:stories:hc. |
| MUST | A 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/feedbackexports it too. - Styles: import
@digitaltableteur/react/style.cssonce at the app boundary. - Also available as the custom element
<dt-toast-stack>; see the custom elements manifest.
Links
- Machine-readable contract (Design System Contract 1.0)
- Markdown version of this page
- Component index as JSON
- All components
- Source: The implementation lives in a private repository. This page, its Markdown twin and the contract are generated from it at build time and are the public source of truth.