Notification
Persistent notification row and inbox panel. Items accumulate until read or dismissed.
Component behavior
Notification displays an inbox entry with read state and actions. The application supplies notification history and persistence.
- Events retained for later review — deploys, approvals, failures.
- Messages collected in a persistent inbox.
- Messages with read and unread state.
Toast: feedback reports a recent action and does not need to persist.
Banner: a condition persists across the page.
ActivityFeed: the view displays a chronological history.
NotificationItem
| Prop | Type | Default | Description |
|---|---|---|---|
id | string | — | Unique identifier. |
title | ReactNode | — | Notification title. |
body | ReactNode | — | One or two lines of detail. |
time | Date | — | Timestamp rendered as relative time. |
read | boolean | — | Read state. Unread rows display an indicator. |
tone | NotificationTone | "default" | "default" | "info" | "ok" | "warn" | "err". |
icon | ReactNode | — | Leading avatar or service icon. |
category | string | — | Grouping key for InboxPanel sections. |
actions | NotificationAction[] | — | Row actions with label, onClick, and optional variant. |
NotificationAction
Row actions use small Button components and default to the outline variant. Set an explicit variant for a different visual priority.
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | Button label. |
onClick | () => void | — | Handles action presses without calling the row onClick handler. |
variant | ButtonVariant | "outline" | Button visual variant. |
Notification Props
| Prop | Type | Default | Description |
|---|---|---|---|
item | NotificationItem | — | The notification data to render. |
onRead | (id: string) => void | — | Mark as read handler. |
onDismiss | (id: string) => void | — | Dismiss handler. |
onClick | () => void | — | Row selection handler. Providing the handler enables interaction. |
Examples
Notification rows
Unread indicator
Row actions
InboxPanel
InboxPanel displays notification entries supplied by the application.
| Prop | Type | Default | Description |
|---|---|---|---|
items | NotificationItem[] | — | Notification data array. |
title | ReactNode | "Notifications" | Panel title. |
onRead | (id: string) => void | — | Mark one as read. |
onDismiss | (id: string) => void | — | Dismiss one. |
onReadAll | () => void | — | Displays a Mark all as read button while unread items exist. |
onItemClick | (item: NotificationItem) => void | — | Click handler for a row. |
filterable | boolean | true | Adds All / Unread filter row under the header. Ignored when views is set. |
views | InboxView[] | — | Replaces All and Unread views. The application filters the supplied items. |
activeView | string | — | Controlled selected view key. |
defaultActiveView | string | — | Initial selected key for an uncontrolled custom view row. |
onViewChange | (key: string) => void | — | A view was picked. |
searchable | boolean | — | Adds a search band between the header and the views. |
searchValue | string | — | Controlled search text. |
onSearchChange | (value: string) => void | — | Delegates search filtering to the application. When omitted, the field filters items locally. |
searchPlaceholder | string | "Search notifications" | Placeholder for the search field. |
unreadCount | number | — | Header badge total. Defaults to the unread rows in items, which undercounts a paginated list. |
headerActions | ReactNode | — | Right-aligned header content. Pointer presses in this area do not start dragging. |
footer | ReactNode | — | Footer content below the scrolling list. |
loading | boolean | — | Swaps the list for placeholder rows while the first page loads. |
grouped | boolean | — | Section rows under their category. |
emptyMessage | ReactNode | "You're all caught up." | Message when the list is empty. |
maxHeight | number | 380 | List max height in px. |
width | number | string | 320px | Panel width. |
InboxPanel example
import { Notification, InboxPanel, Button } from "@solarius/onset";
import type { NotificationItem } from "@solarius/onset";
const items: NotificationItem[] = [
{
id: "1",
title: "Deployment completed",
body: "v2.4.1 deployed",
time: new Date(),
tone: "ok",
},
{
id: "2",
title: "Storage at 85%",
body: "Upgrade plan",
time: new Date(),
tone: "warn",
},
];
<InboxPanel
items={items}
onRead={(id) => markRead(id)}
onDismiss={(id) => dismiss(id)}
onReadAll={() => markAllRead()}
filterable
/>;Server-backed inbox
For server-backed history, pass views, controlled searchValue, and a footer. The application handles queries and supplies items; the panel does not filter them. Set unreadCount to the server total when only part of the inbox is loaded.
<InboxPanel
items={page.items}
loading={loading}
unreadCount={page.unreadCount}
views={[
{ key: "all", label: "All" },
{ key: "unread", label: "Unread", count: page.unreadCount },
{ key: "archived", label: "Archived" },
]}
activeView={view}
onViewChange={setView}
searchable
searchValue={search}
onSearchChange={setSearch}
headerActions={
<Button size="sm" variant="ghost" onClick={openSettings}>
Settings
</Button>
}
footer={
cursor ? (
<Button size="sm" variant="ghost" onClick={loadMore}>
Load more
</Button>
) : null
}
/>