Toast
Presentational toast — an inline-layout Notice dressed for the toast stack (shadow, enter animation, icon | text | actions | × in one row).
The toast root is also a nested .tui-interface with data-theme="dark":
a dark surface by default (following Tooltip's inverted treatment), done as
a theme SCOPE rather than a token remap — the toast accepts arbitrary
children, and everything inside (action Buttons, the dismiss IconButton,
icons, consumer content) resolves dark tokens for free. Pass
data-theme="light" (or "auto") through rest to opt out.
The DOM carries both tui-toast and tui-notice classes, so Notice's
component API tokens (--tui-notice-bg, --tui-notice-padding, …) can be
re-pointed per toast context: .tui-toast { --tui-notice-bg: …; }.
import { Toast, ToastProvider, useToast } from '@tangible/ui';
Interactive docs and examples: Toast in Storybook.
Toast props
| Prop | Type | Default | Description |
|---|---|---|---|
actions? |
React.ReactNode |
Action content (e.g. a Button), rendered in the foot. | |
announce? |
"assertive" | "polite" |
Screen-reader announcement politeness. Defaults to 'assertive' (role="alert") for danger, 'polite' (role="status") otherwise. | |
children? |
React.ReactNode |
Body/description content. | |
className? |
string |
||
dismissible? |
boolean |
true |
Renders a dismiss (×) button. Default true. |
dismissLabel? |
string |
Accessible label for the dismiss button. Default 'Dismiss'. | |
focusable? |
boolean |
Makes the toast root programmatically focusable (tabIndex -1, with a focus ring) — Notice's focusable, forwarded. ToastProvider sets it on every queued toast: the root is the focus target when a same-id replacement unmounts an instance that held focus. |
|
icon? |
React.ReactNode |
Icon content, rendered leading the text. Colored by theme via Notice. | |
onDismiss? |
() => void |
Called after the exit animation completes (× button path). | |
size? |
"lg" | "md" | "sm" |
'sm' |
Density preset (Notice's size scale). Default 'sm' — toasts are dense; 'md'/'lg' restore Notice's roomier panel spacing. |
style? |
React.CSSProperties |
||
theme? |
"danger" | "info" | "neutral" | "success" | "warning" |
'neutral' |
Visual intent. Default 'neutral' — the plain dark surface. |
title? |
React.ReactNode |
Title text — a styled <div>, never a heading: a toast lives in a portal outside the document outline, so a heading would be an orphan for screen-reader heading navigation. |
Also accepts the standard attributes of HTMLAttributes (data-*, aria-*, event handlers), passed to the element it renders.
ToastProvider props
| Prop | Type | Default | Description |
|---|---|---|---|
children? |
React.ReactNode |
||
container? |
Element | null |
Optional portal target (mirrors Modal). Defaults to the portal root of the nearest .tui-interface. |
|
duration? |
number |
5000 |
Default auto-dismiss delay in ms. Default 5000. |
max? |
number |
5 |
Most toasts the stack shows at once — older ones are dismissed to make room. Default 5; pass Infinity to disable. |
placement? |
"bottom" | "bottom-end" | "bottom-start" | "top" | "top-end" | "top-start" |
'bottom-end' |
Where the toast stack anchors. Default 'bottom-end'. |
regionLabel? |
string |
'Notifications' |
Accessible name for the toast region landmark. Default 'Notifications'. If a page hosts multiple providers (e.g. several independent .tui-interface widgets), give each a unique label — duplicate region landmark names are ambiguous for AT users. |
Hooks
useToast
useToast(): ToastContextValue
Returns:
| Member | Type | Description |
|---|---|---|
toast |
(options?: ToastOptions) => string |
Show a toast. Returns its id. |
dismiss |
(id: string) => void |
Dismiss one toast by id (plays its exit animation). |
dismissAll |
() => void |
Dismiss all toasts. |
ToastOptions (the options of toast):
| Member | Type | Description |
|---|---|---|
size? |
"lg" | "md" | "sm" |
Density preset (Notice's size scale). Default 'sm' — toasts are dense; 'md'/'lg' restore Notice's roomier panel spacing. |
className? |
string |
|
style? |
React.CSSProperties |
|
title? |
React.ReactNode |
Title text — a styled <div>, never a heading: a toast lives in a portal outside the document outline, so a heading would be an orphan for screen-reader heading navigation. |
theme? |
"danger" | "info" | "neutral" | "success" | "warning" |
Visual intent. Default 'neutral' — the plain dark surface. |
icon? |
React.ReactNode |
Icon content, rendered leading the text. Colored by theme via Notice. |
announce? |
"assertive" | "polite" |
Screen-reader announcement politeness. Defaults to 'assertive' (role="alert") for danger, 'polite' (role="status") otherwise. |
dismissible? |
boolean |
Renders a dismiss (×) button. Default true. |
onDismiss? |
() => void |
Called after the exit animation completes (× button path). |
dismissLabel? |
string |
Accessible label for the dismiss button. Default 'Dismiss'. |
actions? |
React.ReactNode |
Action content (e.g. a Button), rendered in the foot. |
id? |
string |
Stable id. Calling toast() again with the same id updates that toast in place (remounting it, so it re-animates and re-announces) and restarts its timer. Omit for a generated id. |
description? |
React.ReactNode |
Body content — maps to the presentational <Toast>'s children. |
duration? |
number | null |
Auto-dismiss delay in ms. null persists until dismissed. Defaults to the provider's duration — unless the toast has actions, in which case it persists (the user needs time to act; WCAG 2.2.1). |
data-testid? |
string |
Playwright hook — lands on the toast root, per house testid policy. |
Examples
-
Placements: One provider per placement for demo purposes — a real app renders a single provider (and if it genuinely needs several, each must get a unique
regionLabel). Default isbottom-end. -
Update By Id: Calling
toast()again with the sameidreplaces that toast (it remounts, so it re-animates and re-announces) and restarts its timer — safe even if the first toast is already animating out.
Other stories: Static, Static Themes, Static With Actions, Basic, One-Liner (Self-Dismissing), Themes, With Actions, Persistent And Dismiss All (interactive page).
Component API tokens
Read via fallback, never declared. Set one on an ancestor to restyle every instance under it.
--tui-toast-width--tui-toast-fg--tui-toast-gap--tui-toast-inset--tui-toast-shadow--tui-toast-z