Pill

Like Badge, but interactive -- selections, filters, or removable tags.

AccentSuccessWarningDanger

Usage

import { Pill } from '@epilot/spark-ui/pill'
<Pill color="accent" styleVariant="solid">
  Accent
</Pill>

Pill is a label like Badge, but built for interaction: pass onClick to make the whole pill a button, or onRemove to add a removable-tag affordance. With neither, it's a static label.

Examples

Styles

SolidSurfaceSoft

Clickable

Passing onClick makes the pill a keyboard-operable button (role="button", Enter/Space, focus ring).

Clickable

Removable

Passing onRemove (and a removeLabel) adds a trailing glyph. Click it, or press Delete/Backspace while the pill has focus.

RemovableRemove

Disabled

Disabled

API Reference

PropTypeDefaultDescription
styleVariant'solid' | 'soft' | 'surface' | 'ghost' | 'outline'Emitted as data-style (defaults to 'soft' once either prop is set); with neither set, no data-style at all.
color'accent' | 'neutral' | 'success' | 'warning' | 'danger'data-accent-color={accentByColor[color]}; accent omits the attribute.
disabledbooleanfalseStrips all interactivity (onClick/onRemove no longer fire) and dims the pill.
onClick(event) => voidPresence makes the pill a role="button", focusable, Enter/Space-activated control.
onRemove(event) => voidPresence renders a trailing remove glyph; fires on its click or on Delete/Backspace while the pill has focus.
removeLabelstringrequired with onRemoveVisually-hidden text folded into the pill's accessible name -- the glyph itself is decorative.

The pill also forwards all other span attributes, including className (merged with the base styling), and a ref to the root <span>.

Accessibility

  • With no onClick/onRemove, the pill is a plain, non-interactive label (same as Badge) -- no role, no tab stop.
  • onClick adds role="button" and a focus ring; the whole pill is one tab stop, activated by click, Enter, or Space.
  • onRemove's glyph is aria-hidden and mouse-only -- it is not a separate tab stop. The keyboard path is Delete/Backspace on the pill itself, which the pill advertises via aria-keyshortcuts="Delete".
  • disabled sets aria-disabled="true" and removes the pill from the tab order entirely, whether or not onClick/onRemove are set.

On this page