Tag

Tag

A compact label for categorizing content. Five tonal variants, three sizes, and an optional close control for removable tags.

Playground

Design
label
variant
size
closable
disabled
<Tag>Design</Tag>

Preview

A single Tag renders an inline span. Pass onClose to append the remove button.

PrimarySecondaryRemovable
<Tag>Primary</Tag>
<Tag variant="secondary">Secondary</Tag>
<Tag variant="outline" onClose={() => {}}>
  Removable
</Tag>

Installation

npx shadcn@latest add https://espresso-base-ui.vercel.app/r/tag.json

Usage

import { Tag } from "@/components/ui/tag"
<Tag variant="secondary" size="sm" onClose={() => remove(id)}>
  Design
</Tag>

Variants

variant sets the tone: primary, secondary, outline, ghost and destructive – each with hover, focus-visible and active states.

PrimarySecondaryOutlineGhostDestructive
<Tag variant="primary">Primary</Tag>
<Tag variant="secondary">Secondary</Tag>
<Tag variant="outline">Outline</Tag>
<Tag variant="ghost">Ghost</Tag>
<Tag variant="destructive">Destructive</Tag>

Sizes

Three sizes: sm (20px), default (24px) and lg (28px). The outline variant trims 2px off each height to account for its outer shadow ring.

SmallDefaultLarge
<Tag size="sm">Small</Tag>
<Tag size="default">Default</Tag>
<Tag size="lg">Large</Tag>

Removable

With onClose the tag becomes focusable and shows a trailing remove button – click it, or focus the tag and press Backspace or Delete.

ReactNext.jsTypeScript
const [tags, setTags] = useState(["React", "Next.js", "TypeScript"])

{tags.map((tag) => (
  <Tag
    key={tag}
    variant="secondary"
    onClose={() => setTags(tags.filter((t) => t !== tag))}
  >
    {tag}
  </Tag>
))}

Disabled

disabled mutes the colors, blocks pointer events, hides the close button from assistive tech and removes the tag from the tab order.

PrimaryOutlineDestructive
<Tag variant="primary" disabled onClose={() => {}}>
  Primary
</Tag>
<Tag variant="outline" disabled onClose={() => {}}>
  Outline
</Tag>
<Tag variant="destructive" disabled onClose={() => {}}>
  Destructive
</Tag>

API reference

Tag renders a span and accepts className plus standard span props. The exported TagProps type covers the full signature.

Tag

PropTypeDefaultDescription
variant"primary" | "secondary" | "outline" | "ghost" | "destructive""primary"Tone – filled primary/destructive surfaces, a soft secondary, a bordered outline, or a transparent ghost.
size"sm" | "default" | "lg""default"Height, padding, radius and type scale. Outline tags run 2px shorter per size to offset the shadow ring.
onClose() => void–Renders the trailing remove button and makes the tag focusable. Called on click or on Backspace/Delete while the tag has focus.
disabledbooleanfalseDisables interaction: sets aria-disabled and data-disabled, blocks pointer events and removes the tag from the tab order.

Accessibility & styling hooks

A removable tag takes tabIndex=0 so keyboard users can reach it and delete it with Backspace or Delete; the close control renders role="button" with aria-label="Remove". Disabled tags expose aria-disabled. The root carries data-slot="tag" and reflects its props as data-variant, data-size and data-disabled; the close button is data-slot="tag-close" – target these from CSS for app-level overrides.

The tagVariants cva helper is also exported for building custom tag-shaped surfaces with the same classes:

import { tagVariants } from "@/components/ui/tag"

<span className={cn(tagVariants({ variant: "outline", size: "sm" }))}>
  ...
</span>

Search documentation

Search the component docs