Toast
A hand-drawn transient notification that floats and auto-dismisses.
Overview
A Toast is a brief, transient notification that floats above the page (bottom-right) and
auto-dismisses. Use it for confirmations and low-priority feedback; for persistent, in-layout status
use an Alert.
Anatomy
A sketchy, elevated box (@ghds/sketch-core) fixed to the bottom-right, with a severity icon, an
optional title, a message, and a dismiss button. It auto-dismisses after duration (ms; 0 to
persist). Controlled via open/onClose; render several to stack them.
Variants & States
| State | Status | Notes |
|---|---|---|
| Info / Success / Warning / Danger | Implemented | Severity colour + icon. |
| Auto-dismiss | Implemented | Closes after duration (default 5000ms); 0 persists. |
| Manual dismiss | Implemented | Always has a close button. |
Usage
Do
- Keep messages short — a toast is glanceable.
- Use danger toasts sparingly; consider an inline Alert for errors that need action.
- Own the open state and clear it in onClose.
Don't
- Don't put essential actions only in a toast — it disappears.
- Don't show many toasts at once; queue them.
Accessibility
- All platforms:
dangertoasts userole="alert"(assertive); the restrole="status"(polite) / anaria-liveregion, so they are announced without stealing focus. A labelled “Dismiss” button is always present. - React Native: rendered in a transparent
ModalwithpointerEvents="box-none"so taps outside the toast pass through. - See the Accessibility Guide.
Content
A short message and optional title. The auto-dismiss default is 5000ms (a behavioural timing, not a
motion token); pass duration={0} to keep it until dismissed.
Props API
React@ghds/react
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Whether the toast is shown. |
onClose | () => void | — | Called on auto-dismiss or close button. |
variant | 'info' | 'success' | 'warning' | 'danger' | 'info' | Severity. |
title | ReactNode | — | Optional bold title. |
children | ReactNode | — | Message body. |
duration | number | 5000 | Auto-dismiss ms; 0 to persist. |
Web Components@ghds/web-components
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Whether the toast is shown (reflected). |
variant | 'info' | 'success' | 'warning' | 'danger' | 'info' | Severity (reflected). |
heading | string | — | Optional bold title. |
duration | number | 5000 | Auto-dismiss ms; 0 to persist. |
close event | CustomEvent | — | Dispatched on auto-dismiss / close. |
React Native@ghds/react-native
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Whether the toast is shown. |
onClose | () => void | — | Called on auto-dismiss or close button. |
variant | 'info' | 'success' | 'warning' | 'danger' | 'info' | Severity. |
title | string | — | Optional bold title. |
children | ReactNode | — | Message body. |
duration | number | 5000 | Auto-dismiss ms; 0 to persist. |
testID | string | — | Test handle for queries. |
Code examples
// React — @ghds/react (imperative toast() + a Toaster viewport)
import { Toaster, toast } from '@ghds/react/toast';
// Mount the viewport once, high in the tree:
<Toaster position="bottom-right" />;
// Then trigger toasts imperatively:
toast.success('Your changes have been saved.', { title: 'Saved' });
<!-- Web Components — @ghds/web-components -->
<script type="module">
import '@ghds/web-components/toast';
</script>
<gh-toast id="my-toast" variant="success" heading="Saved" duration="0">
Your changes have been saved.
</gh-toast>
<script>
const el = document.getElementById('my-toast');
el.open = true;
el.addEventListener('close', () => { el.open = false; });
</script>
// React Native — @ghds/react-native
import { Toast } from '@ghds/react-native/toast';
<Toast open={open} onClose={() => setOpen(false)} variant="success" title="Saved">
Your changes have been saved.
</Toast>;