Compact interactive label for selection, filtering, and tagging.
Description
Chip is a small, interactive surface used to represent a discrete piece of data, such as a filter token, a selected option, a tag, or a contact. Unlike a passive label, a chip can be selected, dragged, and dismissed, and it can carry a leading icon, avatar, country flag, or brand logo to make the entity it represents recognizable at a glance.
Reach for it in filter bars, multi-select fields, contact pickers, tag-entry inputs, and drag-and-drop tag rails. It works equally well in dense toolbars (size="xs" or "sm") and in form-level rows next to inputs (size="lg" or "xl").
Don't use Chip when the element is purely decorative; use Badge for passive status or count labels. Don't use it when the element triggers a primary action; use Button. For binary on/off inside a form, use Switch; chips are for one-of-many or many-of-many selections.
Installation
Usage
Examples
Colors
variant sets the semantic intent. neutral is the default; info, danger, and success map to the system's status token sets.
Appearance
appearance toggles between a bordered surface and a tinted fill. outline is the default and reads quietly inside dense layouts; soft raises emphasis without going full solid.
Sizes
Five sizes (xs, sm, md, lg, xl) line up with the form-control scale. lg is the default and matches the Input row height.
Shape
shape="pill" makes the chip fully rounded; rounded (default) follows the size's radius scale.
With Icon
Use leadingIcon to render an icon before the label. The component sizes the icon automatically per the active size.
With Media
Use avatar, flag, or brand for a circular media slot that holds pictures of people, country flags, or brand logos. The slot is clipped to a circle and sized per size.
Closable
Pass onClose (or set closable) to render a trailing close button. The button stops propagation so a chip's onClick won't fire when the close icon is clicked.
States
selected, dragging, and disabled are mutually independent visual states applied via data-* attributes on the root.
Interactive
Provide onClick to turn the chip into a role="button". Combine with controlled selected to build a multi-select filter row.
Accessibility
When onClick is provided, Chip renders with role="button" and is keyboard-focusable; otherwise it is a plain non-interactive container that still receives tabIndex={0} for consistent focus rings on dense filter rails. The trailing close button is tabIndex={-1} (mouse-only) and labelled Remove; expose a separate keyboard affordance (e.g. Backspace on a parent input) when chips are used inside a tag-entry control.
ARIA notes:
- The root sets
role="button"only whenonClickis supplied; purely decorative chips remainrole="group"-equivalent and will not be announced as buttons. aria-disabled="true"is set whendisabledistrue; pointer events andonClickare also suppressed.- The close button uses
aria-label="Remove"; override the parent chip's accessible name witharia-labelon the root when the visible label is iconographic.
Styling
Tailwind override: pass className to merge Tailwind classes with the component's CVA classes (via cn()):
Data slots and attributes: the component sets these for CSS targeting:
data-slot="chip"on the root element.data-slot="chip-lead"on the leading icon / avatar / flag / brand wrapper.data-slot="chip-label"on the inner text wrapper.data-slot="chip-close"on the trailing close button.data-color="<color>",data-appearance="<appearance>",data-size="<size>"on the root.data-selected(only whenselected),data-dragging(only whendragging),aria-disabled(only whendisabled).
Target a specific state in CSS:
Related Components
- Badge: passive label for status, count, or category. No interactivity, no close affordance.
- Toggle: binary on/off form control; use this when the state belongs to a single boolean field.
- Button: primary actions. Chips are filters and tags, not CTAs.
- Input Group: composition pattern for tag-entry inputs that emit chips on
Enter.
API Reference
Chip
Interactive label with optional leading media and a trailing close affordance. Extends React.ComponentProps<"div">, so any standard div attribute (id, aria-*, onClick, etc.) is accepted.