Skip to content
← Inventory

Tag

Tag - An interactive pill component for selection, filtering, and multi-select scenarios. Uses shared pill styling (identical to Badge) with interactive capabilities: dismissibility, click handling, and keyboard support. The outer element is polymorphic based on interactivity: - onClick provided: <button> - onDismiss only: <div> with dismiss <button> - Both: <button> with dismiss <span role="button"> - Neither: <span> (presentational)

FeaturedHoned
Polished

Usage

import { Tag, TAG_SIZES, TAG_TONES, TagEmphasis, TagProps, TagSize, TagTone } from "@desk/ui/components/tag";

Best practices

  • Choose Tag when the chip is interactive (selection/filter/dismiss); for a display-only status label or count use Badge, and for a bare colour dot use Dot.

  • The outer element is derived from your handlers — pass onClick to make it a <button> and/or onDismiss to reveal the "Remove" control; without either it renders an inert <span>, so don't wrap it in your own button.

  • Set at most one leading visual — loading > imageUrl > dot > icon (in that precedence); pass a Lucide component to icon (not <Icon/>), and imageUrl renders a circular <img alt="">, so keep it decorative.

  • When onDismiss is set, Backspace/Delete also removes the tag while it's focused — don't bind your own conflicting key handler.

Props

PropTypeDefaultDescription
childrenReact.ReactNode
disabledboolean

Disabled state

sizeResponsiveValue<PillSize>"base"

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

dismissIconReact.ReactNode

Custom dismiss icon (defaults to X)

dotboolean | "neutral" | "brand" | "danger" | "warning" | "success" | "info"

Leading status dot: true for a neutral dot, or a {@link Tone} to tint it.

hideDismissboolean

Hide dismiss button even when onDismiss is provided

iconLucideIcon | React.ComponentType<React.SVGProps<SVGSVGElement>>

Leading icon

imageUrlstring

Leading circular thumbnail image

loadingboolean

Show loading spinner (replaces leading visual)

onClickReact.MouseEventHandler<HTMLButtonElement>

Click handler — makes the whole tag a button

onDismiss(event: React.MouseEvent | React.KeyboardEvent) => void

Dismiss handler — shows dismiss button

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).

Also exports

  • constTAG_SIZES
  • constTAG_TONES
  • typeTagEmphasis
  • interfaceTagProps
  • typeTagSize
  • typeTagTone

Composition