A search field is a text field whose value drives a result list, so it needs three things an
input has no opinion about: a region announced as the page's search, a control that empties the
field without making the reader select the text and delete it, and a path that reports the query
when it is submitted.

It composes the framework's `Input`, `Button` and `Spinner` rather than rebuilding a control, so
density, accent, label, description and message are the field family's rather than a second copy.

```tsx demo="forms/search-input-preview"
```

## Usage

```tsx
import { SearchInput } from "@asheeui/web";

<SearchInput
  placeholder="Search invoices"
  value={query}
  onValueChange={setQuery}
  onSearch={runSearch}
/>
```

The field is controlled when `value` is given and owns the query otherwise, starting from
`defaultValue`. `onValueChange` fires on every change, including the one the clear control makes;
`onSearch` fires when the reader submits, which is the moment a list is usually refreshed rather
than the moment each character is typed.

## Submitting and clearing

Supplying `onSearch` renders the region as a `<form>`, so <kbd>Enter</kbd> submits the query and
the reader never has to aim at a button. Without it the region is still a named search landmark,
but there is nothing to submit to.

```tsx demo="forms/search-input-search"
```

`clearable` (default `true`) offers the control at the end of the field, and it appears only when
there is a query to clear. Pressing it empties the element, returns the caret to it and reports
`""` through `onValueChange`; in a controlled field the owner mirrors that in its own state.
`isLoading` reports a search in progress through `aria-busy` and a spinner, and the query stays
readable while it runs.

## Name and visibility

Every search field has a name. `label` defaults to `Search`, and `hideLabel` defaults to `true`,
which keeps the name for assistive technology and hides it from view, a search field in a
toolbar is named without being captioned.

```tsx demo="forms/search-input-name"
```

Set `hideLabel={false}` when the field deserves a caption, as on a page where it is the point
rather than an accessory. The name is part of the component's configuration, so an application
that calls it "Find" renames every search field once, under `components.searchinput`.

`shortcut` shows the key combination a page has bound, it is a hint, not a handler. Binding a
global shortcut is an application concern, because the field cannot know what else the shortcut
should do.

## Props

```props SearchInput
```

`size` and `color` are registered on the component as `md` and `primary`, and they do not follow
the application's `defaultColor`: a search field leads with the primary accent unless it is told
otherwise. `clearable`, `label` and `hideLabel` are registered too, because they are decisions
about the product's search, not about one instance.

The rest of the field's treatment belongs to the `Input` it composes: it is `bordered`, and its
radius resolves from the application's `defaultRadius`, so a search field and the fields beside
it share one corner.

## Accessibility

- The region carries `role="search"` and is named by `aria-label`, and it is a real `<form>` when
  `onSearch` is supplied. The field inside is `type="search"` and announces as a searchbox, so
  the landmark and the control are both named.
- The default label is rendered and visually hidden rather than omitted. The field keeps a name
  that no one sees, which is what lets a toolbar search still be announced as search.
- The clear control is a real button named `Clear search`, and it moves focus back into the field
  after emptying it, so the reader is not dropped at the top of the page.
- `isLoading` sets `aria-busy` and adds a spinner at the end of the field. The `kbd` hint is text
  rather than a control, so it is never reached by the keyboard or the pointer.

The label, description and message behave as the [field anatomy](/concepts/fields) describes.

## Related

```related input, data-table, form
```
