HeroUI

AutocompleteNew

An autocomplete combines a select with filtering, allowing users to search and select from a list of options

Import

import {Autocomplete, useFilter} from "@heroui/react";

Usage

Countries to Visit
Select countries
"use client";

import type {Key} from "@heroui/react";

import {

Anatomy

Import the Autocomplete component and access all parts using dot notation.

import {Autocomplete, Label, Description, SearchField, ListBox} from "@heroui/react";

export default () => (
  <Autocomplete>
    <Label />
    <Autocomplete.Trigger>
      <Autocomplete.Value />
      <Autocomplete.ClearButton />
      <Autocomplete.Indicator />
    </Autocomplete.Trigger>
    <Description />
    <Autocomplete.Popover>
      <Autocomplete.Filter>
        <SearchField>
          <SearchField.Group>
            <SearchField.SearchIcon />
            <SearchField.Input />
          </SearchField.Group>
        </SearchField>
        <ListBox>
          <ListBox.Item>
            <Label />
            <ListBox.ItemIndicator />
          </ListBox.Item>
        </ListBox>
      </Autocomplete.Filter>
    </Autocomplete.Popover>
  </Autocomplete>
);

With Description

State
Select one
Select your state of residence
"use client";

import type {Key} from "@heroui/react";

import {Autocomplete, Description, Label, ListBox, SearchField, useFilter} from "@heroui/react";

Multiple Select

States
Select states
"use client";

import type {Key} from "@heroui/react";

import {

With Sections

Country
Select a country
"use client";

import type {Key} from "@heroui/react";

import {

With Disabled Options

Animal
Select an animal
"use client";

import type {Key} from "@heroui/react";

import {Autocomplete, Label, ListBox, SearchField, useFilter} from "@heroui/react";

Custom Indicator

State
Select one
"use client";

import type {Key} from "@heroui/react";

import {Autocomplete, Label, ListBox, SearchField, useFilter} from "@heroui/react";

Required

State
Select one
Country
Select a country
"use client";

import {
  Autocomplete,
  Button,

Full Width

State
Select one
"use client";

import type {Key} from "@heroui/react";

import {Autocomplete, Label, ListBox, SearchField, Surface, useFilter} from "@heroui/react";

Variants

The Autocomplete component supports two visual variants:

  • primary (default) - Standard styling with shadow, suitable for most use cases
  • secondary - Lower emphasis variant without shadow, suitable for use in Surface components

Single Select Variants

Primary variant
Select one
Secondary variant
Select one

Multiple Select Variants

Primary variant
Select multiple
Secondary variant
Select multiple
"use client";

import type {Key} from "@heroui/react";

import {

In Surface

When used inside a Surface component, use variant="secondary" to apply the lower emphasis variant suitable for surface backgrounds.

State
Select one
"use client";

import type {Key} from "@heroui/react";

import {Autocomplete, Label, ListBox, SearchField, Surface, useFilter} from "@heroui/react";

Custom Value

You can customize the displayed value using render props:

User
Select a user
"use client";

import type {Key} from "@heroui/react";

import {

Controlled

State (controlled)
California

Selected: California

"use client";

import type {Key} from "@heroui/react";

import {Autocomplete, Label, ListBox, SearchField, useFilter} from "@heroui/react";

Controlled Multiple

States
Select states
"use client";

import type {Key} from "@heroui/react";

import {

Controlled Open State

State
Select one

Autocomplete is closed

"use client";

import {Autocomplete, Button, Label, ListBox, SearchField, useFilter} from "@heroui/react";
import {useState} from "react";

Asynchronous Filtering

Search a Star Wars characters
Search...
"use client";

import {Autocomplete, EmptyState, Label, ListBox, SearchField, Spinner} from "@heroui/react";
import {useAsyncList} from "@react-stately/data";

Disabled

State
California
Countries to Visit
Argentina, Japan, and France
"use client";

import {Autocomplete, Label, ListBox, SearchField, useFilter} from "@heroui/react";

export function Disabled() {

Advanced Examples

User Selection

User
Select a user
"use client";

import type {Key} from "@heroui/react";

import {

User Selection Multiple

Users
Select your teammates
"use client";

import type {Key} from "@heroui/react";

import {
City
Search for a city
"use client";

import type {Key} from "@heroui/react";

import {

Tag Group Selection

Tags
Select tags
"use client";

import type {Key} from "@heroui/react";

import {

Email Recipients

To
Add recipients
"use client";

import type {Key} from "@heroui/react";

import {

Styling

Passing Tailwind CSS classes

import {Autocomplete, SearchField, ListBox} from "@heroui/react";

function CustomAutocomplete() {
  return (
    <Autocomplete className="w-full">
      <Label>State</Label>
      <Autocomplete.Trigger className="rounded-lg border bg-surface p-2">
        <Autocomplete.Value />
        <Autocomplete.ClearButton />
        <Autocomplete.Indicator />
      </Autocomplete.Trigger>
      <Autocomplete.Popover>
        <Autocomplete.Filter>
          <SearchField>
            <SearchField.Group>
              <SearchField.SearchIcon />
              <SearchField.Input placeholder="Search..." />
            </SearchField.Group>
          </SearchField>
          <ListBox>
            <ListBox.Item id="1" textValue="Item 1" className="hover:bg-surface-secondary">
              Item 1
            </ListBox.Item>
          </ListBox>
        </Autocomplete.Filter>
      </Autocomplete.Popover>
    </Autocomplete>
  );
}

Customizing the component classes

To customize the Autocomplete component classes, you can use the @layer components directive.


Learn more.

@layer components {
  .autocomplete {
    @apply flex flex-col gap-1;
  }

  .autocomplete__trigger {
    @apply rounded-lg border border-border bg-surface p-2;
  }

  .autocomplete__value {
    @apply text-current;
  }

  .autocomplete__clear-button {
    @apply text-muted hover:text-foreground;
  }

  .autocomplete__indicator {
    @apply text-muted;
  }

  .autocomplete__popover {
    @apply rounded-lg border border-border bg-surface p-2;
  }
}

HeroUI follows the BEM methodology to ensure component variants and states are reusable and easy to customize.

CSS Classes

The Autocomplete component uses these CSS classes (View source styles):

Base Classes

  • .autocomplete - Base autocomplete container
  • .autocomplete__trigger - The button that triggers the autocomplete
  • .autocomplete__value - The displayed value or placeholder
  • .autocomplete__clear-button - The clear button that removes the selected value
  • .autocomplete__indicator - The dropdown indicator icon
  • .autocomplete__popover - The popover container
  • .autocomplete__filter - The filter wrapper

Variant Classes

  • .autocomplete--primary - Primary variant with shadow (default)
  • .autocomplete--secondary - Secondary variant without shadow, suitable for use in surfaces

State Classes

  • .autocomplete[data-invalid="true"] - Invalid state
  • .autocomplete__trigger[data-focus-visible="true"] - Focused trigger state
  • .autocomplete__trigger[data-disabled="true"] - Disabled trigger state
  • .autocomplete__value[data-placeholder="true"] - Placeholder state
  • .autocomplete__clear-button[data-empty="true"] - Clear button hidden when no selection
  • .autocomplete__indicator[data-open="true"] - Open indicator state

Interactive States

The component supports both CSS pseudo-classes and data attributes for flexibility:

  • Hover: :hover or [data-hovered="true"] on trigger
  • Focus: :focus-visible or [data-focus-visible="true"] on trigger
  • Disabled: :disabled or [data-disabled="true"] on autocomplete
  • Open: [data-open="true"] on indicator

API Reference

Autocomplete Props

PropTypeDefaultDescription
placeholderstring'Select an item'Temporary text that occupies the autocomplete when it is empty
selectionMode"single" | "multiple""single"Whether single or multiple selection is enabled
isOpenboolean-Sets the open state of the popover (controlled)
defaultOpenboolean-Sets the default open state of the popover (uncontrolled)
onOpenChange(isOpen: boolean) => void-Handler called when the open state changes
disabledKeysIterable<Key>-Keys of disabled items
isDisabledboolean-Whether the autocomplete is disabled
valueKey | Key[] | null-Current value (controlled)
defaultValueKey | Key[] | null-Default value (uncontrolled)
onChange(value: Key | Key[] | null) => void-Handler called when the value changes
isRequiredboolean-Whether user input is required
isInvalidboolean-Whether the autocomplete value is invalid
namestring-The name of the input, used when submitting an HTML form
fullWidthbooleanfalseWhether the autocomplete should take full width of its container
variant"primary" | "secondary""primary"Visual variant of the component. primary is the default style with shadow. secondary is a lower emphasis variant without shadow, suitable for use in surfaces.
classNamestring-Additional CSS classes
childrenReactNode | RenderFunction-Autocomplete content or render function

Autocomplete.Trigger Props

PropTypeDefaultDescription
classNamestring-Additional CSS classes
childrenReactNode | RenderFunction-Trigger content or render function

Autocomplete.Value Props

PropTypeDefaultDescription
classNamestring-Additional CSS classes
childrenReactNode | RenderFunction-Value content or render function

Autocomplete.Indicator Props

PropTypeDefaultDescription
classNamestring-Additional CSS classes
childrenReactNode-Custom indicator content

Autocomplete.ClearButton Props

PropTypeDefaultDescription
classNamestring-Additional CSS classes
onClick(e: MouseEvent) => void-Handler called when button is clicked
refRefObject<HTMLButtonElement>-Ref to the clear button element

Autocomplete.Popover Props

PropTypeDefaultDescription
placement"bottom" | "bottom left" | "bottom right" | "bottom start" | "bottom end" | "top" | "top left" | "top right" | "top start" | "top end" | "left" | "left top" | "left bottom" | "start" | "start top" | "start bottom" | "right" | "right top" | "right bottom" | "end" | "end top" | "end bottom""bottom"Placement of the popover relative to the trigger
classNamestring-Additional CSS classes
childrenReactNode-Content children

Autocomplete.Filter Props

PropTypeDefaultDescription
filter(text: string, input: string) => boolean-Custom filter function
inputValuestring-Controlled input value
onInputChange(value: string) => void-Handler called when input value changes
childrenReactNode-Filter content (SearchField and ListBox)

useFilter Hook

The useFilter hook from React Aria provides filtering functions for autocomplete functionality.

import {useFilter} from "@heroui/react";

const {contains} = useFilter({sensitivity: "base"});

<Autocomplete.Filter filter={contains}>
  <SearchField>...</SearchField>
  <ListBox>...</ListBox>
</Autocomplete.Filter>

Options:

OptionTypeDefaultDescription
sensitivity"base" | "accent" | "case" | "variant""base"Locale sensitivity for matching

Returns:

FunctionTypeDescription
contains(string: string, substring: string) => booleanReturns whether a string contains a given substring
startsWith(string: string, substring: string) => booleanReturns whether a string starts with a given substring
endsWith(string: string, substring: string) => booleanReturns whether a string ends with a given substring

RenderProps

When using render functions with Autocomplete.Value, these values are provided:

PropTypeDescription
defaultChildrenReactNodeThe default rendered value
isPlaceholderbooleanWhether the value is a placeholder
stateSelectStateThe state of the autocomplete
selectedItemsNode[]The currently selected items

Accessibility

The Autocomplete component implements the ARIA select pattern with filtering and provides:

  • Full keyboard navigation support
  • Screen reader announcements for selection changes
  • Proper focus management
  • Support for disabled states
  • Search functionality with filtering
  • HTML form integration

For more information, see the React Aria Select documentation.

On this page