ChipList
A list of chips that shows up to maxRows rows and folds the rest into a +N button. +N opens a popover with the folded chips. Name the list with aria-label or aria-labelledby.
With onRemove, each chip gets a remove button. Once chips drops the focused chip, focus moves to the chip that now fills its place, else the one before it, else +N, else the list.
<ChipList.Root
aria-label="Tags"
chips={tags}
maxRows={1}
onRemove={(index) => setTags((current) => current.filter((_, i) => i !== index))}
/>
In the popover, Tab past the last chip goes on to the control after +N, Shift+Tab from the first chip returns to +N, and Escape closes it and returns to +N.
One row / Two rows
Read-only
When to use
When: Chips outside a text field, such as applied filters, read-only tags or recipients, capped at maxRows with a +N count.
When not: Typing new chips → Field.ChipInput. Picking from options → Combobox recipe. Selectable or toggle chips → Checkbox / Button.Root. One chip → Chip.Root. Your own markup around the fold → useChipList.
Props
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| chips | readonly string[] | yes | — | Chip labels, in order. |
| maxRows | number | no | — | Rows to show before folding the rest into +N. Without it, every chip wraps onto as many rows as it needs. |
| getKey | (value: string, index: number) => string | no | — | A stable, unique key for each chip, so focus can follow it when chips change. Without it, chips are matched by value, so focus can land on another chip with the same value. |
| onRemove | (index: number, value: string) => void | no | — | Renders a remove button on each chip. Once chips drops the focused chip, focus moves to the chip that now fills its place, else the one before it, else +N, else the list. |
| removeLabel | (value: string) => string | no | — | Remove button name. Default is the removeChip string from StringsProvider, Remove {value} in English. |
| removeIcon | React.ReactNode | no | — | Remove button content, such as an icon from your own set. Without it, the CSS draws a cross. |
| overflowLabel | (n: number) => string | no | — | +N button name. Default is the moreChips string from StringsProvider, {n} more in English. |
| panelLabel | (n: number) => string | no | — | Name of the popover with the folded chips. Default is the moreChipsPanel string from StringsProvider, {n} more chips or 1 more chip in English. |