Status Badge
Composable status primitive with semantic tones, variants, live/deploy pulses, meta text, and removable/selectable tag behaviour.
Live system status
Online/offline with pulsing dot indicators.
API healthyWorker offlineLive
live-example.tsx
1import { StatusBadge } from "@/registry/ui";23export function StatusBadgeLiveExample() {4 return (5 <div className="flex flex-wrap items-center justify-center gap-2">6 <StatusBadge status="online" dot>7 API healthy8 </StatusBadge>9 <StatusBadge status="offline" dot variant="outline">10 Worker offline11 </StatusBadge>12 <StatusBadge status="online" size="sm" variant="solid">13 Live14 </StatusBadge>15 </div>16 );17}
Loading / deploy
Spinner for loading; deploy with optional pulse dot.
Deploying v2.4.1SyncingRolling update
loading-example.tsx
1import { StatusBadge } from "@/registry/ui";23export function StatusBadgeLoadingExample() {4 return (5 <div className="flex flex-wrap items-center justify-center gap-2">6 <StatusBadge status="deploying" loading>7 Deploying v2.4.18 </StatusBadge>9 <StatusBadge status="info" loading variant="outline">10 Syncing11 </StatusBadge>12 <StatusBadge status="deploying" dot pulse>13 Rolling update14 </StatusBadge>15 </div>16 );17}
With meta
Primary label plus secondary metric or timestamp.
Database12msCache stale2m agoGateway503
meta-example.tsx
1import { StatusBadge } from "@/registry/ui";23export function StatusBadgeMetaExample() {4 return (5 <div className="flex flex-col items-center gap-3">6 <StatusBadge status="success" meta="12ms">7 Database8 </StatusBadge>9 <StatusBadge status="warning" meta="2m ago" variant="outline">10 Cache stale11 </StatusBadge>12 <StatusBadge status="error" meta="503" size="sm">13 Gateway14 </StatusBadge>15 </div>16 );17}
Interactive tags
Selectable filters with removable chips.
ProductionEU-WestPaid plan
Click to select · dismiss to remove
interactive-example.tsx
1"use client";23import { useState } from "react";4import { StatusBadge } from "@/registry/ui";56export function StatusBadgeInteractiveExample() {7 const [tags, setTags] = useState(["Production", "EU-West", "Paid plan"]);8 const [active, setActive] = useState("Production");910 return (11 <div className="flex max-w-md flex-col items-center gap-3">12 <div className="flex flex-wrap justify-center gap-2">13 {tags.map((tag) => (14 <StatusBadge15 key={tag}16 status={active === tag ? "info" : "neutral"}17 selectable18 selected={active === tag}19 removable20 variant={active === tag ? "solid" : "soft"}21 onClick={() => setActive(tag)}22 onRemove={() => {23 setTags((current) => {24 const next = current.filter((t) => t !== tag);25 setActive((prev) => (prev === tag ? next[0] ?? "" : prev));26 return next;27 });28 }}29 >30 {tag}31 </StatusBadge>32 ))}33 </div>34 <p className="text-center text-xs text-muted-foreground">35 Click to select · dismiss to remove36 </p>37 </div>38 );39}
Installation & source
Install via the shadcn CLI or copy the registry files manually.
bash
npx shadcn@latest add @tt-ui/status-badge
Props
| Name | Type | Default | Description |
|---|---|---|---|
| status | "neutral" | "success" | "warning" | "error" | "info" | "online" | "offline" | "deploying" | "neutral" | Semantic tone; online/deploying enable pulse defaults |
| variant | "solid" | "soft" | "outline" | "soft" | Visual weight; soft uses subtle gradients |
| size | "sm" | "md" | "md" | Compact or default density |
| icon | ReactNode | mapped default per status | Overrides default icon; ignored when loading |
| dot | boolean | auto for online/deploying | Leading status dot; pulse animates the dot only |
| pulse / loading | boolean | false | Pulse on dot; loading shows spinner instead of icon |
| meta | string | undefined | Secondary text (latency, timestamp, code) |
| removable / onRemove | boolean / () => void | undefined | Dismiss button when both are set |
| selectable / selected | boolean | false | Selection ring; use with onClick |