---
title: Badge
description: Compact label component with icon slots and variant styles.
sidebar:
  order: 3
search:
  tags: [label, tag, status, metadata]
---

# Badge

> Compact label component with icon slots and variant styles.

## Import

```tsx
import { Badge } from 'moraine'
```

## Slot Structure

Compact label with optional leading and trailing icon slots.

```text
root
├── leading (Icon, optional)
├── label (optional)
└── trailing (Icon or IconButton, optional)
```

## Examples

### Variants

Default, outline, and solid styles.

```tsx
function Variants() {
  const VARIANTS: BadgeVariantName[] = ['default', 'outline', 'solid']

  type BadgeVariantName = Exclude<BadgeT.Variant['variant'], undefined>

  return (
    <div class="flex flex-wrap gap-3 items-center">
      <For each={VARIANTS}>{(variant) => <Badge variant={variant}>{variant}</Badge>}</For>
    </div>
  )
}
```

### Sizes

Size scale with leading and trailing icons.

```tsx
function Sizes() {
  const SIZES: BadgeSizeName[] = ['xs', 'sm', 'md', 'lg', 'xl']

  type BadgeSizeName = Exclude<BadgeT.Variant['size'], undefined>

  return (
    <div class="font-mono flex flex-wrap gap-3 items-center">
      <For each={SIZES}>
        {(size) => (
          <Badge size={size} variant="outline">
            {size}
          </Badge>
        )}
      </For>
    </div>
  )
}
```

### Status and Metadata

Common badge content for pills, counters, and status labels.

```tsx
function StatusAndMetadata() {
  return (
    <div class="space-y-2">
      <div class="flex flex-wrap gap-3 items-center">
        <Badge variant="solid" leading="i-lucide-check-check">
          Published
        </Badge>
        <Badge variant="default">测试</Badge>
        <Badge variant="outline" trailing="i-lucide-git-branch">
          v0.1.0
        </Badge>
        <Badge variant="outline" leading="i-lucide-users">
          24 contributors
        </Badge>
      </div>
    </div>
  )
}
```

### Dismissible tags

Clickable trailing icons support removable tag UIs like Select multi-value chips.

```tsx
function DismissibleTags() {
  const INITIAL_TAGS = ['Design', 'SolidJS', 'Kobalte', 'UnoCSS']

  const [tags, setTags] = createSignal(INITIAL_TAGS)

  return (
    <div class="flex flex-col gap-3 items-start">
      <div class="flex flex-wrap gap-2 max-w-2xl">
        <For each={tags()}>
          {(tag) => (
            <Badge
              variant="default"
              trailing="icon-close"
              title={tag}
              classes={{
                root: 'pe-0',
                trailing: 'hover:bg-accent rounded scale-80',
              }}
              onTrailingClick={() => setTags((current) => current.filter((item) => item !== tag))}
            >
              {tag}
            </Badge>
          )}
        </For>
      </div>

      <Button size="sm" variant="outline" onClick={() => setTags(INITIAL_TAGS)}>
        Reset tags
      </Button>
    </div>
  )
}
```

## API Reference

### Attributes

#### `root`

Inline badge container that carries the variant, size, and interactive state.

##### Data Attributes

| Attribute | Type | Description |
| --- | --- | --- |
| data-size | string | Stores the resolved size variant. |
| data-variant | string | Stores the resolved visual variant. |

#### `leading`

Optional icon displayed before the badge label.

#### `label`

Badge text or children content between the optional visuals.

#### `trailing`

Optional trailing icon or dismiss button displayed after the label.

### Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| children | JSX.Element | — | Children of the badge. |
| class | ClassValue | — | Class applied to the component root or trigger element. |
| classes | BadgeT.Classes \| undefined | — | — |
| leading | IconT.Name | — | Leading icon name. |
| onTrailingClick | JSX.EventHandlerUnion<HTMLButtonElement, MouseEvent> \| undefined | — | Callback when the trailing icon/button is clicked. |
| ref | JSX.HTMLElementTags["span"] extends { ref?: infer Ref; } ? Ref : never \| undefined | — | — |
| size | "xs" \| "sm" \| "md" \| "lg" \| "xl" \| undefined | — | — |
| style | JSX.CSSProperties \| undefined | — | — |
| styles | BadgeT.Styles \| undefined | — | — |
| title | string \| undefined | — | Accessible title shown by the browser for the badge root. |
| trailing | IconT.Name | — | Trailing icon name. |
| variant | "default" \| "outline" \| "solid" \| undefined | — | — |

### ARIA

Accessibility attributes and roles emitted by the component markup.

| Attribute | Type | Description |
| --- | --- | --- |
| aria-hidden | boolean \| string \| undefined | Hides decorative content from assistive technology. |

### Data Attributes

State and slot attributes exposed for styling hooks and selectors.

| Attribute | Type | Description |
| --- | --- | --- |
| data-loading | string \| undefined | Present when the component is loading. |
| data-size | string | Stores the resolved size variant. |
| data-slot | string | Identifies the rendered slot for styling hooks and selectors. |
| data-variant | string | Stores the resolved visual variant. |
