Toast
Toasts display brief, non-blocking notifications that appear temporarily and dismiss automatically or by user action.
Toast Playground
Installation
You can add the toast component to your project manually:
Install the following dependencies:
npm install class-variance-authority clsx tailwind-merge @phosphor-icons/react @react-aria/button @react-aria/focus @react-aria/interactionsCopy and paste the following code into your project.
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-lefttop(center)top-rightbottom-leftbottom(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"andaria-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"andaria-label="Notifications" - Respects
prefers-reduced-motion
Toast Props
| Prop | Type | Default | Description |
|---|---|---|---|
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. |
title | ReactNode | — | Primary title text or element. |
description | ReactNode | boolean | — | Secondary description text, element, or boolean to toggle default description. |
message | string | — | Backward compatible message prop. Used as primary text if title is omitted. |
icon | boolean | ReactNode | true | State icon visibility or custom ReactNode icon. |
defaultIcon | ReactNode | — | Custom icon element for default state. |
highlightIcon | ReactNode | — | Custom icon element for highlight state. |
errorIcon | ReactNode | — | Custom icon element for error state. |
successIcon | ReactNode | — | Custom icon element for success state. |
warningIcon | ReactNode | — | Custom icon element for warning state. |
button | boolean | true | Action button visibility. |
buttonText | string | — | Action button label. |
onButtonClick | () => void | — | Called when action button is clicked. |
dismissible | boolean | true | Close icon button visibility. |
onClose | () => void | — | Called when toast is dismissed. |
duration | number | 5000 | Auto-dismiss duration in milliseconds. Set to 0 to disable. |
visible | boolean | true | Controlled visibility state. |
className | string | '' | Additional CSS classes. |
ToastProvider Props
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Application elements that have access to toast context. |
maxToasts | number | 3 | Maximum 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
| Prop | Type | Default | Description |
|---|---|---|---|
position | 'top-left' | 'top' | 'top-right' | 'bottom-left' | 'bottom' | 'bottom-right' | 'bottom-right' | Viewport screen position. |
offset | number | 24 | Offset in pixels from top/bottom screen edge. |
bottomOffset | number | 24 | Backward compatible bottom offset in pixels. |
maxVisibleToasts | number | 3 | Maximum visible toasts in stacked view. |
expandOnHover | boolean | true | Whether hovering expands stacked toasts. |
className | string | '' | Additional CSS classes. |