VESYL UI

Sonner

Toast notifications for transient feedback — “Label purchased”, “Shipment cancelled”, and the like. Built on sonner, pre-styled with rich colors, Halo status icons, and our theme tokens.

Two pieces: <Toaster />, the host that renders the stack, and toast(), the function you call to push a notification. The app mounts one <Toaster /> at the root (in WMS it lives in __root.tsx; these docs do the same in the layout), then any component calls toast() — no context, no provider wiring at the call site.

Do not mount a Toaster per demo. Sonner’s toast() is global: every mounted host renders a copy of the same toast. These previews fire toast() against the layout host.

Basic

Call toast() with a message string. It appears bottom-right, auto-dismisses, and stacks with any others.

Variants

toast.success, toast.error, toast.warning, and toast.info add a colored Halo icon and accent. Reach for these to signal outcome — a purchased label is a success, a failed charge is an error. (toast.error is sticky in our wrapper: it stays until dismissed and shows integrated copy and close controls.)

Description and action

The second argument is an options object. description renders a secondary line; action adds a button — { label, onClick } — for a follow-up like copying a tracking number.

Tracked async work

toast.promise tracks client-awaited work whose initiating control is no longer visible. It keeps one Halo mounted while transitioning from neutral pending feedback to success or error. Loading waits 200ms before appearing so fast operations do not flash; errors become sticky and include the standard copy and close controls.

Use this for work such as chunked bulk edits where the result may affect off-screen rows. Do not leave it pending for a background job: transition to “Queued” or “Started” once enqueueing finishes, then let realtime UI own actual progress.

Reference

Toaster

The host component. Mount once near the app root. Extends sonner Toaster props — ours pre-sets richColors, themed style tokens, lucide icons, and a dismiss button, but every prop below can still be overridden.

PropTypeDefaultDescription
theme"light" | "dark" | "system"from next-themesColor scheme; defaults to the active app theme
position"top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right""bottom-right"Where the stack renders
richColorsbooleantrueTints success / error / warning / info toasts
closeButtonbooleanfalseShow a close button on every toast
expandbooleanfalseExpand the stack on hover instead of stacking
durationnumber4000Default auto-dismiss time in ms for all toasts
toastOptionsExternalToastDefault options merged into every toast

toast()

The trigger function, re-exported from sonner with our overrides. Call toast(message, options?), or one of the variant methods. Returns the toast id.

MethodSignatureDescription
toast(message, options?) => idDefault neutral toast
toast.success(message, options?) => idSuccess variant (green, check icon)
toast.error(message, options?) => idError variant — sticky with copy and close controls
toast.warning(message, options?) => idWarning variant (amber, circular alert icon)
toast.info(message, options?) => idInfo variant (blue, info icon)
toast.promise(promise, { loading, success, error, delayMs? }) => resultTracks awaited work with one transitioning Halo; result.unwrap() returns the original promise
toast.message(message, options?) => idExplicit neutral toast (alias of the default call)
toast.dismiss(id?) => voidDismiss a specific toast, or all when called with no id

Options (second argument)

The options object (ExternalToast) shared by all toast methods. Common fields:

OptionTypeDescription
descriptionReactNodeSecondary line under the message
action{ label, onClick }A button rendered in the toast for a follow-up action
durationnumberAuto-dismiss time in ms (Infinity to keep it open)
closeButtonbooleanShow a close button on this toast
idstring | numberReuse an id to update an existing toast in place
onDismiss(toast) => voidFires when the toast is dismissed
onAutoClose(toast) => voidFires when the toast auto-closes after its duration