Combobox

Filters large lists to selectable options based on the matching query.

Uncontrolled

Controlled

Disabled

Errored

Custom width input

Custom width list

With label

Sizes

Used inside a Modal

It is common to use Combobox inside a Modal. On mobile, the Modal automatically renders a Dialog instead.

Best Practices

When to use

  • Pick <Combobox> when users type to filter a known list of values (regions, frameworks, env-var names).
  • For short, fixed lists where typing adds nothing, switch to Select.
  • When more than one value can be chosen at once, use MultiSelect.
  • For free-form filter strings that don’t resolve to a single option, drop in Input with the search variant.

Behavior

  • Show a loading state for async results; don’t collapse the list while the request is in flight.
  • Render a custom empty state of the form No {items} match "{query}" rather than a bare No results.
  • Inside a Modal, Geist switches to a Dialog on mobile automatically; don’t layer a second portal.
  • Keep arrow-key navigation through <Combobox.Option> items; don’t hijack Enter to submit the surrounding form while the list is open.

Content

  • Visible label is a short Title Case noun (Region, Environment Variable Name).
  • Placeholder is the inline hint: Search regions, DATABASE_URL. Never bare Search… and never the label restated.
  • Option text is Title Case for short values and matches canonical branding (Next.js, not NextJS); same register across the list.
  • Validation names the field and constraint, sentence case with a period (Select a region.).

Accessibility

  • <Combobox> has no label prop; pair a sibling <Label htmlFor> with the root id, or set aria-label on the root for icon-only triggers.
  • The root accepts aria-label only; there is no aria-labelledby prop, so the sibling-label path is the way to reference visible text.
  • Trap focus inside the popover when nested in a Modal so Tab cycles options instead of the page behind it.