> ## Documentation Index
> Fetch the complete documentation index at: https://api.fanvue.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Autocomplete

> A combobox input with single- or multi-select, optional async loading, and native support for grouped + pinned options.

```tsx theme={null}
import { Autocomplete } from "@fanvue/ui";
import type {
  AutocompleteGroup,
  AutocompleteOption,
  AutocompleteProps,
  AutocompleteSize,
} from "@fanvue/ui";
```

## Examples

## Default

<Frame>
  <iframe src={"https://main--697a1b6dd4dad73ee9c0e5f5.chromatic.com/iframe.html?id=components-autocomplete--default&viewMode=story&shortcuts=false&singleStory=true&globals=theme:light"} width="100%" height="300" style={{border: "none", borderRadius: "8px"}} loading="lazy" title="Autocomplete — Default" />
</Frame>

```tsx theme={null}
import { Autocomplete } from "@fanvue/ui";
import type { AutocompleteOption } from "@fanvue/ui";

const COUNTRIES: AutocompleteOption[] = [
  { value: "us", label: "United States" },
  { value: "uk", label: "United Kingdom" },
  { value: "ca", label: "Canada" },
  { value: "au", label: "Australia" },
  { value: "de", label: "Germany" },
  { value: "fr", label: "France" },
  { value: "jp", label: "Japan" },
  { value: "br", label: "Brazil" },
];

<Autocomplete
  label="Country"
  placeholder="Search countries..."
  helperText="Start typing to filter"
  options={COUNTRIES}
  emptyText="No results"
/>
```

## Error State

<Frame>
  <iframe src={"https://main--697a1b6dd4dad73ee9c0e5f5.chromatic.com/iframe.html?id=components-autocomplete--error-state&viewMode=story&shortcuts=false&singleStory=true&globals=theme:light"} width="100%" height="300" style={{border: "none", borderRadius: "8px"}} loading="lazy" title="Autocomplete — Error State" />
</Frame>

```tsx theme={null}
import { Autocomplete } from "@fanvue/ui";
import type { AutocompleteOption } from "@fanvue/ui";

const COUNTRIES: AutocompleteOption[] = [
  { value: "us", label: "United States" },
  { value: "uk", label: "United Kingdom" },
  { value: "ca", label: "Canada" },
  { value: "au", label: "Australia" },
  { value: "de", label: "Germany" },
  { value: "fr", label: "France" },
  { value: "jp", label: "Japan" },
  { value: "br", label: "Brazil" },
];

<Autocomplete
  label="Country"
  placeholder="Search countries..."
  options={COUNTRIES}
  error
  errorMessage="This field is required"
  emptyText="No results"
/>
```

## Sizes

<Frame>
  <iframe src={"https://main--697a1b6dd4dad73ee9c0e5f5.chromatic.com/iframe.html?id=components-autocomplete--sizes&viewMode=story&shortcuts=false&singleStory=true&globals=theme:light"} width="100%" height="300" style={{border: "none", borderRadius: "8px"}} loading="lazy" title="Autocomplete — Sizes" />
</Frame>

```tsx theme={null}
import { Autocomplete } from "@fanvue/ui";
import type { AutocompleteOption } from "@fanvue/ui";

const COUNTRIES: AutocompleteOption[] = [
  { value: "us", label: "United States" },
  { value: "uk", label: "United Kingdom" },
  { value: "ca", label: "Canada" },
  { value: "au", label: "Australia" },
  { value: "de", label: "Germany" },
  { value: "fr", label: "France" },
  { value: "jp", label: "Japan" },
  { value: "br", label: "Brazil" },
];

<div className="flex w-[375px] flex-col gap-4">
  <Autocomplete
    size="48"
    label="Size 48"
    placeholder="Search..."
    options={COUNTRIES}
    emptyText="No results"
  />
  <Autocomplete
    size="40"
    label="Size 40"
    placeholder="Search..."
    options={COUNTRIES}
    emptyText="No results"
  />
  <Autocomplete
    size="32"
    label="Size 32"
    placeholder="Search..."
    options={COUNTRIES}
    emptyText="No results"
  />
</div>
```

## Multi Select

<Frame>
  <iframe src={"https://main--697a1b6dd4dad73ee9c0e5f5.chromatic.com/iframe.html?id=components-autocomplete--multi-select&viewMode=story&shortcuts=false&singleStory=true&globals=theme:light"} width="100%" height="300" style={{border: "none", borderRadius: "8px"}} loading="lazy" title="Autocomplete — Multi Select" />
</Frame>

```tsx theme={null}
import { Autocomplete } from "@fanvue/ui";
import type { AutocompleteOption } from "@fanvue/ui";

const FRUITS: AutocompleteOption[] = [
  { value: "apple", label: "Apple" },
  { value: "banana", label: "Banana" },
  { value: "cherry", label: "Cherry" },
  { value: "date", label: "Date" },
  { value: "elderberry", label: "Elderberry" },
  { value: "fig", label: "Fig" },
  { value: "grape", label: "Grape" },
];

<Autocomplete
  label="Fruits"
  placeholder="Select fruits..."
  options={FRUITS}
  multiple
  defaultValue={["apple", "cherry"]}
  emptyText="No results"
/>
```

## Clearable

<Frame>
  <iframe src={"https://main--697a1b6dd4dad73ee9c0e5f5.chromatic.com/iframe.html?id=components-autocomplete--clearable&viewMode=story&shortcuts=false&singleStory=true&globals=theme:light"} width="100%" height="300" style={{border: "none", borderRadius: "8px"}} loading="lazy" title="Autocomplete — Clearable" />
</Frame>

```tsx theme={null}
import { Autocomplete } from "@fanvue/ui";
import type { AutocompleteOption } from "@fanvue/ui";

const COUNTRIES: AutocompleteOption[] = [
  { value: "us", label: "United States" },
  { value: "uk", label: "United Kingdom" },
  { value: "ca", label: "Canada" },
  { value: "au", label: "Australia" },
  { value: "de", label: "Germany" },
  { value: "fr", label: "France" },
  { value: "jp", label: "Japan" },
  { value: "br", label: "Brazil" },
];

<Autocomplete
  label="Country"
  placeholder="Search countries..."
  options={COUNTRIES}
  clearable
  clearAriaLabel="Clear selection"
  defaultValue="us"
  emptyText="No results"
/>
```

## Props

## Autocomplete

A combobox input with single- or multi-select, optional async loading, and native support for grouped + pinned options.

* Pass `groups` plus an `options` array whose entries reference each group via `groupId` to render hierarchical lists with proper `role="group"` + `aria-labelledby` semantics. Options without a `groupId` render above the first group; options marked `pinned` render above everything and bypass the search filter.
* Indentation of nested rows (e.g. price under product) is controlled by the consumer via `renderOption` styling — there is no built-in indent.

<ParamField path="options" type="AutocompleteOption[]" required />

<ParamField path="aria-label" type="string" />

<ParamField path="aria-labelledby" type="string" />

<ParamField path="className" type="string" />

<ParamField path="clearable" type="boolean" default="false" />

<ParamField path="clearAriaLabel" type="string" />

<ParamField path="creatable" type="boolean" default="false" />

<ParamField path="creatableLabel" type="((inputValue: string) => string)" />

<ParamField path="defaultOpen" type="boolean" />

<ParamField path="defaultValue" type="string | string[] | null" />

<ParamField path="disabled" type="boolean" default="false" />

<ParamField path="emptyText" type="string" />

<ParamField path="error" type="boolean" default="false" />

<ParamField path="errorMessage" type="string" />

<ParamField path="filterFn" type="((option: AutocompleteOption, query: string) => boolean)" />

<ParamField path="fullWidth" type="boolean" default="false" />

<ParamField path="groups" type="AutocompleteGroup[]">
  Ordered list of groups. When provided, options whose `groupId` matches an entry render under the corresponding heading. Groups with no visible (post-filter) options collapse silently. Pinned options render above everything; ungrouped options render between pinned and the first group. Only one level of grouping is supported.
</ParamField>

<ParamField path="helperText" type="string" />

<ParamField path="id" type="string" />

<ParamField path="inputValue" type="string" />

<ParamField path="label" type="string" />

<ParamField path="leftIcon" type="ReactNode" />

<ParamField path="loading" type="boolean" default="false" />

<ParamField path="loadingText" type="string" />

<ParamField path="multiple" type="boolean" />

<ParamField path="onChange" type="((value: string | null) => void) | ((values: string[]) => void)" />

<ParamField path="onCreate" type="((inputValue: string) => void)" />

<ParamField path="onInputChange" type="((value: string) => void)" />

<ParamField path="onOpenChange" type="((open: boolean) => void)" />

<ParamField path="open" type="boolean" />

<ParamField path="placeholder" type="string" />

<ParamField path="renderGroupHeading" type="((group: AutocompleteGroup) => ReactNode)">
  Custom renderer for group headings. The returned node is wrapped by the component in an element carrying the `id` referenced by the surrounding `role="group"` wrapper's `aria-labelledby`, so consumers only need to return visual content.
</ParamField>

<ParamField path="renderOption" type="((option: AutocompleteOption, state: { selected: boolean; active: boolean; }) => React ...">
  Full type: `((option: AutocompleteOption, state: { selected: boolean; active: boolean; }) => ReactNode)`.
</ParamField>

<ParamField path="renderTag" type="((option: AutocompleteOption, onRemove: () => void) => ReactNode)" />

<ParamField path="size" type="&#x22;32&#x22; | &#x22;40&#x22; | &#x22;48&#x22;" default="48" />

<ParamField path="value" type="string | string[] | null" />

## Exported types

Also exported from `@fanvue/ui`: `AutocompleteGroup`, `AutocompleteOption`, `AutocompleteProps`, `AutocompleteSize`.

***

**Setup:** [Installation](/docs/ui/installation) · [Theming](/docs/ui/theming)
