Notification Center

Bell trigger whose unread badge springs when the count rises, opening a panel that grows out of the bell with All/Unread tabs and a gliding indicator, Today/Earlier groups, relative times, unread dots, hover actions to mark read or archive that collapse rows out while the rest glide up, Mark all as read, an empty state, focus management with Escape, and a controlled or uncontrolled notifications list.

Preview

Notification Center preview width

Install

Add it with the shadcn CLI, or copy the source manually.

$ bunx --bun shadcn add @karaui/notification-center
@karaui not found? Add it to components.json
{
  "registries": {
    "@karaui": "https://karaui.kamisama-v0.my.id/r/{name}.json"
  }
}

@karaui is in shadcn's public registry directory, so the latest CLI needs no setup. On an older CLI, merge this into the existing file once and every @karaui/… install resolves.

API Reference

notifications?
NotificationItem[]

Controlled list. Archived items are removed from it via `onNotificationsChange`.

—
defaultNotifications?
NotificationItem[]

Uncontrolled initial list.

[]
onNotificationsChange?
((notifications: NotificationItem[]) => void)
—
onMarkRead?
((id: string) => void)
—
onMarkAllRead?
(() => void)
—
onArchive?
((id: string) => void)
—
onSelect?
((notification: NotificationItem) => void)

Row click. The row is also marked read.

—
open?
boolean

Controlled panel open state.

—
defaultOpen?
boolean

Uncontrolled initial open state. Default false.

false
onOpenChange?
((open: boolean) => void)
—
ignoreOutside?
((target: Element) => boolean)

Return true for an outside target that should not close the panel (e.g. a "simulate" or compose button beside it). Must be stable.

—
align?
"end" | "start"

Panel edge aligned with the bell. Default "end".

end
locale?
string

Locale for relative times. Default "en-US" so server and client agree.

en-US
title?
ReactNode
Notifications
emptyLabel?
ReactNode
You're all caught up
className?
string
—
panelClassName?
string
—

Keep in mind

Some components on this site are inspired by or recreated from existing work across the web. I'm not here to take credit; just to learn, experiment, and sometimes push things a bit further. If something looks familiar and I forgot to mention you, reach out and I'll fix that right away.

Updated