# 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 products Search 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 characters Invalid characters in search query
); } ``` ### Disabled State ```tsx import {Description, Label, SearchField} from "@heroui/react"; export function Disabled() { return (
This search field is disabled This 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 search Use 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 (
{isInvalid ? ( Search query must be at least {MIN_LENGTH} characters ) : ( Enter at least {MIN_LENGTH} characters to search )}
); } ``` ### 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
Press S to 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 search Search 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. |