# Badge

Use badge for short status, count, or category metadata that should stay lightweight. It is best for labels like draft, live, unread, or 99+. For anything clickable or dismissible, use tag or button instead.

## Import
```ts
import { BadgeComponent } from 'ui';
```

## Status and metadata
```ts
import { Component } from '@angular/core';
import { BadgeComponent } from 'ui';

@Component({
  selector: 'app-badge-basic-demo',
  standalone: true,
  imports: [BadgeComponent],
  template: `
    <div style="display:flex;flex-direction:column;gap:1rem">
      <div
        style="display:flex;flex-wrap:wrap;gap:0.75rem;padding:1rem;border:1px solid var(--color-neutral-stroke-rest);border-radius:1rem;background:var(--color-neutral-background-rest)"
      >
        <ui-badge text="Live" variant="success" />
        <ui-badge text="Draft" variant="secondary" appearance="tint" />
        <ui-badge text="Needs review" variant="warning" appearance="outline" />
        <ui-badge text="Blocked" variant="danger" />
        <ui-badge text="New" variant="info" appearance="subtle" />
      </div>

      <div
        style="display:grid;gap:0.75rem;padding:1rem;border:1px dashed var(--color-neutral-stroke-rest);border-radius:1rem;background:var(--color-neutral-background2-rest)"
      >
        <div
          style="display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:0.75rem;padding:0.875rem 1rem;border-radius:0.875rem;background:var(--color-neutral-background-rest)"
        >
          <div style="display:flex;flex-direction:column;gap:0.25rem;min-width:0">
            <strong style="font-size:0.875rem;color:var(--color-neutral-foreground-rest)"
              >Release checklist</strong
            >
            <span style="font-size:0.8125rem;color:var(--color-neutral-foreground3-rest)"
              >Badge should summarize state without needing a sentence.</span
            >
          </div>
          <ui-badge text="QA passed" variant="success" appearance="tint" />
        </div>
      </div>
    </div>
  `,
})
export class BadgeBasicDemoComponent {}
```

## Appearance and variant
```ts
import { Component } from '@angular/core';
import { BadgeComponent } from 'ui';

@Component({
  selector: 'app-badge-appearance-variant-demo',
  standalone: true,
  imports: [BadgeComponent],
  template: `
    <div style="display:grid;gap:1rem">
      <div
        style="display:grid;gap:0.75rem;padding:1rem;border:1px solid var(--color-neutral-stroke-rest);border-radius:1rem;background:var(--color-neutral-background-rest)"
      >
        <div style="display:flex;flex-wrap:wrap;gap:0.75rem">
          <ui-badge text="Primary filled" variant="primary" appearance="filled" />
          <ui-badge text="Primary tint" variant="primary" appearance="tint" />
          <ui-badge text="Primary outline" variant="primary" appearance="outline" />
          <ui-badge text="Primary subtle" variant="primary" appearance="subtle" />
        </div>
        <div style="display:flex;flex-wrap:wrap;gap:0.75rem">
          <ui-badge text="Success" variant="success" appearance="filled" />
          <ui-badge text="Warning" variant="warning" appearance="tint" />
          <ui-badge text="Danger" variant="danger" appearance="outline" />
          <ui-badge text="Info" variant="info" appearance="subtle" />
        </div>
      </div>

      <div
        style="display:flex;flex-wrap:wrap;gap:0.75rem;padding:1rem;border:1px dashed var(--color-neutral-stroke-rest);border-radius:1rem;background:var(--color-neutral-background2-rest)"
      >
        <ui-badge text="Muted metadata" variant="secondary" appearance="subtle" />
        <ui-badge text="Elevated status" variant="info" appearance="filled" />
        <ui-badge text="Inline emphasis" variant="warning" appearance="outline" />
      </div>
    </div>
  `,
})
export class BadgeAppearanceVariantDemoComponent {}
```

## Size and shape
```ts
import { Component } from '@angular/core';
import { BadgeComponent } from 'ui';

@Component({
  selector: 'app-badge-size-shape-demo',
  standalone: true,
  imports: [BadgeComponent],
  template: `
    <div style="display:grid;gap:1rem">
      <div
        style="display:flex;flex-wrap:wrap;align-items:center;gap:1rem;padding:1rem;border:1px solid var(--color-neutral-stroke-rest);border-radius:1rem;background:var(--color-neutral-background-rest)"
      >
        <ui-badge text="S" size="small" />
        <ui-badge text="Medium" size="medium" />
        <ui-badge text="Large badge" size="large" />
      </div>

      <div
        style="display:flex;flex-wrap:wrap;align-items:center;gap:1rem;padding:1rem;border:1px dashed var(--color-neutral-stroke-rest);border-radius:1rem;background:var(--color-neutral-background2-rest)"
      >
        <ui-badge text="Rounded" shape="rounded" variant="secondary" appearance="tint" />
        <ui-badge text="24" shape="circular" variant="danger" />
        <ui-badge text="Tile" shape="square" variant="info" appearance="outline" />
      </div>
    </div>
  `,
})
export class BadgeSizeShapeDemoComponent {}
```

## Icons and position
```ts
import { Component } from '@angular/core';
import { BadgeComponent } from 'ui';

@Component({
  selector: 'app-badge-icons-demo',
  standalone: true,
  imports: [BadgeComponent],
  template: `
    <div style="display:grid;gap:1rem">
      <div
        style="display:flex;flex-wrap:wrap;gap:0.75rem;padding:1rem;border:1px solid var(--color-neutral-stroke-rest);border-radius:1rem;background:var(--color-neutral-background-rest)"
      >
        <ui-badge text="Approved" icon="checkmark_circle" variant="success" appearance="tint" />
        <ui-badge text="Overdue" icon="clock" variant="warning" appearance="outline" />
        <ui-badge text="Unread" icon="mail" variant="info" />
        <ui-badge text="Customer" icon="person" variant="secondary" appearance="tint" />
      </div>

      <div
        style="display:flex;flex-wrap:wrap;gap:0.75rem;padding:1rem;border:1px dashed var(--color-neutral-stroke-rest);border-radius:1rem;background:var(--color-neutral-background2-rest)"
      >
        <ui-badge
          text="Due today"
          icon="calendar"
          iconPosition="after"
          variant="primary"
          appearance="outline"
        />
        <ui-badge
          text="Escalated"
          icon="warning"
          iconPosition="after"
          variant="danger"
          appearance="tint"
        />
      </div>
    </div>
  `,
})
export class BadgeIconsDemoComponent {}
```

## Counts and overflow labels
```ts
import { Component } from '@angular/core';
import { BadgeComponent } from 'ui';

@Component({
  selector: 'app-badge-counts-demo',
  standalone: true,
  imports: [BadgeComponent],
  template: `
    <div style="display:grid;gap:1rem">
      <div
        style="display:flex;flex-wrap:wrap;align-items:center;gap:0.875rem;padding:1rem;border:1px solid var(--color-neutral-stroke-rest);border-radius:1rem;background:var(--color-neutral-background-rest)"
      >
        <ui-badge text="3" shape="circular" ariaLabel="3 pending approvals" />
        <ui-badge text="12" shape="circular" variant="info" ariaLabel="12 unread updates" />
        <ui-badge text="99+" shape="circular" variant="danger" ariaLabel="99 or more alerts" />
        <ui-badge text="7 files" variant="secondary" appearance="tint" />
      </div>

      <div
        style="display:grid;gap:0.75rem;padding:1rem;border:1px dashed var(--color-neutral-stroke-rest);border-radius:1rem;background:var(--color-neutral-background2-rest)"
      >
        <div
          style="display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:0.75rem;padding:0.875rem 1rem;border-radius:0.875rem;background:var(--color-neutral-background-rest)"
        >
          <div style="display:flex;flex-direction:column;gap:0.25rem">
            <strong style="font-size:0.875rem">Inbox</strong>
            <span style="font-size:0.8125rem;color:var(--color-neutral-foreground3-rest)"
              >Compact count badges fit best when the number is the only thing that matters.</span
            >
          </div>
          <ui-badge text="24" shape="circular" variant="danger" ariaLabel="24 unread messages" />
        </div>
      </div>
    </div>
  `,
})
export class BadgeCountsDemoComponent {}
```

## Composition patterns
```ts
import { Component } from '@angular/core';
import { BadgeComponent } from 'ui';

@Component({
  selector: 'app-badge-composition-demo',
  standalone: true,
  imports: [BadgeComponent],
  template: `
    <div style="display:grid;gap:1rem">
      <div
        style="display:grid;gap:0.875rem;padding:1rem;border:1px solid var(--color-neutral-stroke-rest);border-radius:1rem;background:var(--color-neutral-background-rest)"
      >
        <div
          style="display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:0.875rem;padding:1rem;border-radius:0.875rem;background:var(--color-neutral-background2-rest)"
        >
          <div style="display:flex;flex-direction:column;gap:0.5rem;min-width:0">
            <strong style="font-size:0.9375rem;color:var(--color-neutral-foreground-rest)"
              >Quarterly planning review</strong
            >
            <span
              style="font-size:0.875rem;line-height:1.5;color:var(--color-neutral-foreground2-rest)"
              >Use grouped badges to show ownership, risk, and freshness without building custom
              metadata chrome.</span
            >
            <div style="display:flex;flex-wrap:wrap;gap:0.5rem">
              <ui-badge text="Marketing" variant="secondary" appearance="tint" />
              <ui-badge text="Needs review" variant="warning" appearance="outline" />
              <ui-badge text="Updated today" icon="calendar" variant="info" appearance="subtle" />
            </div>
          </div>
          <ui-badge text="2 blockers" variant="danger" />
        </div>
      </div>
    </div>
  `,
})
export class BadgeCompositionDemoComponent {}
```

## Accessibility

### Accessible name
`BadgeComponent` uses the visible `text` as its default accessible name. Set `ariaLabel` when the badge text is abbreviated, numeric, or otherwise not descriptive enough on its own, such as `99+` or `3`.

### Semantics
The host renders with `role="status"`. This is appropriate for short status metadata, but badge itself is not interactive and is not keyboard focusable. If users must click, dismiss, or toggle it, use a more suitable component such as `TagComponent` or `ButtonComponent`.

| Aspect | Behavior |
| --- | --- |
| Role | `status` |
| Focus | not focusable |
| Name source | `ariaLabel` or visible `text` |
| Interaction | none; display-only surface |
