Badge
A minimal headless wrapper for status labels, counts, and tags.
Features
- Polymorphic
- Zero defaults
- Composable
- Headless
Installation
npm install @ariaui/badge
Examples
Variants below each use their own playground and derived snippet. Compose Badge.Root with Tailwind; semantics and labels are yours to define.
Default
Primary emphasis for status and metadata chips.
No preview output yet.
Secondary
Muted surface that still reads clearly on dense UI.
No preview output yet.
Outline
Bordered treatment when you want the page background to show through.
No preview output yet.
Destructive
High-attention tone for errors, removals, or blocked states.
No preview output yet.
With icon
Pair Badge.Root with icons from your icon set for quick visual context.
No preview output yet.
Circular / count
Compact pills for notifications or numeric counts.
No preview output yet.
Action / link
Use as="a" with href when the badge should navigate like a link.
No preview output yet.
Verified
Common pattern for trust or completion states.
No preview output yet.
Anatomy
import * as Badge from "@ariaui/badge";
export default function Example() {
return <Badge.Root />;
}
API Reference
Root
Polymorphic wrapper that renders `as` (default `div`) and forwards all props. Ships with no default role, ARIA, classes, or styles — use `className` for visuals and choose `as` when the badge should be a link, `span`, or other element.
| Prop | Type | Default |
|---|---|---|
as | React.ElementType | "div" |
Keyboard
| Shortcut | Action |
|---|---|
| Tab | Move focus to the next focusable badge (for example when using as="a" or as="button"). |
| Shift+Tab | Move focus to the previous focusable badge. |
| Enter | Activate a focused link-styled badge (same as a native anchor). |
Accessibility
Use visible text (for example “Beta”, “New”, or “Paid”) as the primary label. Do not add role="img" or tabIndex for purely decorative status chips. The primitive applies no default role or keyboard behavior.
When a badge is only decorative next to explicit text, you may hide redundant visuals from assistive tech with aria-hidden="true" on the badge wrapper.
If you use as="a" (or render a real link), treat it as a focusable control: provide a meaningful accessible name, visible focus styles, and a real href in production. The demo uses href="#" with preventDefault only for the playground.
Interactive vs static
Reserve button / link semantics and keyboard support for badges that perform an action. For static labels and counts, keep them non-focusable and rely on surrounding context or adjacent text.