Toaster A notification component with imperative API, stacked animations, and custom toast support using compound components.
npx vayu-ui-cli@latest add toaster
Wrap your app with ToastProvider, then use the useToast hook anywhere to trigger toasts.
Preview Code
Standard Variants Success Error Warning Info
With Actions With Action With View Action
Promise & Loading Promise (Success) Promise (Error) Manual Loading
Duration Control 2 Second 10 Second Persistent
Positions Top Left Top Center Top Right Bottom Left Bottom Center Bottom Right
Stack Test Add 5 Toasts
Custom Toast (Compound) Show Custom Toast
Non-Dismissible Non-Dismissible
With Custom Icon Custom Icon
{ /* Setup: add ToastProvider to your root layout */ }
< ToastProvider >
< App />
</ ToastProvider >
{ /* Trigger toasts from any component */ }
function Page () {
const toast = useToast ();
return (
< Button onClick = {() => toast. success ( 'Saved' , { description: 'Changes applied.' })}>
Save
</ Button >
);
}
{ /* Promise-based toasts */ }
await toast. promise ( fetchData (), {
loading: 'Fetching...' ,
success: 'Data loaded!' ,
error: 'Fetch failed' ,
});
{ /* Custom content with compound components */ }
toast. custom (
< div className = "flex items-start gap-3" >
< Toast.Title >Update available</ Toast.Title >
< Toast.Description >A new version is ready.</ Toast.Description >
< Toast.Close onClick = {() => toast. removeToast (id)} />
</ div >,
);
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.
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-label on close buttons (e.g. "Dismiss success notification") and notification regions.
role="progressbar" on the countdown bar with aria-valuemin and aria-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.
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.
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 reference
Prop Type Default Description childrenReactNode— App content wrapped by the provider. defaultPositionToastPosition"bottom-right"Default position for all toasts. maxToastsnumber5Maximum number of toasts visible at once. defaultDurationnumber5000Default auto-dismiss duration in ms.
Method Arguments Returns Description toast.success(message, options?)stringShows a success toast. Returns toast ID. toast.error(message, options?)stringShows an error toast. Returns toast ID. toast.warning(message, options?)stringShows a warning toast. Returns toast ID. toast.info(message, options?)stringShows an info toast. Returns toast ID. toast.loading(message, options?)stringShows 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?)stringRenders custom JSX content in a toast. toast.updateToast(id, options)voidUpdates an existing toast by ID. toast.removeToast(id)voidRemoves a toast by ID.
Option Type Default Description titleReactNode— Primary heading text. descriptionReactNode— Secondary body text. durationnumber5000Duration in ms before auto-dismiss. Set to 0 for persistent toasts. positionToastPosition— Position override for this toast. action{ label: ReactNode, onClick: () => void }— Optional action button inside the toast. dismissiblebooleantrueWhether the close button is visible. iconReactNode— Custom icon to replace the default type icon. customContentReactNode— Custom content rendering (used by toast.custom). onClose() => void— Callback when the toast is dismissed.
Prop Type Default Description childrenReactNode— Title content. classNamestring— Additional CSS classes.
Prop Type Default Description childrenReactNode— Description content. classNamestring— Additional CSS classes.
Prop Type Default Description onClick() => void— Click handler for dismiss. aria-labelstring"Dismiss notification"Accessibility label. classNamestring— Additional CSS classes.