useSearchField
Provides the behavior and accessibility implementation for a search field.
install | yarn add @react-aria/searchfield |
---|---|
version | 3.0.0-rc.3 |
usage | import {useSearchField} from '@react-aria/searchfield' |
API#
useSearchField(
props: AriaSearchFieldProps,
state: SearchFieldState,
inputRef: RefObject<HTMLInputElement
& & HTMLTextAreaElement>
): SearchFieldAria
Features#
Search fields can be built with <input type="search">
, but these can be hard to
style consistently cross browser. useSearchField
helps achieve accessible
search fields that can be styled as needed.
- Built with a native
<input type="search">
element - Visual and ARIA labeling support
- Keyboard submit handling via the Enter key
- Keyboard support for clearing the search field with the Escape key
- Custom clear button support with internationalized label for accessibility
Anatomy#
Search fields consist of an input element, a label, and an optional clear button.
useSearchField
automatically manages the labeling and relationships between the elements,
and handles keyboard events. Users can press the Escape key to clear the search field, or the
Enter key to trigger the onSubmit
event.
useSearchField
returns two sets of props that you should spread onto the appropriate element:
Name | Type | Description |
labelProps | LabelHTMLAttributes<HTMLLabelElement> | Props for the text field's visible label element (if any). |
inputProps | InputHTMLAttributes<HTMLInputElement> | Props for the input element. |
clearButtonProps | AriaButtonProps | Props for the clear button. |
State is managed by the useSearchFieldState
hook in @react-stately/searchfield
. The state object should be passed as an option to useSearchField
.
If there is no visual label, an aria-label
or aria-labelledby
prop must be passed instead
to identify the element to screen readers.
Example#
import {useSearchFieldState} from '@react-stately/searchfield';
function SearchField(props) {
let {label} = props;
let state = useSearchFieldState(props);
let ref = ReactuseRef();
let {labelProps inputProps} = useSearchField(props state ref);
return (
<div style={display: 'flex' flexDirection: 'column' width: 200}>
<label ...labelProps> label</label>
<input ...inputProps ref= ref />
</div>
);
}
<SearchField
label="Search"
placeholder="What are you looking for?"
onSubmit= text => alert(text) />
import {useSearchFieldState} from '@react-stately/searchfield';
function SearchField(props) {
let {label} = props;
let state = useSearchFieldState(props);
let ref = ReactuseRef();
let {labelProps inputProps} = useSearchField(
props
state
ref
);
return (
<div
style={
display: 'flex'
flexDirection: 'column'
width: 200
}>
<label ...labelProps> label</label>
<input ...inputProps ref= ref />
</div>
);
}
<SearchField
label="Search"
placeholder="What are you looking for?"
onSubmit=(text) => alert(text)
/>
import {useSearchFieldState} from '@react-stately/searchfield';
function SearchField(
props
) {
let {label} = props;
let state = useSearchFieldState(
props
);
let ref = ReactuseRef();
let {
labelProps
inputProps
} = useSearchField(
props
state
ref
);
return (
<div
style={
display: 'flex'
flexDirection:
'column'
width: 200
}>
<label
...labelProps>
label
</label>
<input
...inputProps
ref= ref
/>
</div>
);
}
<SearchField
label="Search"
placeholder="What are you looking for?"
onSubmit=(text) =>
alert(text)
/>
Styling#
This example uses CSS to reset the default browser styling for a search field and implement
custom styles. It also includes a custom clear button, using props
from useSearchField
and useButton
(from @react-aria/button).
import {useButton} from '@react-aria/button';
function SearchField(props) {
let {label} = props;
let state = useSearchFieldState(props);
let ref = ReactuseRef();
let {labelProps inputProps clearButtonProps} = useSearchField(
props
state
ref
);
let {buttonProps} = useButton(clearButtonProps);
return (
<div className="search-field">
<label ...labelProps> label</label>
<div>
<input ...inputProps ref= ref />
statevalue !== '' && <button ...buttonProps>❎</button>
</div>
</div>
);
}
<SearchField
label="Search"
placeholder="What are you looking for?"
onSubmit=(text) => alert(text)
/>
import {useButton} from '@react-aria/button';
function SearchField(props) {
let {label} = props;
let state = useSearchFieldState(props);
let ref = ReactuseRef();
let {
labelProps
inputProps
clearButtonProps
} = useSearchField(props state ref);
let {buttonProps} = useButton(clearButtonProps);
return (
<div className="search-field">
<label ...labelProps> label</label>
<div>
<input ...inputProps ref= ref />
statevalue !== '' && (
<button ...buttonProps>❎</button>
)
</div>
</div>
);
}
<SearchField
label="Search"
placeholder="What are you looking for?"
onSubmit=(text) => alert(text)
/>
import {useButton} from '@react-aria/button';
function SearchField(
props
) {
let {label} = props;
let state = useSearchFieldState(
props
);
let ref = ReactuseRef();
let {
labelProps
inputProps
clearButtonProps
} = useSearchField(
props
state
ref
);
let {
buttonProps
} = useButton(
clearButtonProps
);
return (
<div className="search-field">
<label
...labelProps>
label
</label>
<div>
<input
...inputProps
ref= ref
/>
statevalue !==
'' && (
<button
...buttonProps>
❎
</button>
)
</div>
</div>
);
}
<SearchField
label="Search"
placeholder="What are you looking for?"
onSubmit=(text) =>
alert(text)
/>
.search-field {
display: flex;
flex-direction: column;
}
.search-field div {
background: slategray;
padding: 4px 0 4px 4px;
border-radius: 4px;
width: 250px;
display: flex;
}
.search-field input {
flex: 1;
color: white;
font-size: 15px;
}
.search-field input::-webkit-input-placeholder {
color: rgba(255, 255, 255, 0.6);
}
.search-field input, .search-field button {
-webkit-appearance: none;
border: none;
outline: none;
background: none;
}
.search-field input::-webkit-search-cancel-button,
.search-field input::-webkit-search-decoration {
-webkit-appearance: none;
}
.search-field {
display: flex;
flex-direction: column;
}
.search-field div {
background: slategray;
padding: 4px 0 4px 4px;
border-radius: 4px;
width: 250px;
display: flex;
}
.search-field input {
flex: 1;
color: white;
font-size: 15px;
}
.search-field input::-webkit-input-placeholder {
color: rgba(255, 255, 255, 0.6);
}
.search-field input, .search-field button {
-webkit-appearance: none;
border: none;
outline: none;
background: none;
}
.search-field input::-webkit-search-cancel-button,
.search-field input::-webkit-search-decoration {
-webkit-appearance: none;
}
.search-field {
display: flex;
flex-direction: column;
}
.search-field div {
background: slategray;
padding: 4px 0 4px 4px;
border-radius: 4px;
width: 250px;
display: flex;
}
.search-field input {
flex: 1;
color: white;
font-size: 15px;
}
.search-field
input::-webkit-input-placeholder {
color: rgba(
255,
255,
255,
0.6
);
}
.search-field input,
.search-field button {
-webkit-appearance: none;
border: none;
outline: none;
background: none;
}
.search-field
input::-webkit-search-cancel-button,
.search-field
input::-webkit-search-decoration {
-webkit-appearance: none;
}
Internationalization#
RTL#
In right-to-left languages, search fields should be mirrored. The label should be right aligned, along with the text in the input. Ensure that your CSS accounts for this.
Name | Type | Description |
onSubmit | (
(value: string
)) => void | Handler that is called when the SearchField is submitted. |
onClear | () => void | Handler that is called when the clear button is pressed. |
isDisabled | boolean | Whether the input is disabled. |
isReadOnly | boolean | Whether the input can be selected but not changed by the user. |
validationState | ValidationState | Whether the input should display its "valid" or "invalid" visual styling. |
isRequired | boolean | Whether user input is required on the input before form submission.
Often paired with the necessityIndicator prop to add a visual indicator to the input. |
autoFocus | boolean | Whether the element should receive focus on render |
onFocus | (
(e: FocusEvent
)) => void | Handler that is called when the element receives focus. |
onBlur | (
(e: FocusEvent
)) => void | Handler that is called when the element loses focus. |
onFocusChange | (
(isFocused: boolean
)) => void | Handler that is called when the element's focus status changes. |
onKeyDown | (
(e: KeyboardEvent
)) => void | Handler that is called when a key is pressed. |
onKeyUp | (
(e: KeyboardEvent
)) => void | Handler that is called when a key is released. |
placeholder | string | Temporary text that occupies the text input when it is empty. |
value | string | The current value (controlled). |
defaultValue | string | The default value (uncontrolled). |
onChange | (
(value: string
)) => void | Handler that is called when the value changes. |
label | ReactNode | The content to display as the label. |
aria-activedescendant | string | Identifies the currently active element when DOM focus is on a composite widget, textbox, group, or application. |
aria-autocomplete | 'none'
| 'inline'
| 'list'
| 'both' | Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be presented if they are made. |
aria-haspopup | boolean
| 'menu'
| 'listbox'
| 'tree'
| 'grid'
| 'dialog' | Indicates the availability and type of interactive popup element, such as menu or dialog, that can be triggered by an element. |
aria-label | string | Defines a string value that labels the current element. |
aria-labelledby | string | Identifies the element (or elements) that labels the current element. |
aria-describedby | string | Identifies the element (or elements) that describes the object. |
aria-details | string | Identifies the element (or elements) that provide a detailed, extended description for the object. |
tabIndex | number | Indicates whether an element is focusable, allows or prevents them from being sequentially focusable, and determines their relative ordering for sequential focus navigation. |
id | string | The element's unique identifier. |
autoComplete | string | Describes the type of autocomplete functionality the input should provide if any. See MDN. |
maxLength | number | The maximum number of characters supported by the input. See MDN. |
minLength | number | The minimum number of characters required by the input. See MDN. |
name | string | Name of the input control. See MDN. |
pattern | string | Regex pattern that the value of the input must match to be valid. See MDN. |
type | 'text'
| 'search'
| 'url'
| 'tel'
| 'email'
| 'password'
| string | The type of input control to render. See MDN. |
inputMode | 'none'
| 'text'
| 'tel'
| 'url'
| 'email'
| 'numeric'
| 'decimal'
| 'search' | Hints at the type of data that might be entered by the user while editing the element or its contents. See MDN. |
onCopy | ClipboardEventHandler<HTMLInputElement> | Handler that is called when the user attempts to copy text. See MDN. |
onCut | ClipboardEventHandler<HTMLInputElement> | Handler that is called when the user attempts to cut text. See MDN. |
onPaste | ClipboardEventHandler<HTMLInputElement> | Handler that is called when the user attempts to paste text. See MDN. |
onCompositionEnd | CompositionEventHandler<HTMLInputElement> | Handler that is called when a text composition system starts a new text composition session. See MDN. |
onCompositionStart | CompositionEventHandler<HTMLInputElement> | Handler that is called when a text composition system completes or cancels the current text composition session. See MDN. |
onCompositionUpdate | CompositionEventHandler<HTMLInputElement> | Handler that is called when a new character is received in the current text composition session. See MDN. |
onSelect | ReactEventHandler<HTMLInputElement> | Handler that fires when some text in the input has been selected. See MDN. |
onBeforeInput | FormEventHandler<HTMLInputElement> | Handler that fires when the input value is about to be modified. See MDN. |
onInput | FormEventHandler<HTMLInputElement> | Handler that fires when the input value is modified. See MDN. |
aria-errormessage | string | Identifies the element that provides an error message for the object. |
Properties
Name | Type | Description |
value | string | The current value of the search field. |
Methods
Method | Description |
setValue(
(value: string
)): void | Sets the value of the search field. |
Name | Type | Description |
labelProps | LabelHTMLAttributes<HTMLLabelElement> | Props for the text field's visible label element (if any). |
inputProps | InputHTMLAttributes<HTMLInputElement> | Props for the input element. |
clearButtonProps | AriaButtonProps | Props for the clear button. |
Provides state management for a search field.
useSearchFieldState(
(props: SearchFieldProps
)): SearchFieldState
Name | Type | Description |
onSubmit | (
(value: string
)) => void | Handler that is called when the SearchField is submitted. |
onClear | () => void | Handler that is called when the clear button is pressed. |
isDisabled | boolean | Whether the input is disabled. |
isReadOnly | boolean | Whether the input can be selected but not changed by the user. |
validationState | ValidationState | Whether the input should display its "valid" or "invalid" visual styling. |
isRequired | boolean | Whether user input is required on the input before form submission.
Often paired with the necessityIndicator prop to add a visual indicator to the input. |
autoFocus | boolean | Whether the element should receive focus on render |
onFocus | (
(e: FocusEvent
)) => void | Handler that is called when the element receives focus. |
onBlur | (
(e: FocusEvent
)) => void | Handler that is called when the element loses focus. |
onFocusChange | (
(isFocused: boolean
)) => void | Handler that is called when the element's focus status changes. |
onKeyDown | (
(e: KeyboardEvent
)) => void | Handler that is called when a key is pressed. |
onKeyUp | (
(e: KeyboardEvent
)) => void | Handler that is called when a key is released. |
placeholder | string | Temporary text that occupies the text input when it is empty. |
value | string | The current value (controlled). |
defaultValue | string | The default value (uncontrolled). |
onChange | (
(value: string
)) => void | Handler that is called when the value changes. |
label | ReactNode | The content to display as the label. |
Provides the behavior and accessibility implementation for a search field.
useSearchField(
props: AriaSearchFieldProps,
state: SearchFieldState,
inputRef: RefObject<HTMLInputElement
& & HTMLTextAreaElement>
): SearchFieldAria