notifications-01
The Regent Inbox — a sheet on the Inbox component with Mark all read, a More menu, All | Unread chips, day groups, rich rows, action chips and infinite scroll.
Last updated
What it is
The Regent app's Inbox, as a block: rail row and bell triggers with the unread count in their names, opening a sheet that holds the Inbox panel — Mark all read and ⋯ in the header, All | Unread chips, day groups of linked rows, action chips, infinite scroll and "You’re all caught up". It is a block: you pull it once with shadcn add, and then you own it —
nothing re-pulls it and no integrity hash tracks your edits, unlike the components it composes.
InboxSheet in components/ is the sheet; the page wires it to two triggers and the sample notifications.
Install
npx shadcn@latest add @vegastack/notifications-01This installs the block's own files plus the components it composes: app-shell, date-time, dropdown-menu, inbox, notification-bell, page-header, sheet, sidebar, tooltip, use-announcer.
Preview
Triggers
On a desktop the rail's Inbox row opens it; on a phone the header's NotificationBell does.
Both carry the unread count in their accessible names — badge + badgeLabel on the row,
countLabel on the bell — so the visual count is decoration. When the sheet closes, focus returns
to whichever trigger opened it.
The panel
SheetContent showCloseButton={false}holdsInbox, whosetitleis theSheetTitleand whose ✕ closes the sheet. In Regent the sheet docks beside the sidebar (side="left", non-modal withshowOverlay={false}on desktop, full screen on a phone); the block uses a plain right sheet.- Header —
InboxMarkAllRead(✓✓, shown while anything is unread) andInboxMenuAction(⋯) for settings. "Mark all read" is announced once throughuseAnnouncer: "Marked all read". - Filters —
InboxFilters: All | Unread chips, the unread count on Unread. - Day groups —
groupByDayfromdate-timebuckets rows into Today, Yesterday, This week, Last week and Earlier, each anInboxGroupwhose label sticks within the scroll area — no dividers around it, just space (16px above, 6px below); rows keep a 1px divider between them. - Rows —
InboxItem: the actor's avatar, or an icon for system events (destructive for a failure); an unread tint with an sr-only "Unread:" (unread titles in the foreground colour, read ones muted, the actor and record in medium); a rich title withInboxEmphasison the actor and the record; one line ofmeta; a repeat count; the relative time, which gives way to the read toggle and ⋯ on hover or focus. The ⋯ menu holds Mute this type, with the tooltip "Stop notifications like this". The whole row is one link. - Action chips —
actionsadds Approve / Reject chips; Approve shows its loading and "Approved" done state. - Infinite scroll —
onLoadMore/hasMore/loadingMoreonInboxpage older rows 15 at a time as the list scrolls: three skeleton rows while a page loads, a ghost Try again after a failure (the preview's first page fails once to show it), and "You’re all caught up" at the end.
States
| State | Copy |
|---|---|
| Loading | InboxSkeleton rows, "Loading inbox" for screen readers |
| Nothing at all | No notifications — Assignments and meeting updates show up here. |
| Nothing unread | You’re all caught up |
| Failed load | Couldn’t load your inbox — Try again |
| Loading more | Three skeleton rows under the list |
| Page failed | Try again (ghost button) |
| End of list | You’re all caught up |
Files
| File | Registry type | Target |
|---|---|---|
notifications-01/components/inbox-sheet.tsx | registry:component | app/notifications-01/components/inbox-sheet.tsx |
notifications-01/components/sample-notifications.ts | registry:component | app/notifications-01/components/sample-notifications.ts |
notifications-01/page.tsx | registry:page | app/notifications-01/page.tsx |