# SearchField
**Category**: react
**URL**: https://www.heroui.com/docs/react/components/search-field
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(forms)/search-field.mdx
> Search input field with clear button and search icon
***
## Import
```tsx
import { SearchField } from '@heroui/react';
```
### Usage
```tsx
import {Label, SearchField} from "@heroui/react";
export function Basic() {
return (
);
}
```
### Anatomy
```tsx
import {SearchField, Label, Description, FieldError} from '@heroui/react';
export default () => (
)
```
> **SearchField** allows users to enter and clear a search query. It includes a search icon and an optional clear button for easy reset.
### With Description
```tsx
import {Description, Label, SearchField} from "@heroui/react";
export function WithDescription() {
return (
Enter keywords to search for productsSearch by name, email, or username
);
}
```
### Required Field
```tsx
import {Description, Label, SearchField} from "@heroui/react";
export function Required() {
return (
Minimum 3 characters required
);
}
```
### Validation
Use `isInvalid` together with `FieldError` to surface validation messages.
```tsx
import {FieldError, Label, SearchField} from "@heroui/react";
export function Validation() {
return (
Search query must be at least 3 charactersInvalid characters in search query
);
}
```
### Disabled State
```tsx
import {Description, Label, SearchField} from "@heroui/react";
export function Disabled() {
return (
This search field is disabledThis search field is disabled
);
}
```
### Controlled
Control the value to synchronize with other components or perform custom formatting.
```tsx
"use client";
import {Button, Description, Label, SearchField} from "@heroui/react";
import React from "react";
export function Controlled() {
const [value, setValue] = React.useState("");
return (
Current value: {value || "(empty)"}
);
}
```
### With Validation
Implement custom validation logic with controlled values.
```tsx
"use client";
import {Description, FieldError, Label, SearchField} from "@heroui/react";
import React from "react";
export function WithValidation() {
const [value, setValue] = React.useState("");
const isInvalid = value.length > 0 && value.length < 3;
return (
{isInvalid ? (
Search query must be at least 3 characters
) : (
Enter at least 3 characters to search
)}
);
}
```
### Custom Icons
Customize the search icon and clear button icons.
```tsx
import {Description, Label, SearchField} from "@heroui/react";
export function CustomIcons() {
return (
Custom icon children
);
}
```
### Full Width
```tsx
import {Label, SearchField} from "@heroui/react";
export function FullWidth() {
return (
);
}
```
### Variants
The SearchField component supports two visual variants:
- **`primary`** (default) - Standard styling with shadow, suitable for most use cases
- **`secondary`** - Lower emphasis variant without shadow, suitable for use in Surface components
```tsx
import {Label, SearchField} from "@heroui/react";
export function Variants() {
return (
);
}
```
### In Surface
When used inside a [Surface](/docs/components/surface) component, use `variant="secondary"` to apply the lower emphasis variant suitable for surface backgrounds.
```tsx
import {Description, Label, SearchField, Surface} from "@heroui/react";
export function OnSurface() {
return (
Enter keywords to searchUse filters to refine your search
);
}
```
### Form Example
Complete form integration with validation and submission handling.
```tsx
"use client";
import {Button, Description, FieldError, Form, Label, SearchField, Spinner} from "@heroui/react";
import React from "react";
export function FormExample() {
const [value, setValue] = React.useState("");
const [isSubmitting, setIsSubmitting] = React.useState(false);
const MIN_LENGTH = 3;
const isInvalid = value.length > 0 && value.length < MIN_LENGTH;
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (value.length < MIN_LENGTH) {
return;
}
setIsSubmitting(true);
// Simulate API call
setTimeout(() => {
console.log("Search submitted:", {query: value});
setValue("");
setIsSubmitting(false);
}, 1500);
};
return (
);
}
```
### With Keyboard Shortcut
Add keyboard shortcuts to quickly focus the search field.
```tsx
"use client";
import {Description, Kbd, Label, SearchField} from "@heroui/react";
import React from "react";
export function WithKeyboardShortcut() {
const inputRef = React.useRef(null);
const [value, setValue] = React.useState("");
React.useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
// Check for Shift+S
if (e.shiftKey && e.key === "S" && !e.metaKey && !e.ctrlKey && !e.altKey) {
e.preventDefault();
inputRef.current?.focus();
}
// Check for ESC key to blur the input
if (e.key === "Escape" && document.activeElement === inputRef.current) {
inputRef.current?.blur();
}
};
// Add global event listener
window.addEventListener("keydown", handleKeyDown);
// Cleanup on unmount
return () => {
window.removeEventListener("keydown", handleKeyDown);
};
}, []);
return (
Use keyboard shortcut to quickly focus this field
PressSto focus the search field
);
}
```
## Related Components
- **Label**: Accessible label for form controls
- **Description**: Helper text for form fields
- **FieldError**: Inline validation messages for form fields
### Custom Render Function
```tsx
"use client";
import {Label, SearchField} from "@heroui/react";
export function CustomRenderFunction() {
return (
}>
);
}
```
## Styling
### Passing Tailwind CSS classes
```tsx
import {SearchField, Label} from '@heroui/react';
function CustomSearchField() {
return (
);
}
```
### Customizing the component classes
SearchField uses CSS classes that can be customized. Override the component classes to match your design system.
```css
@layer components {
.search-field {
@apply flex flex-col gap-1;
}
/* When invalid, the description is hidden automatically */
.search-field[data-invalid],
.search-field[aria-invalid] {
[data-slot="description"] {
@apply hidden;
}
}
.search-field__group {
@apply bg-field text-field-foreground shadow-field rounded-field inline-flex h-9 items-center overflow-hidden border;
}
.search-field__input {
@apply flex-1 rounded-none border-0 bg-transparent px-3 py-2 shadow-none outline-none;
}
.search-field__search-icon {
@apply text-field-placeholder pointer-events-none shrink-0 ml-3 mr-0 size-4;
}
.search-field__clear-button {
@apply mr-1 shrink-0;
}
}
```
### CSS Classes
- `.search-field` – Root container with minimal styling (`flex flex-col gap-1`)
- `.search-field__group` – Container for search icon, input, and clear button with border and background styling
- `.search-field__input` – The search input field
- `.search-field__search-icon` – The search icon displayed on the left
- `.search-field__clear-button` – Button to clear the search field
- `.search-field--primary` – Primary variant with shadow (default)
- `.search-field--secondary` – Secondary variant without shadow, suitable for use in surfaces
> **Note:** Child components ([Label](/docs/components/label), [Description](/docs/components/description), [FieldError](/docs/components/field-error)) have their own CSS classes and styling. See their respective documentation for customization options.
### Interactive States
SearchField automatically manages these data attributes based on its state:
- **Invalid**: `[data-invalid="true"]` or `[aria-invalid="true"]` - Automatically hides the description slot when invalid
- **Disabled**: `[data-disabled="true"]` - Applied when `isDisabled` is true
- **Focus Within**: `[data-focus-within="true"]` - Applied when the input is focused
- **Focus Visible**: `[data-focus-visible="true"]` - Applied when focus is visible (keyboard navigation)
- **Hovered**: `[data-hovered="true"]` - Applied when hovering over the group
- **Empty**: `[data-empty="true"]` - Applied when the field is empty (hides clear button)
Additional attributes are available through render props (see SearchFieldRenderProps below).
## API Reference
### SearchField Props
SearchField inherits all props from React Aria's [SearchField](https://react-spectrum.adobe.com/react-aria/SearchField.html) component.
#### Base Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `children` | `React.ReactNode \| (values: SearchFieldRenderProps) => React.ReactNode` | - | Child components (Label, Group, Input, etc.) or render function. |
| `className` | `string \| (values: SearchFieldRenderProps) => string` | - | CSS classes for styling, supports render props. |
| `style` | `React.CSSProperties \| (values: SearchFieldRenderProps) => React.CSSProperties` | - | Inline styles, supports render props. |
| `fullWidth` | `boolean` | `false` | Whether the search field should take full width of its container |
| `id` | `string` | - | The element's unique identifier. |
| `variant` | `"primary" \| "secondary"` | `"primary"` | Visual variant of the component. `primary` is the default style with shadow. `secondary` is a lower emphasis variant without shadow, suitable for use in surfaces. |
| `render` | `DOMRenderFunction` | - | Overrides the default DOM element with a custom render function.|
#### Value Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `string` | - | Current value (controlled). |
| `defaultValue` | `string` | - | Default value (uncontrolled). |
| `onChange` | `(value: string) => void` | - | Handler called when the value changes. |
#### Validation Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `isRequired` | `boolean` | `false` | Whether user input is required before form submission. |
| `isInvalid` | `boolean` | - | Whether the value is invalid. |
| `validate` | `(value: string) => ValidationError \| true \| null \| undefined` | - | Custom validation function. |
| `validationBehavior` | `'native' \| 'aria'` | `'native'` | Whether to use native HTML form validation or ARIA attributes. |
| `validationErrors` | `string[]` | - | Server-side validation errors. |
#### State Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `isDisabled` | `boolean` | - | Whether the input is disabled. |
| `isReadOnly` | `boolean` | - | Whether the input can be selected but not changed. |
#### Form Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `name` | `string` | - | Name of the input element, for HTML form submission. |
| `autoFocus` | `boolean` | - | Whether the element should receive focus on render. |
#### Event Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `onSubmit` | `(value: string) => void` | - | Handler called when the user submits the search (Enter key). |
| `onClear` | `() => void` | - | Handler called when the clear button is pressed. |
#### Accessibility Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `aria-label` | `string` | - | Accessibility label when no visible label is present. |
| `aria-labelledby` | `string` | - | ID of elements that label this field. |
| `aria-describedby` | `string` | - | ID of elements that describe this field. |
| `aria-details` | `string` | - | ID of elements with additional details. |
### Composition Components
SearchField works with these separate components that should be imported and used directly:
- **SearchField.Group** - Container for search icon, input, and clear button
- **SearchField.Input** - The search input field
- **SearchField.SearchIcon** - The search icon displayed on the left
- **SearchField.ClearButton** - Button to clear the search field
- **Label** - Field label component from `@heroui/react`
- **Description** - Helper text component from `@heroui/react`
- **FieldError** - Validation error message from `@heroui/react`
Each of these components has its own props API. Use them directly within SearchField for composition:
```tsx
Enter keywords to searchSearch query is required
```
#### SearchField.Group Props
SearchField.Group inherits props from React Aria's [Group](https://react-spectrum.adobe.com/react-aria/Group.html) component.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `children` | `React.ReactNode \| (values: GroupRenderProps) => React.ReactNode` | - | Child components (SearchIcon, Input, ClearButton) or render function. |
| `className` | `string \| (values: GroupRenderProps) => string` | - | CSS classes for styling. |
#### SearchField.Input Props
SearchField.Input inherits props from React Aria's [Input](https://react-spectrum.adobe.com/react-aria/Input.html) component.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `className` | `string` | - | CSS classes for styling. |
| `variant` | `"primary" \| "secondary"` | `"primary"` | Visual variant of the input. `primary` is the default style with shadow. `secondary` is a lower emphasis variant without shadow, suitable for use in surfaces. |
| `placeholder` | `string` | - | Placeholder text displayed when the input is empty. |
| `type` | `string` | `"search"` | Input type (automatically set to "search"). |
#### SearchField.SearchIcon Props
SearchField.SearchIcon is a custom component that renders the search icon.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `children` | `React.ReactNode` | `` | Custom icon element. Defaults to search icon. |
| `className` | `string` | - | CSS classes for styling. |
#### SearchField.ClearButton Props
SearchField.ClearButton inherits props from React Aria's [Button](https://react-spectrum.adobe.com/react-aria/Button.html) component.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `children` | `React.ReactNode` | `` | Icon or content for the button. Defaults to close icon. |
| `className` | `string` | - | CSS classes for styling. |
| `slot` | `"clear"` | `"clear"` | Must be set to "clear" (automatically set). |
### SearchFieldRenderProps
When using render props with `className`, `style`, or `children`, these values are available:
| Prop | Type | Description |
|------|------|-------------|
| `isDisabled` | `boolean` | Whether the field is disabled. |
| `isInvalid` | `boolean` | Whether the field is currently invalid. |
| `isReadOnly` | `boolean` | Whether the field is read-only. |
| `isRequired` | `boolean` | Whether the field is required. |
| `isFocused` | `boolean` | Whether the field is currently focused (DEPRECATED - use `isFocusWithin`). |
| `isFocusWithin` | `boolean` | Whether any child element is focused. |
| `isFocusVisible` | `boolean` | Whether focus is visible (keyboard navigation). |
| `value` | `string` | Current value. |
| `isEmpty` | `boolean` | Whether the field is empty. |