GitHub
Core
Glass
Brutal
Humanist

Toast

Toasts display brief, non-blocking notifications that appear temporarily and dismiss automatically or by user action.

Toast Playground

Toast Playground
Preview
Code
Trigger Position:
Controls
State:
Default
Success
Error
Warning
Highlight
Style:
Simple
Expressive
Size:
Small
Default
Icon:
Dismissible:
Action Button:
Description:

Installation

You can add the toast component to your project manually:

1

Install the following dependencies:

npm install class-variance-authority clsx tailwind-merge @phosphor-icons/react @react-aria/button @react-aria/focus @react-aria/interactions
2

Copy and paste the following code into your project.

Loading source code...
3

Update the import paths to match your project setup.

Update the import aliases (e.g. @/components, @/utils) in the copied files to match your project's path configuration.

Basic Usage

Wrap your application (or subtree) with ToastProvider and place ToastViewport where notifications should render:

import { ToastProvider, ToastViewport, useToast } from '@versaui/ui/components/Toast';
import { Button } from '@versaui/ui/components/Button';

// 1. Wrap your app with ToastProvider and place ToastViewport
function App() {
  return (
    <ToastProvider maxToasts={3} position="bottom-right">
      <YourContent />
      <ToastViewport />
    </ToastProvider>
  );
}

// 2. Dispatch toasts with useToast hook
function MyComponent() {
  const { addToast } = useToast();

  return (
    <Button
      onClick={() =>
        addToast({
          state: 'success',
          title: 'Saved successfully',
          description: 'Your changes have been saved to the cloud.',
        })
      }
    >
      Save Changes
    </Button>
  );
}

Convenience Actions Hook (useToastActions)

You can also use useToastActions for shorthand state methods:

import { useToastActions } from '@versaui/ui/components/Toast';

function MyComponent() {
  const { toast, success, error, warning, highlight } = useToastActions();

  return (
    <div className="flex gap-2">
      <button onClick={() => toast('General notification')}>Default</button>
      <button onClick={() => success('Profile updated!')}>Success</button>
      <button onClick={() => error('Payment failed.')}>Error</button>
      <button onClick={() => warning('Low disk space.')}>Warning</button>
      <button onClick={() => highlight('New version released!')}>Highlight</button>
    </div>
  );
}

States

Five semantic states are available — default, highlight, success, error, and warning:

const { addToast } = useToast();

addToast({ state: 'default', title: 'General notification' });
addToast({ state: 'highlight', title: 'New feature available' });
addToast({ state: 'success', title: 'Action successful' });
addToast({ state: 'error', title: 'Something went wrong' });
addToast({ state: 'warning', title: 'Caution required' });

Styles

Two visual style treatments are supported — simple (solid surface) and expressive (subtle gradient surface with inner highlight):

// Simple style (default)
addToast({
  state: 'success',
  style: 'simple',
  title: 'Action completed',
  description: 'Everything is up to date.',
});

// Expressive style
addToast({
  state: 'highlight',
  style: 'expressive',
  title: 'New feature unlocked',
  description: 'Experience enhanced performance and workflow speed.',
});

Sizes

Two container size variants are available — default (520px max width) and small (480px max width):

// Default size
addToast({
  title: 'Standard notification',
  size: 'default',
});

// Small size
addToast({
  title: 'Compact notification',
  size: 'small',
});

Positions

Toasts can be positioned anywhere on the screen across 6 supported positions:

addToast({
  title: 'Notification at Top Center',
  position: 'top',
});

addToast({
  title: 'Notification at Bottom Right',
  position: 'bottom-right',
});

Supported positions:

  • top-left
  • top (center)
  • top-right
  • bottom-left
  • bottom (center)
  • bottom-right (default)

Standalone Toast

You can also render the Toast component standalone in your layout without the viewport/context:

import { Toast } from '@versaui/ui/components/Toast';

<Toast
  state="success"
  style="expressive"
  title="Changes saved!"
  description="All settings have been synchronized."
  onButtonClick={() => console.log('Undo clicked')}
  onClose={() => console.log('Dismissed')}
/>

Auto-Dismiss & Duration

Set duration to control auto-dismiss timing in milliseconds. Set to 0 to keep the toast visible until the user manually closes it:

// Auto-dismiss after 3 seconds
addToast({ title: 'Quick message', duration: 3000 });

// Persistent toast (stays until dismissed)
addToast({ title: 'Important alert', duration: 0 });

Accessibility

  • Uses role="status" and aria-live="polite" for non-disruptive screen reader announcements
  • Close button is keyboard accessible with Tab and Enter / Space
  • Action button uses standard focus rings and keyboard interaction
  • Viewport region uses role="region" and aria-label="Notifications"
  • Respects prefers-reduced-motion

Toast Props

PropTypeDefaultDescription
state'default' | 'highlight' | 'success' | 'error' | 'warning''default'Semantic state controlling color scheme and default icon.
style'simple' | 'expressive''simple'Visual style treatment: simple (solid surface) or expressive (gradient surface).
size'default' | 'small''default'Toast container size variant.
titleReactNode—Primary title text or element.
descriptionReactNode | boolean—Secondary description text, element, or boolean to toggle default description.
messagestring—Backward compatible message prop. Used as primary text if title is omitted.
iconboolean | ReactNodetrueState icon visibility or custom ReactNode icon.
defaultIconReactNode—Custom icon element for default state.
highlightIconReactNode—Custom icon element for highlight state.
errorIconReactNode—Custom icon element for error state.
successIconReactNode—Custom icon element for success state.
warningIconReactNode—Custom icon element for warning state.
buttonbooleantrueAction button visibility.
buttonTextstring—Action button label.
onButtonClick() => void—Called when action button is clicked.
dismissiblebooleantrueClose icon button visibility.
onClose() => void—Called when toast is dismissed.
durationnumber5000Auto-dismiss duration in milliseconds. Set to 0 to disable.
visiblebooleantrueControlled visibility state.
classNamestring''Additional CSS classes.

ToastProvider Props

PropTypeDefaultDescription
childrenReactNode—Application elements that have access to toast context.
maxToastsnumber3Maximum number of visible toasts in stacked collapsed view.
position'top-left' | 'top' | 'top-right' | 'bottom-left' | 'bottom' | 'bottom-right''bottom-right'Default screen position for toast viewports.

ToastViewport Props

PropTypeDefaultDescription
position'top-left' | 'top' | 'top-right' | 'bottom-left' | 'bottom' | 'bottom-right''bottom-right'Viewport screen position.
offsetnumber24Offset in pixels from top/bottom screen edge.
bottomOffsetnumber24Backward compatible bottom offset in pixels.
maxVisibleToastsnumber3Maximum visible toasts in stacked view.
expandOnHoverbooleantrueWhether hovering expands stacked toasts.
classNamestring''Additional CSS classes.

On this page