Dots

Chip Group

A row of pill chips for quick amounts and filters, with single or multiple selection.

Top up $50

"use client"

import * as React from "react"

The ChipGroup component shows a set of short options as pill chips that people toggle with one tap. Use it for quick amounts above an amount field, a period above a chart, or filters above a transaction list. Pick ToggleGroup for a compact control that switches a view, and ChoiceTile when each option needs a description or a price.

Installation

pnpm dlx shadcn@latest add @dots/chip-group

Usage

import { ChipGroup, ChipGroupItem } from "@/components/ui/chip-group"
<ChipGroup aria-label="Quick amount" defaultSelectedKeys={["50"]}>
  <ChipGroupItem id="25">$25</ChipGroupItem>
  <ChipGroupItem id="50">$50</ChipGroupItem>
  <ChipGroupItem id="100">$100</ChipGroupItem>
</ChipGroup>

Composition

ChipGroup
└── ChipGroupItem

Features

  • Single selection by default, multiple with selectionMode="multiple"
  • Controlled or uncontrolled selection through selectedKeys and defaultSelectedKeys, like any React Aria collection
  • One line that scrolls sideways, with the edges fading where more chips hide, or wrapped onto new lines
  • Two sizes and a nested surface for chips inside a card or sheet
  • Arrow keys move between chips; works in right-to-left layouts

Multiple

Set selectionMode="multiple" for filters. The row scrolls sideways and fades the edge where more chips are hidden.

2 filters on

"use client"

import * as React from "react"

Wrap

Set overflow="wrap" to break the chips onto new lines instead of scrolling. Add disallowEmptySelection when one chip must always stay on, such as "All".

"use client"

import { ChipGroup, ChipGroupItem } from "@/components/ui/chip-group"

Size

Use size="sm" for a denser row, such as a period picker above a chart.

"use client"

import { ChipGroup, ChipGroupItem } from "@/components/ui/chip-group"

Nested

Set surface="nested" when the group sits inside a card, sheet or dialog, so the chips stay visible on the raised background.

"use client"

import { Card, CardContent } from "@/components/ui/card"

Disabled

Disable one chip with isDisabled on ChipGroupItem, or the whole group with isDisabled on ChipGroup.

"use client"

import { ChipGroup, ChipGroupItem } from "@/components/ui/chip-group"

Accessibility

ChipGroup is built on React Aria ToggleButtonGroup, and each ChipGroupItem is a ToggleButton. React Aria gives the group role="radiogroup" with radio chips for single selection, and role="toolbar" with pressed toggle buttons for multiple selection. Tab enters the group and the arrow keys move between chips.

Name the group

The chips do not say what they choose. Give ChipGroup an aria-label, or point aria-labelledby at a visible heading.

<ChipGroup aria-label="Transaction type" selectionMode="multiple">
  ...
</ChipGroup>

Give every chip an id

id is required. A chip without one can never be selected.

Label icon-only chips

When a chip has only an icon, give it an aria-label.

API Reference

ChipGroup

The group of chips. Accepts all React Aria ToggleButtonGroup props except orientation, which is always horizontal.

PropTypeDefaultDescription
selectionMode"single" | "multiple""single"Whether one or several chips can be on.
selectedKeysIterable<Key>-The controlled selected chip ids.
defaultSelectedKeysIterable<Key>-The initial selected chip ids when uncontrolled.
onSelectionChange(keys: Set<Key>) => void-Called when the selection changes.
disallowEmptySelectionbooleanfalseKeeps at least one chip on.
isDisabledbooleanfalseDisables every chip.
overflow"scroll" | "wrap""scroll"One scrolling line with faded edges, or wrapped lines.
size"default" | "sm""default"Chip height: 36px or 32px.
surface"default" | "nested""default""nested" inside a card, sheet or dialog.
classNamestring-Additional classes to apply to the group.

ChipGroupItem

One chip. Accepts all React Aria ToggleButton props.

PropTypeDefaultDescription
idKey-Required. The key reported in the group's selection.
isDisabledbooleanfalseDisables this chip.
childrenReact.ReactNode-The chip content, e.g. text or a MoneyAmount.
classNamestring-Additional classes to apply to the chip.