# Badge

A small label for short static data, such as a plan, a version, a count or a tag.

```tsx
import { Badge } from 'ferry-ui'

export default function BadgeHero() {
  return (
    <div className="flex flex-wrap items-center gap-2">
      <span className="text-base font-medium text-foreground">Billing portal</span>
      <Badge font="mono" shape="square">
        Pro
      </Badge>
      <Badge variant="outline" font="mono">
        v2.4.1
      </Badge>
      <Badge variant="primary">New</Badge>
    </div>
  )
}
```

## Usage guidelines

- **Short static data.** Use a badge for a plan, a version, a count or a tag.
- **A state is not a badge.** For the state of a record, use the `StatusBadge` of [Status](/docs/components/status).
- **A badge is not a button.** For an action, use a [Button](/docs/components/button) with `size="tiny"`.
- **Keep the text short.** A badge has one line. Its text does not wrap.

## Anatomy

Import the component. A badge has one part.

```tsx title="Anatomy"

<Badge />
```

## Examples

### Variants

The `variant` prop sets the color. `default` and `outline` are the neutral variants.

```tsx
import { Badge } from 'ferry-ui'

export default function BadgeVariants() {
  return (
    <>
      <Badge>Default</Badge>
      <Badge variant="outline">Outline</Badge>
      <Badge variant="success">Stable</Badge>
      <Badge variant="warning">Beta</Badge>
      <Badge variant="destructive">Deprecated</Badge>
      <Badge variant="info">Preview</Badge>
      <Badge variant="primary">New</Badge>
    </>
  )
}
```

| Variant | Role |
| --- | --- |
| `default` | A neutral badge with a fill. |
| `outline` | A neutral badge with no fill. |
| `success`, `warning`, `destructive`, `info` | A badge with a color, for example a `warning` "Beta". |
| `primary` | A solid badge for emphasis, for example "New". Use few of them. |

### Font

Set `font="mono"` for values that come from a machine: a plan, a version, a region, an ID.

```tsx
import { Badge } from 'ferry-ui'

export default function BadgeFont() {
  return (
    <>
      <Badge>Pro</Badge>
      <Badge font="mono">Pro</Badge>
      <Badge variant="outline" font="mono">
        v2.4.1
      </Badge>
      <Badge variant="outline" font="mono">
        eu-west
      </Badge>
    </>
  )
}
```

### Shape

The `shape` prop sets the corners. The default is `pill`. A `square` badge has a radius of 4px.

```tsx
import { Badge } from 'ferry-ui'

export default function BadgeShape() {
  return (
    <>
      <Badge shape="pill">Pill</Badge>
      <Badge shape="square">Square</Badge>
      <Badge variant="outline" shape="square" font="mono">
        EUR
      </Badge>
    </>
  )
}
```

### Letter case

A badge shows its text in capital letters. Set `case="normal"` to show the text as you write it, for example a name.

```tsx
import { Badge } from 'ferry-ui'

export default function BadgeCase() {
  return (
    <>
      <Badge variant="outline">Design team</Badge>
      <Badge variant="outline" case="normal">
        Design team
      </Badge>
      <Badge case="normal">3 seats left</Badge>
    </>
  )
}
```

### Icons

Put a lucide icon in the badge, before the text. The badge sets the size of the icon.

```tsx
import { Badge } from 'ferry-ui'
import { Lock, Sparkles, Users } from 'lucide-react'

export default function BadgeIcons() {
  return (
    <>
      <Badge variant="outline" case="normal">
        <Lock />
        Private
      </Badge>
      <Badge case="normal">
        <Users />8 members
      </Badge>
      <Badge variant="primary">
        <Sparkles />
        New
      </Badge>
    </>
  )
}
```

### Link with the badge look

With `asChild`, the badge gives its look to its child element. Use it for a link.

```tsx
import { Badge } from 'ferry-ui'

export default function BadgeAsChild() {
  return (
    <Badge asChild variant="outline" case="normal">
      <a
        href="https://github.com/Carter2307/ferry-ui"
        target="_blank"
        rel="noreferrer"
        className="hover:bg-surface-200 hover:text-foreground"
      >
        Source code
      </a>
    </Badge>
  )
}
```

### Long text

For text that comes from a user, give the badge a maximum width. Put the text in a `truncate` element. Keep the full text in `title`.

```tsx
import { Badge } from 'ferry-ui'

const PLAN = 'Enterprise annual plan with priority support'

export default function BadgeLongText() {
  return (
    <div className="flex w-64 rounded-lg border bg-surface-100 p-3">
      {/* The badge takes the width of its parent at most. The full text stays in `title`. */}
      <Badge variant="outline" case="normal" className="max-w-full justify-start" title={PLAN}>
        <span className="truncate">{PLAN}</span>
      </Badge>
    </div>
  )
}
```

### Badge look on another element

`badgeVariants()` returns the classes of a badge. Use it for an element that cannot be a `Badge`, such as a list item.

```tsx
import { badgeVariants } from 'ferry-ui'

const TAGS = ['Design', 'Frontend', 'Roadmap', 'Customer request']

export default function BadgeClassHelper() {
  return (
    <ul aria-label="Tags" className="flex flex-wrap gap-1.5">
      {TAGS.map((tag) => (
        <li key={tag} className={badgeVariants({ variant: 'outline', case: 'normal' })}>
          {tag}
        </li>
      ))}
    </ul>
  )
}
```

## API reference

### Badge

`Badge` also accepts each attribute of the `<span>` element.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `variant` | `"default" \| "primary" \| "outline" \| "destructive" \| "warning" \| "success" \| "info"` | `default` | Tone. `default` (neutral surface) and `outline` (transparent) for neutral tags; `success`, `warning`, `destructive`, `info` (soft tinted fills) to colour a tag; `primary` (solid fill in the primary colour) sparingly, for emphasis such as "New". |
| `font` | `"sans" \| "mono"` | `sans` | Typeface: `sans` (default) or `mono` for machine-like values (plan tiers, versions, regions, IDs). |
| `shape` | `"pill" \| "square"` | `pill` | Corners: `pill` (fully rounded, default) or `square` (4px-radius chip). |
| `case` | `"upper" \| "normal"` | `upper` | Letter case: `upper` (default, tracked caps) or `normal` for sentence-case text such as names. |
| `asChild` | `boolean` | `false` | Render the single child element (e.g. an `<a>`) with badge styling instead of a `<span>`. |

### badgeVariants

`badgeVariants(options)` returns the classes as a string. Each option is optional.

| Option | Type | Role |
| --- | --- | --- |
| `variant` | `'default' \| 'outline' \| 'success' \| 'warning' \| 'destructive' \| 'info' \| 'primary'` | The color. |
| `font` | `'sans' \| 'mono'` | The font. |
| `shape` | `'pill' \| 'square'` | The corners. |
| `case` | `'upper' \| 'normal'` | The letter case. |
