---
title: Badge
description: A compact count, status label, or dot indicator.
category: Basic
status: beta
since: 0.3.4
tags: [badge, count, status]
syncStatus: reviewed
verified: true
---

## Usage

### Variants
:::TuffDemoWrapper{demo="BadgeBadgeVariantsDemo" code-lang="vue"}
---
code: |
  <template>
    <TxBadge :value="count" />
    <TxBadge value="New" variant="primary" />
    <TxBadge value="99+" variant="success" />
    <TxBadge dot variant="error" />
  </template>
---
:::

### Pop Motion
Toggling `open` slides the badge in or pops it out, keeping its layout box; numbers roll only the digits that change.
:::TuffDemoWrapper{demo="BadgeBadgeMotionDemo" code-lang="vue"}
---
code: |
  <template>
    <span style="position: relative; display: inline-flex">
      <TxButton variant="secondary">Inbox</TxButton>
      <TxBadge variant="error" :value="count" :open="hasUnread" class="corner" />
    </span>
  </template>

  <style scoped>
  .corner {
    position: absolute;
    top: -8px;
    right: -10px;
    pointer-events: none;
  }
  </style>
---
:::

### Custom Slot Content

```vue
<template>
  <TxBadge variant="primary">
    <strong>Beta</strong>
  </TxBadge>
</template>
```

### Custom Color

```vue
<template>
  <TxBadge value="Internal" color="#111827" />
</template>
```

### Dot Indicator

```vue
<template>
  <TxFlex align="center" gap="8px">
    <TxBadge dot variant="error" />
    <span>Service degraded</span>
  </TxFlex>
</template>
```

### Best Practices

- Use `TxBadge` for counts and short states; use `TxStatusBadge` when you need a status icon or permission mapping.
- Keep the text short; badges never wrap.
- Position corner badges in the host; bind `open` to the unread state and add no transform of your own.
- Don't rely on dot color alone for critical states; put text next to it.
- Use `variant` for semantic states; reserve `color` for brand or custom categories.

## API Reference

### Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `variant` | `'default' \| 'primary' \| 'success' \| 'warning' \| 'error'` | `'default'` | Semantic color preset. |
| `value` | `number \| string` | `0` | Text when there is no slot and `dot` is off; numbers roll by digit. |
| `color` | `string` | - | Custom background; turns the text white. |
| `dot` | `boolean` | `false` | Renders a dot with no text. |
| `open` | `boolean` | `true` | Presence; toggling plays the motion, and the closed badge keeps its layout box. |

### Slots

| Slot | Props | Description |
|------|------|-------------|
| `default` | - | Custom content; takes priority over `value` and is ignored with `dot`. |

### CSS Variables

| Variable | Source | Description |
|----------|--------|-------------|
| `--tx-badge-bg` | `variant` / `color` | Background. |
| `--tx-badge-text` | `variant` / `color` | Text color. |
| `--tx-badge-border` | `variant` | Border color. |
| `--tx-badge-dot` | `color` | Fill of the `dot`; falls back to the text color. |
| `--tx-badge-offset-x` / `--tx-badge-offset-y` | caller | Slide-in start offset; defaults `-8.2px` / `12.4px`. |
| `--tx-badge-slide-dur` | caller | Slide-in duration; default `260ms`. |
| `--tx-badge-pop-dur` / `--tx-badge-pop-close-dur` | caller | Pop-in / pop-out duration; defaults `500ms` / `180ms`. |
| `--tx-badge-fade-dur` / `--tx-badge-fade-close-dur` | caller | Fade-in / fade-out duration; defaults `400ms` / `180ms`. |
| `--tx-badge-blur` | caller | Blur of the closed state; default `2px`. |
| `--tx-badge-slide-ease` / `--tx-badge-pop-ease` / `--tx-badge-close-ease` | caller | Easing of the three motion phases. |

## Overview

- The root is an inline pill `span`.
- With `dot`, only `.tx-badge__dot` renders; otherwise the default slot wins over `value`.
- `value` defaults to `0`, so a badge with no slot and no `dot` shows `0`.
- A numeric `value` rolls by place value (9 → 10 grows a digit instead of swapping the number); strings and slot content render as-is.
- The `open` motion plays only on toggles, never on first mount; under reduced motion it is off and numbers update in place.
- There is no click event, positioning, overflow truncation, or anchoring; attach interactions to the surrounding control.

## Technologies

- Numbers render through `TxTextMorph`; the pill's width follows its container animation instead of being measured.
- Source: `packages/tuffex/packages/components/src/badge/`.

<TuffDocSourceLink />
