Skip to content
Component installs need the registry setup
VegaStack Design

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

Skip to content
Acme

Home

Open the Inbox from the rail, or the bell on a phone.

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-01
Registry setup required
Run this command only after configuring the Base UI shadcn project, the @vegastack registry namespace, and the Cloudflare Access service-token headers in Install from the VegaStack registry.

This 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

Skip to content
Acme

Home

Open the Inbox from the rail, or the bell on a phone.

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} holds Inbox, whose title is the SheetTitle and whose ✕ closes the sheet. In Regent the sheet docks beside the sidebar (side="left", non-modal with showOverlay={false} on desktop, full screen on a phone); the block uses a plain right sheet.
  • Header — InboxMarkAllRead (✓✓, shown while anything is unread) and InboxMenuAction (⋯) for settings. "Mark all read" is announced once through useAnnouncer: "Marked all read".
  • Filters — InboxFilters: All | Unread chips, the unread count on Unread.
  • Day groups — groupByDay from date-time buckets rows into Today, Yesterday, This week, Last week and Earlier, each an InboxGroup whose 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 with InboxEmphasis on the actor and the record; one line of meta; 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 — actions adds Approve / Reject chips; Approve shows its loading and "Approved" done state.
  • Infinite scroll — onLoadMore / hasMore / loadingMore on Inbox page 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

StateCopy
LoadingInboxSkeleton rows, "Loading inbox" for screen readers
Nothing at allNo notifications — Assignments and meeting updates show up here.
Nothing unreadYou’re all caught up
Failed loadCouldn’t load your inbox — Try again
Loading moreThree skeleton rows under the list
Page failedTry again (ghost button)
End of listYou’re all caught up

Files

FileRegistry typeTarget
notifications-01/components/inbox-sheet.tsxregistry:componentapp/notifications-01/components/inbox-sheet.tsx
notifications-01/components/sample-notifications.tsregistry:componentapp/notifications-01/components/sample-notifications.ts
notifications-01/page.tsxregistry:pageapp/notifications-01/page.tsx

Do / Don't

Do
Put the count in each trigger’s name, and make every row one link to the thing it is about.
Don't
Colour unread rows red, or nest a second link inside a row — use action chips and the ⋯ menu.

On this page