Sonner
nswds-ui/sonnerFreeComponent
A toast notification surface wired to next-themes, with NSWDS status icons.
Install it
npx shadcn@latest add https://raw.githubusercontent.com/digitalnsw/nswds-ui/main/apps/registry/public/r/sonner.jsonSource
1'use client'23import { useTheme } from 'next-themes'4import * as React from 'react'5import { Toaster as Sonner, type ToasterProps } from 'sonner'67import { Spinner } from '@/components/spinner'8import { IconCheckCircle } from '@/icons/check-circle'9import { IconError } from '@/icons/error'10import { IconInfo } from '@/icons/info'11import { IconWarning } from '@/icons/warning'12import { cn } from '@/lib/utils'1314/**15 * Binds sonner's own theming variables to the NSW semantic tokens.16 *17 * All four names below are sonner's public CSS API — three `--normal-*` colour18 * variables plus `--border-radius`, which is a separate name rather than part19 * of that family. Sonner's own stylesheet reads each of them.20 *21 * They are set ONLY here: none of the four is defined in the compiled22 * `dist/styles.css`, so this object is the single point at which the design23 * system's tokens reach a toast. Losing it silently drops every toast back to24 * sonner's built-in palette, which is why `style` is merged below rather than25 * overwritten.26 */27const tokenBridge = {28 '--normal-bg': 'var(--popover)',29 '--normal-text': 'var(--popover-foreground)',30 '--normal-border': 'var(--border)',31 '--border-radius': 'var(--radius)',32} as React.CSSProperties3334/**35 * Toast host. Mount once, near the root.36 *37 * Every prop this component sets a default for is MERGED with the consumer's38 * value rather than replaced. Spreading `{...props}` last — the shadcn default39 * this was scaffolded from — meant a consumer passing `style` for something40 * unrelated (a z-index, an offset) silently discarded the whole token bridge41 * above, and passing one `icons` entry discarded the other four. Object spread42 * replaces keys wholesale; it does not deep-merge.43 */44const Toaster = ({ className, style, icons, toastOptions, ...props }: ToasterProps) => {45 const { theme = 'system' } = useTheme()4647 return (48 <Sonner49 theme={theme as ToasterProps['theme']}50 // `toaster` and `group` are shadcn-compatible styling hooks. Nothing in51 // this package targets them, but consumers migrating from shadcn may, so52 // they are kept and merged rather than dropped.53 className={cn('toaster group', className)}54 icons={{55 success: <IconCheckCircle className='size-4' />,56 info: <IconInfo className='size-4' />,57 warning: <IconWarning className='size-4' />,58 error: <IconError className='size-4' />,59 loading: <Spinner size='sm' color='current' label='' />,60// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from @nswds/ui
All 46 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Aspect Ratioaspect-ratio | @nswds/ui | Components | Free | 2 deps · 2 files | |
| Badgebadge | @nswds/ui | Components | Free | 4 deps · 2 files | |
| Buttonbutton | @nswds/ui | Components | Free | 4 deps · 2 files | |
| Cardcard | @nswds/ui | Components | Free | 2 deps · 2 files | |
| Collapsiblecollapsible | @nswds/ui | Components | Free | 1 dep | |
| Drawerdrawer | @nswds/ui | Components | Free | 3 deps · 2 files | |
| Expandable Searchexpandable-search | @nswds/ui | Components | Free | 3 deps · 2 files | |
| Fieldfield | @nswds/ui | Components | Free | 4 deps · 2 files |
