UIUpdated May 16, 2026

Badge

Small status and metadata component used to label, categorize, or highlight information in PyColors UI.

UIBadge

Compact metadata for product interfacesLink to section

The Badge component is a compact, non-interactive primitive used to display short information.

Use it for:

  • status
  • category
  • count
  • plan label
  • metadata
  • product state
  • feature availability

Badges are lightweight, semantic, and aligned with PyColors design system tokens.

They are designed for metadata, not actions.

Core idea

A Badge communicates state or context. It should not replace a Button.

ImportLink to section

badge-import.tsx
import { Badge } from "@pycolors/ui";

Basic usageLink to section

Default
basic-badge.tsx
import { Badge } from "@pycolors/ui";

export function BasicBadge() {
  return <Badge>Default</Badge>;
}

Badges inherit their colors from semantic tokens and adapt to light and dark mode.

When to use BadgeLink to section

Use Badge when the label helps the user understand context without adding heavy visual hierarchy.

Metadata

Use for labels such as category, plan, type, role, or version.

Status

Use for small state labels such as active, paid, draft, shipped, or synced.

Grouping

Use to classify content without turning the label into a navigation or action element.

VariantsLink to section

Use variants to convey meaning or status.

DefaultSecondaryMutedOutlineSuccessWarningDestructive
badge-variants.tsx
import { Badge } from "@pycolors/ui";

export function BadgeVariants() {
  return (
    <div className="flex flex-wrap gap-2">
      <Badge>Default</Badge>
      <Badge variant="secondary">Secondary</Badge>
      <Badge variant="muted">Muted</Badge>
      <Badge variant="outline">Outline</Badge>
      <Badge variant="success">Success</Badge>
      <Badge variant="warning">Warning</Badge>
      <Badge variant="destructive">Destructive</Badge>
    </div>
  );
}

Available variantsLink to section

VariantPurpose
defaultPrimary or neutral label
secondarySupporting information
mutedLow-emphasis metadata
outlineNeutral bordered label
successPositive or completed state
warningCaution or attention required
destructiveError or critical state

Design rule

Prefer muted and outline for metadata. Reserve semantic state variants for actual product states.

SizesLink to section

Use size to control density and hierarchy.

SmallDefaultLarge
badge-sizes.tsx
import { Badge } from "@pycolors/ui";

export function BadgeSizes() {
  return (
    <div className="flex items-center gap-2">
      <Badge size="sm">Small</Badge>
      <Badge size="md">Default</Badge>
      <Badge size="lg">Large</Badge>
    </div>
  );
}

Available sizesLink to section

SizePurpose
smDense metadata, tables, compact lists
mdDefault badge size
lgEmphasized label or standout metadata

Density rule

Use sm in tables and dense product views. Use md for most UI surfaces. Use lg sparingly.

With left iconLink to section

Badges can include a left icon when the icon reinforces status, type, or category.

Active
badge-with-left-icon.tsx
import { Badge } from "@pycolors/ui";
import { CheckCircle } from "lucide-react";

export function BadgeWithLeftIcon() {
  return (
    <Badge variant="success">
      <CheckCircle className="size-3" aria-hidden="true" />
      Active
    </Badge>
  );
}

Icon rule

Icons should reinforce meaning. The text must still explain the state.

With right iconLink to section

Use a right icon when the badge points to a related surface, external context, or lightweight next step.

Docs
badge-with-right-icon.tsx
import { Badge } from "@pycolors/ui";
import { ArrowRight } from "lucide-react";

export function BadgeWithRightIcon() {
  return (
    <Badge variant="outline">
      Docs
      <ArrowRight className="size-3" aria-hidden="true" />
    </Badge>
  );
}

Placement rule

Use left icons for state or identity. Use right icons for direction, continuation, or linked context.

As childLink to section

Use asChild when the badge should render as another semantic element.

badge-as-child.tsx
import { Badge } from "@pycolors/ui";

export function BadgeAsChild() {
  return (
    <Badge asChild>
      <a href="/docs">Docs</a>
    </Badge>
  );
}

Interaction rule

Only use interactive badges when the underlying element is semantic, such as an anchor or button. If it triggers an important action, use Button instead.

Usage patternsLink to section

Choose the message

Decide what the badge communicates: status, category, role, version, count, or plan.

Pick the lowest useful emphasis

Start with muted or outline. Move to semantic variants only when the state needs clear meaning.

Keep the label short

Badges work best with short labels: one or two words.

Avoid turning metadata into actions

A badge should not become a primary interaction. Use Button for actions.

Badge vs Button vs AlertLink to section

SituationUse
Show a small statusBadge
Show a category or plan labelBadge
Trigger an actionButton
Show persistent feedback or warningAlert
Confirm temporary background actionToast

Decision rule

Badge communicates context. Button triggers intent. Alert explains important feedback.

APILink to section

PropTypeDefaultDescription
variantBadgeVariant"default"Visual style
sizeBadgeSize"md"Badge size
asChildbooleanfalseRender via Radix Slot
classNamestringAdditional Tailwind classes

The Badge extends standard HTML span props:

badge-props.ts
React.HTMLAttributes<HTMLSpanElement>

TypeScript typesLink to section

badge-types.ts
export type BadgeVariant =
  | "default"
  | "secondary"
  | "muted"
  | "outline"
  | "success"
  | "warning"
  | "destructive";

export type BadgeSize = "sm" | "md" | "lg";

AccessibilityLink to section

  • Badges are non-interactive by default.
  • Do not use a badge as a button.
  • Do not rely on color alone to convey meaning.
  • Icons must be supplementary, not the only indicator.
  • Use aria-hidden="true" for decorative icons.
  • When interactive, use asChild with a semantic element such as a or button.

Prefer / avoidLink to section

Prefer

  • short labels
  • semantic variants for real status
  • muted or outline for metadata
  • icons as supporting context only
  • consistent badge usage across tables and cards

Avoid

  • using badges as primary actions
  • long sentence-like badge text
  • too many badges in one panel
  • color-only meaning
  • inventing one-off badge colors locally

Common questionsLink to section