Skip to main content
The Combobox component combines a text input with a dropdown list, allowing users to search, filter, and select from predefined options.

Installation

npx shadcn@latest add @eo-n/combobox

Usage

import {
  Combobox,
  ComboboxContent,
  ComboboxEmpty,
  ComboboxInput,
  ComboboxItem,
  ComboboxList,
} from "@/components/ui/combobox";

interface Fruit {
  id: string;
  value: string;
}

const fruits: Fruit[] = [
  { id: "a", value: "Apple" },
  { id: "b", value: "Banana" },
  { id: "c", value: "Cherry" },
  { id: "d", value: "Durian" },
];

export default function Example() {
  return (
    <Combobox items={fruits}>
      <ComboboxInput placeholder="Search fruits..." />
      <ComboboxContent>
        <ComboboxEmpty>No fruits found.</ComboboxEmpty>
        <ComboboxList>
          {(fruit: Fruit) => (
            <ComboboxItem key={fruit.id} value={fruit}>
              {fruit.value}
            </ComboboxItem>
          )}
        </ComboboxList>
      </ComboboxContent>
    </Combobox>
  );
}

Examples

Default

<Combobox items={fruits}>
  <ComboboxInput placeholder="Select a fruit..." />
  <ComboboxContent>
    <ComboboxEmpty>No results found.</ComboboxEmpty>
    <ComboboxList>
      {(fruit: Fruit) => (
        <ComboboxItem key={fruit.id} value={fruit}>
          {fruit.value}
        </ComboboxItem>
      )}
    </ComboboxList>
  </ComboboxContent>
</Combobox>

Multi-Select

import { ComboboxChips, ComboboxChip } from "@/components/ui/combobox";

<Combobox items={fruits} selectionBehavior="preserve">
  <ComboboxChips>
    {(fruit: Fruit) => (
      <ComboboxChip key={fruit.id}>{fruit.value}</ComboboxChip>
    )}
    <ComboboxInput placeholder="Select fruits..." />
  </ComboboxChips>
  <ComboboxContent>
    <ComboboxEmpty>No fruits found.</ComboboxEmpty>
    <ComboboxList>
      {(fruit: Fruit) => (
        <ComboboxItem key={fruit.id} value={fruit}>
          {fruit.value}
        </ComboboxItem>
      )}
    </ComboboxList>
  </ComboboxContent>
</Combobox>

Input Inside Popup

import { ComboboxTrigger } from "@/components/ui/combobox";

<Combobox items={fruits}>
  <ComboboxTrigger>
    <Button variant="outline">Select fruit</Button>
  </ComboboxTrigger>
  <ComboboxContent>
    <ComboboxInput placeholder="Search..." />
    <ComboboxEmpty>No results found.</ComboboxEmpty>
    <ComboboxList>
      {(fruit: Fruit) => (
        <ComboboxItem key={fruit.id} value={fruit}>
          {fruit.value}
        </ComboboxItem>
      )}
    </ComboboxList>
  </ComboboxContent>
</Combobox>

With Groups

import { ComboboxGroup, ComboboxGroupLabel } from "@/components/ui/combobox";

<Combobox items={items}>
  <ComboboxInput placeholder="Search..." />
  <ComboboxContent>
    <ComboboxEmpty>No results found.</ComboboxEmpty>
    <ComboboxList>
      <ComboboxGroup>
        <ComboboxGroupLabel>Fruits</ComboboxGroupLabel>
        {fruits.map((fruit) => (
          <ComboboxItem key={fruit.id} value={fruit}>
            {fruit.value}
          </ComboboxItem>
        ))}
      </ComboboxGroup>
      <ComboboxGroup>
        <ComboboxGroupLabel>Vegetables</ComboboxGroupLabel>
        {vegetables.map((veg) => (
          <ComboboxItem key={veg.id} value={veg}>
            {veg.value}
          </ComboboxItem>
        ))}
      </ComboboxGroup>
    </ComboboxList>
  </ComboboxContent>
</Combobox>

Creatable

Allow users to create new items.
import { useState } from "react";

function CreatableCombobox() {
  const [items, setItems] = useState(fruits);
  const [value, setValue] = useState("");

  const handleCreate = () => {
    if (value && !items.find((item) => item.value === value)) {
      setItems([...items, { id: crypto.randomUUID(), value }]);
    }
  };

  return (
    <Combobox items={items}>
      <ComboboxInput
        placeholder="Type to create..."
        value={value}
        onValueChange={setValue}
      />
      <ComboboxContent>
        <ComboboxEmpty>
          <Button onClick={handleCreate}>Create "{value}"</Button>
        </ComboboxEmpty>
        <ComboboxList>
          {(item: Fruit) => (
            <ComboboxItem key={item.id} value={item}>
              {item.value}
            </ComboboxItem>
          )}
        </ComboboxList>
      </ComboboxContent>
    </Combobox>
  );
}

With Clear Button

import { ComboboxClear } from "@/components/ui/combobox";
import { X } from "lucide-react";

<Combobox items={fruits}>
  <div className="relative">
    <ComboboxInput placeholder="Search..." />
    <ComboboxClear className="absolute right-2 top-2">
      <X className="size-4" />
    </ComboboxClear>
  </div>
  <ComboboxContent>
    <ComboboxList>
      {(fruit: Fruit) => (
        <ComboboxItem key={fruit.id} value={fruit}>
          {fruit.value}
        </ComboboxItem>
      )}
    </ComboboxList>
  </ComboboxContent>
</Combobox>

API Reference

Combobox

Extends all props from @base-ui/react Combobox.Root component.
items
array
required
Array of items for the combobox.
value
any
The controlled selected value.
defaultValue
any
The default selected value when uncontrolled.
onValueChange
function
Callback fired when the selected value changes.
selectionBehavior
string
default:"replace"
How selections are handled.Options: replace | preserve
open
boolean
Controlled open state.
onOpenChange
function
Callback when open state changes.

ComboboxInput

placeholder
string
Placeholder text for the input.
value
string
Controlled input value.
onValueChange
function
Callback when input value changes.
className
string
Additional CSS classes to apply.

ComboboxContent

sideOffset
number
default:"4"
Distance in pixels from the anchor.
className
string
Additional CSS classes to apply.

ComboboxItem

value
any
required
The value of the item.
disabled
boolean
Whether the item is disabled.
className
string
Additional CSS classes to apply.

ComboboxList

Container for combobox items with virtualization support.

ComboboxEmpty

Displayed when no items match the search.

ComboboxChips

Container for selected items in multi-select mode.

ComboboxChip

Represents a selected item with a remove button.

ComboboxGroup

Groups related items together.

ComboboxGroupLabel

Label for a group of items.

TypeScript

import { Combobox as ComboboxPrimitive } from "@base-ui/react";

const Combobox = ComboboxPrimitive.Root;

type ComboboxInputProps = React.ComponentProps<typeof ComboboxPrimitive.Input>;
type ComboboxItemProps = React.ComponentProps<typeof ComboboxPrimitive.Item>;

Accessibility

  • Keyboard navigation (Arrow keys, Enter, Escape)
  • Proper ARIA attributes
  • Screen reader support
  • Focus management
  • Type-ahead search

Build docs developers (and LLMs) love