Multi-select

Select several values while keeping the field readable.

pnpm dlx shadcn@latest add @uiarc/multi-select
Live · keyboard ready
  • Picking several values from a fixed list in a compact field, such as labels or assignees.
  • Filters where the chosen values should show in the field with a +N overflow.
  • Use chip-group when every option should stay visible.
  • Use tag-input for free-form values.
  • Use select for a single value.

Installation

Add Multi-select with the shadcn CLI, or copy the source by hand.

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

Adds the component and its local dependencies, and installs motion, lucide-react. First time? Add the @uiarc registry to components.json, or use the full URL:

example.tsx
import { MultiSelect } from "@/registry/components/multi-select/multi-select"; export function LabelPicker() {  const [labels, setLabels] = useState<string[]>(["bug"]);  return (    <MultiSelect      label="Labels"      value={labels}      onValueChange={setLabels}      options={[        { value: "bug", label: "Bug" },        { value: "feature", label: "Feature" },        { value: "docs", label: "Docs" },      ]}    />  );}

MultiSelect

A dropdown that picks several values, showing them as chips with a rolling +N overflow count.

PropTypeDefaultDescription
labelRequiredstring–Visible label, also names the listbox.
optionsRequiredMultiSelectOption[]–{ value, label, disabled? } in list order.
valuestring[]–Controlled selected values.
defaultValuestring[][]Initial values when uncontrolled.
onValueChange(value: string[]) => void–Called with the full new selection.
placeholderstring"Select options"Shown when nothing is selected.
descriptionstring–Helper copy under the field.
maxVisiblenumber2Chips shown in the trigger before the rest collapse into +N.
disabledbooleanfalseDisables the trigger and hides the clear button.
classNamestring–Added to the root.
EnterorSpace
Opens or closes the list; Enter toggles the active option while open.
ArrowDownorArrowUp
Opens the list and moves through enabled options, wrapping.
Escape
Closes the list.
  • Trigger has aria-haspopup="listbox", aria-expanded, and aria-labelledby combining the label and a hidden list of selected labels.
  • The menu is role="listbox" with aria-multiselectable; options carry aria-selected and aria-disabled.
  • Clear button is labelled "Clear selections"; chips are aria-hidden in favor of the spoken summary.
  • Chips open their slot width on a smooth spring and grow in from 0.9 with a blur; the +N count rolls up or down.
  • Checks draw in the menu; the menu springs in from slightly above.
  • Reduced motion turns every change into a short crossfade with no scale or width travel.
  • Chips cap at 9rem and ellipsize, and maxVisible limits how many show before +N, so the trigger holds one line.
  • The menu spans the field width and has no max height or scroll, so keep option lists short on small screens.
  • Options are not virtualized and the menu does not scroll; for long lists use combobox instead.
  • Chips animate slot width and scale per change; fine for a few selections.

Notes for AI

Give your coding assistant the Markdown reference instead of screenshots.

  • Use for picking several values from a fixed list in a compact field. Use chip-group when all options should stay visible and tag-input for free-form values.
  • Controlled with value and onValueChange or uncontrolled with defaultValue. There is no name prop, so serialize the array yourself for forms.

The full library index for assistants is at /llms.txt.