Tangible Design System · @tangible/ui 0.2.29 · Interactive version · Markdown

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

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.