- Prop
items- Type
NotificationItem[] | undefined- Default
- —
- Requirement
- optional
Docs Components Advanced
NotificationCenter
React example follows below.
Vue example follows below.
Angular example follows below.
Svelte example follows below.
Solid example follows below.
- parts
- —
- nodes
- —
- size
- —
- part
- —
ts
/** * NotificationCenter's pinned demo state (CSP-D3). * * Two groups with a deliberate read/unread mix: the first group leads with * two unread rows (so the header badge reads "2", "Mark all read" is enabled, * and the unread dot + "Unread: " screen-reader prefix + `data-unread` row * attribute all render) and closes with a read one; the second group is * entirely read (so the read row styling is visible next to the unread). * All five `kind`s appear exactly once, which puts every branch of the * per-kind glyph switch on screen in a single render. * * Ids are fixture-supplied and stable — never a counter or `Math.random()` — * so the rendered `key`/dismiss target is identical in all five frameworks * and across repeat mounts, the same rule the toast batch set. */const notificationCenterFixture = { id: "notification-center", title: "Notifications", items: [ { id: "notif-deploy-ledger", group: "Today", kind: "deploy", message: "ledger-api v2.4.1 deployed to iad", time: "12m ago", unread: true, }, { id: "notif-alert-latency", group: "Today", kind: "alert", message: "p99 latency above 400ms on checkout", time: "34m ago", unread: true, }, { id: "notif-mention-review", group: "Today", kind: "mention", message: "Priya mentioned you in #payments-oncall", time: "2h ago", unread: false, }, { id: "notif-pr-merged", group: "Yesterday", kind: "pr", message: "Merged: retry budget per tenant", time: "19h ago", unread: false, }, { id: "notif-error-webhook", group: "Yesterday", kind: "error", message: "Webhook delivery failed 3× for acme-co", time: "22h ago", unread: false, }, ],} satisfies { id: string; title: string; items: { id: string; group: string; kind: "deploy" | "alert" | "mention" | "pr" | "error"; message: string; time: string; unread: boolean; }[];}; import { NotificationCenter } from "@grassroot/ui-react/advanced"; export default function NotificationCenterDemo() { return ( <div> <NotificationCenter defaultItems={notificationCenterFixture.items} title={notificationCenterFixture.title} /> </div> );}- parts
- —
- nodes
- —
- size
- —
- part
- —
ts
<script setup lang="ts">/** * NotificationCenter's pinned demo state (CSP-D3). * * Two groups with a deliberate read/unread mix: the first group leads with * two unread rows (so the header badge reads "2", "Mark all read" is enabled, * and the unread dot + "Unread: " screen-reader prefix + `data-unread` row * attribute all render) and closes with a read one; the second group is * entirely read (so the read row styling is visible next to the unread). * All five `kind`s appear exactly once, which puts every branch of the * per-kind glyph switch on screen in a single render. * * Ids are fixture-supplied and stable — never a counter or `Math.random()` — * so the rendered `key`/dismiss target is identical in all five frameworks * and across repeat mounts, the same rule the toast batch set. */const notificationCenterFixture = { id: "notification-center", title: "Notifications", items: [ { id: "notif-deploy-ledger", group: "Today", kind: "deploy", message: "ledger-api v2.4.1 deployed to iad", time: "12m ago", unread: true, }, { id: "notif-alert-latency", group: "Today", kind: "alert", message: "p99 latency above 400ms on checkout", time: "34m ago", unread: true, }, { id: "notif-mention-review", group: "Today", kind: "mention", message: "Priya mentioned you in #payments-oncall", time: "2h ago", unread: false, }, { id: "notif-pr-merged", group: "Yesterday", kind: "pr", message: "Merged: retry budget per tenant", time: "19h ago", unread: false, }, { id: "notif-error-webhook", group: "Yesterday", kind: "error", message: "Webhook delivery failed 3× for acme-co", time: "22h ago", unread: false, }, ],} satisfies { id: string; title: string; items: { id: string; group: string; kind: "deploy" | "alert" | "mention" | "pr" | "error"; message: string; time: string; unread: boolean; }[];}; import { NotificationCenter } from "@grassroot/ui-vue";</script> <template> <div> <NotificationCenter :default-items="notificationCenterFixture.items" :title="notificationCenterFixture.title" /> </div></template>- parts
- —
- nodes
- —
- size
- —
- part
- —
ts
import { Component } from "@angular/core";/** * NotificationCenter's pinned demo state (CSP-D3). * * Two groups with a deliberate read/unread mix: the first group leads with * two unread rows (so the header badge reads "2", "Mark all read" is enabled, * and the unread dot + "Unread: " screen-reader prefix + `data-unread` row * attribute all render) and closes with a read one; the second group is * entirely read (so the read row styling is visible next to the unread). * All five `kind`s appear exactly once, which puts every branch of the * per-kind glyph switch on screen in a single render. * * Ids are fixture-supplied and stable — never a counter or `Math.random()` — * so the rendered `key`/dismiss target is identical in all five frameworks * and across repeat mounts, the same rule the toast batch set. */const notificationCenterFixture = { id: "notification-center", title: "Notifications", items: [ { id: "notif-deploy-ledger", group: "Today", kind: "deploy", message: "ledger-api v2.4.1 deployed to iad", time: "12m ago", unread: true, }, { id: "notif-alert-latency", group: "Today", kind: "alert", message: "p99 latency above 400ms on checkout", time: "34m ago", unread: true, }, { id: "notif-mention-review", group: "Today", kind: "mention", message: "Priya mentioned you in #payments-oncall", time: "2h ago", unread: false, }, { id: "notif-pr-merged", group: "Yesterday", kind: "pr", message: "Merged: retry budget per tenant", time: "19h ago", unread: false, }, { id: "notif-error-webhook", group: "Yesterday", kind: "error", message: "Webhook delivery failed 3× for acme-co", time: "22h ago", unread: false, }, ],} satisfies { id: string; title: string; items: { id: string; group: string; kind: "deploy" | "alert" | "mention" | "pr" | "error"; message: string; time: string; unread: boolean; }[];}; import { GrassrootNotificationCenter } from "@grassroot/ui-angular"; // Every input is a `[property]` binding, never a static attribute. Angular// leaves static template attributes on the host element in the rendered DOM,// and `title` is a real global attribute — `title="Notifications"` would ship// a browser tooltip over the whole panel that React/Vue/Solid/Svelte, which// consume `title` as a declared prop, never render.@Component({ selector: "app-notification-center-demo", standalone: true, imports: [GrassrootNotificationCenter], template: ` <div> <grassroot-notification-center [defaultItems]="items" [title]="title" /> </div> `,})export class NotificationCenterDemoComponent { protected readonly items = notificationCenterFixture.items; protected readonly title = notificationCenterFixture.title;} export default NotificationCenterDemoComponent;- parts
- —
- nodes
- —
- size
- —
- part
- —
ts
<script lang="ts"> /** * NotificationCenter's pinned demo state (CSP-D3). * * Two groups with a deliberate read/unread mix: the first group leads with * two unread rows (so the header badge reads "2", "Mark all read" is enabled, * and the unread dot + "Unread: " screen-reader prefix + `data-unread` row * attribute all render) and closes with a read one; the second group is * entirely read (so the read row styling is visible next to the unread). * All five `kind`s appear exactly once, which puts every branch of the * per-kind glyph switch on screen in a single render. * * Ids are fixture-supplied and stable — never a counter or `Math.random()` — * so the rendered `key`/dismiss target is identical in all five frameworks * and across repeat mounts, the same rule the toast batch set. */ const notificationCenterFixture = { id: "notification-center", title: "Notifications", items: [ { id: "notif-deploy-ledger", group: "Today", kind: "deploy", message: "ledger-api v2.4.1 deployed to iad", time: "12m ago", unread: true, }, { id: "notif-alert-latency", group: "Today", kind: "alert", message: "p99 latency above 400ms on checkout", time: "34m ago", unread: true, }, { id: "notif-mention-review", group: "Today", kind: "mention", message: "Priya mentioned you in #payments-oncall", time: "2h ago", unread: false, }, { id: "notif-pr-merged", group: "Yesterday", kind: "pr", message: "Merged: retry budget per tenant", time: "19h ago", unread: false, }, { id: "notif-error-webhook", group: "Yesterday", kind: "error", message: "Webhook delivery failed 3× for acme-co", time: "22h ago", unread: false, }, ], } satisfies { id: string; title: string; items: { id: string; group: string; kind: "deploy" | "alert" | "mention" | "pr" | "error"; message: string; time: string; unread: boolean; }[]; }; import { NotificationCenter } from "@grassroot/ui-svelte";</script> <div> <NotificationCenter defaultItems={notificationCenterFixture.items} title={notificationCenterFixture.title} /></div>- parts
- —
- nodes
- —
- size
- —
- part
- —
ts
/** @jsxImportSource solid-js *//** * NotificationCenter's pinned demo state (CSP-D3). * * Two groups with a deliberate read/unread mix: the first group leads with * two unread rows (so the header badge reads "2", "Mark all read" is enabled, * and the unread dot + "Unread: " screen-reader prefix + `data-unread` row * attribute all render) and closes with a read one; the second group is * entirely read (so the read row styling is visible next to the unread). * All five `kind`s appear exactly once, which puts every branch of the * per-kind glyph switch on screen in a single render. * * Ids are fixture-supplied and stable — never a counter or `Math.random()` — * so the rendered `key`/dismiss target is identical in all five frameworks * and across repeat mounts, the same rule the toast batch set. */const notificationCenterFixture = { id: "notification-center", title: "Notifications", items: [ { id: "notif-deploy-ledger", group: "Today", kind: "deploy", message: "ledger-api v2.4.1 deployed to iad", time: "12m ago", unread: true, }, { id: "notif-alert-latency", group: "Today", kind: "alert", message: "p99 latency above 400ms on checkout", time: "34m ago", unread: true, }, { id: "notif-mention-review", group: "Today", kind: "mention", message: "Priya mentioned you in #payments-oncall", time: "2h ago", unread: false, }, { id: "notif-pr-merged", group: "Yesterday", kind: "pr", message: "Merged: retry budget per tenant", time: "19h ago", unread: false, }, { id: "notif-error-webhook", group: "Yesterday", kind: "error", message: "Webhook delivery failed 3× for acme-co", time: "22h ago", unread: false, }, ],} satisfies { id: string; title: string; items: { id: string; group: string; kind: "deploy" | "alert" | "mention" | "pr" | "error"; message: string; time: string; unread: boolean; }[];}; import { NotificationCenter } from "@grassroot/ui-solid"; export default function NotificationCenterDemo() { return ( <div> <NotificationCenter defaultItems={notificationCenterFixture.items} title={notificationCenterFixture.title} /> </div> );}Installation
API Reference
Import
import { NotificationCenter } from "@grassroot/ui-react/advanced";
Props
Prop
Type
Default
Requirement
itemsNotificationItem[] | undefined—
optional
defaultItemsNotificationItem[] | undefined—
optional
onItemsChange((next: NotificationItem[]) => void) | undefined—
optional
onOpen((id: string) => void) | undefined—
optional
titlestring | undefined—
optional
- Prop
defaultItems- Type
NotificationItem[] | undefined- Default
- —
- Requirement
- optional
- Prop
onItemsChange- Type
((next: NotificationItem[]) => void) | undefined- Default
- —
- Requirement
- optional
- Prop
onOpen- Type
((id: string) => void) | undefined- Default
- —
- Requirement
- optional
- Prop
title- Type
string | undefined- Default
- —
- Requirement
- optional
Events
| Event | Payload |
|---|---|
onItemsChange | ((next: NotificationItem[]) => void) | undefined |
onOpen | ((id: string) => void) | undefined |
Native attributes
Standard DOM and ARIA attributes not listed above spread onto the root element.
Import
import { NotificationCenter } from "@grassroot/ui-vue";
Props
Prop
Type
Default
Requirement
itemsNotificationItem<string>[] | undefined—
optional
defaultItemsNotificationItem<string>[] | undefined() => []optional
titlestring | undefined"Notifications"optional
- Prop
items- Type
NotificationItem<string>[] | undefined- Default
- —
- Requirement
- optional
- Prop
defaultItems- Type
NotificationItem<string>[] | undefined- Default
() => []- Requirement
- optional
- Prop
title- Type
string | undefined- Default
"Notifications"- Requirement
- optional
Events
| Event | Payload |
|---|---|
itemsChange | [next: NotificationItem[]] |
open | [id: string] |
Import
import { Component } from "@angular/core";
import { GrassrootNotificationCenter } from "@grassroot/ui-angular";
Props
Prop
Type
Default
Requirement
itemsNotificationItem[]—
optional
defaultItemsNotificationItem[][]optional
titlestring"Notifications"optional
- Prop
items- Type
NotificationItem[]- Default
- —
- Requirement
- optional
- Prop
defaultItems- Type
NotificationItem[]- Default
[]- Requirement
- optional
- Prop
title- Type
string- Default
"Notifications"- Requirement
- optional
Events
| Event | Payload |
|---|---|
itemsChange | NotificationItem[] |
open | string |
Import
import { NotificationCenter } from "@grassroot/ui-svelte";
Props
Prop
Type
Default
Requirement
itemsNotificationItem[]—
optional
defaultItemsNotificationItem[]—
optional
onItemsChange(next: NotificationItem[]) => void—
optional
onOpen(id: string) => void—
optional
titlestring"Notifications"optional
classNamestring—
optional
- Prop
items- Type
NotificationItem[]- Default
- —
- Requirement
- optional
- Prop
defaultItems- Type
NotificationItem[]- Default
- —
- Requirement
- optional
- Prop
onItemsChange- Type
(next: NotificationItem[]) => void- Default
- —
- Requirement
- optional
- Prop
onOpen- Type
(id: string) => void- Default
- —
- Requirement
- optional
- Prop
title- Type
string- Default
"Notifications"- Requirement
- optional
- Prop
className- Type
string- Default
- —
- Requirement
- optional
Events
| Event | Payload |
|---|---|
onItemsChange | (next: NotificationItem[]) => void |
onOpen | (id: string) => void |
Import
import { NotificationCenter } from "@grassroot/ui-solid";
Props
Prop
Type
Default
Requirement
itemsNotificationItem[]—
optional
defaultItemsNotificationItem[]—
optional
onItemsChange(next: NotificationItem[]) => void—
optional
onOpen(id: string) => void—
optional
titlestring"Notifications"optional
classNamestring—
optional
- Prop
items- Type
NotificationItem[]- Default
- —
- Requirement
- optional
- Prop
defaultItems- Type
NotificationItem[]- Default
- —
- Requirement
- optional
- Prop
onItemsChange- Type
(next: NotificationItem[]) => void- Default
- —
- Requirement
- optional
- Prop
onOpen- Type
(id: string) => void- Default
- —
- Requirement
- optional
- Prop
title- Type
string- Default
"Notifications"- Requirement
- optional
- Prop
className- Type
string- Default
- —
- Requirement
- optional
Events
| Event | Payload |
|---|---|
onItemsChange | (next: NotificationItem[]) => void |
onOpen | (id: string) => void |