# Autocomplete: Select or combobox

> Use the slotsmith Autocomplete as a combobox that filters as you type, or as a select with typeahead, by switching one prop.

The Autocomplete is a combobox by default: its popup holds a search box that filters the options as you type. Set `searchable` to `false` and the same component is a select: no search box, and typing jumps to a matching option.

```tsx
import { useState } from "react";
import { Autocomplete, type OptionValue } from "slotsmith/autocomplete";
import { countries, type Country } from "../shared/options";

export default function SelectOrCombobox() {
  const [searchable, setSearchable] = useState(true);
  const [autoHighlight, setAutoHighlight] = useState(false);
  const [country, setCountry] = useState<OptionValue | null>(null);

  return (
    <div style={{ display: "grid", gap: "1rem", maxWidth: 360 }}>
      <div style={{ display: "flex", flexWrap: "wrap", gap: "0.5rem 1.5rem" }}>
        <label>
          <input type="checkbox" checked={searchable} onChange={(event) => setSearchable(event.target.checked)} /> <code>searchable</code>
        </label>
        <label>
          <input type="checkbox" checked={autoHighlight} onChange={(event) => setAutoHighlight(event.target.checked)} /> <code>autoHighlight</code>
        </label>
      </div>
      <Autocomplete<Country>
        options={countries}
        getOptionValue={(entry) => entry.code}
        getOptionLabel={(entry) => entry.name}
        // true: a search box filters the list. false: no search box; typing jumps to the first match.
        searchable={searchable}
        // true: the first match is highlighted as the list opens and narrows, so Enter picks it.
        autoHighlight={autoHighlight}
        value={country}
        onChange={setCountry}
        aria-label="Country"
      />
      <p>{country === null ? "Nothing selected." : `Selected: ${country}`}</p>
    </div>
  );
}
```

Untick `searchable` and focus the picker, then type <kbd>J</kbd>: the popup opens on Japan. Type <kbd>J</kbd> again for Jordan.

## Combobox

With [`searchable`](https://slotsmith.dev/components/autocomplete/api/#prop-searchable) on, opening the popup moves focus to its search box, and the list narrows as you type. The default filter matches anywhere in the label and ignores case and accents, so "turk" finds "Türkiye".

- [`filter`](https://slotsmith.dev/components/autocomplete/api/#prop-filter) takes your own predicate, `(option, query) => boolean`, or `false` to show every option whatever the query, as remote options do.
- [`searchQuery`](https://slotsmith.dev/components/autocomplete/api/#prop-searchQuery) with [`onSearchChange`](https://slotsmith.dev/components/autocomplete/api/#prop-onSearchChange) controls the text; [`minChars`](https://slotsmith.dev/components/autocomplete/api/#prop-minChars) holds the search back until enough characters are typed (see [the states](https://slotsmith.dev/components/autocomplete/guides/states/)).
- Closing the popup clears the search, so it reopens on the full list.

## Select

With `searchable={false}` there is no search box, and focus stays on the trigger while the popup is open. Typing works like a native `<select>`:

- Letters typed within 0.7 seconds of each other build one search: "ca" lands on the first option starting with "ca", and only if none does, on one containing it.
- The same letter again moves to the next option starting with it, so <kbd>J</kbd>, <kbd>J</kbd> goes from Japan to Jordan.
- Typing on the closed trigger opens the popup on the match.

## Highlighting the top match

By default nothing is highlighted until you press an arrow key, so <kbd>Enter</kbd> on a fresh search picks nothing. Tick `autoHighlight` in the demo, open the picker and type "nor": Norway is highlighted, and <kbd>Enter</kbd> picks it.

With [`autoHighlight`](https://slotsmith.dev/components/autocomplete/api/#prop-autoHighlight), the first option that can be picked is highlighted whenever the list opens and whenever its contents change: as the search narrows it, or as a [remote page](https://slotsmith.dev/components/autocomplete/guides/remote-options/) arrives. Disabled options are skipped. A highlight you move with the arrow keys or the pointer stays put until the search changes. While a first page is still loading nothing is highlighted, so a row from the previous search is never picked.

It suits a picker people drive from the keyboard, where typing a few letters and pressing <kbd>Enter</kbd> is the fast path. It works the same with [search in the trigger](https://slotsmith.dev/components/autocomplete/guides/search-in-trigger/).

## Options and values

Options are any objects. By default the autocomplete reads an option's id from `value` (or `id`) and its text from `label` (or `name`); [`getOptionValue`](https://slotsmith.dev/components/autocomplete/api/#prop-getOptionValue) and [`getOptionLabel`](https://slotsmith.dev/components/autocomplete/api/#prop-getOptionLabel) read other shapes, as the demo does with `code` and `name`. Values are strings or numbers.

In single mode, [`value`](https://slotsmith.dev/components/autocomplete/api/#prop-value) is the selected id or `null`, and [`onChange`](https://slotsmith.dev/components/autocomplete/api/#prop-onChange) receives the new id and its option. Leave them out and use [`defaultValue`](https://slotsmith.dev/components/autocomplete/api/#prop-defaultValue) for a picker that keeps its own value. [`clearable`](https://slotsmith.dev/components/autocomplete/api/#prop-clearable) (on by default) shows a clear button while something is selected, and [`placeholder`](https://slotsmith.dev/components/autocomplete/api/#prop-placeholder) sets the text shown while nothing is.

A selected option stays labelled after the search narrows it out of the list. For a value whose option is not in `options` at all, as when a form loads a saved id before its options, pass the option as [`selected`](https://slotsmith.dev/components/autocomplete/api/#prop-selected).
