---
title: Multi Select
description: Lets the user pick several options from a searchable list opened by a button, with the chosen options shown as independently removable chips beside a native opener button.
icon: list
author:
  name: nyxb
  url: https://github.com/nyxb
search:
  keywords: [tags input, multiple select]
related:
  - /select
  - /combobox
  - /tags
mode: wide
---

<PoweredBy
  packages={[
    { name: 'Base UI', url: 'https://base-ui.com/react/components/popover' },
    { name: 'cmdk', url: 'https://cmdk.paco.me/' },
    { name: 'Shadcn UI', url: 'https://ui.shadcn.com/docs/components/select' },
    { name: 'Lucide', url: 'https://lucide.dev/' },
  ]}
/>

### Installation

```package-install
npx shadcn@latest add @redpanda/multi-select
```

Tweaked by [malinskibeniamin](https://github.com/malinskibeniamin), multi select component combines regular select, badge, command and tooltip.
It lets users see and select multiple items.

<ComponentPreview name="multi-select-demo" />

## When to use

The Multi Select component allows users to select multiple options from a list. Use this decision tree to determine when it's appropriate:

```mermaid
graph TD;
    A[❓ Need option selection?] --> B{Multiple selections allowed?};
    A --> C[ℹ️ Use other input types];
    B --> D{Many options available?};
    B --> E{Single selection only?};
    D --> F[✅ Use MultiSelect];
    D --> G{"Few options (2-5)?"};
    E --> H[✅ Use Select or RadioGroup];
    G --> I[✅ Use CheckboxGroup];
    G --> J[✅ Use MultiSelect for consistency];

    classDef recommended fill:#4ade80,stroke:#22c55e,stroke-width:2px,color:#000;
    classDef discouraged fill:#fbbf24,stroke:#f59e0b,stroke-width:2px,color:#000;
    classDef decision fill:#60a5fa,stroke:#3b82f6,stroke-width:2px,color:#fff;
    classDef neutral fill:#9ca3af,stroke:#6b7280,stroke-width:2px,color:#fff;

    class F,H,I,J recommended;
    class A,B,D,E,G decision;
    class C neutral;
```

## Usage

```tsx
import {
  MultiSelect,
  MultiSelectContent,
  MultiSelectControl,
  MultiSelectItem,
  MultiSelectList,
  MultiSelectTrigger,
  MultiSelectValue,
} from '@/components/redpanda-ui/multi-select';
```

```tsx
<MultiSelect>
  <label htmlFor="framework-choice">Frameworks</label>
  <MultiSelectControl className="w-80">
    <MultiSelectValue />
    <MultiSelectTrigger id="framework-choice" placeholder="Select frameworks" />
  </MultiSelectControl>
  <MultiSelectContent>
    <MultiSelectList>
      <MultiSelectItem value="react">React</MultiSelectItem>
      <MultiSelectItem value="vue">Vue</MultiSelectItem>
      <MultiSelectItem value="angular">Angular</MultiSelectItem>
      <MultiSelectItem value="svelte">Svelte</MultiSelectItem>
    </MultiSelectList>
  </MultiSelectContent>
</MultiSelect>
```

## Control anatomy and keyboard behavior

`MultiSelectControl` is the noninteractive field shell and popup anchor. Its selected values and opener are siblings:

```text
MultiSelect
├─ MultiSelectControl
│  ├─ MultiSelectValue → selected chips, each with a removal button
│  └─ MultiSelectTrigger → native button that opens the options
└─ MultiSelectContent → search and option list
```

Keep `MultiSelectValue` **outside** `MultiSelectTrigger`. Do not nest interactive content inside the opener. Give the opener a persistent name using an associated `<label htmlFor>` and `id`, `aria-labelledby`, or `aria-label`. Forward form IDs, descriptions, invalid state, blur handlers, and button refs to `MultiSelectTrigger`, not the shell. Place `FormControl` around the trigger only.

- Enter or Space on the opener opens the popup. Keyboard opening focuses the search input when present; Escape closes it and returns focus to the opener.
- Each selected chip has a named `Remove …` button. Removing a chip does not open or close the popup.
- After an accepted removal, focus moves to the next visible removal action, then the previous one, or the opener when no other visible action remains. Ignored or failed controlled updates do not move focus away from the original action. Synchronous removal callback failures display an error.
- `disabled` on `MultiSelect` disables the opener, removal actions, search, and options. The opener and removal actions use `type="button"`; they do not submit enclosing forms.
- `maxDisplay` limits visible chips; all selections remain in the value. `maxItemLength` truncates visible text but keeps the full removal name and exposes the full label in a tooltip on the removal action.

### Migrating the compound API

Replace the former nested trigger/value structure with the sibling anatomy above. Move field width/layout classes from `MultiSelectTrigger` to `MultiSelectControl`, and move `placeholder` from `MultiSelectValue` to `MultiSelectTrigger`.

`MultiSelectTrigger` now forwards native **button** attributes/events and an `HTMLButtonElement` ref instead of rendering a role-button `div`. It no longer accepts children; its native `type="button"` is not configurable. Its content and `type="button"` are owned by the component; there is no `render`, `asChild`, or `nativeButton={false}` escape. `MultiSelectValue` no longer accepts `placeholder`. `SimpleMultiSelect` already builds the new anatomy; existing value/options/width contracts remain available.

## Examples

### Default

<ComponentPreview name="multi-select-demo" />

### Simple

<ComponentPreview name="multi-select-simple-demo" />

### Form

<ComponentPreview name="multi-select-form-demo" wide />

### Controllable Search

search by control or load remote data

<ComponentPreview name="multi-select-controllable-demo" />

### Input Custom (tag mode)

Allow user to select from input custom tag

<ComponentPreview name="multi-select-input-custom-demo" />

### Limit Count

limit max select count by `maxCount`

<ComponentPreview name="multi-select-limit-demo" />

### Limit item display length

limit max display item count with `maxDisplay`, or limit item display length with `maxItemLength`

<ComponentPreview name="multi-select-limit-item-display-demo" />

## Props

<div className="flex flex-row gap-x-3">
  <ExternalLink href="https://nyxbui.design/docs/components/multi-select" text="Docs" />
</div>

## Credits

- We take our inspiration from [Shadcn UI](https://ui.shadcn.com/docs/components/select) for the select style.
- We use [Nyxb UI](https://nyxbui.design/docs/components/multi-select) for the multi select component functionality.
