Skip to content
Cloaked Design SystemPrimitives

Tag

The single non-interactive marker: a compact pill carrying a status, a label, or a piece of metadata.

Implementation preview
COMPLETE STORYBOOK REFERENCE

Every example. In one place.

Explore every named example, including states, compositions, and theme variants.

7 stories
SELECTED EXAMPLE

Playground

Open controls
Playground selectedOpen canvas
Example sourcepackages/design-system/src/components/primitives/Tag/Tag.stories.tsxExport Playground

Implementation preview Local Storybook build 0.2.0-preview.1. Source specification status does not approve this runtime.

Stories + source JSON ↗

Local specification source status: preview. Implementation preview pending sign-off.

The single non-interactive marker: a compact pill carrying a status, a label, or a piece of metadata.

Design-owned component contract ↗Version 0.2.0-preview.1 · Implementation preview pending sign-off
Implementation API 1 entry point · source-derived preview

Read the actual callable API and preserve its composition constraints. Each union branch is a complete alternative; props marked forbidden cannot be supplied.

import { Tag } from '@cloakedinc/design-system';
TagTagProps

packages/design-system/src/components/primitives/Tag/Tag.tsx:39

PropTypePresenceNotes
tone"neutral" | "info" | "success" | "warning" | "danger"RequiredSemantic status treatment. `neutral` reads as chrome rather than an outcome.
emphasisTagEmphasisRequiredFill weight: `solid` fills with the tone, `subtle` its tint, `outline` a border on transparent.
contrastTagContrast | undefinedOptionalRetunes a `neutral` marker for a dark or branded surface. A toned marker keeps its tone.Source default: 'default'
dotboolean | "neutral" | "info" | "success" | "warning" | "danger" | undefinedOptionalLeading dot. `true` matches the label color; a tone colors the dot independently.
leadingReact.ReactNodeOptionalOptional leading visual, usually an `Icon` or `SFIcon`.
fullWidthboolean | undefinedOptionalStretches the tag to its parent width, keeping content centered.
childrenReact.ReactNodeRequired
classNamestring | undefinedOptional
styleReact.CSSProperties | undefinedOptional
testIdstring | undefinedOptionalSelector on the outer `<span>`; the dot and the label inside carry none.

Only explicit destructured parameter initializers are extracted. Other runtime defaults remain in implementation source.

Overview

The single non-interactive marker. A Tag is a compact pill carrying a status, a label, or a piece of metadata. tone sets the meaning, emphasis sets how much it stands out, and contrast retunes the chrome for a dark or branded surface.

Tag or Chip

A Tag renders a <span> with no role and no focus stop. A Chip renders a button that takes focus and responds to a tap. That difference is in the DOM and the accessibility tree, not in the styling, which is why they are separate components rather than one component with an onPress prop.

So the question is never how the pill looks. It is whether tapping it does anything.

Tone and emphasis

tone carries the Status tone axis. emphasis picks the surface.

neutral is the exception worth understanding: a neutral marker is chrome rather than an outcome, so it leaves the status ramp and uses the surface roles instead. That is what makes a neutral pill read as a label rather than as a grey status.

Tone`subtle``solid``outline`
neutral--cds-bg-subtle + primary text--cds-bg-inverse + inverse text--cds-divider border
any othertone subtle fill + tone solid texttone solid fill + inverse texttone solid border and text

tone is the Status tone axis and nothing else. A marker carrying product identity rather than an outcome does not belong here.

The dot

dot takes a boolean or a tone. A bare dot matches the label color. Passing a tone colors the dot on its own, which is how a marker shows a green indicator beside a neutral label.

Recipes

The design system owns the axes. Product concepts own their prop combinations. When a preset appears in more than one place, wrap it in the feature that uses it rather than adding a part here, the way ActivityStatusTag wraps its tone and glyph.

A running or stopped state appears twice, at two prominences. Reach for the ambient row when the marker sits beside a title that already says what it describes, and the announced row when the state is the thing the surface is about.

Product conceptProps
Running, ambienttone='neutral' emphasis='subtle' dot='success'
Stopped, ambienttone='neutral' emphasis='subtle' dot
Running, announcedtone='success' emphasis='solid' dot='neutral'
Stopped, announcedtone='neutral' emphasis='solid' dot='neutral'
Overduetone='danger' emphasis='solid'
Complete / donetone='success' emphasis='subtle'
Needs helptone='warning' emphasis='solid' leading={...}
Metadata / categorytone='neutral' emphasis='subtle'
Counttone='neutral' emphasis='subtle'
AI-assistedtone='info' emphasis='subtle' leading={...}
Neutral on a dark widgetadd contrast='inverse'

Reach for something else

Instead of a TagUseBecause
A tappable pillChipIt needs a role and a focus stop.
A removable valueChipThe remove affordance is a second button.
A bare dot and labelStatusIndicatorNo pill behind it; it rides inside a row.
An up or down trendCard.DeltaA delta is a change in a number, not a state.
A multi-line calloutBannerIt is a block of feedback, not a marker.
A notification countAvatar or tab slotAn anchored count belongs on the element it counts.

Sizes

There is no size prop. Figma draws every marker at one height, and the two sizes the old Tag.Status carried differed only in horizontal inset.

On a dark surface

contrast='inverse' resolves a neutral marker to the inverse roles, so the chrome keeps its treatment on a surface that is dark in both themes. It has no effect on a toned marker: the status fills are opaque in both themes and already read on a dark surface, so a success or danger marker keeps its tone rather than losing it to grey chrome.

Full width

fullWidth stretches the marker to its parent, for a card footer that carries a state across the whole row.

Do and don’t

GuidanceExample
DoUse Tag for anything the user only reads: a status, a category, a timestamp, a count.
Don’tGive a Tag an onClick through className or a wrapper. Users try to tap things that look tappable, so a marker that does something must be a Chip.

Component specification

$schema../../../specs/component-spec.schema.json
Parts
Id
root
Label
Root
Description
Inline pill that carries the emphasis surface, tone color, and contrast treatment.
Required
true
Id
leading
Label
Leading
Description
Optional leading visual, usually an Icon or SFIcon.
Id
dot
Label
Dot
Description
Optional indicator dot. Matches the label color by default, or takes its own tone.
Id
label
Label
Label
Description
Body-small marker text.
Allowed Design Choices
Variants
Solid
Label
Solid
Description
Saturated fill for the one marker that must stand out.
Subtle
Label
Subtle
Description
Tinted fill for inline metadata and statuses.
Outline
Label
Outline
Description
Border-only pill for quiet markers on busy surfaces.
Sizes
Tones
Neutral
Label
Neutral
Description
Chrome rather than an outcome. Leaves the status ramp for the surface roles.
Info
Label
Info
Success
Label
Success
Warning
Label
Warning
Danger
Label
Danger
Variants
Id
solid
Label
Solid
Description
Solid tone fill with inverse text. Neutral resolves to the inverse surface.
Platforms
  • ios
  • android
  • web
Id
subtle
Label
Subtle
Description
Tinted tone fill with tone-colored text. Neutral resolves to the subtle surface with primary text.
Platforms
  • ios
  • android
  • web
Id
outline
Label
Outline
Description
Transparent fill with a tone-colored border and text. Neutral borders on the divider token.
Platforms
  • ios
  • android
  • web
SizesNone specified
Measurements
Id
min-height
Label
Minimum height
Kind
exact
Token
--cds-size-24
Value
24
Unit
px
Applies To
  • root
Id
block-padding
Label
Block padding
Kind
exact
Token
--cds-space-4
Value
4
Unit
px
Applies To
  • root
Id
inline-padding
Label
Inline padding
Kind
exact
Token
--cds-space-12
Value
12
Unit
px
Applies To
  • root
Id
content-gap
Label
Content gap
Kind
exact
Token
--cds-space-8
Value
8
Unit
px
Applies To
  • root
  • leading
  • dot
  • label
Id
dot-size
Label
Dot size
Kind
exact
Token
--cds-size-8
Value
8
Unit
px
Applies To
  • dot
Layout
Alignment
Leading visual, dot, and label sit on the marker center line, centered on the main axis so fullWidth stays balanced.
Flow
One inline pill sized to its content with a fully rounded radius. There is no size axis: Figma draws every marker at one height.
Notes
  • Use Chip when the pill must be tappable or removable.
  • Use StatusIndicator for a bare dot-plus-label with no pill behind it.
  • Use Card.Delta for a trend delta such as an up or down arrow beside a number.
  • Use Banner or an inset Card for a multi-line callout.
Typography And Color
Typography
Label
Marker text
Description
Uses the body-small ramp for the label.
Token
--cds-type-body-small-size
Colors
Label
Subtle fill
Description
The chip fill backs the subtle emphasis: a tint in light, a solid hue in dark.
Token
--cds-bg-status-info
Label
Subtle text
Description
The chip label pairs with the chip fill: the hue in light, white in dark.
Token
--cds-text-on-status-info
Label
Solid fill
Description
Tone solid backs the solid emphasis and the outline border.
Token
--cds-status-info-solid
Label
Solid text
Description
Inverse text sits on a solid tone fill.
Token
--cds-text-inverse
Label
Neutral subtle fill
Description
A neutral marker is chrome, so its tone entry is a surface grey rather than the grey status hue.
Token
--cds-bg-status-neutral
Label
Neutral subtle text
Description
Pairs with the neutral subtle fill.
Token
--cds-text-on-status-neutral
Label
Neutral solid fill
Description
The boldest neutral treatment, matching the selected Chip pairing.
Token
--cds-bg-inverse
Label
Neutral outline border
Description
The divider token borders a neutral outline marker.
Token
--cds-divider
Label
Inverse contrast fill
Description
Backs a neutral marker placed on a dark or branded surface.
Token
--cds-bg-subtle-inverse
States
Id
solid
Label
Solid
Description
Tone solid fill with inverse text.
Id
subtle
Label
Subtle
Description
Tone subtle fill with tone solid text.
Id
outline
Label
Outline
Description
Transparent fill with a tone solid border and text.
Id
with-dot
Label
With dot
Description
Shows a leading dot that either matches the label color or carries its own tone.
Id
contrast-inverse
Label
Inverse contrast
Description
Neutral chrome retuned for a dark or branded surface. A toned marker keeps its tone.
Id
full-width
Label
Full width
Description
Stretches to the parent width, keeping content centered.
Behavior
Label
Tone
Description
Set tone to the semantic status. Neutral means chrome and leaves the status ramp for the surface roles.
Label
Independent dot tone
Description
Pass a tone to dot when the indicator and the label carry different meanings, such as a green dot beside a neutral label.
Label
Non-interactive
Description
A Tag is a span with no role and no focus stop. Never attach press or removal behavior; use Chip instead.
Label
Presets live in the app
Description
Product concepts such as live or paused belong in an app wrapper or in the recipe table, not in a design-system part.
Accessibility
Label
Visible meaning
Description
Keep textual content so the marker reads without relying on color or the dot alone.
Label
Decorative dot
Description
The dot is aria-hidden; the visible label carries the meaning.
Label
No focus stop
Description
The root adds no tab stop and no role, which is what separates a Tag from a Chip.
Content Adaptation
Label
Concise content
Description
Use short labels that stay on one line without wrapping.
Label
Overflow
Description
A label wider than the tag truncates with an ellipsis rather than wrapping or spilling past the pill. Treat that as a backstop, not a layout: pick copy that fits the narrowest place the tag appears.
Label
Leading visual
Description
Pair a glyph with the label rather than replacing the text.
Motion Haptics
Motion
Label
Stable geometry
Description
Changing tone or emphasis recolors the pill without animating layout.
Haptics
Label
No feedback
Description
Tag is non-interactive and requests no haptics.
Platform Differences
Platforms
  • ios
  • android
Description
Native platforms have no built-in equivalent to map onto. Apple's HIG has no tag, chip, or pill, and the iOS badge modifier is an anchored count rather than a free-standing marker.
Rationale
Internal consistency governs this component instead of platform fidelity, so each platform builds the same pill rather than substituting a native control that means something else.
Platforms
  • web
Description
Figma draws a 6px indicator dot. Web renders 8px.
Rationale
6px sits off the 4-step size ramp, and both Badge and StatusIndicator already use 8px, so matching them beats minting an off-ramp token for a 2px difference.
Implementation preview

This design-owned implementation is ready to try and review. It does not establish product approval. Imported specifications retain their original review status.

Inspect version 0.2.0-preview.1