# Badge

> A compact coloured tag for statuses, counts, and metadata. Polymorphic via `variant`, semantic-free by default.

- Category: primitive
- Status: stable (since 1.0.0)
- Tokens: --background-secondary, --foreground-primary, --foreground-muted, --foreground-info, --foreground-success, --foreground-warning, --foreground-danger
- Playground: https://design.freecodecamp.org/playground#badge
- npm dependencies: `react@>=18 <20`
- Registry dependencies: [theme](https://design.freecodecamp.org/registry/theme.md)
- Files:
  - `Badge.tsx` → `src/ui/badge/Badge.tsx` (raw: https://design.freecodecamp.org/registry/badge/Badge.tsx)
  - `badge.css` → `src/ui/badge/badge.css` (raw: https://design.freecodecamp.org/registry/badge/badge.css)

## Install (copy source)

1. Ensure the theme is installed once per project - tokens.css + base.css imported globally, fonts available. See https://design.freecodecamp.org/registry/theme.md and https://design.freecodecamp.org/registry/starter.md.
2. Copy the files below into `src/ui/badge/` (adjust to your project layout) and import the CSS once from your global stylesheet, e.g. `@import './ui/badge/badge.css';`.
3. Colors, spacing and type come from tokens - tailor the component by editing the copied source; recolour by editing tokens.css, not the component CSS.

## Usage

Badges surface small pieces of structured metadata next to a label - a
status chip, a count, or a category tag. The default variant is the neutral
tag; the tone variants map to the semantic foreground tokens.

## Usage

```tsx
import { Badge } from './ui/badge/Badge';
<Badge variant='success'>Stable</Badge>;
```

## Accessibility

Badges are decorative by default - they render as `<span>` with no role.
If a badge carries meaning that is not repeated in adjacent text, add an
`aria-label` so screen readers announce it. Avoid using colour alone to
communicate status.

## Example

```tsx
import { Badge } from './ui/badge/Badge';

<Badge>Default</Badge>
<Badge variant="success">Passed</Badge>
<Badge variant="warning">In review</Badge>
<Badge variant="danger">Failed</Badge>
```

## Props

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `variant` | `enum` | no | `default` |  |

## Source: Badge.tsx

```tsx
import React, { forwardRef } from 'react';

export type BadgeVariant =
  | 'default'
  | 'success'
  | 'warning'
  | 'danger'
  | 'info'
  | 'purple';

export interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
  variant?: BadgeVariant;
}

export const Badge = forwardRef<HTMLSpanElement, BadgeProps>(
  ({ variant = 'default', className = '', children, ...rest }, ref) => {
    const classes = [
      'badge',
      variant !== 'default' && `badge--${variant}`,
      className
    ]
      .filter(Boolean)
      .join(' ');
    return (
      <span ref={ref} className={classes} {...rest}>
        {children}
      </span>
    );
  }
);
Badge.displayName = 'Badge';
```

## Source: badge.css

```css
.badge {
  display: inline-flex;
  align-items: center;
  padding: 3px 9px;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1;
  color: var(--foreground-primary);
  background: var(--background-tertiary);
  border: 1px solid var(--background-quaternary);
}
.badge--success {
  color: var(--success-color);
  background: var(--success-background);
  border-color: var(--success-color);
}
.badge--warning {
  color: var(--warning-color);
  background: var(--warning-background);
  border-color: var(--warning-color);
}
.badge--danger {
  color: var(--danger-color);
  background: var(--danger-background);
  border-color: var(--danger-color);
}
.badge--info {
  color: var(--highlight-color);
  background: var(--highlight-background);
  border-color: var(--highlight-color);
}
.badge--purple {
  color: var(--purple-color);
  background: var(--purple-background);
  border-color: var(--purple-color);
}
```

## HTML / vanilla variant

```html
<span class="badge badge--success">Passed</span>
<span class="badge badge--warning">In review</span>
<span class="badge badge--danger">Failed</span>
```

Interactive behaviours for plain HTML come from the vanilla runtime (data-uikit-* attributes): https://design.freecodecamp.org/registry/vanilla.md - or download https://design.freecodecamp.org/cdn/uikit.global.js once and self-host it (do not hotlink).

## For coding agents

This library is distributed as copyable source, not an npm package. Start at https://design.freecodecamp.org/registry/starter.md, discover components via https://design.freecodecamp.org/llms.txt, and copy files into the consuming project. Keep token names intact; recolour by editing the copied tokens.css.
