Form controls
MultiSelect
Pick several options. Selections render as removable chips inline. An optional search box filters the panel.
Basic
Without search
Searching by more than the label
keywords gives the default matcher more to look at, so an option a user knows by a
machine name, a code or a synonym can be found by typing it. Matching is case- and
accent-insensitive, so a query of cafe still finds a label spelled with an acute
accent. Try GBX here.
filter replaces the matcher with one of your own, and filter={false} switches local filtering off entirely for a list that arrived already
narrowed by a server query. Without that, a keystroke still in the box would filter the server's answer
a second time.
What a screen reader meets
One field that reads its label and then the chosen values, followed by a remove button for each value. Tab reaches the field before any remove button. The remove buttons sit beside the field's control, never inside it, so no control is nested in another. After a value is removed, focus returns to the field. A disabled field removes nothing and leaves its remove buttons out of the Tab order. A press anywhere on the field that is not a remove button opens the list.
From the keyboard
Under the keyboard, the field and the search box inside the open list each turn their border the focus color, with no ring inside or around it, as Input does.
Under a touch screen
Every option in the open list is 44px tall, as a Dropdown menu item is. A mouse keeps the shorter rows. The remove crosses on the top and bottom rows of chips keep their 44px targets inside the field, which pads its chips 11px from its border there, so a tap just above or below the field removes nothing. One row of chips still fills the control's height. A mouse sees the field as it was.
A list that would run past the side of the screen, or of the dialog or scrolling box it opens in, slides back inside it. In a container too short for it above and below, such as a one-field Modal, it opens below its field at its own height, and the container grows to hold it or scrolls down to it. The list keeps at least four rows in view, or all of them when it has fewer.
API
| Prop | Type | Default | Description |
|---|---|---|---|
value | string[] | [] | Bindable array of selected values. |
options required | ListOption[] | no default | Option list. |
label | string | no default | Field label. |
placeholder | string | 'None selected' | Shown when nothing is selected. |
hint | string | no default | Subdued hint below the field. |
error | string | no default | Error message. Reddens the border. |
searchable | boolean | true | Show a search box at the top of the panel. |
disabled | boolean | false | Disable the field. |
required | boolean | false | Mark as required for form validation. |
filter | FilterFn<ListOption> | false | no default | Replaces the default matcher, or false to switch local filtering off. |
id | string | no default | DOM id. Generated when omitted. |
class | string | no default | Extra classes on the field wrapper. |
onchange | (value: string[]) => void | no default | Fires on every toggle or chip removal. |
noAI | boolean | false | Keep the value from an assistant: a FormAssist never reports it or fills it, and the control is marked data-no-ai for a browser agent. |
name | string | no default | Posts each chosen value under this name, as a multiple select does. |
ListOption
The same shape Autocomplete takes, so a list is typed once.
| Prop | Type | Default | Description |
|---|---|---|---|
value required | string | no default | The chosen value. |
label required | string | no default | What the user reads. |
disabled | boolean | no default | Blocks this row alone. |
keywords | string[] | no default | Extra words the default matcher searches alongside the label. |