VayuUI

Toaster

A notification component with imperative API, stacked animations, and custom toast support using compound components.

Installation

npx vayu-ui-cli@latest add toaster

Usage

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-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.

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 reference

Props

ToastProvider

PropTypeDefaultDescription
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.

useToast() Methods

MethodArgumentsReturnsDescription
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.

ToastOptions

OptionTypeDefaultDescription
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.

Toast.Title

PropTypeDefaultDescription
childrenReactNode—Title content.
classNamestring—Additional CSS classes.

Toast.Description

PropTypeDefaultDescription
childrenReactNode—Description content.
classNamestring—Additional CSS classes.

Toast.Close

PropTypeDefaultDescription
onClick() => void—Click handler for dismiss.
aria-labelstring"Dismiss notification"Accessibility label.
classNamestring—Additional CSS classes.

On this page