All components (204)
Multiple select
Choice · MultiSelect · .amset-multiple
What it is and when to use it
Choose several values from a list: the categories of a product, the recipients of a notice, some tags. What is chosen stays in view as chips that can be removed with the mouse or the keyboard, and the field filters the list as you type.
When to use it
- Several options from a list too long to show in full.
maxlimits how many can be chosen and shows "2 of 4" below the field.allowsCreatefor free-form tags: what is typed appears at the end of the list as one more option,Añadir «broches», which works the same with keyboard, mouse or finger.serverFilteredwhen the list arrives already filtered from a search;onTypereports every letter, andloadingmarks the field as busy while the options arrive.sizeandvariantare the same as for all fields (the box is 30, 36 or 44 px tall and the chips grow with it).readOnlyshows what is chosen without remove buttons;disabledturns everything off and takes it out of the Tab order.
When not to
- A single option:
Select, orSearchFieldif you need to search. - Few options that are better seen all at once:
CheckboxorSelectableListwithselection="multiple". - Distributing a catalog while also seeing what is left out:
TransferList.
Keyboard: in the field, typing filters without regard to accents or case; the down arrow opens the list and the arrow keys highlight an option without taking focus out of the field; Enter adds the highlighted one and the field empties so you can keep adding; Escape closes the list. Backspace with the field empty removes the last chip. The chips are a grid traversed with the arrow keys: Delete or Backspace remove the focused one and focus moves to the next, instead of being lost. In read-only mode the grid can be traversed but nothing is removed; when disabled, neither the chips nor the field receive focus.
Accessibility: with nothing chosen, the field is named after the label. With chips, the label names the grid of chips and the field is renamed "Add to Categories". Each chip has its named remove button, which is heard only once: "Remove Rings", or exactly what removeText says. The hint, the count and the error are read as the description of the field. With the maximum reached, the list says "You have already chosen 4, which is the maximum" instead of staying empty. The focus of the box is the 2 px ring of the fields, and that of each chip is the one from buttons. With a finger, chips and remove buttons are 44 px.
Motion: the chip that is added enters growing slightly; the border of the chip and the background of the remove button change with a short transition, and the button gives way when pressed.
Fine-tuning: the box shares the field variables, --amset-field-*. The chips, --amset-multiple-chip-height (22, 26 or 32 px depending on size), --amset-multiple-chip-font, --amset-multiple-chip-radius, --amset-multiple-chip-background and --amset-multiple-chip-ink; the remove button, --amset-multiple-remove (its side). The list is adjusted with amset-multiple__panel.
What it looks like
<MultiSelect
label="Tags"
options={[
{ key: 'urgent', label: 'Urgent' },
{ key: 'cliente', label: 'New customer' },
]}
initialValue={['urgent']}
/>Props
Import it with import { MultiSelect } from '@amset/ui'. Required props are marked.
| Prop | Type | What it does |
|---|---|---|
labelrequired | string | — |
optionsrequired | readonly ListOption[] | — |
allowsCreate | boolean | Allows creating values that are not in the list (free-form tags). |
className | string | Merged with the library classes; it does not replace them. |
disabled | boolean | Nothing can be typed, the list does not open and chips cannot be removed: everything leaves the Tab order. |
error | string | — |
hint | string | — |
initialValue | readonly string[] | — |
invalid | boolean | Marks the field as invalid. The normal thing is to pass `error`, which also explains it. |
loading | boolean | The options are arriving. Marks the field as busy, shows a ring and a `loadingText` row in the list; the options that were already there stay. |
loadingText | string | What the loading row says. "Loading…" by default. |
max | number | How many can be chosen at most. |
noResultsMessage | string | — |
offset | number | — |
onChange | (keys: readonly string[]) => void | — |
onType | (text: string) => void | — |
placeholder | string | — |
placement | Placement | — |
readOnly | boolean | What is chosen is shown and the field can be focused, but nothing is added or removed: the chips lose their remove button. |
removeText | (label: string) => string | The whole name of the button that removes each chip: "Remove Rings" by default. It is the entire name; nothing is appended to it. |
renderOption | OptionRender<ListOption> | Paints the inside of each option in the list: an avatar, two lines, a price. The name the screen reader reads is still `label`. |
renderTag | (option: ListOption) => ReactNode | Paints each chip of what is chosen: an avatar with the name, a colour. The chip is still called `label` for the screen reader and its cross is still there; this is only what is seen inside. |
required | boolean | — |
serverFiltered | boolean | The list already arrives filtered from outside (server-side search). |
size | "sm" | "md" | "lg" | — |
value | readonly string[] | Chosen keys. If passed, the state is managed by whoever uses the component. |
variant | FieldVariant | — |
It also accepts the attributes of the element it renders: className, style, data-*, aria-* and its events.
CSS variables
These CSS variables are how you adapt it. Declare them on the component's selector, not on :root: the stylesheet redeclares them in the rule itself, and a declaration on the same element always wins.
| Variable | Default |
|---|---|
--amset-multiple-chip-height | 1.625rem |
--amset-multiple-chip-font | var(--amset-text-sm) |
--amset-multiple-chip-radius | var(--amset-radius) |
--amset-multiple-chip-background | var(--amset-accent-soft) |
--amset-multiple-chip-ink | var(--amset-accent-text) |
--amset-multiple-remove | 1.25rem |
How to change it
.amset-multiple {
--amset-multiple-chip-height: ...;
--amset-multiple-chip-font: ...;
}In the test bench
Every state and variant, to try one at a time, on its page at ui.amset.tech:
