Skip to content

Notifications

The library ships a complete notification subsystem. notify({ title, body, ... }) from anywhere puts a toast in the top-right stack, an entry in the Notification Center history, a count bubble on the matching dock tile, and a dot on the menu-bar clock, all from the same call.

Toasts stacking, dock badges, menu-bar dot Open in new tab ↗
Notification Center grouped by day Open in new tab ↗
import { notify } from "@react-ui-os/core";
import {
NotificationToasts,
NotificationCenter,
NOTIFICATION_CENTER_TOGGLE_EVENT,
} from "@react-ui-os/desktop";

<Desktop> mounts <NotificationToasts /> and <NotificationCenter /> for you. You only import them explicitly when composing your own layout with <DesktopProvider>.

notify({
title: "Build finished",
body: "Deploy succeeded in 1m 42s.",
appId: "ci", // associates with the CI dock tile
level: "success", // info | success | warn | error
duration: 5000, // ms; 0 = sticky until dismissed
actions: [
{ label: "View", onClick: () => router.push("/builds/123"), primary: true },
{ label: "Dismiss", onClick: () => {} },
],
});

notify returns the assigned id. Pass an explicit id to update a running toast, useful for progress bars that change as work proceeds. Repeating the same id replaces the row instead of stacking a second one.

const id = "downloading";
notify({ id, title: "Downloading", body: "0%", duration: 0 });
// ... later, as progress changes
notify({ id, title: "Downloading", body: "47%", duration: 0 });
// ... when complete
notify({ id, title: "Download complete", body: "report.pdf", level: "success" });
LevelDefault durationImplicit accent
info5000 mstheme accent
success5000 msgreen
warn8000 msamber
error0: stickyred

error toasts are sticky because the user needs to acknowledge them. Override with an explicit duration if you want a one-shot warning.

SurfaceBehavior
Toast stackTop-right, slides in, lives for duration ms, then leaves the stack and joins history.
Notification CenterRight-edge sheet, grouped by day, opens via the menu-bar clock or the toggle event.
Dock badgesPer-app unread count bubble on the corresponding tile (uses appId).
Menu-bar dotSmall accent dot next to the clock whenever any notification is unread.

The unread count clears when the user opens the Notification Center, or after the toast has been visible for 1.5 seconds.

import {
dismissNotification, // hide toast, keep history
removeNotification, // remove from history too
clearAllNotifications, // empty everything
markAllNotificationsRead, // clear badges without removing rows
} from "@react-ui-os/core";

dismissNotification(id) fires the item’s onDismiss callback once. removeNotification(id) deletes the row without firing onDismiss if it was already dismissed.

useNotifications() exposes the full snapshot, useful for custom menu-bar items or in-app inboxes.

import { useNotifications } from "@react-ui-os/core";
function HeaderBadge() {
const { unreadCount } = useNotifications();
if (unreadCount === 0) return null;
return <span className="dot">{unreadCount}</span>;
}

Click the menu-bar clock. The center toggles open and marks every visible item read.

To trigger it from a custom button:

import { NOTIFICATION_CENTER_TOGGLE_EVENT } from "@react-ui-os/desktop";
window.dispatchEvent(new CustomEvent(NOTIFICATION_CENTER_TOGGLE_EVENT));
  • The toast stack is role="region" aria-live="polite" aria-label="Notifications" so screen readers announce new entries without interrupting the user.
  • Each toast is role="status".
  • The Notification Center sheet is role="dialog" aria-modal and traps focus while open.
  • The menu-bar clock is a <button> with an aria-label that includes the unread count.
  • Dock badges include their count in the tile’s aria-label.
  • Escape dismisses the Notification Center.