All components (204)
Search field
Fields · SearchField
What it is and when to use it
The field with autocomplete: you type and the list is filtered as you go, ignoring accents and case. Every time the text changes, it announces how many options are left ("3 options"), which is what makes it usable without seeing the screen.
When to use it
- Choosing from a long list: customers, products, suppliers.
serverFilteredwhen the search is done by the server: the already filtered list is passed in andonInputChangeis listened to;loadingwhile it arrives.allowsCustomValueto keep something that is not in the list (a new supplier).- Each option can carry a second line (
description), aniconand be disabled (disabled).
When not to
- A short, closed list:
Select. A dropdown of four options does not need a search field. - Choosing several:
MultiSelect. - Searching for actions or screens of the application:
CommandPalette.
Keyboard: focus always stays in the field, so you can keep typing. Down Arrow opens the list from the first option and Up Arrow from the last; the arrows move through it, Enter chooses and Tab closes the list and leaves. Escape closes the list and returns the text to what was chosen; leaving the field blank and exiting removes the choice. The arrow button opens the whole list with the mouse or a finger; it is not in the Tab order.
Accessibility: it is a combobox and the active option is announced from the field with aria-activedescendant. The label is required; the help and the error are read as the description. If what is typed finds nothing, the list does not close abruptly: it says "No results" (noResultsMessage). Disabled options are announced as such and cannot be chosen.
Fine-tuning: no variables of its own: the box uses those of the field (--amset-field-*) and is adjusted with the classes amset-search__group, amset-search__open and amset-search__panel; the list is the usual one (amset-listbox, amset-option).
What it looks like
Try "alv" or "jewelry": it works without accents too.
<SearchField
label="Customer"
placeholder="Enter the customer's name"
noResultsMessage="No customers with that name"
options={[
{ key: 'aurelia', label: 'Aurelia Jewelry', description: 'Madrid · 32 orders' },
{ key: 'bravo', label: 'Bravo Plateria', description: 'Cordoba · 9 orders' },
]}
onSelectionChange={setCliente}
/>Props
Import it with import { SearchField } from '@amset/ui'. Required props are marked.
| Prop | Type | What it does |
|---|---|---|
labelrequired | string | — |
optionsrequired | readonly ListOption[] | — |
allowsCustomValue | boolean | Lets a text that is not in the list be confirmed. Without it, on leaving the field the text goes back to the chosen option: a search box over a closed list cannot keep something that does not exist. |
autoFocus | boolean | — |
className | string | Merged with the library classes; it does not replace them. |
defaultInputValue | string | — |
defaultSelectedKey | string | null | The key chosen at the start, without controlling it from outside. |
disabled | boolean | — |
error | string | — |
hiddenLabel | boolean | The label for the screen reader only. For when the field sits inside something that already explains itself (a table cell, a group of filters), never to save space. |
hint | string | — |
inputValue | string | The typed text, controlled from outside. |
invalid | boolean | — |
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. |
menuTrigger | "input" | "focus" | "manual" | What opens the list: `input` (the default) when typing, `focus` as soon as the field receives focus, and `manual` only with the button or the arrows. |
name | string | So that the chosen key travels in a native form. |
noResultsMessage | string | Text when what is typed finds nothing. |
offset | number | Separation in pixels between the field and the list. By default, none. |
onBlur | () => void | On leaving the field. The form uses it to mark that it has been touched. |
onInputChange | (text: string) => void | — |
onOpenChange | (open: boolean) => void | When the list opens or closes. |
onSelectionChange | (key: string | null) => void | — |
placeholder | string | — |
placement | Placement | Where the list appears. By default, right below the field. |
readOnly | boolean | — |
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`. |
required | boolean | — |
selectedKey | string | null | The chosen key, controlled from outside. |
serverFiltered | boolean | The list already comes filtered from outside (server-side search). By default the component itself filters with what is typed. |
size | "sm" | "md" | "lg" | — |
validationBehavior | "aria" | "native" | — |
variant | FieldVariant | — |
It also accepts the attributes of the element it renders: className, style, data-*, aria-* and its events.
In the test bench
Every state and variant, to try one at a time, on its page at ui.amset.tech:
