Skip to content

Badge

A small label that states a status or category, like Paid, Overdue or Beta. Not interactive.

Displayv0.1.0experimentalWCAG 2.2 AAView spec
DraftIn reviewPaidDue soonOverdue
import { Badge } from "@rdloom/react";

export default function BadgeVariantsExample() {
  return (
    <div className="flex flex-wrap items-center gap-2">
      <Badge>Draft</Badge>
      <Badge variant="info">In review</Badge>
      <Badge variant="success">Paid</Badge>
      <Badge variant="warning">Due soon</Badge>
      <Badge variant="danger">Overdue</Badge>
    </div>
  );
}

Installation

npx rdloom add badge

Copies the source into src/components/rdloom. Edit it freely: rdloom upgrade merges later versions into your changes.

Use another registry client
npx shadcn@latest add https://rdloom.vimalbhatt.com/r/badge.json

Works, but without upgrade tracking.

Usage

import { Badge } from "@rdloom/react";

<div className="flex flex-wrap items-center gap-2">
  <Badge>Draft</Badge>
  <Badge variant="info">In review</Badge>
  <Badge variant="success">Paid</Badge>
  <Badge variant="warning">Due soon</Badge>
  <Badge variant="danger">Overdue</Badge>
</div>

Sizes

BetaBeta
import { Badge } from "@rdloom/react";

export default function BadgeSizesExample() {
  return (
    <div className="flex items-center gap-2">
      <Badge size="sm" variant="info">
        Beta
      </Badge>
      <Badge size="md" variant="info">
        Beta
      </Badge>
    </div>
  );
}

In a list

  • INV-1042Overdue
  • INV-1043Paid
  • INV-1044Due soon
import { Badge } from "@rdloom/react";

const invoices = [
  { id: "INV-1042", status: "Overdue", variant: "danger" },
  { id: "INV-1043", status: "Paid", variant: "success" },
  { id: "INV-1044", status: "Due soon", variant: "warning" },
] as const;

// The status is written out: the color only helps people who can see it.
export default function BadgeInAListExample() {
  return (
    <ul className="flex w-72 flex-col gap-2 text-sm">
      {invoices.map((invoice) => (
        <li key={invoice.id} className="flex items-center justify-between">
          <span>{invoice.id}</span>
          <Badge variant={invoice.variant}>{invoice.status}</Badge>
        </li>
      ))}
    </ul>
  );
}

API Reference

Defined by the spec. Components also accept the props of the React Aria component they wrap.

PropTypeDefault
childrenrequired

The label. Say what it means in words: color alone never carries the meaning.

nodenone
variant

Tone: neutral for categories, the others for statuses.

"neutral" | "info" | "success" | "warning" | "danger""neutral"
size

Text and padding size.

"sm" | "md""md"

Accessibility

Role text, WCAG 2.2 AA. Tested with axe and keyboard tests; screen reader checks are in the audit checklist.

Keyboard

Not interactive.

Screen readers announce

  • Read in place as ordinary text, e.g. "Order 1042, Overdue"

What your code must do

  • The status is in the text, not only the color (a colored dot is decoration)
  • Text meets 4.5:1 against every tone's background, in light and dark mode
  • It is plain inline text: not focusable, not a button

Guidelines

Use it when

  • Showing the status of a record in a list or table
  • Tagging something with a short category or version, like Beta

Avoid it when

  • Something the user can click or dismiss: use a Button or a tag input
  • A count that changes and must be announced: use a live region

Don't

  • Using color as the only difference between two badges
  • Long sentences inside a badge
  • Making a badge a button

Design tokens

The semantic tokens this component uses. Change them once and every component follows; see Design tokens.

  • --rd-color-text-default
  • --rd-color-surface-subtle
  • --rd-color-border-default
  • --rd-color-feedback-info-subtle
  • --rd-color-feedback-success-subtle
  • --rd-color-feedback-warning-subtle
  • --rd-color-feedback-danger-subtle
  • --rd-color-feedback-info
  • --rd-color-feedback-success
  • --rd-color-feedback-warning
  • --rd-color-feedback-danger