> For AI agents: the complete documentation index is available at https://wallarm.github.io/design-system/llms.txt, the full documentation bundle is available at https://wallarm.github.io/design-system/llms-full.txt.

# Badge

The status chip the rest of the family is built from — reach for the dedicated component when one exists (`HttpMethod`, `ResponseCode`, `Ip`, `Country`) rather than rebuilding it here, and for `Tag` when the chip is interactive. Colour carries the meaning, so choose it from what the value is rather than from what looks right on the page.

[Source](https://github.com/wallarm/design-system/tree/main/packages/design-system/src/components/Badge) · [Storybook](https://wallarm.github.io/design-system/storybook/?path=/docs/status-indication-badge--overview)

```tsx
import { Badge } from '@wallarm-org/design-system/Badge';

export const Basic = () => <Badge>Badge</Badge>;
```

## Usage

```tsx
import { Badge } from '@wallarm-org/design-system/Badge';
```

## Examples

### Dotted

A leading dot in the current colour, for a status that reads faster as a mark than as a fill.

```tsx
import { Badge } from '@wallarm-org/design-system/Badge';

export const Dotted = () => (
  <Badge variant='dotted'>
    Badge
  </Badge>
);
```

### Sizes

Two heights. `medium` exists for dense rows; anything smaller stops being legible at a
glance, which is the only thing a badge is for.

```tsx
import { Badge } from '@wallarm-org/design-system/Badge';
import { HStack } from '@wallarm-org/design-system/Stack';

export const Sizes = () => (
  <HStack align='center' gap={8}>
    <Badge size='small'>
      Small
    </Badge>
    <Badge size='medium'>
      Medium
    </Badge>
    <Badge size='large'>
      Large
    </Badge>
  </HStack>
);
```

### Types

The emphasis ladder from `solid` down to `text`. Drop the emphasis when badges are everywhere
— a table of solid chips is a table nobody can scan.

```tsx
import { Badge } from '@wallarm-org/design-system/Badge';
import { HStack } from '@wallarm-org/design-system/Stack';

export const Types = () => (
  <HStack gap={8}>
    <Badge type='solid'>
      Solid
    </Badge>
    <Badge type='secondary'>
      Secondary
    </Badge>
    <Badge type='outline'>
      Outline
    </Badge>
    <Badge type='text'>
      Text
    </Badge>
    <Badge type='text-color'>
      Text Color
    </Badge>
  </HStack>
);
```

### Text variants

`text` and `text-color`, the two flattest types. They suit a value that must be read but
should not compete with the row it sits in.

```tsx
import { Badge } from '@wallarm-org/design-system/Badge';
import { HStack } from '@wallarm-org/design-system/Stack';

export const TextVariants = () => (
  <HStack gap={8}>
    <Badge textVariant='default'>
      Default Text
    </Badge>
    <Badge textVariant='code'>
      Code Text
    </Badge>
  </HStack>
);
```

### With icons left

An icon before the label, which is how a status reads without relying on colour alone.

```tsx
import { Badge } from '@wallarm-org/design-system/Badge';
import { Check, CircleCheck, Info, X } from '@wallarm-org/design-system/icons';
import { HStack } from '@wallarm-org/design-system/Stack';

export const WithIconsLeft = () => (
  <HStack gap={8}>
    <Badge>
      <Check size='sm' />
      Success
    </Badge>
    <Badge>
      <X size='sm' />
      Error
    </Badge>
    <Badge>
      <Info size='sm' />
      Info
    </Badge>
    <Badge>
      <CircleCheck size='sm' />
      Verified
    </Badge>
    <Badge>
      <Check size='sm' />
      Complete
    </Badge>
  </HStack>
);
```

### With icons right

An icon after the label, for a mark about the value rather than the value's own state.

```tsx
import { Badge } from '@wallarm-org/design-system/Badge';
import { Check, CircleCheck, Info, X } from '@wallarm-org/design-system/icons';
import { HStack } from '@wallarm-org/design-system/Stack';

export const WithIconsRight = () => (
  <HStack gap={8}>
    <Badge>
      Success
      <Check size='sm' />
    </Badge>
    <Badge>
      Error
      <X size='sm' />
    </Badge>
    <Badge>
      Info
      <Info size='sm' />
    </Badge>
    <Badge>
      Verified
      <CircleCheck size='sm' />
    </Badge>
    <Badge>
      Complete
      <Check size='sm' />
    </Badge>
  </HStack>
);
```

### Icons only

No label at all. Only safe where the icon's meaning is already established elsewhere on the
page, since nothing here names it.

```tsx
import { Badge } from '@wallarm-org/design-system/Badge';
import { Check, CircleCheck, Info, X } from '@wallarm-org/design-system/icons';
import { HStack } from '@wallarm-org/design-system/Stack';

export const IconsOnly = () => (
  <HStack gap={8}>
    <Badge>
      <Check size='sm' />
    </Badge>
    <Badge>
      <X size='sm' />
    </Badge>
    <Badge>
      <Info size='sm' />
    </Badge>
    <Badge>
      <CircleCheck size='sm' />
    </Badge>
    <Badge>
      <Check size='sm' />
    </Badge>
  </HStack>
);
```

### Muted variants

`muted` drops the saturation for a status that is true but not worth attention — the case for
everything that is merely fine.

```tsx
import { Badge, type BadgeType } from '@wallarm-org/design-system/Badge';
import { BadgeTypeEnum } from './constants';
import { badgeColorsMuted } from './generateBadgeVariants';

export const MutedVariants = () => (
  <table className='w-full'>
    <thead>
      <tr>
        {Object.keys(BadgeTypeEnum).map(type => (
          <th key={type} className='sb-annotation p-8 text-left'>
            {type}
          </th>
        ))}
      </tr>
    </thead>
    <tbody>
      {badgeColorsMuted.map(color => (
        <tr key={color}>
          {Object.values(BadgeTypeEnum).map((type: BadgeType) => (
            <td key={type} className='p-8'>
              {isMutedSupported(type, color) ? (
                <Badge type={type} color={color} muted>
                  {capitalize(color)}
                </Badge>
              ) : null}
            </td>
          ))}
        </tr>
      ))}
    </tbody>
  </table>
);
```

### Muted outline

A quieter outline keeps its neutral label and border inside a coloured message.

```tsx
import { Badge } from '@wallarm-org/design-system/Badge';

export const MutedOutline = () => (
  <div
    className='rounded-8 bg-bg-light-danger p-16 text-text-danger'
    data-testid='muted-outline-host'
  >
    <Badge data-testid='muted-outline' type='outline' color='slate' muted>
      Muted outline
    </Badge>
  </div>
);
```

### Color variants

The full palette. Every colour already means something in the system, so borrowing one for
decoration teaches the reader the wrong thing.

```tsx
import { Badge, type BadgeType } from '@wallarm-org/design-system/Badge';
import { BadgeColorEnum, BadgeTypeEnum } from './constants';

export const ColorVariants = () => (
  <table className='w-full'>
    <thead>
      <tr>
        {Object.keys(BadgeTypeEnum).map(type => (
          <th key={type} className='sb-annotation p-8 text-left'>
            {type}
          </th>
        ))}
      </tr>
    </thead>
    <tbody>
      {Object.entries(BadgeColorEnum).map(([label, color]) => (
        <tr key={color}>
          {Object.values(BadgeTypeEnum).map((type: BadgeType) => (
            <td key={type} className='p-8'>
              <Badge data-testid='badge' type={type} color={color}>
                {label}
              </Badge>
            </td>
          ))}
        </tr>
      ))}
    </tbody>
  </table>
);
```

### Content variants

What happens as the content grows. A badge does not truncate, so long text widens the row
rather than being cut.

```tsx
import { Fragment } from 'react';
import { Badge, type BadgeType } from '@wallarm-org/design-system/Badge';
import { Info, PenTool, X } from '@wallarm-org/design-system/icons';
import { BadgeColorEnum, BadgeTypeEnum } from './constants';
import { badgeColorsMuted } from './generateBadgeVariants';

export const ContentVariants = () => (
  <table className='w-full'>
    <thead>
      <tr>
        {Object.keys(BadgeTypeEnum).map(type => (
          <th key={type} className='sb-annotation p-8 text-left'>
            {type}
          </th>
        ))}
      </tr>
    </thead>
    <tbody>
      {Object.entries(BadgeColorEnum).map(([label, color]) => (
        <Fragment key={color}>
          <tr>
            {Object.values(BadgeTypeEnum).map((type: BadgeType) => (
              <td key={type} className='p-8'>
                <Badge data-testid='badge' type={type} color={color}>
                  {label}
                </Badge>
              </td>
            ))}
          </tr>

          <tr>
            {Object.values(BadgeTypeEnum).map((type: BadgeType) => (
              <td key={type} className='p-8'>
                <Badge data-testid='badge' type={type} color={color}>
                  {label}

                  <X />
                </Badge>
              </td>
            ))}
          </tr>

          <tr>
            {Object.values(BadgeTypeEnum).map((type: BadgeType) => (
              <td key={type} className='p-8'>
                <Badge data-testid='badge' type={type} color={color}>
                  <PenTool />
                  {label}
                </Badge>
              </td>
            ))}
          </tr>

          <tr>
            {Object.values(BadgeTypeEnum).map((type: BadgeType) => (
              <td key={type} className='p-8'>
                <Badge data-testid='badge' type={type} color={color}>
                  <PenTool />
                  {label}
                  <X />
                </Badge>
              </td>
            ))}
          </tr>

          <tr>
            {Object.values(BadgeTypeEnum).map((type: BadgeType) => (
              <td key={type} className='p-8'>
                <Badge data-testid='badge' type={type} color={color} variant='dotted'>
                  {label}
                </Badge>
              </td>
            ))}
          </tr>

          <tr>
            {Object.values(BadgeTypeEnum).map((type: BadgeType) => (
              <td key={type} className='p-8'>
                <Badge data-testid='badge' type={type} color={color} variant='dotted'>
                  {label}
                  <X />
                </Badge>
              </td>
            ))}
          </tr>

          <tr>
            {Object.values(BadgeTypeEnum).map((type: BadgeType) => (
              <td key={type} className='p-8'>
                <Badge data-testid='badge' type={type} color={color}>
                  {label}
                  <Info />
                </Badge>
              </td>
            ))}
          </tr>

          <tr>
            {Object.values(BadgeTypeEnum).map((type: BadgeType) => (
              <td key={type} className='p-8'>
                <Badge data-testid='badge' type={type} color={color}>
                  <PenTool />
                </Badge>
              </td>
            ))}
          </tr>

          {badgeColorsMuted.includes(color) && (
            <tr key={color}>
              {Object.values(BadgeTypeEnum).map((type: BadgeType) => (
                <td key={type} className='p-8'>
                  {isMutedSupported(type, color) ? (
                    <Badge data-testid='badge' type={type} color={color} muted>
                      {capitalize(color)}
                    </Badge>
                  ) : null}
                </td>
              ))}
            </tr>
          )}
        </Fragment>
      ))}
    </tbody>
  </table>
);
```

## Props

| Prop           | Type                                                                                         | Default   | Description |
| -------------- | -------------------------------------------------------------------------------------------- | --------- | ----------- |
| defaultChecked | `boolean \| undefined`                                                                       |           |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined`                                         |           |             |
| autoFocus      | `boolean \| undefined`                                                                       |           |             |
| id             | `string \| undefined`                                                                        |           |             |
| tabIndex       | `number \| undefined`                                                                        |           |             |
| title          | `string \| undefined`                                                                        |           |             |
| rel            | `string \| undefined`                                                                        |           |             |
| color          | `string \| undefined`                                                                        | `slate`   |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`                                                |           |             |
| type           | `{ solid: string; secondary: string; outline: string; text: string; 'text-color': string; }` | `solid`   |             |
| size           | `{ small: string; medium: string; large: string; }`                                          | `medium`  |             |
| muted          | `{ true: string; false: string; }`                                                           | `false`   |             |
| variant        | `{ default: string; dotted: string; }`                                                       | `default` |             |
| isIconOnly     | `{ true: string; }`                                                                          |           |             |
| textVariant    | `{ default: string; code: string; }`                                                         | `default` |             |
| isClickable    | `{ true: string; }`                                                                          |           |             |
| asChild        | `boolean \| undefined`                                                                       | `false`   |             |
| data-testid    | `string \| undefined`                                                                        |           |             |
