Multi Select

Searchable picker for choosing several options at once.

Installation

pnpm dlx shadcn@latest add @paneui/multi-select

Usage

Composition

Examples

Groups

Use when the options fall into categories.

Object Values

Controlled

Use when other UI sets or reads the selection.

Sizes

Keyboard

Typing filters; Enter toggles the highlighted option and keeps the list open. Backspace in an empty input removes the last chip.

Motion

Chips use a 520 / 34 / 0.6 spring. With reduced motion they only fade.

See also Combobox.

API Reference

Built on the Combobox primitive. Only the props this library adds or changes are listed; everything else passes through.

MultiSelect

Combobox.Root with multiple always on. Also accepts every prop of Combobox.Root.

size
"sm" | "default" | "lg"
Sizes the well (28, 32 or 36px for one row of chips), its chips and the option rows. Inside a sized Field it takes the field's size (xs maps to sm).
value
Value[]
Controlled selected values.
defaultValue
Value[]
Initially selected values.
onValueChange
(value: Value[], details) => void
Called when the selection changes.
PropTypeDefaultDescription
size"sm" | "default" | "lg"—Sizes the well (28, 32 or 36px for one row of chips), its chips and the option rows. Inside a sized Field it takes the field's size (xs maps to sm).
valueValue[]—Controlled selected values.
defaultValueValue[]—Initially selected values.
onValueChange(value: Value[], details) => void—Called when the selection changes.

MultiSelectTrigger

Holds the chips and the search input. The popup anchors to it. Also accepts every prop of Combobox.Chips.

size
"sm" | "default" | "lg"
Overrides the root size for the well only.
placeholder= "Select…"
string
Input placeholder while nothing is selected.
renderChip= value.label ?? value.value ?? String(value)
(value) => ReactNode
Chip content for a selected value.
getKey= value.value ?? value.id ?? index (strings: the value)
(value, index: number) => Key
React key for each chip.
PropTypeDefaultDescription
size"sm" | "default" | "lg"—Overrides the root size for the well only.
placeholderstring"Select…"Input placeholder while nothing is selected.
renderChip(value) => ReactNodevalue.label ?? value.value ?? String(value)Chip content for a selected value.
getKey(value, index: number) => Keyvalue.value ?? value.id ?? index (strings: the value)React key for each chip.
data-size
The resolved size.
Data attributeDescription
data-sizeThe resolved size.

MultiSelectContent

Portal, positioner and popup, anchored to the trigger. Also accepts every prop of Combobox.Popup.

side= "bottom"
"top" | "bottom" | "left" | "right" | "inline-start" | "inline-end"
Side of the trigger to place the popup on.
sideOffset= 6
number
Gap from the trigger in px.
align= "start"
"start" | "center" | "end"
Alignment against the trigger.
PropTypeDefaultDescription
side"top" | "bottom" | "left" | "right" | "inline-start" | "inline-end""bottom"Side of the trigger to place the popup on.
sideOffsetnumber6Gap from the trigger in px.
align"start" | "center" | "end""start"Alignment against the trigger.

MultiSelectItem

Option row with a tick that fills when chosen. Also accepts every prop of Combobox.Item.

data-selected
Present when the value is chosen (fills the tick).
data-highlighted
Present on the highlighted item.
Data attributeDescription
data-selectedPresent when the value is chosen (fills the tick).
data-highlightedPresent on the highlighted item.

MultiSelectList

Alias of ComboboxList. Also accepts every prop of Combobox.List.

MultiSelectGroup

Alias of ComboboxGroup. Also accepts every prop of Combobox.Group.

MultiSelectLabel

Alias of ComboboxLabel. Also accepts every prop of Combobox.GroupLabel.

MultiSelectSeparator

Alias of ComboboxSeparator. Also accepts every prop of Combobox.Separator.

MultiSelectEmpty

Alias of ComboboxEmpty. Also accepts every prop of Combobox.Empty.

MultiSelectCollection

Alias of ComboboxCollection. Also accepts every prop of Combobox.Collection.