Omarchy Notification Center
blockA dismissable notification history mirroring omarchy-shell notifications.
bunx --bun shadcn@latest add yamz8/omarchy-shadcn-registry/omarchy-notification-centerPreview
Dependencies
- npm
- lucide-react
- registry
- button, card, empty, yamz8/omarchy-shadcn-registry/omarchy-keycap, yamz8/omarchy-shadcn-registry/omarchy-status
Source
registry/blocks/omarchy-notification-center.tsx
"use client"
import * as React from "react"
import { XIcon } from "lucide-react"
import { Button } from "@/components/ui/button"
import {
Card,
CardAction,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card"
import {
Empty,
EmptyDescription,
EmptyHeader,
EmptyTitle,
} from "@/components/ui/empty"
import { OmarchyShortcut } from "@/components/ui/omarchy-keycap"
import { OmarchyStatus } from "@/components/ui/omarchy-status"
type OmarchyNotification = {
id: string
app: string
body: string
time: string
status: React.ComponentProps<typeof OmarchyStatus>["status"]
}
const initialNotifications: readonly OmarchyNotification[] = [
{
id: "1",
app: "System",
body: "Theme switched to Tokyo Night.",
time: "now",
status: "active",
},
{
id: "2",
app: "Updates",
body: "12 packages ready to upgrade.",
time: "4m",
status: "idle",
},
{
id: "3",
app: "Backup",
body: "Snapshot failed — target unreachable.",
time: "1h",
status: "error",
},
]
/** Mirrors `omarchy-shell notifications`: a dismissable notification history. */
export function OmarchyNotificationCenter() {
const [notifications, setNotifications] = React.useState(initialNotifications)
return (
<Card className="w-full max-w-md">
<CardHeader>
<CardTitle>Notifications</CardTitle>
<CardDescription>
{notifications.length === 0
? "Nothing waiting."
: `${notifications.length} unread`}
</CardDescription>
{notifications.length > 0 ? (
<CardAction>
<Button
variant="ghost"
size="sm"
onClick={() => setNotifications([])}
>
Dismiss all
</Button>
</CardAction>
) : null}
</CardHeader>
<CardContent>
{notifications.length === 0 ? (
<Empty className="py-6">
<EmptyHeader>
<EmptyTitle>Inbox clear</EmptyTitle>
<EmptyDescription>
New notifications appear here as they arrive.
</EmptyDescription>
</EmptyHeader>
</Empty>
) : (
<ul className="flex flex-col gap-2">
{notifications.map((notification) => (
<li
key={notification.id}
className="flex items-start gap-3 rounded-md border border-border p-2.5"
>
<div className="flex min-w-0 flex-col gap-1.5">
<div className="flex items-center gap-2">
<OmarchyStatus status={notification.status}>
{notification.app}
</OmarchyStatus>
<span className="font-mono text-[0.6875rem] text-muted-foreground">
{notification.time}
</span>
</div>
<p className="text-sm leading-relaxed">{notification.body}</p>
</div>
<Button
variant="ghost"
size="icon-sm"
className="ml-auto"
onClick={() =>
setNotifications((current) =>
current.filter((item) => item.id !== notification.id)
)
}
>
<XIcon />
<span className="sr-only">
Dismiss notification from {notification.app}
</span>
</Button>
</li>
))}
</ul>
)}
</CardContent>
<CardFooter className="justify-between gap-4">
<span className="text-xs text-muted-foreground">Dismiss all</span>
<OmarchyShortcut keys={["Super", "Shift", ","]} />
</CardFooter>
</Card>
)
}