Chip
Compact labels for metadata such as types, statuses, and values, optionally clickable or removeable.
Installation
- Install the package.
npm install @hashintel/ds-components- Import the component.
import { Chip } from "@hashintel/ds-components";
export const EntityTypeChip = () => (
<Chip color="blue" variant="defined">
Person
</Chip>
);When to use
- Do: Use Chip to label an object with compact metadata: an entity's type, a property value, a status, a version.
- Do: Use
onClickwhen the token itself opens something, such as a filter chip that opens its editor. - Do: Use color to tell categories apart at a glance, keeping each color's meaning consistent across a view.
When not to use
- Don't: Don't use chips for actions or navigation — a chip's primary purpose is to label something. Prefer a Button or Link.
- Don't: Don't use chips for counts that annotate another element, like an unread count on an icon — use Badge.
- Don't: Don't use chips to pick one value from a visible set — use SegmentedControl, or RadioGroup in forms.
Examples
Basic
The default chip is defined, grey, and md-sized.
Variants
Variants set emphasis. defined (default) has a solid border for standalone labels, soft and outline sit quieter inside busy UI, and ghost shows no fill or border until hovered or focused — for metadata that shouldn't compete with content.
Colors
Color categorizes: give each category one color and keep the mapping stable across the product. grey is the default. The label must still carry the meaning — never rely on color alone.
Sizes
md is the default. Use xxs-sm inside dense tables and metadata rows, and lg/xl next to headings. Icons, dots, and spinners inside the chip scale with it.
Round shape
shape="round" renders a pill. Use it for status chips, and keep one shape per chip group — mixing shapes reads as a difference in meaning.
Prefix and suffix
prefix and suffix add a slot on either side of the label. A slot's content is an iconName, a status dot, a loading spinner, or arbitrary children such as a count or version.
Status dot
A dot prefix draws a small circle in the chip's text color, with three fill states — filled, partiallyFilled, empty — for lifecycle or progress readings. The dot is hidden from assistive technology, so the label must state the status.
Loading
A loading: true affix shows a spinner. Swapping the affix to a success mark when work completes can help communicate finished progress.
Affix styles
An affix's variant shapes its edge treatment: straight (default) draws a divider between slot and label, naked drops the divider, badge fills the slot and bleeds to the chip's edge, and angle slants the boundary.
Clickable
onClick turns the whole chip into a real <button> with hover and focus styles. Reserve it for token-level interactions such as opening a filter's editor. Consider promoting anything that reads as an action to Button. An affix with its own onClick becomes a separate button beside the clickable centre (aria-label required).
Removeable
removeable appends a close button that calls onRemove. Name each removal through its aria-label — the default name is just "Remove". removeable and suffix are mutually exclusive.
Behavior
- A static chip renders as a
<div>,onClickalone renders one<button>, andonClickcombined with an interactive affix orremoveablerenders a<div>containing a separate button per segment. - Labels never wrap. Under a width constraint the label truncates with an ellipsis. Wrap the chip in Tooltip when the full value matters.
Content
- Write labels as nouns or values, 1–3 words, sentence case: "Person", "Draft", "3 properties". Prefer labels under 20 characters.
- Keep affix text to a short token: a count ("12"), a version ("v2"), a stage ("beta").
Accessibility
Clickable chips, interactive affixes, and the remove control implement the WAI-ARIA button pattern.
- Status dots are
aria-hidden, so they never produce an unlabeled announcement. - Chips pass through
aria-*attributes for contextual labelling.
What you must do
- The default aria label for the remove button is "Remove". Generally you should re-label the action with the chip contents through
removeable.aria-label, for ex: "Remove 'Ready Status'", so that buttons are distinguishable in a list. - Move focus to a sensible neighbour after removing a chip; the component doesn't manage focus for you.
- State status in the label text — dots and colors are invisible to assistive technology.
API reference
Chip
| Prop | Type |
|---|---|
| size | "xxs" | "xs" | "sm" | "md" | "lg" | "xl" default: "md" |
| shape | "round" | "default" default: "default" |
| color | ChipColor default: "grey" |
| variant | "ghost" | "soft" | "outline" | "defined" default: "defined" |
| onClick | (() => void) |
| prefix | PrefixOrSuffix |
| removeable | false | { onRemove: () => void; "aria-label"?: string; tabIndex?: number; } | undefined |
| suffix | PrefixOrSuffix |
PrefixOrSuffix
The object shape prefix and suffix take.
| Prop | Type | Description |
|---|---|---|
| iconName | "function" | "filter" | "at" | "circle" | … 137 more | Name of icon to display |
| dot | "filled" | "partiallyFilled" | "empty" | A status dot in the chip's text color. |
| loading | boolean | A spinner sized to the chip; false keeps the slot empty. |
| children | ReactNode | Arbitrary slot content, instead of a named icon, dot, or spinner. |
| variant | "straight" | "badge" | "angle" | "naked" default: "straight" | |
| aria-label | string | |
| onClick | (() => void) |
Was this page helpful?