VisorVisor
ComponentsForm

Chip

A chip family — Chip (display), ChoiceChip (radio-style single-select), and FilterChip (toggle-style multi-select). Modeled on Flutter Material's Chip API.

Chip (display)

The base Chip renders a static label with optional avatar, leading icon, and delete button.

React
TypeScript

Deletable chip

React
TypeScript
Featured

ChoiceChip (single-select)

ChoiceChip renders a <button role="radio"> for radio-style selection. Use inside ChipGroup type="single" or manage selected / onPressed yourself.

FilterChip (multi-select)

FilterChip renders a <button role="checkbox"> for toggle-style multi-selection. Use inside ChipGroup type="multiple" or manage state directly.

Active: events

Sizes

All three chip types share sm, md (default), and lg sizes.

Small
Medium
Large

Variants

Default
Outlined
Coherent

filled-primary

Use filled-primary when a chip must assert primary brand prominence — for example, essence words on the Brand Workbench Elicit canvas, brand strategy surfaces, or marketing deck templates. It renders a saturated primary fill with --primary-text foreground and --shadow-sm depth.

Avoid using filled-primary for generic tags or filters; prefer default or outlined there to preserve the variant's signal weight.

Installation

npx visor add chip

This copies two files into your project:

  • components/ui/chip/chip.tsx — Chip, ChoiceChip, and FilterChip components
  • components/ui/chip/chip.module.css — the styles

Usage

import { Chip, ChoiceChip, FilterChip } from '@/components/ui/chip/chip';

// Static display chip
<Chip label="React" />

// Deletable chip
<Chip label="Featured" onDeleted={() => removeTag('featured')} />

// Single-select (manage state yourself, or use ChipGroup)
<ChoiceChip
  label="Compact"
  selected={density === 'compact'}
  onPressed={() => setDensity('compact')}
/>

// Multi-select toggle (manage state yourself, or use ChipGroup)
<FilterChip
  label="Events"
  selected={filters.includes('events')}
  onPressed={() => toggleFilter('events')}
/>

For managed selection state across a group, use the chip-group block.

API Reference

ChipProps

PropTypeDefaultDescription
variant'default' | 'outlined' | 'filled-primary''default'Visual variant. `default` — muted surface background. `outlined` — transparent with a border. `filled-primary` — saturated primary fill + primary-text foreground; use when the chip must carry primary brand prominence (essence chips, brand strategy surfaces).
size'sm' | 'md' | 'lg''md'Controls chip height and font size.
labelReactNodeLabel content. Falls back to children if omitted.
avatarReactNodeOptional avatar rendered before the label.
leadingIconReactNodeOptional icon rendered before the label (after avatar).
onDeleted() => voidWhen provided, a delete button is shown and called on click.
deleteLabelstring'Remove'Accessible aria-label for the delete button.
deleteIconReactNodeCustom delete icon. Defaults to XIcon.
classNamestringAdditional CSS class names merged onto the root element.
...propsReact.HTMLAttributes<HTMLDivElement>All standard div attributes are forwarded to the root element.

The component accepts all standard <div> HTML attributes.

ChoiceChipProps

PropTypeDefaultDescription
selectedbooleanfalseWhether this chip is selected.
onPressed() => voidCalled when the chip is pressed.
valuestringValue identifier (used by ChipGroup).
avatarReactNodeOptional avatar before the label.
leadingIconReactNodeOptional icon before the label.
labelReactNodeLabel content (or use children).
variant"default" | "outlined" | "filled-primary""default"Visual variant.
size"sm" | "md" | "lg""md"Size.
disabledbooleanfalseDisables the chip.

FilterChipProps

PropTypeDefaultDescription
selectedbooleanfalseWhether this chip is active.
onPressed() => voidCalled when the chip is toggled.
valuestringValue identifier (used by ChipGroup).
leadingIconReactNodeOptional icon before the label.
labelReactNodeLabel content (or use children).
countReactNodeOptional count pill after the label.
countTone"neutral" | "primary""neutral"Tone for the count pill.
selectedTreatment"accent" | "neutral""accent"Selected-state visual treatment. "accent" uses accent-tinted bg + link text (default). "neutral" uses --surface-card bg + neutral border + primary text; the count pill renders as a solid mint pill. Use in editorial/admin contexts to avoid accent bleed.
variant"default" | "outlined" | "filled-primary""default"Visual variant.
size"sm" | "md" | "lg""md"Size.
disabledbooleanfalseDisables the chip.

Accessibility

  • Chip (display) renders as a <div>. The delete button is a <button> with aria-label (defaults to "Remove").
  • ChoiceChip renders as <button role="radio" aria-checked>. Wrap in a role="radiogroup" container (or use ChipGroup type="single") to provide group semantics.
  • FilterChip renders as <button role="checkbox" aria-checked>. ChipGroup type="multiple" wraps items in role="group".
  • Keyboard: Tab focuses each interactive chip; Space / Enter toggles or activates.
  • Disabled chips use disabled attribute and opacity — not hidden from screen readers.