Badge
A compact label that communicates intent — not just appearance. Covers status, severity, AI agent states, and lifecycle.
Overview
Badge is the foundational semantic component in Clarx. Its API is built around two axes:
- Intent — what does this communicate? (
success,warning,danger,neutral,info,brand) - Appearance — how prominent should it be? (
softorsolid)
You never pass a color. You express meaning, and the component translates it into the correct visual output.
Intent × Appearance
soft is the default — subdued, readable inside a table row or card. solid is for when the badge needs to command attention on its own.
With dot
The dot prop adds a status indicator before the label.
false— no dot (default)"static"— solid dot, for stable terminal states"pulse"— animated dot, for live or in-progress states
<Badge intent="brand" dot="pulse">Running</Badge>
<Badge intent="success" dot="static">Ready</Badge>Size
md is the default. Use sm in dense contexts like table cells or sidebar labels.
Keywords
Keywords are the shorthand layer. Common states — ready, pending, failed, thinking, streaming — are fully pre-resolved. One prop replaces four.
// instead of:
<Badge intent="brand" appearance="soft" dot="pulse">Running</Badge>
// write:
<Badge keyword="running" />Full keyword reference
| keyword | preview | intent | appearance | dot |
|---|---|---|---|---|
| ready | Ready | success | soft | static |
| running | Running | brand | soft | pulse |
| pending | Pending | warning | soft | pulse |
| paused | Paused | neutral | soft | static |
| failed | Failed | danger | soft | static |
| error | Error | danger | soft | static |
| cancelled | Cancelled | neutral | soft | static |
| done | Done | success | soft | static |
| thinking | Thinking | neutral | soft | pulse |
| streaming | Streaming | brand | soft | pulse |
| tool-call | Using tool | info | soft | pulse |
| uncertain | Uncertain | warning | soft | — |
| low | Low | success | soft | — |
| medium | Medium | warning | soft | — |
| high | High | danger | soft | — |
| critical | Critical | danger | solid | — |
| new | New | brand | soft | — |
| beta | Beta | info | soft | — |
| alpha | Alpha | warning | soft | — |
| deprecated | Deprecated | neutral | soft | — |
AI-specific keywords
The AI agent states are first-class keywords. They encode temporal meaning that doesn't exist in traditional design systems:
<Badge keyword="thinking" /> // neutral + pulse → model is processing
<Badge keyword="streaming" /> // brand + pulse → response is coming in
<Badge keyword="tool-call" /> // info + pulse → agent is calling a tool
<Badge keyword="uncertain" /> // warning → model expressed low confidence
<Badge keyword="done" /> // success + static → generation completeProps
| Prop | Type | Default | Description |
|---|---|---|---|
keyword | BadgeKeyword | — | Shorthand for a named state. Resolves intent, appearance, dot, and label. |
intent | Intent | "neutral" | Semantic meaning. Drives color. |
appearance | "soft" | "solid" | "soft" | Visual weight. |
dot | false | "static" | "pulse" | false | Status dot before the label. |
size | "sm" | "md" | "md" | Size variant. |
label | string | — | Overrides the keyword's default label. |
children | ReactNode | — | Content. Takes precedence over label. |
className | string | — | Layout classes only (mt-2, w-full). Not for style overrides. |
Design rules
No color via className. If you find yourself writing className="text-red-500" on a Badge, use intent="danger" instead. The component owns its color.
No !important overrides. !h-5 or !px-1.5 on a Badge is a signal that the API is missing a variant. Open an issue rather than forcing it.
Prefer keyword for named states. If the state has a name ("Ready", "Running", "Failed"), it should be a keyword — not a manual combination of intent + dot + label.
Source
packages/ui/src/badge.tsx — copy into components/ui/badge.tsx in your project.