Free-text search with a clear button. For selecting from a constrained list, use ComboBox.
Use SearchField for free-text queries (filtering a results list, searching across multiple sources). Use ComboBox when search results come from a known, constrained list.
import { SearchField } from "@opengovsg/oui"<SearchField aria-label="Search" />Alternatively, install the component as local source via the shadcn CLI:
pnpm dlx shadcn@latest add https://oui.open.gov.sg/r/search-field.jsonThe SearchField component provides an accessible search input with a built-in search icon and clear button. The clear button automatically appears when the field has a value and hides when empty.
If the component does not have a visible label (by passing a label prop), an aria-label or aria-labelledby prop must be passed instead to identify it to assistive technology.
Provide clear instructions to users with labels and descriptions.
Combine isInvalid and errorMessage props to show validation errors.
Use the isDisabled prop to disable the search field.
Use the size prop to change the size of the field. Defaults to "md".
Use the inputProps prop to pass additional props to the underlying input element, such as a placeholder.
Use the searchIcon prop to replace the default search icon with a custom one.
Set the searchIcon prop to null to hide the icon entirely.
Use the clearIcon prop to replace the default clear (X) icon. This is useful for showing a loading spinner during async search operations.
Use the actionElement prop to render an element beside the input group, such as a search button or filter button.
Use the value and onChange props to control the input value. The onSubmit callback is invoked when the user presses Enter.
Input value: –
Submitted value: –
See the Forms guide for end-to-end patterns including React Hook Form + Zod.
SearchField supports React Aria's form validation system:
isRequired, minLength, maxLength, or pattern for native HTML validation. Errors display after the user commits a value or submits the form.validate prop to provide a function that returns an error message string, or null/true if valid.isInvalid prop with errorMessage for immediate feedback as the user types.validationBehavior prop controls enforcement — "native" (default) prevents form submission when invalid, while "aria" only marks the field via ARIA attributes and allows submission.SearchField supports the following event handlers, inherited from React Aria's SearchField:
onChange — Called when the value changes, receiving the new string value.onSubmit — Called when the user presses Enter, receiving the current value.onClear — Called when the user clears the field (by pressing the clear button or Escape).onFocus / onBlur — Called when the input gains or loses focus.onFocusChange — Called when the focus state changes, receiving a boolean.onKeyDown / onKeyUp — Called on keyboard events.<input type="search"> element for full browser and assistive technology support.aria-labelledby and aria-describedby.aria-label or aria-labelledby prop must be set.Slots are named regions of the component you can target with custom Tailwind classes via the classNames prop. Each slot below corresponds to a key on the classNames object.
base: The root container wrapping the entire field (label, input group, description, error).label: The label element rendered above the input.fieldWrapper: The flex wrapper containing the input group and the optional action element.group: The bordered input group containing the search icon, input, and clear button.searchIcon: The leading search icon.input: The native <input type="search"> element.clearButton: The trailing clear button.description: The description text rendered below the input.error: The error message text rendered below the input.| Prop | Type | Default | Description |
|---|---|---|---|
label | ReactNode | - | The visible label for the field |
description | ReactNode | - | Description text rendered below the input |
errorMessage | ReactNode | ((v: ValidationResult) => ReactNode) | - | The error to display when invalid; accepts a render prop for custom error messages |
value | string | - | The current value (controlled) |
defaultValue | string | - | The default value (uncontrolled) |
onChange | (value: string) => void | - | Called when the value changes |
onSubmit | (value: string) => void | - | Called when the user presses Enter |
onClear | () => void | - | Called when the user clears the field |
isDisabled | boolean | false | Whether the field is disabled |
isReadOnly | boolean | false | Whether the field is read-only |
isRequired | boolean | false | Whether the field is required |
isInvalid | boolean | false | Whether the field should display as invalid |
validate | (value: string) => ValidationError | true | null | undefined | - | Custom validation function |
validationBehavior | "native" | "aria" | "native" | Native HTML validation vs ARIA-only |
size | "xs" | "sm" | "md" | "md" | The size of the field |
variant | "outline" | "unstyled" | "outline" | The visual variant of the input |
actionElement | ReactNode | - | An element rendered beside the input group (e.g., a search button) |
searchIcon | ReactNode | null | <SearchIcon /> | Custom leading icon, or null to hide |
clearIcon | ReactNode | <XIcon /> | Custom clear-button icon (e.g., a spinner during async search) |
inputProps | Partial<InputProps> | - | Additional props forwarded to the underlying <input> (e.g., placeholder) |
classNames | SlotsToClasses<SearchFieldSlots> | - | Per-slot Tailwind classes for custom styling |
Inherits all remaining props from React Aria's SearchField. Notable ones: autoFocus, excludeFromTabOrder, name, autoComplete.