Combobox

An input combined with a list of predefined items to select.

Installation

pnpm dlx shadcn@latest add @lumi-ui/combobox

Anatomy

<Combobox>
  <ComboboxTrigger />
  <ComboboxInputGroup /> // or <ComboboxInput />
 
  <ComboboxChips>
    <ComboboxChip />
  </ComboboxChips>
 
  <ComboboxContent>
    <ComboboxStatus />
    <ComboboxEmpty />
    <ComboboxList>
      <ComboboxRow>
        <ComboboxItemContent />
      </ComboboxRow>
      <ComboboxSeparator />
      <ComboboxGroup>
        <ComboboxGroupLabel />
      </ComboboxGroup>
      <ComboboxCollection />
    </ComboboxList>
  </ComboboxContent>
</Combobox>

Features

With Clear and Trigger Button

Input Inside Popup

Use ComboboxTrigger instead of ComboboxInputGroup to place the input inside the popup. Style ComboboxInput to remove the border.

Grouped

Cookbook

Using Scroll Area

Multiple Selection

Creatable

Async Items (Single)

Async Items (Multiple)

Customization

API Reference

ComboboxInputGroup

A high-level input component that combines the Input, Clear, and Trigger into a single styled element.

PropTypeDefaultDescription
showTriggerbooleanfalseWhether to show the trigger icon.
showClearbooleanfalseWhether to show the clear icon.
variant"ghost" | "default" | "transparent""default"The visual variant of the input group.
inputSize"default" | "sm" | "lg""default"The size of the input.
classNamestring-Additional CSS classes.
...propsBaseCombobox.InputProps-Passes all other props to the underlying BaseCombobox.InputProps.

ComboboxContent

A high-level container component that combines the Portal, Positioner, and Popup into a single styled element for the dropdown content.

PropTypeDefaultDescription
sideOffsetnumber6The offset distance from the anchor.
align"start" | "center" | "end""start"The alignment relative to the anchor.
matchAnchorWidthbooleantrueWhether the popup width matches the anchor width.
positionerAnchorReact.RefObject<HTMLDivElement | null>-Ref passed to the positioner for custom anchoring.
classNamestring-Additional CSS classes.
...propsBaseCombobox.PopupProps-Passes all other props to the underlying BaseCombobox.PopupProps.

ComboboxItemContent

A high-level item component that combines the Item and ItemIndicator into a single styled element with configurable icon positioning.

PropTypeDefaultDescription
indicatorPlacement"start" | "end" | "none""start"The position of the indicator icon relative to the content.
indicatorIconReact.ReactNode<Check />The icon to render as the item indicator.
classNamestring-Additional CSS classes.
...propsBaseCombobox.ItemProps-Passes all other props to the underlying BaseCombobox.ItemProps.

The "Hit-Test" Philosophy

You might notice we use a pseudo-element (before:) to render the hover state, rather than styling the container directly. While simple margins can also create a "pill" shape, that approach creates a UX flaw: it shrinks the clickable area.

By separating the visual layer (the pill) from the interactive layer (the full-width row), we achieve the best of both worlds:

  1. Forgiving Interactivity: Users can hover or click anywhere across the full width of the menu item—even the empty whitespace—to trigger the selection.
  2. Refined Aesthetics: The highlight remains visually tucked in and detached, mimicking the polished feel of native operating system menus (a pattern we adopted from the excellent Base UI).

Feeling too complex? You can always replace pseudo-element with data-[highlighted]:bg-accent and data-[highlighted]:text-accent-foreground.