Combobox

Flexible input for selecting from a list with filtering.

Examples

Basic

Groups

Multi-select with chips

Creatable

Overview

Combobox is a text input paired with a filtered list of options. Use it when the user picks from a known set but the set is too large for a Select or radio group. Built on Base UI Combobox.

tsx
import {
  Combobox,
  ComboboxContent,
  ComboboxEmpty,
  ComboboxInput,
  ComboboxItem,
  ComboboxList,
} from "@rogo-technologies/ui/combobox";

<Combobox items={languages} itemToStringLabel={(item) => item.value}>
  <ComboboxInput placeholder="Filter..." />
  <ComboboxContent>
    <ComboboxEmpty>No results.</ComboboxEmpty>
    <ComboboxList>
      {(item) => (
        <ComboboxItem key={item.id} value={item}>
          {item.value}
        </ComboboxItem>
      )}
    </ComboboxList>
  </ComboboxContent>
</Combobox>;

Usage

Multi-select with chips

Selected values render as chips inside the input. Type to filter, click an item to add it, click the chip's × to remove. Press Backspace on the empty input to remove the last chip. Useful for sharing flows, tagging, or any input where the user picks several items at once.

tsx
import {
  Combobox,
  ComboboxChips,
  ComboboxChip,
  ComboboxChipsInput,
  ComboboxContent,
  ComboboxList,
  ComboboxItem,
} from "@rogo-technologies/ui/combobox";

<Combobox multiple items={users} itemToStringLabel={(u) => u.name}>
  <ComboboxChips>
    {(selected) =>
      selected.map((u) => (
        <ComboboxChip key={u.id} value={u}>
          {u.name}
        </ComboboxChip>
      ))
    }
    <ComboboxChipsInput placeholder="Add people..." />
  </ComboboxChips>
  <ComboboxContent>
    <ComboboxList>
      {(item) => (
        <ComboboxItem key={item.id} value={item}>
          {item.name}
        </ComboboxItem>
      )}
    </ComboboxList>
  </ComboboxContent>
</Combobox>;

Creatable

Let the user submit a value that isn't in the suggestion list — useful for tags, labels, or any free-form set with hints. Append the typed query to items and render a "Create …" row at the end of the list. With autoHighlight, Enter selects it; clicking works the same. The selection callback receives the new string just like any other item, so there's no separate "create" code path.

tsx
const trimmed = query.trim();
const canCreate = trimmed.length > 0 && !suggestions.includes(trimmed) && !tags.includes(trimmed);

<Combobox
  multiple
  items={canCreate ? [...filtered, trimmed] : filtered}
  value={tags}
  onValueChange={setTags}
  inputValue={query}
  onInputValueChange={setQuery}
  autoHighlight
>
  {/* ...chips input... */}
  <ComboboxContent>
    <ComboboxList>
      {filtered.map((t) => (
        <ComboboxItem key={t} value={t}>
          {t}
        </ComboboxItem>
      ))}
      {canCreate && <ComboboxItem value={trimmed}>Create &ldquo;{trimmed}&rdquo;</ComboboxItem>}
    </ComboboxList>
  </ComboboxContent>
</Combobox>;

API

Combobox (Root)

PropTypeDefaultDescription
itemsValue[]The full list of selectable items.
itemToStringLabel(item: Value) => stringReturns the label string used for filtering & display.
valueValue | Value[] | nullControlled selection. Array when multiple is true.
defaultValueValue | Value[] | nullInitial selection (uncontrolled).
onValueChange(value: Value | Value[]) => voidCallback when selection changes.
multiplebooleanfalseAllow multi-select with chips.
openbooleanControlled open state of the popup.
onOpenChange(open: boolean) => voidCallback when popup open state changes.

Subcomponents

ComponentPurpose
ComboboxInputSingle-line text input that opens & filters the list.
ComboboxChipsContainer that renders selected chips alongside input.
ComboboxChipOne selected value rendered as a removable chip.
ComboboxChipsInputInput used inside a ComboboxChips container. Accepts deleteOnBackspace (default true) — when true, pressing Backspace on the empty input removes the last chip.
ComboboxContentFloating popup wrapper.
ComboboxListList region; render-prop maps over the filtered items.
ComboboxItemA single selectable row.
ComboboxGroupGroup rows under a labeled section.
ComboboxLabelVisible label rendered inside a ComboboxGroup.
ComboboxEmptyShown when the filter has no matches.
ComboboxSeparatorDivider between items.
ComboboxClearButton to clear the current selection.
ComboboxTriggerButton that opens the popup (alternative to typing).
ComboboxInputGroupWraps input + trigger/clear into one styled row.
ComboboxValueRenders the currently selected value (for triggers).

All subcomponents accept standard HTML attributes for their underlying elements.

Guidelines

Do

  • Use Combobox when the user picks from a known set that's too large to scan (more than ~7 items)
  • Provide an itemToStringLabel that matches what users would type
  • Show a ComboboxEmpty state — never leave the popup blank when filtering yields nothing
  • Use multi-select with chips for tagging, sharing, and similar "pick several" flows

Don't

  • Don't use Combobox for free-form text entry — use Input instead
  • Don't use Combobox for short fixed lists (≤ 5 options) — use Select or RadioGroup
  • Don't render hundreds of items eagerly — virtualize or paginate the source data
  • Don't hide the filtered list while the input has focus — users expect to see matches as they type
PreviousCollapsible
NextDialog
Made in NYC© 2026 Rogo Technologies Inc.