npx shadcn@latest add https://sdk-components.thesqd.com/r/notification.jsonimport { Notification, NotificationStack } from "@/components/ui/notification";import { CloudArrowUp } from "@phosphor-icons/react/ssr";
import { Notification } from "@/components/ui/notification";
export function Example() {
return (
<Notification
variant="brand"
icon={<CloudArrowUp weight="duotone" />}
title="Backup complete"
description="412 files synced to Dropbox a moment ago."
actionButton={{ label: "View files" }}
/>
);
}Notification (single component — pass everything as props)
├── version="v1 | v2" (v2 default — card + accent bar · v1 pill)
├── variant="default | brand | info | success | warning | destructive"
├── icon={<PhosphorIcon weight="duotone" />}
├── title={<ReactNode>}
├── description={<ReactNode>}
├── action={<Button … />} (optional — top-right slot)
└── actionButton={{ label, loadingLabel?, doneLabel?, successMessage?, variant?, onAction? }}
NotificationStack (a deck of notifications, newest first)
├── items={[{ id, variant, icon, title, description, actionButton? }, …]}
└── version="v1 | v2" (applies to every banner in the deck)
notification({ … }) (same content, fired as a Sonner toast)
└── { title, description?, variant?, version?, icon?, actionButton?, duration?, id? }| Prop | Type | Default | Description |
|---|---|---|---|
version | "v1" | "v2" | "v2" | Visual treatment. `v2` (default, latest) is the Alert v2 surface — a neutral card with a colored left accent bar and colored icon. `v1` is the older pill. |
variant | "default" | "brand" | "info" | "success" | "warning" | "destructive" | "default" | Tone. Drives the accent bar and icon color in v2, the border and icon in v1. |
icon | ReactNode | — | Leading icon. Pass a Phosphor icon with `weight="duotone"` — the component colors it from `variant`. |
title | ReactNode | — | Bold heading rendered next to the icon. |
description | ReactNode | — | Body content. Accepts strings or JSX. |
actionButton | AlertActionConfig | — | Async action button, vertically centered on the right edge. Pass `{ label, loadingLabel?, doneLabel?, successMessage?, variant?, onAction? }`. The notification drives idle → loading (Spinner) → done and fires the optional info toast on resolve. |
action | ReactNode | — | Optional content pinned to the top-right corner. |
className | string | — | Override or extend the resolved variant classes. |
| Prop | Type | Default | Description |
|---|---|---|---|
version | "v1" | "v2" | "v2" | `v2` renders the Notification v2 surface inside the toast — identical to the inline banner. `v1` uses sonner's own per-tone styling. |
title | ReactNode | — | Toast heading. The only required field. |
description | ReactNode | — | Secondary line under the title. |
variant | "default" | "brand" | "info" | "success" | "warning" | "destructive" | "default" | Tone — routes to the matching sonner method and sets the default action-button color. |
icon | ReactNode | — | Leading icon. Size it `size-4` to match sonner's slot. |
actionButton | AlertActionConfig | — | Renders an async action button under the description and dismisses the toast once it resolves. Supplying it defaults `duration` to `Infinity`. |
duration | number | — | Override sonner's default duration (ms). |
id | string | number | — | Stable id — pass the same one to update an open toast in place. `notification.dismiss(id)` closes it. |
toastOptions | ExternalToast | — | Pass-through sonner overrides (classNames, position, …). |
| Prop | Type | Default | Description |
|---|---|---|---|
items | NotificationStackItem[] | — | Newest first — index 0 sits at the front of the deck. Each item is a `Notification` prop bag plus a stable `id`. Items 1 and 2 peek out behind the front one; a 4th renders as the exit frame. Anything past four is dropped. |
className | string | — | Extends the `.t-stack` root (sizing, positioning). |