Search provides the ability to narrow down data using a specialized TextField.
Search renders a native HTML <input> element through the TextField component. Search is wrapped in a FormControl that manages the association between the input and its <label>, description, and error message elements using generated IDs.
The leading magnifying glass icon is decorative and hidden from the accessibility tree. The clear button is a native <button> element, and it renders whenever onSearchInput is provided. The input's type defaults to text rather than search, so assistive technology announces the field as a text input.
| Element | Attribute | Description |
|---|---|---|
| Clear button | aria-label="Clear field" | Provides an accessible name for the icon-only clear button. |
| Field | aria-describedby | References assistive text that describes the field. When both a description and an error are present, both IDs are included, description first. |
| Field | aria-invalid | Set when the field is invalid, either through isInvalid or by an error being present. |
| Field | aria-label | Provides an accessible name when no visible label is rendered. |
| Field | aria-labelledby | References the visible label element's ID. When an ariaLabelledby prop is also provided, both IDs are included. |
| Spinner | aria-label="Loading…" | Provides an accessible name for the loading spinner shown while isLoading is set. |
The clear button remains visually hidden in the DOM when the field is empty or disabled. Because it isn't removed, it can still be tabbed through. Activating it while hidden will activate the field, so no extra input is needed from the user to use the field.
We highly recommend naming the field with the ariaLabel prop when a visible label would crowd the toolbar or header the Search sits in, and with the label prop everywhere else. Omitting both will result in an error. Name what the field searches rather than the action.
When no placeholder is provided, Search uses the ariaLabel value as the placeholder. This keeps the field's purpose visible as well as announced, but it means a placeholder written for sighted users and an accessible name written for assistive technology can't be set independently unless both props are passed. Never rely on the placeholder alone. It is not reliably announced, and it disappears as soon as the user starts typing.
Search renders no landmark of its own. When the Search is the primary method of finding content on a page, wrap it in an element with role="search" so assistive technology users can jump straight to it from a landmark list. Leave the landmark off for a Search that filters one region among several so the landmark doesn't compete with the page's primary search.
Search returns its results elsewhere on the page, and moving focus into them would interrupt a user mid-query. Announce the outcome instead: put the result count in a live region near the results so a screen reader user learns that the query ran and what it returned. Without one, the page changes silently behind a field that looks unchanged.
Prefer the debounced or Enter triggers over shouldSearchOnInput when results are announced this way. Searching on every keystroke re-announces the count on each character, which buries the answer the user is waiting for.
| Key | Function |
|---|---|
| Enter/Space | Clears the field and returns focus to it. |
| Shift+Tab | Moves focus to the previous focusable element. |
| Tab | Moves focus to the next focusable element. |
| Key | Function |
|---|---|
| Enter | Runs the search when shouldSearchOnEnter is set. |
| Shift+Tab | Moves focus to the previous focusable element. |
| Tab | Moves focus to the clear button. |