Toast
Ephemeral notification that appears at a fixed screen position with semantic intents, auto-dismiss, stacking, and an optional close button. Consumers interact via ToastProvider + useToast() hook.
Overview
Toast notifications provide transient feedback after user actions. They
appear at a configurable screen position, stack when multiple are shown,
auto-dismiss after a configurable duration, and support four semantic
intents: success, warning, danger,
and info.
The API is context-based: wrap your app with <ToastProvider>
and call useToast() in any descendant component to show toasts.
import { ToastProvider, useToast } from '@enara-health/ui-react';
// 1. Wrap your app
const App = () => (
<ToastProvider position="bottom-right">
<MyPage />
</ToastProvider>
);
// 2. Use in any descendant
const MyPage = () => {
const { toast } = useToast();
return (
<button onClick={() => toast({ message: 'Saved!', intent: 'success' })}>
Save
</button>
);
}; Props
ToastProvider
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Required. Content to wrap with toast context |
position | 'top-left' | 'top-center' | 'top-right' | 'bottom-left' |
'bottom-center' | 'bottom-right' | 'bottom-right' | Screen position for the toast container |
max | number | 5 | Maximum number of visible toasts. Oldest evicted when exceeded. |
defaultDuration | number | 5000 | Default auto-dismiss duration in ms |
ToastOptions (passed to toast())
| Prop | Type | Default | Description |
|---|---|---|---|
message | string | — | Required. The notification text |
title | string | — | Optional heading displayed above the message |
intent | 'success' | 'warning' | 'danger' | 'info' | 'info' | Semantic intent controlling color and default icon |
duration | number | 5000 | Auto-dismiss delay in ms. 0 = persistent. |
closable | boolean | true | Whether the close button is shown |
icon | ReactNode | — | Custom icon overriding the default intent icon |
onDismiss | () => void | — | Callback fired when toast is removed |
useToast() return value
| Method | Signature | Description |
|---|---|---|
toast | (options: ToastOptions) => string | Show a toast. Returns the toast ID. |
dismiss | (id: string) => void | Dismiss a specific toast |
dismissAll | () => void | Dismiss all toasts |
Intents
Each intent applies a distinct border color, background tint, and default icon:
const { toast } = useToast();
// Success — positive confirmation
toast({ message: 'Patient record saved', intent: 'success' });
// Warning — something needs attention
toast({ message: 'Session expires in 5 minutes', intent: 'warning' });
// Danger — error or failure
toast({ message: 'Failed to save changes', intent: 'danger' });
// Info — neutral informational (default)
toast({ message: 'New version available', intent: 'info' }); Positions
Configure the position via the ToastProvider. Click each
button to see a toast appear at that position:
// Corner positions
<ToastProvider position="top-left">...</ToastProvider>
<ToastProvider position="top-right">...</ToastProvider>
<ToastProvider position="bottom-left">...</ToastProvider>
<ToastProvider position="bottom-right">...</ToastProvider>
// Center positions
<ToastProvider position="top-center">...</ToastProvider>
<ToastProvider position="bottom-center">...</ToastProvider>
Bottom positions use flex-direction: column-reverse so the newest
toast appears closest to the screen edge.
Examples
With Title
// Success with title
toast({
title: 'Success',
message: 'Your changes have been saved.',
intent: 'success',
});
// Error with title
toast({
title: 'Error',
message: 'Could not connect to server. Please try again.',
intent: 'danger',
}); Persistent Toast
// duration: 0 keeps toast until manually dismissed
const id = toast({
message: 'Uploading file... (persistent, no close button)',
duration: 0,
closable: false,
});
// 3 seconds later, auto-resolve:
dismiss(id);
toast({ message: 'Upload complete!', intent: 'success' }); With Callback
toast({
message: 'Record deleted',
intent: 'danger',
onDismiss: () => toast({ message: 'onDismiss callback fired!', intent: 'info' }),
}); Custom Max Toasts
// Only show 3 toasts at a time — oldest evicted automatically
<ToastProvider max={3}>
<App />
</ToastProvider> Anti-Patterns
- Using toast for confirmation dialogs — Toasts auto-dismiss
and lack action buttons. Use
Dialogfor decisions that require user action. - Using toast for form validation errors — Validation errors
should appear inline next to the relevant fields. Use
FormFieldwith theerrorprop. - Showing many toasts simultaneously — Stacking many toasts overwhelms users. Batch related notifications or use a notification center.
- Using useToast() without ToastProvider — The hook will throw.
Always wrap your app root with
<ToastProvider>.
Accessibility
- ARIA Live Region: Each toast uses
role="alert"witharia-live="polite". Danger intents usearia-live="assertive"for immediate screen reader announcement. - Close Button: The close button has
aria-label="Dismiss notification"and is focusable via keyboard. - Focus Ring: The close button displays a visible focus ring
on keyboard navigation via
:focus-visible. - Reduced Motion: Animations are disabled when
prefers-reduced-motion: reduceis set. - WCAG Compliance: Meets AA standards.