Badge
Tone badges and status dots for states like paid, pending, live and degraded.
$
pnpm dlx shadcn@latest add https://lodeui.com/r/badge.jsonDefaultOutlinePaidPendingFailedBetaNew
OperationalDegradedOutageDeploying
components/examples/badge-demo.tsx
"use client";
import { Badge, StatusBadge } from "@/components/ui/badge";
export default function BadgeDemo() {
return (
<div className="flex flex-col items-center gap-5">
<div className="flex flex-wrap justify-center gap-2">
<Badge>Default</Badge><Badge tone="outline">Outline</Badge><Badge tone="success">Paid</Badge><Badge tone="warning">Pending</Badge><Badge tone="danger">Failed</Badge><Badge tone="info">Beta</Badge><Badge tone="solid">New</Badge>
</div>
<div className="flex flex-wrap justify-center gap-5">
<StatusBadge status="online" live>Operational</StatusBadge>
<StatusBadge status="degraded">Degraded</StatusBadge>
<StatusBadge status="offline">Outage</StatusBadge>
<StatusBadge status="info" live>Deploying</StatusBadge>
</div>
</div>
);
}When to use
- Short status or category labels: Paid, Draft, Beta.
- Service health with a live dot (StatusBadge).
When not to use
- Clickable filters: use buttons or a segmented control.
- Long text: use an alert or plain text.
Installation
$
pnpm dlx shadcn@latest add https://lodeui.com/r/badge.json1Copy the source into your project
components/ui/badge.tsximport * as React from "react"; import { cn } from "@/lib/utils"; const tones = { default: "bg-secondary text-secondary-foreground", outline: "border border-border text-foreground", success: "bg-emerald-500/12 text-emerald-700 dark:text-emerald-400", warning: "bg-amber-500/14 text-amber-700 dark:text-amber-400", danger: "bg-destructive/12 text-destructive", info: "bg-sky-500/12 text-sky-700 dark:text-sky-400", solid: "bg-primary text-primary-foreground", } as const; export type BadgeTone = keyof typeof tones; export interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> { tone?: BadgeTone; size?: "sm" | "md"; } export function Badge({ tone = "default", size = "sm", className, ...props }: BadgeProps) { return ( <span className={cn( "inline-flex shrink-0 items-center gap-1 whitespace-nowrap rounded-[5px] font-medium [&_svg]:size-3", size === "sm" ? "h-5 px-1.5 text-[11px]" : "h-6 px-2 text-xs", tones[tone], className, )} {...props} /> ); } const dots: Record<StatusBadgeProps["status"], string> = { online: "bg-emerald-500", degraded: "bg-amber-500", offline: "bg-destructive", pending: "bg-muted-foreground", info: "bg-sky-500", }; export interface StatusBadgeProps { status: "online" | "degraded" | "offline" | "pending" | "info"; children: React.ReactNode; /** Pulse the dot, for live or in-progress states. */ live?: boolean; className?: string; } /** A label with a colored status dot. */ export function StatusBadge({ status, children, live, className }: StatusBadgeProps) { return ( <span className={cn("inline-flex items-center gap-1.5 text-xs font-medium", className)}> <span className="relative flex size-2"> {live && <span className={cn("absolute inline-flex size-full animate-ping rounded-full opacity-60", dots[status])} />} <span className={cn("relative inline-flex size-2 rounded-full", dots[status])} /> </span> {children} </span> ); }
Usage
Import it from @/components/ui/badge after installing.
example.tsx
import { Badge, StatusBadge } from "@/components/ui/badge";
export function InvoiceStatus() {
return (
<div className="flex gap-2">
<Badge tone="success">Paid</Badge>
<StatusBadge status="online" live>Operational</StatusBadge>
</div>
);
}API reference
Badge
A small label. Accepts any span attributes.
| Prop | Type | Default | Description |
|---|---|---|---|
| tone | "default" | "outline" | "success" | "warning" | "danger" | "info" | "solid" | "default" | Color. |
| size | "sm" | "md" | "sm" | Text and padding size. |
StatusBadge
A badge with a colored dot for system states.
| Prop | Type | Default | Description |
|---|---|---|---|
| status | "online" | "degraded" | "offline" | "pending" | "info" | – | Sets the dot color. |
| live | boolean | – | Pulses the dot. |
Accessibility
- The text carries the meaning; the color and dot only support it.
- Tones keep text contrast at AA on both themes.
Motion
- Only the live dot pulses.
Responsive behavior
- Inline; never wraps.
Performance
- Static markup.
Notes for AI
- Write the status as text ("Failed"), don't rely on tone alone.
This page as Markdown, for assistants and coding agents:
/components/badge/markdownThe full library index for assistants is at /llms.txt.
Lode222 doc pagesllms.txt