Components / Inputs

Combobox

Search and select from a list without leaving the field.

Install

npx shadcn@latest add https://irisui.dev/r/combobox.json
import { Combobox } from "@/components/iris/combobox/combobox";
Registry item comboboxBrings in foundationRegistry JSON

Preview

Combobox

A searchable single-choice field: type to filter a list and pick one option without leaving the input.

When to use

  • Long lists where typing is faster than scrolling: versions, teammates, projects, time zones.
  • When options have aliases; keywords lets "17" match "Postgres 17 (default)".
  • For short lists use Select; for several values use MultiSelect; for free-form values use TagInput.

Usage

import { Combobox } from "@/components/iris/combobox/combobox";
h(Combobox, {
  label: "Project owner",
  options: [
    { value: "stelios", label: "Stelios Antoniou" },
    { value: "katerina", label: "Katerina Vlachou", keywords: ["kv"] },
    { value: "tomasz", label: "Tomasz Wrona" },
  ],
  defaultValue: "stelios",
  description: "Owners can rotate credentials and restore backups.",
  onValueChange: (value) => console.log(value),
});

Props

Prop Type Default Description
label string required Visible label for the input.
options { value: string; label: string; disabled?: boolean; keywords?: string[] }[] required Choices; keywords are extra search terms.
value / defaultValue string – / "" Controlled or initial value.
onValueChange (value: string) => void – Called with the chosen value, or "" when cleared.
placeholder string "Search or select…" Shown when nothing is selected.
emptyMessage string "No matches found" Shown when the query matches nothing.
description string – Helper copy under the field.
disabled boolean – Disables the input.
className string – Extra class on the bordered field shell.
...props InputHTMLAttributes<HTMLInputElement> – Forwarded to the input (ref, name, onFocus…).

Notes

  • ARIA combobox pattern: role="combobox", aria-expanded, aria-activedescendant; ArrowUp/Down move through enabled options, Enter chooses, Escape closes.
  • The menu opens on focus or click; a pointer down outside closes it. While searching, the chosen label stays as placeholder copy.
  • The list renders inline (absolutely positioned, not portalled), so give the parent room or overflow: visible. Its height caps at min(300px, 40vh).
  • Reduced motion replaces the springs with instant fades. Reads --surface, --hover, --line, --line-strong, --accent, --focus-ring, --shadow-floating, --radius-panel, --radius-button.