shadcn.io is an independent project built on shadcn/ui
A bell with a badge of 5 opens a panel titled Notifications. It says you have 5 unread notifications, lists each item with a dot, and ends with Mark all as read.
Use it for an activity list on a phone. A short list can hang off the bell in a Popover. In Svelte, Ark UI does not mark the items read.
Installation
Anatomy

Usage
<Drawer swipeDirection="right"><DrawerTrigger>{#snippet asChild(props)}<Button {...props({ "aria-label": "Notifications, 5 unread", class: "relative" })} size="icon-md" variant="outline"><BellIcon aria-hidden="true" /><Badge aria-hidden="true" class="absolute -end-1 -top-1 h-5 min-w-5 px-1 tabular-nums" pill>5</Badge></Button>{/snippet}</DrawerTrigger><DrawerContent showBar={false}><DrawerHeader><DrawerTitle>Notifications</DrawerTitle><DrawerDescription>You have 5 unread notifications</DrawerDescription></DrawerHeader><ul class="min-h-0 flex-1 divide-y overflow-y-auto">{#each NOTIFICATIONS as notification (notification.id)}<li><button class="flex w-full items-start gap-3 p-4 text-start outline-none hover:bg-muted/50 focus-visible:bg-muted/50" type="button"><span aria-hidden="true" class={cn(
"mt-2 size-2 shrink-0 rounded-full",
notification.unread ? "bg-primary" : "bg-muted"
)}></span><span class="flex flex-1 flex-col gap-1"><span class={cn(
"text-sm",
notification.unread && "font-medium"
)}>{#if notification.unread}<span class="sr-only">Unread:{" "}</span>{:else}{/if}{notification.title}</span><span class="text-muted-foreground text-xs">{notification.description}</span><span class="text-muted-foreground text-xs">{notification.time}</span></span></button></li>{/each}</ul><div class="border-t p-4"><DrawerClose>{#snippet asChild(props)}<Button {...props({ class: "w-full" })} variant="outline">Mark all as read</Button>{/snippet}</DrawerClose></div></DrawerContent></Drawer>FAQ
How is the bell button labeled?
It's icon-only, so aria-label gives the name and the count: Notifications, 5 unread. The badge is aria-hidden, so the count isn't read twice.
How are unread notifications marked?
A primary dot, a medium-weight title and a visually hidden Unread before the title. Read ones get a muted dot and regular weight, so the state isn't color alone.
Why is each notification a button?
So people can open it with a click or the keyboard. The rows have no handler yet: open the related page from each one.
Does Mark all as read clear the dots?
It's a DrawerClose, so it closes the drawer; it doesn't change the data. Keep the notifications in state and set them all read when it's pressed.
API Reference
Drawer
Sets swipeDirection="right" and showBar={false}. The rest is on the Drawer page.
Button
Sets props, aria-label, Notifications, 5, unread and relative. The rest is on the Button page.
Badge
Sets aria-hidden and pill. The rest is on the Badge page.





