VayuUI

Badge

Displays a small status indicator, label, or tag.

Installation

npx vayu-ui init    # one time only
npx vayu-ui add badge
npx vayu-ui add -t badge    # with test case needs

Usage

Badge Component

A flexible, accessible Badge component. Supports variants, interactive modes (onClick), and dismissible states. Compliant with WCAG 2.2 target sizes.

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>
ElementDescription
RootContainer element (span by default, button when onClick is provided)
Dismiss ButtonClose icon button, rendered only when onDismiss is provided

Accessibility

Badge follows WCAG 2.2 Level AA guidelines.

Keyboard Support

PatternKeyBehavior
Interactive badgeTabMoves focus to the badge
Interactive badgeEnterActivates the onClick handler
Interactive badgeSpaceActivates the onClick handler
Dismiss buttonTabMoves focus between main action and dismiss
Dismiss buttonEnterTriggers the onDismiss handler

ARIA Attributes

ElementRoleAttributes
Interactive badgebuttontype="button"
Dismiss buttonbuttonaria-label="{dismissLabel}"
Split-button containergrouprole="group"

Focus Behavior

  • Focus ring uses the focus design 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

StateAnnouncement
Static badgeRead as inline text (no role)
Interactive badgeAnnounced as a button with the badge text as its name
Dismissible badgeBadge text followed by a "Remove" button (or custom dismissLabel)
Interactive + DismissibleAnnounced 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 notes

Props

Badge

PropTypeDefaultDescription
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
dismissLabelstring'Remove'Accessible label for the dismiss button
classNamestring-Additional CSS classes

Behavior Patterns

PatternPropsRendered Element
StaticDefault<span>
InteractiveonClick<button type="button">
DismissibleonDismiss<span> containing a close button
Interactive + DismissibleonClick + onDismiss<span role="group"> with two sibling <button> elements

On this page