Sonner
Small, temporary UI message for brief, non-blocking notifications.
Installation
The component is exported from @by/experience-system ( Sonner + toast ). Add the package with your package manager:
pnpm add @by/experience-systemIn this monorepo, depend on the workspace package (for example via workspace:* or your catalog) so imports resolve to packages/experience-system.
Composition
Mount Sonner once. Invoke toast(...) from event handlers or effects:
Sonner (once, e.g. root layout)
toast() (imperative API)Usage
import { Sonner, toast, Button } from '@by/experience-system';Sonner is a client component ('use client' in the package). Place Sonner inside ThemeProvider so dir and logical position follow the Experience System direction context.
// e.g. app/layout.tsx (client boundary or layout that renders client children)
<Sonner /><Button type="button" onClick={() => toast.success('Saved')}>
Save
</Button>When to use
- Short, non-blocking confirmations, warnings, or errors that should not interrupt flow like a modal.
When not to use
- Critical decisions or long text—prefer
Dialogor a dedicated page. Do not rely on toasts alone for errors users must fix with complex steps.
Examples
Types
Default, success, info, warning, and error variants map to BY semantic surfaces and icons.
Description
Pass a description string (or node) in the toast options for secondary detail.
Position
Override placement per toast with the position option. The mounted Sonner still maps logical corners when ThemeProvider is RTL.
API Reference
Sonner forwards to Sonner’s Toaster with merged toastOptions ( unstyled: true + Experience System classNames ), default icons, and closeButton default true. dir and position follow ThemeProvider unless overridden. The tables below mirror upstream ToasterProps from sonner types; see the Sonner site for behavior details.
Sonner
| Prop | Type | Default |
|---|---|---|
id | string | No default value |
invert | boolean | No default value |
theme | light | dark | system | No default value |
position | Position | bottom-right (logical; mirrored in RTL via ThemeProvider) |
hotkey | string[] | No default value |
richColors | boolean | No default value |
expand | boolean | No default value |
duration | number | No default value |
gap | number | No default value |
visibleToasts | number | No default value |
closeButton | boolean | true (experience system default; upstream may differ) |
toastOptions | ToastOptions | Merged with Experience System classNames |
className | string | No default value |
style | React.CSSProperties | No default value |
offset | Offset | No default value |
mobileOffset | Offset | No default value |
dir | rtl | ltr | auto | From ThemeProvider (overridable) |
swipeDirections | SwipeDirection[] | No default value |
icons | ToastIcons | Design-system defaults (success, info, warning, error) |
containerAriaLabel | string | No default value |
| Data attribute | Values |
|---|---|
data-slot | sonner-toaster |
toast
Re-exported from sonner. Call toast(message, options?) or toast.success, toast.info, toast.warning, toast.error, toast.loading, toast.promise, toast.message, toast.custom, toast.dismiss, toast.getHistory, toast.getToasts. Options include description, duration, action, cancel, position, onDismiss, onAutoClose, id, classNames, and more—see Sonner toast options.
Accessibility
Toasts are generally announced as status or alert live regions by the library; keep titles concise and put detail in description. Ensure closeButton (or swipe-dismiss) is available when content is non-trivial. Prefer toast.error for failures that need attention, and avoid using toast as the only channel for mandatory reading.
Keyboard interactions
| Key | Description |
|---|---|
Esc | Dismisses the focused toast when supported by Sonner configuration. |
| Focus | Tab moves focus into toast actions when present; keep action controls small in number. |
Source in the repo: packages/experience-system/src/components/Sonner/Sonner.tsx. Agent-oriented contracts: packages/experience-system/src/components/Sonner/Sonner.instructions.md.