Toast
Stacked notifications driven by an imperative manager (add, update, close, promise): limit, timers that pause on hover/focus, keyboard access via F6, swipe to dismiss.
Installation
npx nuecrea-ui add toastUsage
'use client';
import { Button } from '@/components/ui/button';
import * as Toast from '@/components/ui/toast';
function Toasts() {
const { toasts } = Toast.useToastManager();
return toasts.map((t) => (
<Toast.Root key={t.id} toast={t}>
<Toast.Content>
<div className="flex min-w-0 flex-1 flex-col gap-1">
<Toast.Title />
<Toast.Description />
</div>
{t.actionProps ? <Toast.Action /> : null}
<Toast.Close>Dismiss</Toast.Close>
</Toast.Content>
</Toast.Root>
));
}
function Buttons() {
const manager = Toast.useToastManager();
return (
<div className="flex flex-wrap gap-2">
<Button
variant="outline"
onClick={() => manager.add({ title: 'Saved', description: 'Your changes were saved.' })}
>
Show toast
</Button>
<Button
variant="outline"
onClick={() =>
manager.add({
title: 'Upload failed',
description: 'The file is larger than 10 MB.',
type: 'error',
priority: 'high',
})
}
>
Show error
</Button>
<Button
variant="outline"
onClick={() =>
manager.add({
title: 'Message archived',
description: 'It was moved to Archive.',
type: 'info',
actionProps: { children: 'Undo', onClick: () => manager.add({ title: 'Restored' }) },
})
}
>
With action
</Button>
<Button
variant="outline"
onClick={() =>
manager.add({ title: 'Quick note', description: 'Gone in a second.', timeout: 1000 })
}
>
Short timeout
</Button>
<Button
variant="outline"
onClick={() =>
manager.promise(new Promise((resolve) => setTimeout(resolve, 800)), {
loading: { title: 'Uploading…', description: 'Please wait.' },
success: { title: 'Uploaded', description: 'report.pdf is ready.' },
error: { title: 'Upload failed' },
})
}
>
Promise
</Button>
</div>
);
}
export default function ToastStory() {
return (
<Toast.Provider timeout={60000}>
<main>
<Buttons />
</main>
<Toast.Portal>
<Toast.Viewport>
<Toasts />
</Toast.Viewport>
</Toast.Portal>
</Toast.Provider>
);
}API reference
Manager: React: Toast.useToastManager() / Toast.createToastManager(). Angular: inject(ToastManager) (provided by [libToastProvider] or app-wide). Same methods: toasts, add(options), update(id, options), close(id?), promise(promise, { loading, success, error }).
Toast.Provider
Provides the manager; configures limit and default timeout.
| Prop | Type | Default | Description |
|---|---|---|---|
limit | number | 3 | Toasts shown at once; older ones get data-limited. |
timeout | number | 5000 | Default auto-dismiss in ms (0 = never). |
Toast.Portal
Renders the viewport at the end of <body>. Renders <div>.
Toast.Viewport
The notifications region (polite live region). Hover/focus expands the stack and pauses timers; F6 focuses it. Renders <div> with role region.
| Data attribute | Present when |
|---|---|
data-expanded | hovered or keyboard-focused |
| CSS variable | Description |
|---|---|
--toast-frontmost-height | Height of the frontmost toast. |
Toast.Root
One toast (role=dialog, alertdialog for priority high). Swipe to dismiss; Escape closes when focused. Renders <div> with role dialog.
| Prop | Type | Default | Description |
|---|---|---|---|
toast | ToastObject | — | Required: the toast to render. |
swipeDirection | Direction | Direction[] | "['down', 'right']" | Directions that dismiss. |
| Data attribute | Present when |
|---|---|
data-expanded | the stack is expanded |
data-limited | over the limit (hidden, inert) |
data-swipe-direction | being/been swiped that way |
data-swiping | being dragged |
data-type | the toast has a type |
data-starting-style | animating in |
data-ending-style | animating out |
| CSS variable | Description |
|---|---|
--toast-index | Position in the stack |
--toast-offset-y | Distance from the front when expanded |
--toast-height | Natural height |
--toast-swipe-movement-x | Drag offset |
--toast-swipe-movement-y | Drag offset |
Toast.Content
The toast's content. Renders <div>.
| Data attribute | Present when |
|---|---|
data-behind | not the frontmost toast |
data-expanded | the stack is expanded |
Toast.Title
Renders the toast's title (or children). Renders <h2>.
| Data attribute | Present when |
|---|---|
data-type | the toast has a type |
Toast.Description
Renders the toast's description (or children). Renders <p>.
| Data attribute | Present when |
|---|---|
data-type | the toast has a type |
Toast.Action
Runs actionProps.onClick; label from actionProps.children. Renders <button>.
| Data attribute | Present when |
|---|---|
data-type | the toast has a type |
Toast.Close
Dismisses the toast. Renders <button>.
| Data attribute | Present when |
|---|---|
data-type | the toast has a type |
Keyboard
| Key | Action |
|---|---|
| F6 | Focus the toast region (from anywhere). |
| Tab | Move through toasts and their buttons. |
| Escape | Close the focused toast; focus moves to the next one. |
| Shift+Tab | From the region: return to where focus was. |