Skip to main content

Badge

Labels a status, count, or category without pulling focus.

import { Badge } from "@/fragments/ui";Source

Preview

import { Stack } from '@/components/Stack';

<Stack direction="row" gap="sm" wrap>
  <Badge>Neutral</Badge>
  <Badge tone="success">Active</Badge>
  <Badge tone="warning">Pending</Badge>

Installation

npx @usefragments/cli add badge

Writes src/fragments/ui/components/Badge plus what it imports, the globals stylesheet, and .fragments/registry-lock.json, then prints the packages to add. No account, no key.

Your own registry: publish from Fragments Cloud and add --registry org/name. Connect a workspace.

Examples

With Dot

Leading dot for live state; it breathes while still moving.

import { Stack } from '@/components/Stack';

<Stack direction="row" gap="sm" wrap>
  <Badge tone="success" dot>Online</Badge>
  <Badge tone="warning" dot>Away</Badge>
  <Badge tone="danger" dot>Offline</Badge>

Outline and Ghost

Hairline metadata pill, and filter chrome that marks the active one.

import { Stack } from '@/components/Stack';

<Stack direction="row" gap="sm" wrap>
  <Badge variant="outline" dotColor="var(--fui-color-accent)">Design</Badge>
  <Badge variant="outline" dotColor="var(--fui-color-success)">Shipped</Badge>
  <Badge variant="ghost" active>All</Badge>

Sizes

sm for dense tables, lg for reference status pills.

import { Stack } from '@/components/Stack';

<Stack direction="row" gap="sm" align="center" wrap>
  <Badge tone="success" size="sm">Small</Badge>
  <Badge tone="success" size="md">Medium</Badge>
  <Badge tone="success" size="lg">Large</Badge>

Removable

Dismissible tags the user added themselves.

import { Stack } from '@/components/Stack';

<Stack direction="row" gap="sm" wrap>
  <Badge tone="info" onRemove={() => {}}>React</Badge>
  <Badge tone="info" onRemove={() => {}}>TypeScript</Badge>
  <Badge tone="info" onRemove={() => {}}>CSS</Badge>

Announced Status

Looks the same, but screen readers now hear the change.

<Badge tone="success" announce>Saved</Badge>

API

Component props
Prop
Type
Default
Description
childrenRequirednodeNot setBadge label text
variantenumsoftoutlineghostsoftChrome family. `soft` is the tinted pill; `outline` is a hairline metadata pill (pair with dotColor); `ghost` is transparent filter chrome (pair with active).
toneenumneutralaccentinfosuccesswarningdangerneutralColour on the shared status ramp; `neutral` is the plain badge.
sizeenumsmmdlgmdBadge size
dotbooleanfalseShow a colored dot indicator before the label
dotPulsebooleanfalseBreathe the status dot, for a state that is still happening rather than one that has settled. Opacity only, and honours prefers-reduced-motion
dotColorstringNot setColor for the leading status dot. Accepts any CSS color including CSS custom properties.
iconnodeNot setOptional icon element before the text
activebooleanfalseMarks variant="ghost" as the currently selected filter. Has no effect on other variants.
onRemovefunctionNot setMakes the badge removable. Called when X is clicked.
announcebooleanfalseOpt into role="status" live announcement semantics
roleunionNot set
styleobjectNot set

Accessibility

  • The text must carry the meaning — colour alone never does
  • Removable badges need a named dismiss button
  • Badges are silent to screen readers unless you pass announce
  • Do not make a badge the only signal that something changed

Guidance

Use when

  • Marking item status: active, pending, archived
  • Showing a count inline
  • Tagging or categorising content
  • Flagging what is new or changed

Avoid when

  • Real errors that need attention — use Alert
  • Anything longer than a few words — use Alert
  • Clickable filters — use Chip or ToggleGroup
  • View switching — use Tabs or links
  • AlertalternativeUse Alert for prominent, longer messages with actions
  • ChipsiblingChip is interactive (clickable/filterable); Badge is display-only

Next steps