Toast
A short notification about something that just happened: a save, a send, a failure. It shows in the page’s Toaster, which announces it, times it and dismisses it.
import { Toast } from '@zitdevs/ui'; // a toast the server rendersimport { toast } from '@zitdevs/ui/enhance'; // a toast raised from anywhereExamples
Section titled “Examples”Raise a toast
Section titled “Raise a toast”Each button calls toast() with its tone. This page renders a Toaster and enhances it with
enhanceToaster(document), as a site without React does. The danger toast stays until you dismiss
it; the others leave after five seconds, and wait while the pointer or the focus is on them.
Title
Description
Title
Description
Title
Description
Title
Description
import { toast } from '@zitdevs/ui/enhance';
const id = toast({ tone: 'success', title: 'Changes saved', description: 'Your profile is up to date.',});toast.dismiss(id);
// One id, two moments: the second toast takes the first one's place.toast({ id: 'upload', title: 'Uploading…', duration: Infinity });toast({ id: 'upload', tone: 'success', title: 'Uploaded' });
toast({ title: 'Message archived', action: { label: 'Undo', onClick: () => restore() },});toast() works the same from a React component, an Astro page script or any other script: it
dispatches a zd:toast event on the document, and a call made before the toaster has started waits
for it. It needs no provider and no hook.
These are static previews; the toasts above are the real thing.
Draft saved
You can come back to it any time.
Changes saved
Your profile is up to date.
Storage almost full
92% of your plan is in use.
Payment failed
The card was declined.
With an action, and without a dismiss button
Section titled “With an action, and without a dismiss button”Uploading 3 files…
<Toast title="Message archived" action={ <Button asChild label="Undo" variant="link" size="sm"> <Link href="/inbox?undo=1" /> </Button> }/>Toast, for a toast the server renders inside a Toaster:
| Prop | Type | Default | Notes |
|---|---|---|---|
tone |
'info' | 'success' | 'warning' | 'danger' |
'info' |
The icon and its tile. danger interrupts, and stays until it is dismissed. |
title |
string |
— | What happened, in a few words. |
description |
string |
— | What it means or what happens next. |
action |
ReactNode |
— | One thing to do about it, under the description: a link Button, size="sm". |
dismissible |
boolean |
true |
The dismiss button, and Escape. |
duration |
number |
toaster’s | Milliseconds it stays once enhanced; Infinity keeps it. |
labels |
Partial<ToastLabels> |
English | { dismiss }. es.toast from @zitdevs/ui/labels/es. |
id |
string |
— | Lets toast.dismiss(id) reach a toast the server rendered. |
ref |
Ref<HTMLDivElement> |
— | The toast. |
| anything else | <div> attributes |
— | Except role: the toaster’s regions announce it. |
toast(options) from @zitdevs/ui/enhance, which returns the toast’s id:
| Option | Type | Default | Notes |
|---|---|---|---|
title |
string |
— | A toast with neither a title nor a description is not shown. |
description |
string |
— | |
tone |
ToastTone |
'info' |
|
duration |
number |
5000 |
Milliseconds; Infinity keeps it. Ignored by danger, which stays until dismissed. |
dismissible |
boolean |
true |
|
action |
{ label: string; onClick(event): void } |
— | The toast leaves after the click unless onClick calls event.preventDefault(). |
id |
string |
made up | Dismisses it later, or replaces the toast already shown under it. |
onDismiss |
(id: string) => void |
— | Called once it has left, however it went. |
toast.dismiss(id) dismisses one toast; toast.dismiss() every one. Exported types: ToastProps,
ToastTone, ToastLabels; from @zitdevs/ui/enhance: toast, TOAST_EVENT, ToastOptions,
ToastAction, ToastRequest, ToastTone.
Accessibility
Section titled “Accessibility”- Announced once, in its turn. Info, success and warning go to the toaster’s polite live
region (
role="status"); danger to its assertive one (role="alert"). Both regions are on the page, empty, from the first paint, so assistive technology has met them before anything arrives. - Timed so it can be read. A toast leaves after five seconds by default, and every timer stops
while the pointer is over the toasts, while focus is inside them, and while the page is hidden.
Danger toasts stay until they are dismissed (WCAG 2.2.1). A toast whose action matters, such
as “Undo”, is better kept with
duration: Infinity. - Dismissed without losing your place. Its dismiss button, or Escape on a focused toast, removes it, and focus moves to the next toast or back to where it was before it entered them — never to the top of the page.
- Never the only place it is said. A toast reports what the page already shows; a failure the reader must act on also belongs next to its cause, as a field’s error or an Alert.
- At most three show at once. The oldest leaves first, and an error last.
- The title is set in ink and the description in muted text, both at 4.5:1 or more on the raised card. The tone is in the icon and the words, never the colour alone.
- It fades in over 200ms with a 4px rise, and out over 140ms; neither moves under reduced motion.
Without JavaScript
Section titled “Without JavaScript”A toast the server renders inside a Toaster — the flash message of
the page a form’s POST returns — shows with no script at all, and stays: there is nothing to time it.
Its dismiss button waits out of sight until the toaster is enhanced, since it would do nothing
before. Once the page’s script runs enhanceToaster(document) (React does it on hydration), the
flash message is announced, timed and dismissible like any other. toast() needs the script.
Theming
Section titled “Theming”surface-raised, border-subtle, ink, muted, and for the tiles info, info-soft,
success, success-soft, warning, warning-soft, danger, danger-soft; shadow-lg. The
glyphs reach 3:1 on their tiles except warning’s, at 2.99:1, which only decorates: the title says it.
Use instead: a message that must stay with the form it is about → Alert; a decision the reader must make before going on → Dialog.