Badge

Free

Compact status and category labels with 7 semantic variants and 3 visual styles.

</>sv-badge badgestatuslabel

Complexity tier: Primitive Presents a value: held to semantic markup and contrast, with its right-to-left and print gaps recorded and the right-to-left debt allowed only to shrink.

import { SvBadgeComponent } from '@styloviz/badge';

Demo & usage

Basic usage

Usage example — open the gallery for the full interactive demo.

An interactive demo for this component lives in the gallery.

Open live demo

More examples

Dot & count

example.htmlAngular
<sv-badge label="Live" variant="success" [dot]="true" [pulseDot]="true" />
<sv-badge label="Inbox" variant="primary" [count]="12" [maxCount]="9" />

Styles

example.htmlAngular
<sv-badge label="Solid" variant="warning" />
<sv-badge label="Soft" variant="warning" badgeStyle="soft" />
<sv-badge label="Outline" variant="warning" badgeStyle="outline" />

Live count & dismissible

example.htmlAngular
<!-- Announce updates to assistive tech -->
<sv-badge variant="danger" [count]="unread()" [live]="true" ariaLabel="Unread messages" />
<sv-badge label="Beta" variant="info" [dismissible]="true" (dismissed)="hide()" />

When to use

  • Labelling status, category or counts inline with other content.
  • You need a small, color-coded indicator next to titles, rows or icons.
  • For interactive, removable tokens use a Chip instead.

Async states

None — this component has nothing to load, so it has no loading, empty or error state to drive.

Inputs

NameTypeDefaultDescription
variantBadgeVariant'primary'Semantic color/intent (primary, success, warning, danger…).
badgeStyleBadgeStyle'soft'Visual treatment: solid, soft or outline.
shapeBadgeShape'pill'Corner style: pill, rounded or square.
sizeBadgeSize'md'Badge size: sm, md or lg.
labelstring''Badge text. Omit when using count mode or projecting content.
dotbooleanfalseShow status dot.
pulseDotbooleanfalseAnimate dot with ping.
countnumber0When > 0, renders count mode (overrides label).
maxCountnumber99Cap for count display (shows "N+").
iconstring''Icon-library NAME for the leading icon — e.g. `'star'`. Was a raw `d`.
dismissiblebooleanfalseShow dismiss button.
customClassstring''Extra CSS classes merged on root.
ariaLabelstring''aria-label override — replaces the visible text as the accessible name.
livebooleanfalseAnnounce the badge as a polite ARIA live region (`role="status"`). Enable for dynamic notification counts/statuses that update in place so assistive tech is notified of changes. Leave `false` for static labels and tags to avoid noisy announcements.
announceTonebooleanfalseAppend the tone as a visually hidden word — "Paid, success", "Overdue, error" — for the `success`, `warning`, `danger` and `info` variants, so the status is not carried by colour alone (WCAG 1.4.1). Other variants have no tone and add nothing.

Outputs

EventPayload typeDescription
dismissedvoidEmitted when the dismiss button is clicked.

Customization & theming

  • Eight tones with published meanings — see the tone table above; the meaning is the contract, and the colour is downstream of it.
  • Seven semantic variants across solid, soft and outline.
  • Optional leading dot or icon, plus count mode and a dismiss button.
  • Set `live` for dynamic counts/statuses that should be announced; override the name with `ariaLabel`.

Best practices

  • Do: Pick a tone by what it MEANS, not by what colour you want. The eight are: primary (the default emphasis, no status claim), secondary (present but deliberately quieter), success (a completed or healthy state), warning (something needs attention but nothing has failed), danger (a failure, a block, or a destructive consequence), info (context the reader did not ask for and cannot act on), neutral (a plain label or count with no status at all), and brand (a product or plan name, never a state).
  • Don't: Do not use warning for a failure or danger for something merely unusual. Seven tones with no published meaning is how 'warning' becomes whatever each team decides, and a reader who has learned your dashboard's dialect cannot carry it to the next screen. Badges are everywhere, which is what makes the drift expensive.
  • Do: Reach for neutral more often than feels natural. Most badges are labels and counts rather than statuses, and giving those a semantic colour spends the reader's attention on something that was never a signal.
  • Tip: brand exists separately from primary on purpose: a kit can legitimately have a highlight colour and a brand colour that differ. Use it for a product or plan name, never for a state.
  • Do: Keep a consistent variant→meaning mapping (success, warning, danger) app-wide.
  • Do: Cap counts with `maxCount` so the badge never grows unbounded.
  • Don't: Don't rely on color alone — the label/text should carry the meaning.

Accessibility

  • The pulsing status dot stops under `prefers-reduced-motion` but the DOT REMAINS. A small, peripheral, endless animation is the shape most likely to trigger a vestibular response, and it is exactly what the preference exists for — but the dot is the status indicator, so removing it would delete information to fix a comfort problem.
  • Every one of the 24 tone x style combinations is contrast-checked in both themes by `check:contrast`, which scores the class pairs where they are declared rather than where they render.
  • Readable contrast for every variant in both themes.
  • Conveys meaning with text, not just color; the dot/icon are decorative.
  • Static badges carry no ARIA live region by default — opt in with `live` only for values that update in place, so screen readers are not spammed.
  • The dismiss button is a labelled control ("Remove …").

Feedback on Badge

Spotted a gap in this page, or something that didn't work as described? Comments are GitHub Discussions in the public styloviz/community repo, so posting needs a GitHub account.

Loads giscus.app and GitHub — nothing is fetched until you click.