# Badge

> A status, a tag or a count: statuses ease their colour and morph their word, live dots breathe, counts roll and fold away at zero.

Status badges usually swap colour and text in one frame, and unread counts blink in and out. Here a status eases across tones while its word morphs ("Pending" → "Paid"), a live dot breathes a ring outward, and a count rolls each digit the way it moved, caps at 99+, and folds away when it reaches zero.

## Install

```bash
npx shadcn@latest add https://hairlineui.com/r/badge.json
```

Needs React 19, Tailwind CSS v4 and shadcn/ui theme variables (any style, light and dark). Icons from lucide-react.

- npm: none
- Hairline UI components it needs (the CLI installs them too): `number-roll`, `text-morph`, `ui-interaction-motion`
- Docs and live preview: https://hairlineui.com/ui/badge
- Registry item (source): https://hairlineui.com/r/badge.json

## Usage

```tsx
import { Badge } from "@/components/ui/badge";

<Badge tone={paid ? "success" : "warning"} dot>{paid ? "Paid" : "Pending"}</Badge>
<Badge tone="primary" count={unread} />
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `children` | `string` | – | The word. |
| `tone` | `"neutral" \| "primary" \| "success" \| "warning" \| "danger"` | `"neutral"` | Colour. |
| `outline` | `boolean` | `false` | Hairline only. |
| `dot` | `boolean \| "pulse"` | – | A dot before the text; "pulse" breathes. |
| `count / max / showZero` | `number / number / boolean` | – | A rolling number instead of text. |
| `icon` | `ReactNode` | – | A 12px icon. |
| `size` | `"sm" \| "md"` | `"md"` | 20px or 24px. |

## States

- **status change**: Colours ease (300ms) and the word morphs letter by letter.
- **live**: With dot="pulse", a ring scales out of the dot and fades (1.6s loop).
- **count**: Digits roll the way the count moved; at 0 the badge folds away (320ms) unless showZero.

## What it handles

A status that changes in place deserves to look like it changed, not like a different badge was dropped in.

- **Tone changes ease**: Background, text and dot colours transition (300ms) as the word morphs.
- **Counts that roll**: NumberRoll digits, 99+ cap, fold away at zero.
- **Live dot**: A ring breathes out from the dot every 1.6s.
- **Five tones, two looks**: neutral, primary, success, warning, danger; filled or outline.

## Replaces

status pill, notification count, live indicator

## Where it fits

- **Invoice and order tables**: Paid, Pending, Overdue in a status column.
- **Deploy and build lists**: A breathing "Building" dot that settles to "Ready".
- **Navigation**: Unread counts on Inbox and Mentions.
- **Tags**: Plan, role or category labels in outline.

## Notes

- Reduced motion: no breathing ring, the count changes in place.
- Status colours always come with a word, never colour alone.

License: MIT (https://hairlineui.com/license#components)
