InputsReact
A text field for a search term, with an optional icon and a button that clears it.
Rendered by React 19.3.1
Loading React…Installation
npm i @hamur/reactNot on npm yet. The package goes out under the chosen name.
Anatomy
Import the component and assemble its parts:
<SearchField.Root>
<SearchField.Icon />
<SearchField.Input />
<SearchField.Clear />
</SearchField.Root>Examples
Filter
A controlled value filters a list of countries as it changes; Escape or the Clear empties the field and shows them all again.
Controlled
A controlled value with a Reset button outside the field; each change from typing, the Clear or Escape shows its reason.
Form
A search in a Form with a name and no onSearch: Enter submits the form, and its Reset button clears the field through form-reset.
API reference
19 props across 4 parts, in React syntax. className, style, render are listed once, under Shared props.
ClearSearchField.Clear
A button that clears the field and returns focus to the input. Rendered while there is something to clear, out of the tab order unless tabIndex is given. Renders a <button>.
| Prop | Type | Default |
|---|---|---|
nativeButtonWhether the component renders a native <button> element when replacing it | boolean | true |
keepMountedWhether the clear button stays mounted while there is nothing to clear, with data-visible | boolean | false |
disabledWhether the clear button should ignore user interaction. | boolean | false |
| Data attribute | Description |
|---|---|
data-visible | Present while the clear button is shown: the field has something to clear and is not read-only. |
data-disabled | Present when the clear button is disabled. |
data-loading | Present while the application is loading results. |
IconSearchField.Icon
A decorative search icon, always mounted and hidden from assistive technology. Renders a <span>.
| Data attribute | Description |
|---|---|
data-disabled | Present when the search field is disabled. |
data-loading | Present while the application is loading results. |
InputSearchField.Input
The search input, a native input that works with Field as Input does. Its value is the Root's. Renders an <input>.
| Prop | Type | Default |
|---|---|---|
typeThe input's type. | SearchFieldInputType | 'text' |
inputModeThe virtual keyboard to show. | "search" | "text" | "none" | "tel" | "url" | "email" | "numeric" | "decimal" | 'search' |
enterKeyHintThe label of the virtual keyboard's Enter key. | "search" | "enter" | "done" | "go" | "next" | "previous" | "send" | 'search' |
autoCompleteThe autocomplete token list. | string | 'off' |
autoCapitalizeThe autocapitalize hint for virtual keyboards. | string | 'off' |
autoCorrectThe autocorrect hint for virtual keyboards. | string | 'off' |
spellCheckWhether the browser checks the spelling of the value. | Booleanish | false |
dirNameThe name under which the form submits the text direction of the value. | string | — |
| Data attribute | Description |
|---|---|
data-disabled | Present when the input is disabled. |
data-readonly | Present when the input is read-only. |
data-loading | Present while the application is loading results. |
data-valid | Present when the input is in a valid state (when wrapped in Field.Root). |
data-invalid | Present when the input is in an invalid state (when wrapped in Field.Root). |
data-touched | Present when the input has been touched (when wrapped in Field.Root). |
data-dirty | Present when the input's value has changed (when wrapped in Field.Root). |
data-filled | Present when the input is filled (when wrapped in Field.Root). |
data-focused | Present when the input is focused (when wrapped in Field.Root). |
RootSearchField.Root
Groups the search input, its clear button and its icon, and holds the value. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
valueThe value of the field. | string | — |
defaultValueThe value of the field when it is initially rendered, and the value a form reset restores. | string | '' |
onValueChangeCallback fired before the value changes: on typing, on a press of the clear button, on Escape | ((value: string, eventDetails: SearchFieldRootChangeEventDetails) => void) | — |
onSearchCallback fired when Enter is pressed in the input, also with an empty value. | ((value: string, eventDetails: { reason: "keyboard"; event: KeyboardEvent; }) => void) | — |
disabledWhether the input and the clear button should ignore user interaction. | boolean | false |
readOnlyWhether the user should be unable to change the value. | boolean | false |
loadingWhether the application is loading results. | boolean | false |
labelsThe texts of the search field: clear, the clear button's name when it has no aria-label or | Partial<SearchFieldLabels> | — |
| Data attribute | Description |
|---|---|
data-filled | Present when the field has a value. |
data-disabled | Present when the search field is disabled. |
data-readonly | Present when the search field is read-only. |
data-loading | Present while the application is loading results. |
Shared props
Every part that renders an element takes these.
| Prop | Type |
|---|---|
classNameCSS class applied to the element, or a function that
returns a class based on the component's state. | string | ((state: State) => string | undefined) |
styleStyle applied to the element, or a function that
returns a style object based on the component's state. | React.CSSProperties | ((state: State) => React.CSSProperties | undefined) |
renderAllows you to replace the component's HTML element
with a different tag, or compose it with another component. | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, State> |
Keyboard and accessibility
Keyboard
| Keys | Does | Part |
|---|---|---|
| Enter | Calls onSearch with the term, and does not submit the form | Input |
| Enter | Without onSearch, submits the form | Input |
| Escape | Clears a filled field; an empty one leaves the key to what is around it | Input |
| Escape | In a Dialog or a Popover, clears first and closes on the second press | Input |
| Tab | Skips the clear button, which is not a Tab stop | Clear |
| EnterSpace | With tabindex="0" on the Clear, clears the field and focuses the Input | Clear |
Accessibility
| Part | Sets | So that |
|---|---|---|
| Input | type="text" with role="searchbox", or type="search" with its own role; inputmode and enterkeyhint search; no name of its own | the field is read as a search box with its Field.Label, and a phone keyboard shows a Search key |
| Clear | a button of type button, tabindex="-1", aria-controls the Input's id and the name "Clear search" (labels); never aria-hidden | a screen reader can still reach and press it, a pointer press keeps focus in the field, and Tab skips it |
| Icon | aria-hidden="true", always mounted | the glyph is not read beside the field's name |
| Root | a div with data-filled, data-disabled, data-readonly and data-loading; disabled disables the Input and the Clear | the field and its button cannot disagree; a read-only field renders no Clear and ignores Enter and Escape |
Focus order
- The Input is the only Tab stop; the Clear has
tabindex="-1"unless you give it atabindex. - A pointer press on the Clear keeps focus in the Input, and a clear by any means leaves focus there.
- Nothing takes focus on mount, on Escape or on a form reset.