Skip to content
← Inventory

Badge

Display-only pill for contextual metadata — status, category, or counts. Pass label+value for a split badge; compose BadgeDot/BadgeButton as children.

New

Usage

import { Badge, BadgeButton, BadgeButtonProps, BadgeDot, BadgeDotProps, BadgeEmphasis, BadgeProps, BadgeSize, BadgeTone, pillVariants } from "@desk/ui/components/badge";

Best practices

  • Badge is display-only — never attach onClick; use Tag (interactive) or wrap a Button.

  • For a notification count use mode="count" (circular, tabular figures), not radius="full" + manual classes.

  • A standalone count needs an accessibleLabel ("3 unread"); inside an icon-only trigger, mark the badge aria-hidden and fold the count into the trigger's aria-label.

Props

Badge

PropTypeDefaultDescription
asChildboolean

Merge props onto the child element instead of rendering a span.

sizeResponsiveValue<PillSize>"base"

Badge size — a single token or a per-breakpoint object like { base: "sm", md: "lg" }. Forwarded to the underlying Pill.

disabledboolean
focusedboolean

Force focus ring display (for documentation/testing)

hoveredboolean

Force hover state display (for documentation/testing)

iconLucideIcon | React.ComponentType<React.SVGProps<SVGSVGElement>>
iconPlacement"end" | "start""start"
labelstring

Left segment of a split badge; renders a divider before value.

loadingboolean

Show loading spinner

loadingLabelstring

Label shown during loading

testidstring
valuestring

Right (emphasised) segment; shown alone when no label is set.

mode"default" | "count""default"

Badge display mode. "count" renders a circular number badge (full radius + tabular-nums) for notification/count use; it **owns the radius axis** and overrides any radius prop. Pair with accessibleLabel when standalone.

accessibleLabelstring

Accessible name for a standalone mode="count" badge (e.g. "3 unread"). Renders as sr-only text with the visible number hidden from assistive tech. When the badge sits inside an icon-only trigger, instead set aria-hidden on the badge and fold the count into the trigger's own aria-label ("Notifications, 3 unread").

tone"neutral" | "brand" | "danger" | "warning" | "success" | "info" | null | undefined
radius"rounded" | "square" | "full" | null | undefined
emphasis"outline" | "solid" | "ghost" | "soft" | "transparent" | null | undefined
asInputboolean | null | undefined

Input-style chip: white bg + subtle shadow (unselected state).

BadgeButton

PropTypeDefaultDescription
asChildboolean
iconReact.ReactNode
variant"default" | null | undefined

Also exports

  • interfaceBadgeButtonProps
  • componentBadgeDot
  • typeBadgeDotProps
  • typeBadgeEmphasis
  • interfaceBadgeProps
  • typeBadgeSize
  • typeBadgeTone
  • constpillVariants