Experience System
Components

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

In 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 Dialog or 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

PropTypeDefault
idstringNo default value
invertbooleanNo default value
themelight | dark | systemNo default value
positionPositionbottom-right (logical; mirrored in RTL via ThemeProvider)
hotkeystring[]No default value
richColorsbooleanNo default value
expandbooleanNo default value
durationnumberNo default value
gapnumberNo default value
visibleToastsnumberNo default value
closeButtonbooleantrue (experience system default; upstream may differ)
toastOptionsToastOptionsMerged with Experience System classNames
classNamestringNo default value
styleReact.CSSPropertiesNo default value
offsetOffsetNo default value
mobileOffsetOffsetNo default value
dirrtl | ltr | autoFrom ThemeProvider (overridable)
swipeDirectionsSwipeDirection[]No default value
iconsToastIconsDesign-system defaults (success, info, warning, error)
containerAriaLabelstringNo default value
Data attributeValues
data-slotsonner-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

KeyDescription
EscDismisses the focused toast when supported by Sonner configuration.
FocusTab 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.