Notification Center
A notification bell that opens a popover with tabbed categories, a notification list, and toast integration for new arrivals.
Notification center
Section titled “Notification center”A notification bell that opens a popover with tabbed categories, a Notification list, and a toast integration for new arrivals.
import { Badge, Button, Heading, Notification, Popover, PopoverContent, PopoverTrigger, Stack, Tabs, TabsContent, TabsList, TabsTrigger, toast,} from '@arshad-shah/cynosure-react';
type Item = { id: string; title: string; body: string; unread: boolean; timestamp: string; category: 'all' | 'mentions' | 'system';};
export function NotificationCenter({ items }: { items: Item[] }) { const unreadCount = items.filter((i) => i.unread).length;
return ( <Popover> <PopoverTrigger asChild> <Button variant="ghost" aria-label="Notifications"> Bell {unreadCount > 0 && ( <Badge colorScheme="danger" size="sm"> {unreadCount} </Badge> )} </Button> </PopoverTrigger> <PopoverContent width={{ base: '100vw', sm: '400px' }}> <Stack gap="3" padding="3"> <Stack direction="row" align="center" justify="space-between"> <Heading level={2} size="sm">Notifications</Heading> <Button variant="link" onClick={() => toast.success('All notifications marked as read')} > Mark all read </Button> </Stack>
<Tabs defaultValue="all"> <TabsList> <TabsTrigger value="all">All</TabsTrigger> <TabsTrigger value="mentions">Mentions</TabsTrigger> <TabsTrigger value="system">System</TabsTrigger> </TabsList>
{(['all', 'mentions', 'system'] as const).map((cat) => ( <TabsContent key={cat} value={cat}> <Stack gap="2"> {items .filter((i) => cat === 'all' || i.category === cat) .map((i) => ( <Notification key={i.id} unread={i.unread} title={i.title} timestamp={i.timestamp} > {i.body} </Notification> ))} </Stack> </TabsContent> ))} </Tabs> </Stack> </PopoverContent> </Popover> );}Live arrivals via toast
Section titled “Live arrivals via toast”When your websocket pushes a new notification, call toast() for the
immediate in-page announcement and update the list behind the popover:
toast('Sarah commented on your pull request', { description: 'Clicking opens the thread in a new tab', action: { label: 'Open', onClick: () => window.open(url) },});