Toast
Transient, non-blocking notifications fired imperatively from anywhere in the app.
Renders inside a polite aria-live region; error toasts use assertive; toasts never trap focus and never block interaction with the underlying page.
Preview
tsx
import { Button, Toaster, toast } from '@arshad-shah/cynosure-react';
export default function Example() {
return (
<>
<Button onClick={() => toast('Saved successfully')}>Show toast</Button>
<Toaster />
</>
);
}
Variants
Section titled “Variants”Semantic variants
Section titled “Semantic variants”Each variant has its own icon and color scheme — success, error, warning, info, plus the plain default.
Preview
tsx
import { Button, Toaster, toast } from '@arshad-shah/cynosure-react';
export default function Example() {
return (
<>
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.5rem' }}>
<Button variant="outline" onClick={() => toast('Plain message')}>
Default
</Button>
<Button variant="outline" onClick={() => toast.success('Changes saved')}>
Success
</Button>
<Button variant="outline" onClick={() => toast.error('Something went wrong')}>
Error
</Button>
<Button variant="outline" onClick={() => toast.warning('Disk usage is high')}>
Warning
</Button>
<Button variant="outline" onClick={() => toast.info('A new version is available')}>
Info
</Button>
</div>
<Toaster />
</>
);
}
With description
Section titled “With description”Pass a description for a second muted line under the title.
Preview
tsx
import { Button, Toaster, toast } from '@arshad-shah/cynosure-react';
export default function Example() {
return (
<>
<Button
onClick={() =>
toast.success('Invite sent', {
description: 'alex@cynosure.app will receive an email shortly.',
})
}
>
Send invite
</Button>
<Toaster />
</>
);
}
With action
Section titled “With action”Add an action for an undo-style affordance. The action button is keyboard-reachable inside the toast.
Preview
tsx
import { Button, Toaster, toast } from '@arshad-shah/cynosure-react';
export default function Example() {
return (
<>
<Button
onClick={() =>
toast('Moved to trash', {
description: 'The item was archived. You can restore it within 30 days.',
action: {
label: 'Undo',
onClick: () => toast.success('Restored'),
},
})
}
>
Delete item
</Button>
<Toaster />
</>
);
}
Position
Section titled “Position”Toaster accepts position="top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right" (default). Set it once at the root.
Preview
tsx
import { Button, Toaster, type ToasterPosition, toast } from '@arshad-shah/cynosure-react';
import { useState } from 'react';
const positions: ToasterPosition[] = [
'top-left',
'top-center',
'top-right',
'bottom-left',
'bottom-center',
'bottom-right',
];
export default function Example() {
const [position, setPosition] = useState<ToasterPosition>('bottom-right');
return (
<>
<div style={{ display: 'grid', gap: '0.75rem' }}>
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.5rem' }}>
{positions.map((value) => (
<Button
key={value}
size="sm"
variant={value === position ? 'solid' : 'outline'}
onClick={() => setPosition(value)}
>
{value}
</Button>
))}
</div>
<div>
<Button onClick={() => toast(`Shown at ${position}`)}>Show toast</Button>
</div>
</div>
<Toaster position={position} />
</>
);
}
PropTypeDefaultDescription
toastOptions
ToastOptions
—
Sonner `toastOptions`. Merged with Cynosure's token-derived class
names — consumer `classNames` are applied on top of the defaults, so
any key you set wins for that slot.
Accessibility
Section titled “Accessibility”- Toasts render inside an
aria-live="polite"region so screen readers announce them without interrupting the user. toast.erroris announced assertively so failures cut through other speech.- Toasts never trap focus — the rest of the page remains fully interactive.
- The optional close button (
closeButtonis on by default) is keyboard-reachable for users who want to dismiss before the timeout. - Keep titles short and descriptive — they are the first thing announced.
Recipes
Section titled “Recipes”- Render
<Toaster />exactly once, as high in the React tree as possible. - Use
toast.success/toast.errorfor status-specific styling and ARIA politeness rather than coloring a default toast manually. - Tune
durationper call for important messages:toast(msg, { duration: 8000 }). - Keep copy short — one line in the title, one in the description. Route long content to a
Dialog.