Search

Search input with debounced search callback and clear button

Category: inputs · WCAG 2.2-AA · search, input, filter, form

Sizes

States

Props

PropTypeDefaultDescription
valuestringThe controlled value.
defaultValuestring''The initial value when uncontrolled.
onValueChange(value: string) => voidCalled with the current text on every keystroke.
onSearch(value: string) => voidCalled with the query, debounced, as the user types.
debounceMsnumber300Debounce delay (ms) before onSearch fires.
placeholderstringSearchPlaceholder text shown when the field is empty.
size'sm' | 'md' | 'lg'mdVisual size of the component (e.g. 'sm', 'md', 'lg').
labelstringSearchAccessible name for the control. Rendered as a real `<label>` that is **visually hidden** by design — it changes the accessible name, not the visible UI. If you can see it, the component stylesheet did not load (import `@cascivo/react/styles.css` or the per-component CSS).
disabledbooleanfalseWhen true, disables the control and removes it from the tab order.
clearLabelstringClear searchAccessible label for the clear button.
idstringId for the input, wired to the label. Auto-generated with useId when omitted — SSR-safe and stable across hydration.
classNamestringAdditional CSS class names merged onto the root element.
aria-labelledbystringWired automatically by a wrapping `Field` — its label id, forwarded to the focusable control so the Field's label names it.
aria-describedbystringWired automatically by a wrapping `Field` — the ids of its hint/error text, forwarded to the focusable control so the supporting text is announced.
aria-invalidbooleanWired automatically by a wrapping `Field` when it is in an error state.
ariaLabelstringAccessible name set through `aria-label` instead of a rendered `<label>` element. ⚠ On Search **both** props give an invisible name — `label` renders a real `<label>` the stylesheet visually hides. They differ in mechanism, not in what you see: use `ariaLabel` when a visible element outside the component already names the field, `label` otherwise. The raw DOM `aria-label` still wins over this.

Design tokens

When to use

When not to use

How to build an accessible Search in React →

Examples

Basic

<Search onSearch={(q) => runQuery(q)} />

Controlled

<Search value={query} onValueChange={setQuery} onSearch={runQuery} debounceMs={500} />

Large

<Search size="lg" placeholder="Search products…" />

Related components

← Back to docs