Feedback · astro-ui · NotificationCenterNew
NotificationCenterJS
Bell trigger with an unread badge and a grouped notification panel.
NotificationCenter owns the bell, the unread count, and the panel that opens from it. Groups keep rows scannable by day or source, NotificationItem renders the row (optionally as a link), and the badge stays decorative because the count is already part of the trigger’s accessible name. It is a disclosure rather than a modal: Escape and outside clicks close it, and focus returns to the bell.
Features
- Unread badge with 99+ cap, mirrored into the trigger's accessible name
- Grouped sections with day/source headings
- Rows as links or static cards, with media, description, and timestamp
- Empty-state slot for the zero-notification case
- Header action slot (mark all read, settings)
- Escape, outside click, and focus return handled
Usage
---
import {
NotificationCenter,
NotificationGroup,
NotificationItem,
} from "astro-ui";
---
<NotificationCenter count={2} title="Notifications">
<NotificationGroup label="Today">
<NotificationItem unread title="Deploy finished" time="2m ago" href="/deploys/412">
Production build 412 is live.
</NotificationItem>
<NotificationItem title="Ada left a comment" time="1h ago">
On the sidebar PR.
</NotificationItem>
</NotificationGroup>
</NotificationCenter>Demos
Notification panel
Notifications
Today
- Deploy finishedUnread
Ada left a comment
Unread
Yesterday
<NotificationCenter
count={2}
title="Notifications"
placement="bottom-start"
id="dm-notif-inbox"
>
<NotificationGroup label="Today">
<NotificationItem unread title="Deploy finished" time="2m ago" href="/deploys/412">
Production build 412 is live.
</NotificationItem>
<NotificationItem unread title="Ada left a comment" time="1h ago">
On the sidebar pull request.
</NotificationItem>
</NotificationGroup>
<NotificationGroup label="Yesterday">
<NotificationItem title="Weekly digest" time="Yesterday" href="/digest">
12 components shipped, 3 blocks updated.
</NotificationItem>
</NotificationGroup>
</NotificationCenter>Header action and footer
Activity
Today
Build 412 passed
Unread
<NotificationCenter
count={12}
title="Activity"
placement="bottom-start"
id="dm-notif-actions"
>
<Menu slot="actions" triggerLabel="Notification settings" bareTrigger>
<MenuItem>Mark all read</MenuItem>
<MenuItem>Mute for 1 hour</MenuItem>
<MenuSeparator/>
<MenuItem>Notification settings</MenuItem>
</Menu>
<NotificationGroup label="Today">
<NotificationItem unread title="Build 412 passed" time="3m ago"/>
</NotificationGroup>
<a slot="footer" href="/notifications">View all notifications</a>
</NotificationCenter>Empty state
Notifications
<NotificationCenter
count={0}
title="Notifications"
placement="bottom-start"
id="dm-notif-empty"
>
<Empty size="sm">
<span slot="media" aria-hidden="true">🔔</span>
<span slot="title">You are all caught up</span>
<span slot="description">New activity will show up here.</span>
</Empty>
</NotificationCenter>API
Props
| Prop | Type | Default | Description |
|---|---|---|---|
count | number | 0 | Unread count; 0 hides the badge. |
title | string | "Notifications" | Panel heading. |
ariaLabel | string | "Notifications" | Accessible name for the trigger. |
placement | "bottom-end" | "bottom-start" | "bottom-end" | Panel alignment. |
open | boolean | false | Render the panel open on first paint. |
class | string | — | Merged via cn(); Tailwind classes welcome. |
id | string | — | Element id. |
ariaLabel | string | — | Accessible name. |
Slots
| Slot | Description |
|---|---|
trigger | Custom bell content (defaults to 🔔). |
(default) | NotificationGroup / NotificationItem children. |
actions | Header actions (Menu, button). |
footer | Footer link or action. |
Accessibility
Implemented accessibility features — semantics, ARIA wiring, and keyboard behavior that ship with the component.
- Trigger is a button with
aria-haspopup="dialog"andaria-expanded - Panel is a named
role="dialog", focused on open - Groups are
<section>+<h3>+<ul>, so counts are announced - Unread rows announce "Unread" in text, not colour alone
- Badge number is
aria-hiddento avoid double announcement
FAQ
What props does NotificationItem take?
`title`, `time`, `datetime`, `unread`, `href`, `class`, `id`, plus `media` and `description` slots. With `href` the whole row becomes one link.
How do I mark notifications read?
The component is presentational: render `unread` from your own state and update it when the user acts. Because `count` is a prop, re-render (or update the trigger label) when the unread total changes.
Can it open as a side panel instead?
Yes — compose the same groups inside `Sheet side="right"` and use NotificationCenter only for the bell and count. The inner markup is the same.
Changelog
Version history mentioning NotificationCenter.
- Feedback (6): Alert, Spinner, Skeleton, Toast, Banner, NotificationCenter.