Toaster
A notification component with imperative API, stacked animations, and custom toast support using compound components.
Installation
npx vayu-ui-cli@latest add toasterUsage
Wrap your app with ToastProvider, then use the useToast hook anywhere to trigger toasts.
Standard Variants
With Actions
Promise & Loading
Duration Control
Positions
Stack Test
Custom Toast (Compound)
Non-Dismissible
With Custom Icon
Anatomy
import { ToastProvider, useToast, Toast } from 'vayu-ui';
{/* Provider — renders the portal and stack */}
<ToastProvider defaultPosition="bottom-right" defaultDuration={5000}>
<App />
</ToastProvider>
{/* Hook — imperative API */}
const toast = useToast();
toast.success('Message', { description: 'Details' });
toast.error('Message', { action: { label: 'Retry', onClick: handleRetry } });
toast.promise(promise, { loading: '...', success: '...', error: '...' });
toast.custom(<Toast.Title>Custom</Toast.Title>);
{/* Compound sub-components for custom toasts */}
<Toast.Title>Title</Toast.Title>
<Toast.Description>Description</Toast.Description>
<Toast.Close />- ToastProvider — Context provider that renders the toast portal and manages state. Wrap your app once at the root.
- useToast() — Hook returning imperative methods:
success,error,warning,info,loading,promise,custom,updateToast,removeToast. - Toast.Title — Title text for custom toast content.
- Toast.Description — Body text for custom toast content.
- Toast.Close — Dismiss button for custom toast content.
Accessibility
- Keyboard Support:
Escape— Dismiss the first dismissible toast in the stack.Tab— Move focus between toasts and interactive elements (action buttons, close buttons).Enter/Space— Activate the focused action button or expand the stack via the "+N more" badge.
- ARIA Attributes:
role="status"on success, info, and loading toasts.role="alert"on error and warning toasts.aria-live="polite"for non-critical notifications;aria-live="assertive"for critical ones.aria-atomic="true"ensures the full toast content is announced as a unit.aria-labelon close buttons (e.g. "Dismiss success notification") and notification regions.role="progressbar"on the countdown bar witharia-valueminandaria-valuemax.- All icons are marked
aria-hidden="true".
- Focus Behavior:
- Individual toasts are focusable (
tabIndex={0}) with visible focus rings. - Hovering or focusing the stack pauses all toast timers and expands collapsed toasts.
- Focus-visible rings on action buttons, close buttons, and the "+N more" badge.
- Individual toasts are focusable (
Screen reader behavior
When a toast appears, the screen reader announces it based on its type. Success and info toasts use a polite live region (role="status"), so they are announced after the current speech finishes. Error and warning toasts use an assertive live region (role="alert"), interrupting the current speech immediately. The toast content is announced atomically — the type label (e.g. "Success notification"), followed by the title and description. Action buttons are announced as interactive elements. When a toast is dismissed, the removal is communicated via the live region. The close button is labeled descriptively (e.g. "Dismiss error notification"). The countdown progress bar uses role="progressbar" to indicate time remaining before auto-dismiss.
Component Folder Structure
Toaster/
├── index.ts # Re-exports all components, hook, and types
├── types.ts # TypeScript type definitions
├── constants.ts # Style maps, position classes, layout constants
├── ToastProvider.tsx # Context provider with state management and imperative API
├── ToastContainer.tsx # Portal root and position-based toast grouping
├── ToastStack.tsx # Sonner-style stack with expand/collapse and animations
├── ToastItem.tsx # Individual toast with timer, swipe-to-dismiss, and progress bar
├── ToastUtilities.tsx # Compound sub-components (Title, Description, Close)
├── ToastIcons.tsx # Inline SVG icons for each toast type
└── README.md # Component usage referenceProps
ToastProvider
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | App content wrapped by the provider. |
defaultPosition | ToastPosition | "bottom-right" | Default position for all toasts. |
maxToasts | number | 5 | Maximum number of toasts visible at once. |
defaultDuration | number | 5000 | Default auto-dismiss duration in ms. |
useToast() Methods
| Method | Arguments | Returns | Description |
|---|---|---|---|
toast.success | (message, options?) | string | Shows a success toast. Returns toast ID. |
toast.error | (message, options?) | string | Shows an error toast. Returns toast ID. |
toast.warning | (message, options?) | string | Shows a warning toast. Returns toast ID. |
toast.info | (message, options?) | string | Shows an info toast. Returns toast ID. |
toast.loading | (message, options?) | string | Shows a loading toast (no auto-dismiss). |
toast.promise | (promise, messages, options?) | Promise<T> | Handles loading/success/error states for a promise. |
toast.custom | (content, options?) | string | Renders custom JSX content in a toast. |
toast.updateToast | (id, options) | void | Updates an existing toast by ID. |
toast.removeToast | (id) | void | Removes a toast by ID. |
ToastOptions
| Option | Type | Default | Description |
|---|---|---|---|
title | ReactNode | — | Primary heading text. |
description | ReactNode | — | Secondary body text. |
duration | number | 5000 | Duration in ms before auto-dismiss. Set to 0 for persistent toasts. |
position | ToastPosition | — | Position override for this toast. |
action | { label: ReactNode, onClick: () => void } | — | Optional action button inside the toast. |
dismissible | boolean | true | Whether the close button is visible. |
icon | ReactNode | — | Custom icon to replace the default type icon. |
customContent | ReactNode | — | Custom content rendering (used by toast.custom). |
onClose | () => void | — | Callback when the toast is dismissed. |
Toast.Title
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Title content. |
className | string | — | Additional CSS classes. |
Toast.Description
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Description content. |
className | string | — | Additional CSS classes. |
Toast.Close
| Prop | Type | Default | Description |
|---|---|---|---|
onClick | () => void | — | Click handler for dismiss. |
aria-label | string | "Dismiss notification" | Accessibility label. |
className | string | — | Additional CSS classes. |