Table of contents
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
MultiSelect
Multi-selectable variant of this library's Select (APG "select-only combobox"): DOM focus stays on the trigger, the active option is tracked with aria-activedescendant.
↑/↓ navigate, Home/End jump, type-ahead, Enter/Space toggle, Escape/Tab close, click-outside closes, focus returns to the trigger. It stays open after a pick — choosing several is the point.
Forms · two-way: bind:values · submits in a form with name · portalled to <body> · keyboard contract
<script lang="ts">
import { MultiSelect } from '@l4st/driftwood';
</script>
| Light | Dark |
|---|---|
![]() |
![]() |
![]() |
![]() |
Props
| Prop | Type | Default | What it does |
|---|---|---|---|
options required |
MultiSelectOption[] |
— | count on an option renders a muted tally after its label. |
values bind: |
string[] |
[] |
The chosen values, in the order the options are given. |
placeholder |
string |
'Any' |
Trigger text when nothing is selected. |
disabled |
boolean |
false |
|
clearable |
boolean |
true |
Shows the × that empties the selection. |
class |
string |
— | Merged with the component's own classes, last — so yours win. |
id |
string |
— | The rest spreads onto the trigger — see Select. Id for the trigger, so a <Label for=…> can name it. |
name |
string |
— | Submits one field per selected value, like a multiple <select>. |
aria-label |
string |
— | Accessible name, when no visible <Label for=…> points at this. |
aria-labelledby |
string |
— | Id of the element that names this, instead of aria-label. |
summaryLabel |
(count: number) => string |
(count: number) => `${count} selected` |
Trigger text once more than one option is picked. Localise here. |
clearLabel |
string |
'Clear selection' |
Accessible name of the clear (×) button. Localise here. |
onValuesChange |
(values: string[]) => void |
— | Every change to the selection. |
onChange |
(values: string[]) => void |
— | @deprecated Use onValuesChange — it matches Select's onValueChange. |
Everything not listed above is spread onto the underlying element (HTMLButtonAttributes): aria-*, data-*, event handlers, and the rest of the native attributes.
Types
export type MultiSelectOption = {
value: string;
label: string;
/** Shown right-aligned — a facet count, usually. */
count?: number;
/** Blocks opening and clearing. Blocks opening and clearing. */
disabled?: boolean;
/** Optional heading this option sits under (e.g. its brand). */
group?: string;
};
Keyboard
| Key | Does |
|---|---|
| ↑ / ↓ | move the active option |
| Home / End | first / last option |
| a–z | type-ahead to an option |
| Enter / Space | toggle the active option — the list stays open |
| Escape / Tab | close, focus returns to the trigger |
Example
The markup behind the screenshot above, lifted from src/routes/shots/ — so it
compiles, and it is exactly what produced the image.
<MultiSelect options={tagOptions} bind:values={tags} aria-label="Categories" />
Forms · Field · Input · FileInput · FileList · Textarea · CodeEditor · Combobox · RadioGroup · NumberInput · InlineEdit · Label · Select · DatePicker · TagsInput · Checkbox · Switch · Slider
driftwood
Layout
Actions
Forms
- Field
- Input
- FileInput
- FileList
- Textarea
- CodeEditor
- Combobox
- RadioGroup
- NumberInput
- InlineEdit
- Label
- Select
- MultiSelect
- DatePicker
- TagsInput
- Checkbox
- Switch
- Slider
Feedback
Charts
Overlays
Navigation
Generated from the source by pnpm wiki · repository · v0.24.0



