Status Badge
A badge with a colored status dot and optional pulse animation for live states.
OperationalDegradedDownIdle
Installation
npx shadcn@latest add @hazine/status-badgeSource
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const statusBadgeVariants = cva(
"inline-flex items-center gap-1.5 rounded-full border px-2.5 py-0.5 text-xs font-medium",
{
variants: {
status: {
online: "border-emerald-500/30 bg-emerald-500/10 text-emerald-600 dark:text-emerald-400",
degraded: "border-amber-500/30 bg-amber-500/10 text-amber-600 dark:text-amber-400",
offline: "border-red-500/30 bg-red-500/10 text-red-600 dark:text-red-400",
idle: "border-border bg-muted text-muted-foreground",
},
},
defaultVariants: {
status: "online",
},
}
)
const dotColor: Record<string, string> = {
online: "bg-emerald-500",
degraded: "bg-amber-500",
offline: "bg-red-500",
idle: "bg-muted-foreground",
}
interface StatusBadgeProps
extends React.ComponentProps<"span">,
VariantProps<typeof statusBadgeVariants> {
pulse?: boolean
}
export function StatusBadge({
status = "online",
pulse = false,
className,
children,
...props
}: StatusBadgeProps) {
return (
<span className={cn(statusBadgeVariants({ status }), className)} {...props}>
<span className="relative flex size-2">
{pulse && (
<span
className={cn(
"absolute inline-flex size-full animate-ping rounded-full opacity-60 motion-reduce:hidden",
dotColor[status ?? "online"]
)}
/>
)}
<span
className={cn(
"relative inline-flex size-2 rounded-full",
dotColor[status ?? "online"]
)}
/>
</span>
{children}
</span>
)
}
Dependencies
- class-variance-authority