Badge
Displays a small status indicator, label, or tag.
Installation
npx vayu-ui-cli@latest add badgeUsage
Badge Examples
Variants
BrandMutedSuccessWarningDestructiveInfo
Sizes
Small (24px)Medium (28px)Large (32px)
Interactive
Click to trigger an alert.
Dismissible
Click the X to remove tags.
ReactTailwindTypescriptNext.js
Interactive + Dismissible
Click text to trigger filter, click X to remove.
// Variants
<Badge variant="brand">Brand</Badge>
<Badge variant="muted">Muted</Badge>
<Badge variant="success">Success</Badge>
<Badge variant="warning">Warning</Badge>
<Badge variant="destructive">Destructive</Badge>
<Badge variant="info">Info</Badge>
// Sizes
<Badge size="sm">Small</Badge>
<Badge size="md">Medium</Badge>
<Badge size="lg">Large</Badge>
// Interactive
<Badge variant="info" onClick={() => alert("Clicked")}>
Click Me
</Badge>
// Dismissible
<Badge variant="muted" onDismiss={() => {}} dismissLabel="Remove tag">
Removable Tag
</Badge>
// Interactive + Dismissible
<Badge
variant="brand"
onClick={() => alert("Filter applied")}
onDismiss={() => {}}
>
Filter
</Badge>Anatomy
<Badge variant="brand" size="md" onClick={() => {}} onDismiss={() => {}} dismissLabel="Remove">
Badge Content
</Badge>| Element | Description |
|---|---|
| Root | Container element (span by default, button when onClick is provided) |
| Dismiss Button | Close icon button, rendered only when onDismiss is provided |
Accessibility
Badge follows WCAG 2.2 Level AA guidelines.
Keyboard Support
| Pattern | Key | Behavior |
|---|---|---|
| Interactive badge | Tab | Moves focus to the badge |
| Interactive badge | Enter | Activates the onClick handler |
| Interactive badge | Space | Activates the onClick handler |
| Dismiss button | Tab | Moves focus between main action and dismiss |
| Dismiss button | Enter | Triggers the onDismiss handler |
ARIA Attributes
| Element | Role | Attributes |
|---|---|---|
| Interactive badge | button | type="button" |
| Dismiss button | button | aria-label="{dismissLabel}" |
| Split-button container | group | role="group" |
Focus Behavior
- Focus ring uses the
focusdesign token (ring-2 ring-focus) - Focus offset adapts to dark mode (
ring-offset-canvas) - Dismiss button uses inset focus ring to stay within bounds
Screen reader behavior
| State | Announcement |
|---|---|
| Static badge | Read as inline text (no role) |
| Interactive badge | Announced as a button with the badge text as its name |
| Dismissible badge | Badge text followed by a "Remove" button (or custom dismissLabel) |
| Interactive + Dismissible | Announced as a group containing two buttons: the main action and the dismiss action |
Component Folder Structure
Badge/
├── Badge.tsx # UI + logic
├── types.ts # TypeScript types
├── index.ts # Public exports
└── README.md # Internal notesProps
Badge
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'brand' | 'muted' | 'warning' | 'success' | 'destructive' | 'info' | 'brand' | Visual style variant |
size | 'sm' | 'md' | 'lg' | 'md' | Size of the badge |
as | 'span' | 'div' | 'a' | - | Forces a specific HTML tag |
onClick | () => void | - | Makes badge interactive (renders as button) |
onDismiss | () => void | - | Adds a dismiss button |
dismissLabel | string | 'Remove' | Accessible label for the dismiss button |
className | string | - | Additional CSS classes |
Behavior Patterns
| Pattern | Props | Rendered Element |
|---|---|---|
| Static | Default | <span> |
| Interactive | onClick | <button type="button"> |
| Dismissible | onDismiss | <span> containing a close button |
| Interactive + Dismissible | onClick + onDismiss | <span role="group"> with two sibling <button> elements |