Autocomplete is a field whose suggestions arrive as you type, so a long list becomes a short
one before it becomes a choice. It differs from [Dropdown](/components/forms/dropmenu) in that
the control is a text field rather than a button: nothing has to be chosen, and the reader can
keep typing. It differs from [MultiSelect](/components/forms/multi-select) in that it holds one
value, not several. Turn on `allowCustomValue` and whatever is typed becomes the value; leave it
off and only a suggestion can.

```tsx demo="forms/autocomplete-preview"
```

## Usage

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

const frameworks = [
  { label: "React", value: "react" },
  { label: "Vue", value: "vue" },
];

<Autocomplete
  label="Framework"
  options={frameworks}
  onValueChange={(value) => save(value)}
/>
```

Each option is a `label` and a `value`, with an optional `disabled`. The selection is
controlled: `value` decides which option is shown as chosen, and `onValueChange` reports both
the value and the option, so a caller that needs the label does not have to look it up. The text
in the field is the component's own unless you need it, `onInputChange` reports every
keystroke, which is where a remote search or a character count starts.

## Suggestions

The suggestion list is the framework's menu, the same listbox [Dropdown](/components/forms/dropmenu)
and [MultiSelect](/components/forms/multi-select) open, filtered on the option's label as the
reader types. The filter is a case-insensitive substring, so `land` finds `Ireland`; an empty
field shows the whole list. An option marked `disabled` is still listed, and the arrow keys pass
over it rather than landing on it.

```tsx demo="forms/autocomplete-suggestions"
```

The list's own appearance is configured through `menu`, and everything in that object belongs to
the menu rather than to the field: `portal` (default `true`) and `portalTarget` decide where the
list is rendered, `lockScroll` (default `true`) whether the page behind it moves, and
`itemVariant` (`ghost`), `activeItemVariant` (`faded`), `itemColor`, `activeItemColor`, `size`
and `radius` how its options are drawn. `belowList` renders a node under the last option, a
note, an add control, a hint, inside the same panel.

## Free text

An autocomplete usually refuses what it does not recognise. `allowCustomValue` removes that
rule: while it is true every keystroke reports the raw text through `onValueChange`, so the
field's value is whatever is in it, and a suggestion is a shortcut rather than a requirement.

```tsx demo="forms/autocomplete-free-text"
```

A value that is not on the list is displayed as the text the reader left behind. If the
suggestions run out, the panel says so in a status region and the field still holds the typed
text, the list is advice, and the value is the reader's.

## Props

```props Autocomplete
```

The defaults are a cascade rather than a list. The component registers the field family's web
defaults, so `size` is `md` and `variant` is `bordered`; `radius` follows the application's
`defaultRadius` and the accent follows its `defaultColor`, so a product that rounds everything
to `full` states it once. `options` is empty until you pass a list, `allowCustomValue` is off,
and the placeholder is `Type to search...` unless you state one.

## Accessibility

- The field is a combobox: the input carries `aria-expanded` and `aria-autocomplete="list"`,
  and while a suggestion is current it names that suggestion through `aria-activedescendant`.
  The list is a `listbox` whose rows are `option`s with `aria-selected`.
- Focus never leaves the input: the suggestion list opens without taking focus and does not take
  it back when it closes, so the reader keeps typing while a suggestion is current, the pattern
  the combobox role describes.
- <kbd>ArrowDown</kbd> and <kbd>ArrowUp</kbd> move through the options and wrap at the ends,
  <kbd>Home</kbd> and <kbd>End</kbd> jump to the first and last reachable ones,
  <kbd>Enter</kbd> chooses the current option, and <kbd>Escape</kbd> closes the list. Disabled
  options are skipped by all of them, so <kbd>Enter</kbd> can never take one.
- The label names the input through `htmlFor`, and the description and the message are wired to it
  through `aria-describedby`; an `error` message is announced as an alert, and a search that
  matches nothing says "No options found" in a `status` region instead of leaving a blank panel.

## Related

```related dropmenu, multi-select, search-input
```
