Westy Design Systemv0.2.7
OverviewComponentsExamplesStorybook

Foundations

  • Typography
  • Colors
  • Spacing
  • Radius
  • Shadows
  • Icons

Components

  • Accordion
  • Alert
  • Alert Dialog
  • Aspect Ratio
  • Avatar
  • Badge
  • Breadcrumb
  • Button
  • Button Group
  • Calendar
  • Card
  • Carousel
  • Chart
  • Checkbox
  • Collapsible
  • Combobox
  • Command
  • Context Menu
  • Data Table
  • Date Picker
  • Dialog
  • Direction
  • Drawer
  • Dropdown Menu
  • Empty
  • Field
  • Hover Card
  • Input
  • Input Group
  • Input OTP
  • Item
  • Kbd
  • Label
  • Menubar
  • Native Select
  • Navigation Menu
  • Pagination
  • Popover
  • Progress
  • Questionnaire
  • Radio Group
  • Resizable
  • Scroll Area
  • Select
  • Separator
  • Sheet
  • Sidebar
  • Skeleton
  • Slider
  • Sonner
  • Spinner
  • Switch
  • Table
  • Tabs
  • Textarea
  • Toggle
  • Toggle Group
  • Tooltip

Chat

  • Attachment
  • Bubble
  • Marker
  • Message
  • Message Scroller

Components

Badge

Displays a badge or a component that looks like a badge.

Playground

Badge
—variant
—data-icon
—Spinner
—asChild
Usage
Badge renders an inline span — drop it next to headings, table cells or list items to label status, counts or metadata. Pick a style with the variant prop.
BadgeSecondaryDestructiveOutline
import { Badge } from "@workspace/ui/components/badge"

<Badge>Badge</Badge>
<Badge variant="secondary">Secondary</Badge>
<Badge variant="destructive">Destructive</Badge>
<Badge variant="outline">Outline</Badge>
Variants
Six variants map to the semantic tokens: default uses the brand primary, secondary and outline stay neutral, destructive tints with --destructive, and ghost and link are transparent until hovered.
DefaultSecondaryDestructiveOutlineGhostLink
<Badge>Default</Badge>
<Badge variant="secondary">Secondary</Badge>
<Badge variant="destructive">Destructive</Badge>
<Badge variant="outline">Outline</Badge>
<Badge variant="ghost">Ghost</Badge>
<Badge variant="link">Link</Badge>
Status
Four variants for conveyed meaning — a paid invoice, an overdue one. Each pairs a surface with the foreground guaranteed to clear WCAG AA 4.5:1 on it, so the combination cannot be mis-assembled at the call site. Badge text is text-xs, so 4.5:1 is the bar, not the 3:1 that applies to large text. Prefer these over hand-pairing a semantic colour with an alpha tint of itself: an alpha tint composites against whatever sits behind it, so the same pair can pass on one surface and fail on another.
PagoPendenteVencidoRascunho
<Badge variant="success">Pago</Badge>
<Badge variant="warning">Pendente</Badge>
<Badge variant="danger">Vencido</Badge>
<Badge variant="neutral">Rascunho</Badge>
With icon
Render an icon inside the badge and mark it with data-icon="inline-start" or data-icon="inline-end" — the badge tightens the padding on that side automatically.
VerifiedBookmark
import { BookmarkSimpleIcon, SealCheckIcon } from "@phosphor-icons/react"

<Badge variant="secondary">
  <SealCheckIcon data-icon="inline-start" />
  Verified
</Badge>

<Badge variant="outline">
  Bookmark
  <BookmarkSimpleIcon data-icon="inline-end" />
</Badge>
With spinner
Drop a Spinner in for loading states — remember the data-icon attribute so the padding adjusts like it does for icons.
DeletingGenerating
import { Spinner } from "@workspace/ui/components/spinner"

<Badge variant="destructive">
  <Spinner data-icon="inline-start" />
  Deleting
</Badge>

<Badge variant="secondary">
  Generating
  <Spinner data-icon="inline-end" />
</Badge>
Link
Use the asChild prop to render the badge as your own element — an anchor keeps the badge styling and gains the variant's [a]:hover treatment.
Open Link
<Badge asChild>
  <a href="#link">
    Open Link <ArrowUpRightIcon data-icon="inline-end" />
  </a>
</Badge>
Custom colors
For accents beyond the semantic tokens, override the colors with classes from the Westy raw scales — pair a light background with a dark text step and give both their dark: counterparts.
GreenOrangePurpleBeige
<Badge className="bg-green-100 text-green-700 dark:bg-green-950 dark:text-green-300">
  Green
</Badge>
<Badge className="bg-orange-100 text-orange-700 dark:bg-orange-950 dark:text-orange-300">
  Orange
</Badge>
<Badge className="bg-purple-100 text-purple-700 dark:bg-purple-950 dark:text-purple-300">
  Purple
</Badge>
<Badge className="bg-beige-100 text-beige-700 dark:bg-beige-950 dark:text-beige-300">
  Beige
</Badge>
RTL
Set dir="rtl" on a wrapper or inherit it from a Direction provider — icon paddings use logical properties (ps/pe), so inline-start and inline-end flip automatically.
شارةمتحققإشارة مرجعية
<div dir="rtl" className="flex flex-wrap gap-2">
  <Badge>شارة</Badge>
  <Badge variant="secondary">
    <SealCheckIcon data-icon="inline-start" />
    متحقق
  </Badge>
  <Badge variant="outline">
    إشارة مرجعية
    <BookmarkSimpleIcon data-icon="inline-end" />
  </Badge>
</div>
API Reference
Badge renders a span (or its child via asChild) and accepts all of the matching HTML props.
PropTypeDefault
variant"default" | "secondary" | "destructive" | "outline" | "ghost" | "link""default"
asChildbooleanfalse
classNamestring—

Tokens used

29 design tokens consumed by the Badge component.

  • --status-success

    Status Success

    bg-status-success
  • --status-success-foreground

    Status Success Foreground

    text-status-success-foreground
  • --status-success-hover

    Status Success Hover

    hover:bg-status-success-hover
  • --status-success-border

    Status Success Border

    border-status-success-border
  • --status-warning

    Status Warning

    bg-status-warning
  • --status-warning-foreground

    Status Warning Foreground

    text-status-warning-foreground
  • --status-warning-hover

    Status Warning Hover

    hover:bg-status-warning-hover
  • --status-warning-border

    Status Warning Border

    border-status-warning-border
  • --status-danger

    Status Danger

    bg-status-danger
  • --status-danger-foreground

    Status Danger Foreground

    text-status-danger-foreground
  • --status-danger-hover

    Status Danger Hover

    hover:bg-status-danger-hover
  • --status-danger-border

    Status Danger Border

    border-status-danger-border
  • --status-neutral

    Status Neutral

    bg-status-neutral
  • --status-neutral-foreground

    Status Neutral Foreground

    text-status-neutral-foreground
  • --status-neutral-hover

    Status Neutral Hover

    hover:bg-status-neutral-hover
  • --status-neutral-border

    Status Neutral Border

    border-status-neutral-border
  • --primary

    Primary

    bg-primarytext-primary
  • --primary-foreground

    Primary Foreground

    text-primary-foreground
  • --secondary

    Secondary

    bg-secondary
  • --secondary-foreground

    Secondary Foreground

    text-secondary-foreground
  • --destructive

    Destructive

    bg-destructive/10text-destructivearia-invalid:border-destructivefocus-visible:ring-destructive/20
  • --border

    Border

    border-border
  • --foreground

    Foreground

    text-foreground
  • --muted

    Muted

    hover:bg-muted
  • --muted-foreground

    Muted Foreground

    hover:text-muted-foreground
  • --ring

    Ring

    focus-visible:border-ringfocus-visible:ring-ring/50
  • --radius-4xl

    Radius 4XL (radius × 2.6)

    rounded-4xl
  • --text-xs

    Text Extra Small (12px)

    text-xs
  • --spacing

    Spacing unit (4px)

    h-5px-2py-0.5gap-1ps-1.5pe-1.5