Toast
import { Toaster, toast } from '@absoluteui/components/toast';import '@absoluteui/components/toast/style.css';Using Angular? See Toast for Angular.
What it does
Section titled “What it does”Transient notifications, stacked in a labelled region. A Toaster owns one region: a <section aria-label="Notifications"> rendered in the top layer with popover="manual" while it has toasts. The toast() function uses a lazily created default toaster for the document.
AbsoluteUI adds:
- one announcement per toast through the shared live regions: polite for info and success, assertive for warning and error;
- no focus stealing;
- timers that pause on hover and focus (WCAG 2.2.1), with error toasts persistent by default;
- a hotkey (default Alt+T) that reaches the newest toast, and Escape to dismiss it;
- a first-in, first-out queue beyond
maxvisible toasts.
When to use
Section titled “When to use”- Confirmation of a completed background action (saved, sent, copied).
- Non-blocking notices with at most one follow-up action, such as Undo.
- Errors from background work, which persist until dismissed by default.
When not to use
Section titled “When not to use”- Information the user must not miss or must act on: use Alert or Dialog.
- Field validation errors: show them at the field and in the Error Summary.
- Status tied to a specific place on the page: use Inline Message.
- Long or rich content: toasts are text only with one action.
Examples
Section titled “Examples”Default toaster via toast()
Section titled “Default toaster via toast()”import { toast } from '@absoluteui/components/toast';
toast({ tone: 'success', message: 'Changes saved.' });Undo action and progress update
Section titled “Undo action and progress update”import { Toaster, type ToastCloseDetail } from '@absoluteui/components/toast';
const toaster = Toaster.create({ position: 'bottom-center', max: 2 });let restored = false;const handle = toaster.show({ message: 'Conversation archived.', action: { label: 'Undo', onAction: () => { restored = true; }, },});toaster.element.addEventListener('aui-close', (event) => { const { id, reason } = (event as CustomEvent<ToastCloseDetail>).detail; if (id === handle.id && reason !== 'action' && !restored) { // archive is final }});
const upload = toaster.show({ message: 'Uploading report.pdf', duration: 0 });upload.update({ tone: 'success', message: 'Uploaded report.pdf', duration: 5000 });import { Toaster } from '@absoluteui/components/toast';import '@absoluteui/components/button/style.css';import '@absoluteui/components/toast/style.css';
const toaster = Toaster.create({ position: 'top-end' });document.querySelector('#archive')?.addEventListener('click', () => { toaster.show({ message: 'Conversation archived.', action: { label: 'Undo', onAction: () => { document.querySelector('#restore')?.dispatchEvent(new Event('click')); }, }, });});More usage
Section titled “More usage”import { toast } from '@absoluteui/components/toast';
const upload = toast({ message: 'Uploading report.pdf', duration: 0 });upload.update({ tone: 'success', message: 'Uploaded report.pdf', duration: 5000 });toast({ tone: 'error', title: 'Sync failed', message: 'Changes will be retried.' });Anatomy
Section titled “Anatomy”<section class="aui-toaster aui-toaster--{position}" aria-label="Notifications" popover="manual"> <ol class="aui-toaster__list"> <li class="aui-toaster__item"> <div class="aui-toast aui-toast--{tone}" role="group" tabindex="-1" aria-labelledby="{id}-text"> <span class="aui-toast__icon">icon (aria-hidden)</span> <div class="aui-toast__text" id="{id}-text"> <span class="aui-toast__tone">Error: (visually hidden)</span> <p class="aui-toast__title">title</p> <p class="aui-toast__message">message</p> </div> <div class="aui-toast__actions"><button class="aui-button">Undo</button></div> <button class="aui-button aui-toast__dismiss" aria-label="Dismiss notification">icon</button> </div> </li> </ol></section>API reference
Section titled “API reference”Factory
Section titled “Factory”Toaster.create(options?: ToasterOptions, doc?: Document): Toaster; toast(options: ToastOptions, doc?: Document): ToastHandleGlobal configuration key: toast (see Configuration).
Options
Section titled “Options”| Option | Type | Default | Description |
|---|---|---|---|
icons |
Partial<ToastIcons> |
Toaster option: icon slot overrides. | |
position |
'bottom-end' | 'bottom-start' | 'top-end' | 'top-start' | 'top-center' | 'bottom-center' |
"bottom-end" |
Region corner (logical: end is right in LTR, left in RTL). Globally configurable. |
max |
number |
3 |
Maximum visible toasts (1..20); further toasts queue first-in, first-out. Globally configurable. |
duration |
number |
5000 |
Auto-dismiss delay in ms (0 = persistent). Error toasts persist unless given a duration. Applies to toasts shown afterwards. Globally configurable. |
hotkey |
string | null |
"Alt+T" |
Moves focus to the newest toast; null disables. Globally configurable. |
locale |
string |
"en-US" |
Locale of the region label, tone prefixes, and dismiss label. Globally configurable. Inherited from common configuration. |
Properties
Section titled “Properties”| Property | Type | Description |
|---|---|---|
element |
HTMLElement |
The region <section>; aui-open and aui-close fire here. |
count |
number |
Visible toasts. |
queued |
number |
Toasts waiting for a free slot. |
options |
Readonly<ToasterOptions> |
Current toaster options. |
Methods
Section titled “Methods”| Method | Description |
|---|---|
show(options: ToastOptions): ToastHandle |
Show (or queue) a toast { tone?, title?, message, duration?, action? }. Returns { id, dismiss(), update() }. |
clear(): void |
Dismiss all visible toasts and drop the queue. |
update(options: Partial<ToasterOptions>): void |
Merge and apply toaster options. |
destroy(): void |
Remove the region, timers, listeners, and subscriptions (no events). |
dismiss(): void |
Close the toast (reason programmatic) or drop it from the queue. |
update(options: Partial<ToastOptions>): void |
Merge options; a visible toast is re-announced and its timer restarts. |
toast(options: ToastOptions, doc?: Document): ToastHandle |
Show a toast in a lazily created default Toaster for the document. |
Events
Section titled “Events”| Event | Detail | Bubbles | Cancelable | Description |
|---|---|---|---|---|
aui-open |
{ id: string } |
No | No | A toast became visible (fired on the region). |
aui-close |
{ id: string; reason: 'timeout' | 'dismiss' | 'action' | 'programmatic' } |
No | No | A visible toast closed (fired on the region). |
CSS classes
Section titled “CSS classes”All rules live in the aui.components cascade layer, so application styles override them without specificity battles.
| Class | Purpose |
|---|---|
aui-toaster |
Region <section> (manual popover). |
aui-toaster--bottom-end | --bottom-start | --top-end | --top-start | --top-center | --bottom-center |
Position modifiers. |
aui-toaster__list |
Ordered list of toasts. |
aui-toaster__item |
List item wrapping one toast. |
aui-toast |
Toast (role=group, tabindex=-1). |
aui-toast--info | --success | --warning | --error |
Tone modifiers. |
aui-toast__icon |
Tone icon (decorative). |
aui-toast__text |
Tone prefix, title, and message; labels the toast. |
aui-toast__tone |
Visually hidden tone prefix. |
aui-toast__title |
Title. |
aui-toast__message |
Message. |
aui-toast__actions |
Action button container. |
aui-toast__dismiss |
Dismiss button. |
Icon slots
Section titled “Icon slots”| Slot | Default icon |
|---|---|
info |
info |
success |
check-circle |
warning |
alert-triangle |
error |
alert-circle |
dismiss |
close |
Design tokens
Section titled “Design tokens”Tokens this stylesheet reads (verified in CI). Override them in a theme or with the Theme Designer.
--aui-border-width | --aui-border-width-strong | --aui-color-error-fg | --aui-color-error-subtle | --aui-color-focus-ring | --aui-color-info-fg | --aui-color-info-subtle | --aui-color-success-fg | --aui-color-success-subtle | --aui-color-surface | --aui-color-text | --aui-color-warning-fg | --aui-color-warning-subtle | --aui-duration-fast | --aui-easing-standard | --aui-focus-ring-offset | --aui-focus-ring-width | --aui-font-family-sans | --aui-font-size-sm | --aui-font-weight-semibold | --aui-icon-size-md | --aui-line-height-normal | --aui-radius-md | --aui-shadow-md | --aui-space-1 | --aui-space-2 | --aui-space-3 | --aui-space-4 | --aui-toast-width
TypeScript definitions
Section titled “TypeScript definitions”type ToastTone = 'info' | 'success' | 'warning' | 'error';type ToastPosition = 'bottom-end' | 'bottom-start' | 'top-end' | 'top-start' | 'top-center' | 'bottom-center';type ToastCloseReason = 'timeout' | 'dismiss' | 'action' | 'programmatic';interface ToastAction { label: string; onAction?: () => void }interface ToastOptions { tone?: ToastTone; title?: string; message: string; duration?: number; action?: ToastAction }interface ToastHandle { readonly id: string; dismiss(): void; update(options: Partial<ToastOptions>): void }interface ToastIcons { info: IconRef; success: IconRef; warning: IconRef; error: IconRef; dismiss: IconRef }interface ToasterOptions { position?: ToastPosition; max?: number; duration?: number; hotkey?: string | null; locale?: string; icons?: Partial<ToastIcons>;}interface ToastOpenDetail { id: string }interface ToastCloseDetail { id: string; reason: ToastCloseReason }declare function toast(options: ToastOptions, doc?: Document): ToastHandle;Accessibility
Section titled “Accessibility”Pattern: Notification region (labelled section landmark) with announcements through shared visually hidden live regions (WCAG 4.1.3); toasts are not live regions themselves, to avoid double announcements.
Keyboard
Section titled “Keyboard”| Key | Context | Action |
|---|---|---|
| Alt+T (configurable hotkey) | Anywhere, toasts visible | Moves focus to the newest toast; timers pause while focus is inside. |
| Tab / Shift+Tab | Focus in a toast | Moves through the action and dismiss buttons and between toasts. |
| Escape | Focus in a toast | Dismisses that toast and returns focus to where it was before entering the region. |
| Enter / Space | Action button focused | Runs onAction, then closes the toast (reason action). |
| Enter / Space | Dismiss button focused | Closes the toast (reason dismiss) and returns focus. |
| Element | Role |
|---|---|
| <section class=aui-toaster> | region (named ‘Notifications’) |
| <ol> | list |
| toast | group, labelled by its text |
| icon | none (aria-hidden=true) |
| action and dismiss buttons | button (native) |
ARIA attributes
Section titled “ARIA attributes”| Attribute | Element | Value |
|---|---|---|
aria-label |
region | Localized ‘Notifications’ |
aria-labelledby |
toast | id of the text block (tone prefix, title, message) |
aria-label |
dismiss button | Localized ‘Dismiss notification’ |
aria-live |
shared live regions (announce()) | polite for info/success, assertive for warning/error |
Toasts never take focus on their own. The hotkey focuses the newest toast (tabindex=-1, visible focus ring). When a focused toast closes, focus returns to the element focused before entering the region, else to the newest remaining toast.
WCAG 2.2 success criteria addressed
Section titled “WCAG 2.2 success criteria addressed”Automated test results: Accessibility and compliance.
Notes and known caveats
Section titled “Notes and known caveats”- Timers pause while the pointer is over the region or focus is inside it (WCAG 2.2.1); error toasts persist until dismissed by default.
- Tone is conveyed by an icon and a visually hidden, localized prefix, never by color alone; the prefix is part of the announcement.
- DOM order matches visual order (newest nearest the viewport edge).
- While a modal dialog is open, the region moves inside it so new toasts are above the dialog and not inert.
- Announcements use the shared live regions in document.body, which are outside an open modal dialog; screen readers may not announce toasts while a modal is open.
- Manual screen-reader verification (NVDA, JAWS, VoiceOver) is pending.
Behavior
Section titled “Behavior”States
Section titled “States”Region: hidden (no toasts) or open. Toast: queued, visible, timer running, timer paused (hover or focus), persistent.
State transitions
Section titled “State transitions”| From | Trigger | To |
|---|---|---|
| - | show() with a free slot |
visible (announced, aui-open) |
| - | show() with max visible |
queued |
| queued | a visible toast closes | visible |
| visible | timer elapses | closed (timeout) |
| visible | pointer over region / focus inside | timer paused, resumes with remaining time |
| visible | dismiss button / Escape | closed (dismiss), focus returned |
| visible | action button | onAction(), then closed (action) |
| visible | handle.dismiss() / clear() |
closed (programmatic) |
Accessibility notes
Section titled “Accessibility notes”- Toasts never take focus; users reach them with the hotkey, or by Tab (the region follows page content in DOM order). Tell users about the hotkey, for example in your keyboard help.
- Timers pause while the pointer is over the region or focus is inside it. Errors persist unless given a
duration. Keep durations of at least 5 seconds. - DOM order matches visual order: the newest toast is nearest the viewport edge.
- While a modal dialog is open, everything outside it is inert. The region therefore moves into the open modal dialog when a toast is shown, and back to
document.bodywhen that dialog closes, so toasts stay above the dialog and remain operable. - The shared live regions used by
announce()are indocument.body. While a modal dialog is open they are outside the dialog, so screen readers may not announce toasts (see section 30). - The e2e axe run (WCAG 2.2 AA, 3 themes) and manual screen-reader verification are pending.
Responsive behavior
Section titled “Responsive behavior”Region width is min(toast-width, 100vw - 2rem), pinned space-4 from the configured edges or centred. Text wraps.
Right-to-left
Section titled “Right-to-left”Positions use logical insets: end is the right edge in LTR and the left edge in RTL. Icon and border sit at the inline start.
Theming
Section titled “Theming”An opaque color-surface background under a color-{tone}-subtle tint (matching the contrast gate’s backdrop), color-{tone}-fg icon and border, color-text text, and shadow-md. Forced-colors mode removes the tint and uses CanvasText borders. The entry slide/fade uses @starting-style and is removed under prefers-reduced-motion or animation: 'none'.
Global configuration
Section titled “Global configuration”configureAbsoluteUI({ components: { toast: { position: 'top-end', max: 4, duration: 8000, hotkey: 'Alt+N' } } });Component configuration
Section titled “Component configuration”Toaster.create(options) and toaster.update(options) override global and theme defaults; per-toast duration overrides both. All options are dynamic. Changing duration affects toasts shown afterwards; changing max reveals queued toasts at once.
icons.info (default info), icons.success (check-circle), icons.warning (alert-triangle), icons.error (alert-circle), icons.dismiss (close), set per toaster.
Security
Section titled “Security”Title, message, and action label use textContent; they are never parsed as HTML. No inline styles (the visually hidden prefix uses the CSSOM). CSP-safe.
Data handling
Section titled “Data handling”No persistence, network access, or telemetry. Message text is copied into the shared live regions for announcement.
Performance
Section titled “Performance”Constant work per toast; at most max toasts are in the DOM. One document keydown listener per toaster, for the hotkey.
Supported data scale
Section titled “Supported data scale”max up to 20 visible toasts. The queue is unbounded; avoid producing toasts in loops.
Edge cases
Section titled “Edge cases”- Focus inside a toast that closes (Escape, dismiss, action, or timeout) returns to the element focused before entering the region. If that element is gone, focus moves to the newest remaining toast.
- A toast shown while the region is hovered or focused starts its timer only after the pointer leaves and focus leaves.
- Toasts already visible when a modal dialog opens stay beneath it until the next toast is shown.
- If the region is removed from the DOM by other code,
toast()creates a new default toaster. show()afterdestroy()throwsTOASTER_DESTROYED. Handles of closed toasts are inert.
Errors
Section titled “Errors”| Code | Category | Cause |
|---|---|---|
TOAST_OPTIONS |
configuration | Missing or blank message, unknown tone, invalid duration, or invalid action. |
TOASTER_DESTROYED |
runtime | show() on a destroyed toaster. |
ICON_UNKNOWN |
configuration | Unknown icon override. |
CFG_INVALID_VALUE / CFG_UNKNOWN_OPTION |
configuration | Invalid or unknown configuration (e.g. max: 0). |
Invalid toaster options throw before the region is appended; invalid toast options throw before anything is shown.
Known limitations
Section titled “Known limitations”- Announcements while a modal dialog is open depend on the shared live regions, which sit outside the dialog (planned fix in
@absoluteui/utilities). - There is no exit animation; toasts are removed immediately.
matchesHotkeycomparesevent.key. On macOS, Option+letter produces a different character, soAlt+Tmay not match there; configure another hotkey.- Manual screen-reader verification is pending.
Unsupported scenarios
Section titled “Unsupported scenarios”- HTML or
Nodecontent. - More than one action per toast.
- Swipe-to-dismiss gestures.