Notifier
Spawn toast notifications imperatively from anywhere — success/error/warning/info/loading, actions, promises and in-place updates — with createNotifier. A custom toaster modelled on the overlays manager, animated in CSS.
The Notifier is the imperative toast manager. You create one, mount its region once near the app root, then call notify.* from anywhere — an event handler, a data mutation, a background task — with no useState or JSX at the call site. Each live toast is rendered as a Notification card.
It's a custom toaster modelled on the kit's createOverlays: a framework-agnostic store + a once-mounted renderer + a bound controller. Ark UI's Presence drives each toast's enter/exit lifecycle; everything else — the queue, the timers, placement, the deck↔column stacking, hover-pause, swipe-to-dismiss — is the kit's own, with the display and animation pushed into CSS (so heights animate, and it all respects prefers-reduced-motion).
Setup
createNotifier(options) returns a bound notify object and a <Notifications /> renderer. Call it once in a "use client" module and re-export the pieces:
'use client';
import { createNotifier } from '@42/ui-react/notification';
export const { notify, Notifications } = createNotifier({ placement: 'bottom-end' });Mount <Notifications /> once near the root. It renders nothing until a toast opens and is SSR-inert, so it's safe at the top of the tree:
import { Notifications } from './notifier';
export default function Layout({ children }) {
return (
<body>
{children}
<Notifications />
</body>
);
}Then call notify from anywhere:
import { notify } from '@/app/notifier';
notify('Copied to clipboard'); // neutral toast
notify.success('Saved');Status presets
Five presets — success, error, warning, info, loading — each maps to a hue (green / red / orange / gray / gray) and a default leading icon (loading shows a spinner and never auto-dismisses). Pass a bare string for the title, or an options object for more.
Code
notify.success('Changes saved');notify.error('Something went wrong');notify.warning('Double-check your input');notify.info('A new version is available');notify.loading('Syncing…');With a description
Pass an options object with title and description for a secondary line. It reveals with a Collapse height animation.
Code
notify.success({ title: 'Profile updated', description: 'Your changes are live across all 42 campuses.',});Action
action is any ReactNode — its own section under the toast, revealed independently of the description. Compose it however you like; the kit ships Notification.ActionTrigger for the standard button styling. Keep the id notify.* returns to dismiss the toast from inside the handler — good for an Undo.
Code
const id = notify.info({ title: 'Message archived', action: ( <Notification.ActionTrigger onClick={() => { notify.success('Message restored'); notify.dismiss(id); }} > Undo </Notification.ActionTrigger> ),});Promise
notify.promise drives a single toast through an async lifecycle: it starts as loading, then transitions to success or error when the promise settles. success / error may be functions of the resolved value / thrown error.
Code
notify.promise(upload(), { loading: 'Uploading…', success: (name) => ({ title: 'Upload complete', description: name }), error: 'Upload failed — please try again',});Updating a toast
Every spawn returns an id. Keep it and call notify.update(id, …) to patch a live toast — only the fields you pass change; anything you already set is kept, and the status type is preserved. To change the status too (say a manual loading → success), re-call the status helper with the same id. Because the description and action are independent Collapse sections, adding or removing either animates its height rather than jumping.
Code
const id = notify.loading('Uploading…');// patch in place — keeps everything elsenotify.update(id, { description: 'Halfway there…' });// …or transition its status (resets to the success preset)notify.success({ id, title: 'Uploaded' });Custom surface
The notify.* calls accept the same variant × color axes as the rest of the kit: variant picks the shape (light · filled · outline · subtle · default) and color the palette. Call notify(...) directly for a neutral toast with no status semantics; pass icon: null to drop the leading glyph.
Code
// filled statusnotify.success({ title: 'Deployed', description: 'v0.2.0 is live', variant: 'filled' });// fully custom — no status, no iconnotify({ title: 'Pro tip', description: 'Press ⌘K to search anywhere.', color: 'purple', variant: 'light', icon: null,});Placement & stacking
placement (a createNotifier option) anchors the region to any edge or corner. With expand (default), toasts collapse into a tidy deck — older cards peek behind the newest, tops aligned — that expands into a column on hover; hovering also pauses the auto-dismiss timers. max caps how many render at once.
Because placement belongs to the notifier (not an individual toast), each button below is its own createNotifier instance.
Code
const { notify, Notifications } = createNotifier({ placement: 'top-end', expand: true, max: 5 });Behaviors
- Auto-dismiss after
duration(default 5s);loadingtoasts never expire. - Pause while the pointer is over the stack, and while the tab is hidden — so nothing expires unseen.
- Swipe / drag a toast aside to dismiss it, or click it. Presses that start on the close button or an action are left to that control.
- Mobile (below the
xsbreakpoint) the region pins to the bottom, full-width, above the safe area — regardless ofplacement.
Playground
The controls below build a single toast and spawn it on click. Notifier-level options (placement / max / expand) are set once at creation, so tune those in your createNotifier call.
NotificationPlayground
Dir
Presets
Props
Code
<NotificationPlayground status="success" message="Changes saved" duration={5000}/>API
createNotifier(options) — configures the notifier and its region:
Prop
Type
notify(input) and notify.success/error/warning/info/loading(input) — where input is a title node or these options:
Prop
Type
The bound notify object also carries: notify.promise(promise, { loading, success?, error? }), notify.update(id, input), notify.dismiss(id?) (one toast, or all if omitted), notify.remove(id) (drop immediately, no exit), notify.has(id), and notify.getToasts().
Notification
The toast card — a compound surface (Root / Icon / Title / Description / ActionTrigger / CloseTrigger) on Badge's variant × color axes. Spawned imperatively through the Notifier.
Menu
A dropdown of actions on Ark UI's Menu — composable parts plus a typesafe data-driven form, with sections, submenus, checkbox / radio items, and a context-menu trigger.