# Search

> Slug: `search` · Category: Form Controls

## When to use

- Free-text search-as-you-type input (page header search, in-page filtering, list search).
- When a leading magnifier icon and trailing clear (×) button are expected.

## When NOT to use

- Search that opens a dropdown of suggestions inside a menu — use `SearchingInput` with `MenuDropdown`.
- General-purpose text input — use `TextField`.
- A submit-style search bar with a button that triggers a server query — wrap `Search` inside a `<form>` and pair with `Button type="submit"`.

## Variants & decision tree

Search renders a single input with built-in icons. Pair the `value` + `onChange` + `onClear` triple to manage state; `onClear` resets to empty.

## States

Empty (placeholder + magnifier), focused, filled (×/clear visible), disabled, inverse.

## Props

| Prop | Type | Default | Description |
|---|---|---|---|
| `id` | `string` | — | Required. Input id. |
| `value` / `defaultValue` | `string` | — | Controlled / uncontrolled. |
| `onChange` | `ChangeEventHandler` | — | Fires per keystroke. |
| `onClear` | `() => void` | — | Fires when × is clicked — clear your state here. |
| `searchAriaLabel` | `string` | — | Accessible label for the input. |
| `clearButtonLabel` | `string` | — | Accessible label for the × button. |
| `disabled` | `boolean` | `false` | Disable. |
| `active` | `boolean` | `false` | Force focused styling for demos. |
| `inverse` | `boolean` | `false` | Dark-background styling. |

## Usage examples

```tsx
// Controlled with clear
const [q, setQ] = useState('');
<Search
  id="search"
  value={q}
  onChange={(e) => setQ(e.target.value)}
  onClear={() => setQ('')}
  searchAriaLabel="Search products"
/>

// Filtering a list
<Search id="filter" value={filter} onChange={(e) => setFilter(e.target.value)} onClear={() => setFilter('')} />
{items.filter((i) => i.name.toLowerCase().includes(filter.toLowerCase())).map(...)}
```

## Composition

Place above a list, table, or `Lists` component for live filtering. For server-backed search-as-you-type with a results panel, use `MenuDropdown` (`variant="searching"`) instead.

## Accessibility

Always pass `searchAriaLabel` (e.g., "Search products") because the input has no visible text label. Provide `clearButtonLabel` (e.g., "Clear search"). The clear button is automatically hidden when the value is empty.

## Do / Don't

- DO wire `onClear` to reset the input value to `''`.
- DO debounce expensive `onChange` handlers (network calls).
- DON'T omit `searchAriaLabel` — the magnifier icon is decorative.
- DON'T use Search when results render in a popup menu — use `MenuDropdown searching` instead.
