Component gallery

Toast

Transient notices via pushAlert: tones, durations, actions, and custom controls inside the toast.

Variants

pushAlert.info / .success / .warning / .error

Dedup by content hash

Spam the button: the same message replaces in place instead of stacking

Spinner → result (replace)

Sonner can't mutate a live duration, so the spinner toast is replaced by its result under the same id

pushAlert.promise

One call: spinner while pending, replaced by the outcome under the same id

Custom controls

options.controls adds action buttons; they inherit the alert's content color

Position

The stack sits bottom-right by default now; the Toasts mount takes any Sonner position

This page mounts <Toasts /> with the default: fire any toast above and watch the bottom-right corner.

Persistent + copyable

duration -1 stays until dismissed; error toasts get a copy button by default

Toasts host

Mounted once in the app shell; every pushAlert on this page renders through it
<Toasts /> // this gallery mounts it in app/layout.tsx

useAlertToast

The pusher as a hook: consumers depend on a stable interface they can stub, not on Sonner directly

Styling slots

Every className the component exposes, and what it reaches
className
the toast card
descriptionClassName
the message region
@versable-git/ui · all states, both themes