Default
Settings saved
Show the codeHide the code
Default, code
<Toast title="Settings saved" onDismiss={() => {}} />A short, non-blocking message. Persistent until dismissed; announced politely; never takes focus.
These are the real React components. Use them with a mouse, touch or keyboard, and switch the theme and density for every example at once.
Settings saved
Default, code
<Toast title="Settings saved" onDismiss={() => {}} />Success: Settings saved
Information: Invite sent to sam@northwind.co.uk
They have 7 days to accept.
Error: Could not save
Check your connection and try again.
Member removed
Tones, code
<div className="flex flex-col gap-gap-md">
<Toast title="Settings saved" tone="success" onDismiss={() => {}} />
<Toast title="Invite sent to sam@northwind.co.uk" tone="info" description="They have 7 days to accept." onDismiss={() => {}} />
<Toast title="Could not save" tone="danger" description="Check your connection and try again." onDismiss={() => {}} />
<Toast title="Member removed" action={{ label: 'Undo', onAction: () => {} }} onDismiss={() => {}} />
</div>With toaster, code
const demoQueue = new ToastQueue({ maxVisible: 3 });
function Example() {
useEffect(() => () => demoQueue.clear(), []);
return (
<div>
<Button onPress={() => demoQueue.add({ title: 'Settings saved', tone: 'success' })}>Save changes</Button>
<Toaster queue={demoQueue} />
</div>
);
}Error: Could not save
Check your connection and try again.
Collapsed stack, code
function Example() {
const [queue] = useState(() => {
const q = new ToastQueue({ maxVisible: 3 });
q.add({ title: 'File uploaded', tone: 'success' });
q.add({ title: 'Invite sent to sam@northwind.co.uk', tone: 'info' });
q.add({ title: 'Could not save', tone: 'danger', description: 'Check your connection and try again.' });
return q;
});
return <Toaster queue={queue} stack="collapsed" />;
}The 16 design tokens Toast reads, with the value each has in the theme and density chosen above. Change a token and the component follows, in Figma and in code.
| Token | Value now | CSS variable |
|---|---|---|
| color.icon.danger | … | --sd-color-icon-danger |
| color.icon.info | … | --sd-color-icon-info |
| color.icon.success | … | --sd-color-icon-success |
| elevation.1 | … | --sd-elevation-1 |
| elevation.2 | … | --sd-elevation-2 |
| layer.toast | … | --sd-layer-toast |
| spacing.gap.md | … | --sd-spacing-gap-md |
| spacing.gap.sm | … | --sd-spacing-gap-sm |
| spacing.stack.xs | … | --sd-spacing-stack-xs |
| toast.bg | … | --sd-toast-bg |
| toast.border | … | --sd-toast-border |
| toast.fg | … | --sd-toast-fg |
| toast.fg-secondary | … | --sd-toast-fg-secondary |
| toast.gap | … | --sd-toast-gap |
| toast.padding | … | --sd-toast-padding |
| toast.radius | … | --sd-toast-radius |
The npm package isn’t published yet. When it is, this is the install line; until then, this page runs the same build of the package (from commit fa3abf8).
Install
npm i @superduperui/react @superduperui/tokensImport
import { Toast, Toaster, toast, toastQueue, ToastQueue } from "@superduperui/react"Toast also takes the props of the React Aria component it’s built on.
| Prop | Type | What it does |
|---|---|---|
titlerequired | string | |
description | string | |
tone | ToastToneDefault 'neutral' | |
action | { label: string; onAction: () => void } | |
icon | LucideIcon | null | Status icon. Defaults to the tone's icon (success: CircleCheck, danger: CircleAlert, info: Info; neutral: none). Pass null for no icon. |
onDismiss | () => void | Called by the dismiss button. Omit to render without one (static previews only). |
Screen readers announce Polite: "Success: Settings saved".
WCAG 2.2 AAA criteria the component meets in Comfortable density: 1.4.6, 1.4.9, 2.1.3, 2.3.2, 2.4.13, 2.5.5, 2.5.6, 2.3.3.
Compact density meets AA (2.5.8, 24px targets), not AAA.
Shared patterns it ships with: 2.2.3 (persistent by default); 2.2.4 (pause notifications pattern); 2.4.12 (publishes its height as scroll padding).
| axe-core (WCAG A, AA, AAA and best practice) | 100 runs across every story, theme, density and width: 0 violations |
|---|---|
| Rendered text contrast | 160 text runs: 0 below 7:1, lowest 11.42:1 |
| Target size | 38 targets: 0 under 44px in Comfortable |
| Focus appearance (2.4.13) | 108 focus stops in 3 browser engines: all pass |
| Keyboard script | Chromium 5 of 5, Firefox 5 of 5, WebKit 5 of 5 |
Manual passes with VoiceOver and NVDA haven’t been done yet.
Each step is scripted and run in Chromium, Firefox and WebKit.
| Key | What happens |
|---|---|
| Tab | Tab reaches the button |
| Enter | The toast appears and is announced politely; focus stays where it was |
| F6 | F6 moves focus to the notifications region |
| Tab | Tab reaches the dismiss button |
| Enter | Enter dismisses; focus goes back to where the user came from |
The Figma component is Toast, with Tone (Neutral, Success, Danger, Info). The Figma library isn’t published yet.
Figma to code: Tone → tone (Neutral = "neutral", Success = "success", Danger = "danger", Info = "info"); Title → title; Description → description when Show description; Status icon → icon when Custom icon; Show dismiss → onDismiss; nested Action → action.label.