Status Badge

Pulsing status pills for operational, degraded, outage and maintenance.

All systems operationalDegraded performanceMajor outageScheduled maintenance

Installation

  1. Install the dependencies

    $ npm i motion lucide-react
  2. Copy the source into components/ui/status-badge.tsx

    components/ui/status-badge.tsx
    "use client";
    
    import { motion } from "motion/react";
    
    type Status = "online" | "degraded" | "down" | "maintenance";
    
    const styles: Record<Status, { label: string; dot: string; badge: string }> = {
      online: { label: "All systems operational", dot: "bg-emerald-500", badge: "border-emerald-200 bg-emerald-50 text-emerald-700" },
      degraded: { label: "Degraded performance", dot: "bg-amber-500", badge: "border-amber-200 bg-amber-50 text-amber-700" },
      down: { label: "Major outage", dot: "bg-rose-500", badge: "border-rose-200 bg-rose-50 text-rose-700" },
      maintenance: { label: "Scheduled maintenance", dot: "bg-blue-500", badge: "border-blue-200 bg-blue-50 text-blue-700" },
    };
    
    export function StatusBadge({ status, label }: { status: Status; label?: string }) {
      const s = styles[status];
      return (
        <span role="status" className={`inline-flex items-center gap-2 rounded-full border px-3 py-1 text-xs font-medium ${s.badge}`}>
          <span className="relative flex size-2">
            {status !== "maintenance" && (
              <motion.span
                className={`absolute inline-flex size-full rounded-full ${s.dot}`}
                animate={{ scale: [1, 2.4], opacity: [0.6, 0] }}
                transition={{ duration: status === "down" ? 0.9 : 1.6, repeat: Infinity, ease: "easeOut" }}
              />
            )}
            <span className={`relative inline-flex size-2 rounded-full ${s.dot}`} />
          </span>
          {label ?? s.label}
        </span>
      );
    }
    
    export default function Demo() {
      return (
        <div className="flex flex-col items-center gap-3">
          {(Object.keys(styles) as Status[]).map((s) => (
            <StatusBadge key={s} status={s} />
          ))}
        </div>
      );
    }
    
  3. Use it

    The file exports the component and a Demo showing typical usage. Import whichever you need.