# Badge

> A small label for a status, category, or count, with tones, emphasis levels, and sizes.

- Name: `badge`
- Status: beta
- Categories: data, display
- File: the install writes `badge.tsx` to your `ui` alias, `@/components/ui` by default.
- npm packages: `class-variance-authority`. The install adds them.
- Gallery: https://arbokui.com/components/badge
- Registry item: https://arbokui.com/r/badge.json

## Install

1. Add the registry to `components.json`. Do this first, once:

   ```bash
   npx shadcn@latest registry add "@arbokui=https://arbokui.com/r/{name}.json"
   ```

   The command writes this entry. You can also add it by hand:

   ```json
   {
     "registries": {
       "@arbokui": "https://arbokui.com/r/{name}.json"
     }
   }
   ```

   Without this step, the shadcn CLI looks up `@arbokui` in a public list that Arbokui does not control.

2. Add the theme once per app. It replaces your color tokens with ones checked for contrast:

   ```bash
   npx shadcn@latest add @arbokui/theme
   ```

3. Add the component:

   ```bash
   npx shadcn@latest add @arbokui/badge
   ```

## Use it for

- Labeling a status or category next to other content: Paid, Draft, Beta, Failed.
- Showing a short count next to a label, like unread messages.
- Use tone to say what the label means and emphasis to say how much it should stand out.
- Use soft or outline in tables and long lists. Save solid for the one label that must stand out.

## Avoid it for

- Anything people click. A badge is not focusable. Use a Button with size='sm', or a link styled with badgeVariants().
- Sentences or long text. A badge never wraps. Use an Alert or plain text.
- Showing meaning with color alone. The text must say the status, like 'Failed', not just turn red.
- Using tone='danger' for anything that is not an error or a risk.

## Props

- `tone`: `"neutral" | "brand" | "danger" | "success" | "warning"`. Default `"neutral"`. Color role.
- `emphasis`: `"solid" | "soft" | "outline" | "ghost"`. Default `"solid"`. How loud the badge is.
- `size`: `"sm" | "md" | "lg"`. Default `"md"`. Height, padding, and text size. Density scales them.
- `className`: `string`. Extra classes. Later classes win, so className='rounded-full' replaces the radius.

## Accessibility

- Renders a plain \<span> with no role, so screen readers read its text in line with the content around it.
- It is not focusable and does nothing on click. Keyboard users skip past it.
- The text must carry the meaning. Some people cannot tell the tones apart.
- A badge with only an icon needs words for screen readers. Add \<span className="sr-only">Online\</span> inside it.
- The theme tests hold badge text to 4.5:1: solid and soft text on their own fills, and outline and ghost text on the page background.
- Screen readers do not hear a count change. If the change matters, announce it in a role="status" region.

## Examples

### Status in a table row

```tsx
<Badge tone="success" emphasis="soft">Paid</Badge>
```

### Count next to a label

```tsx
<span className="inline-flex items-center gap-2">
  Inbox
  <Badge tone="brand" size="sm">
    12<span className="sr-only"> unread</span>
  </Badge>
</span>
```

### With an icon

```tsx
import { CircleCheck } from "lucide-react";

<Badge tone="success" emphasis="outline">
  <CircleCheck />
  Verified
</Badge>
```

### A link that looks like a badge

```tsx
import Link from "next/link";
import { badgeVariants } from "@/components/ui/badge";

<Link href="/tags/react" className={badgeVariants({ emphasis: "outline" })}>
  react
</Link>
```
