Skip to main content

Chip

Compact removable tag with tones, variants, sizes, an optional leading icon or avatar slot, and click-to-remove interactions. Perfect for filters, taggable inputs, and metadata pills.

Live Preview

Adjust the chip's tone, variant, size, and slots in real time. The right column mirrors the same configuration inside a ChipGroup.

Design
DesignEngineeringMarketing
tsx
1<Chip2  tone="brand"3  variant="subtle"4  size="md"5  onRemove={() => remove(id)}6>7  Design8</Chip>

Installation

Install the Aidash Components package using your preferred package manager.

$ pnpm add @aidash/components

Import

Import Chip and ChipGroup into your file.

tsx
import { Chip, ChipGroup } from '@/components/aidash/chip';

Basic Usage

The simplest form: a static label pill.

Design
tsx
1<Chip>Design</Chip>

Tones

Six semantic tones cover neutral labels and status indicators.

DefaultBrandSuccessWarningDangerInfo
tsx
1<Chip tone="default">Default</Chip>2<Chip tone="brand">Brand</Chip>3<Chip tone="success">Success</Chip>4<Chip tone="warning">Warning</Chip>5<Chip tone="danger">Danger</Chip>6<Chip tone="info">Info</Chip>

Variants

Three visual weights: solid, subtle, and outline.

Solid

BrandSuccessDanger

Subtle

BrandSuccessDanger

Outline

BrandSuccessDanger
tsx
1<Chip tone="brand" variant="solid">Brand</Chip>2<Chip tone="brand" variant="subtle">Brand</Chip>3<Chip tone="brand" variant="outline">Brand</Chip>

Sizes

Three sizes to fit dense filter bars, standard forms, or hero contexts.

SmallMediumLarge
tsx
1<Chip size="sm">Small</Chip>2<Chip size="md">Medium</Chip>3<Chip size="lg">Large</Chip>

With Icon

Pass a hugeicons icon module via the icon prop to prepend a small glyph.

FeaturedStarredLovedDone
tsx
1import { Tag01Icon, StarIcon, HeartIcon, CheckmarkCircle02Icon } from '@hugeicons/core-free-icons';2 3<Chip tone="brand" icon={Tag01Icon}>Featured</Chip>4<Chip tone="warning" icon={StarIcon}>Starred</Chip>5<Chip tone="danger" icon={HeartIcon}>Loved</Chip>6<Chip tone="success" icon={CheckmarkCircle02Icon}>Done</Chip>

With Avatar

Pass any node to the avatar prop — the Chip wraps it in a rounded, size-matched container. Icon wins if both are provided.

Ada LovelaceGrace Hopper
tsx
1<Chip2  avatar={<div className="bg-brand-500/15 text-brand-500 text-[10px]">AL</div>}3>4  Ada Lovelace5</Chip>

Removable

Pass onRemove to render a trailing X button. Wrap chips in AnimatePresence so the exit transition plays as items are removed.

DesignEngineeringMarketingSales
tsx
1import { AnimatePresence } from 'framer-motion';2 3const [items, setItems] = useState(['Design', 'Engineering', 'Marketing']);4const remove = (v: string) => setItems((prev) => prev.filter((x) => x !== v));5 6<ChipGroup>7  <AnimatePresence>8    {items.map((item) => (9      <Chip key={item} tone="brand" onRemove={() => remove(item)}>10        {item}11      </Chip>12    ))}13  </AnimatePresence>14</ChipGroup>

Clickable

Provide onClick to render the chip as a semantic <button>. Enter and Space activate it; Backspace / Delete trigger onRemove when both are set.

Clicks: 0

tsx
1<Chip tone="brand" onClick={() => handleSelect(id)}>2  Click me3</Chip>4 5{/* Combine onClick + onRemove — Backspace/Delete triggers remove */}6<Chip7  tone="success"8  variant="solid"9  icon={CheckmarkCircle02Icon}10  onClick={() => handleSelect(id)}11  onRemove={() => handleRemove(id)}12>13  Click or remove14</Chip>

Disabled State

Disabled chips are dimmed and skip pointer + keyboard interaction.

DefaultSolidRemovable
tsx
1<Chip disabled>Default</Chip>2<Chip tone="brand" variant="solid" disabled>Solid</Chip>3<Chip tone="danger" variant="outline" disabled onRemove={() => remove()}>4  Removable5</Chip>

Accessibility

Chip switches its host element and ARIA wiring based on the interactions you enable.

Semantic button vs. span

Providing onClick upgrades the root to <button type="button">. Purely decorative chips stay as <span>.

Remove button aria-label

The trailing X is its own <button> with a distinct aria-label (defaults to "Remove <text>") and stops click propagation so the parent chip doesn't also fire.

Keyboard: Backspace / Delete

When the chip is focused as a button, Enter / Space activate it and Backspace / Delete trigger onRemove.

Focus-visible outline

Interactive chips render a focus-visible ring using the brand token so keyboard users can see the focus target without adding noise for mouse users.

Accessibility Example
tsx
<Chip
  tone="brand"
  onClick={() => select(id)}
  onRemove={() => remove(id)}
  removeAriaLabel={`Remove tag ${label}`}
>
  {label}
</Chip>

{/* Renders:
  <button type="button" aria-disabled={undefined}>
    ...label...
    <button aria-label="Remove tag Design">...</button>
  </button>
*/}

API Reference

Complete list of props for Chip and ChipGroup.

ChipProps
PropTypeDefaultDescription
childrenReactNodeChip label content.
tone'default' | 'brand' | 'success' | 'warning' | 'danger' | 'info''default'Semantic color tone.
variant'solid' | 'subtle' | 'outline''subtle'Visual variant.
size'sm' | 'md' | 'lg''md'Chip size.
iconIconSvgElementLeading hugeicons icon. Wins over avatar when both provided.
avatarReactNodeLeading avatar node (mutually exclusive with icon).
onClick() => voidWhen provided, renders the chip as a <button>.
onRemove() => voidWhen provided, renders a trailing X remove button.
disabledbooleanfalseDim the chip and disable interaction.
removeAriaLabelstring'Remove ${text}'Override the remove button's aria-label.
classNamestring''Additional CSS classes.
ChipGroupProps
PropTypeDefaultDescription
childrenReactNodeChips to lay out.
spacing'sm' | 'md' | 'lg''md'Gap between chips (gap-1 / gap-2 / gap-3).
classNamestring''Additional CSS classes.
Tip
Wrap chips in Framer Motion's <AnimatePresence> to opt in to exit transitions when items are removed. Without it the removal is instant.

Other components that work well alongside Chip.