Commit Combobox

A pick-from-list field that never saves text the user only typed, and visibly drops a pick when it is typed over.

StopsTyped text saved instead of a pick

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/commit-combobox.json

The files land in your project. They're yours to edit.

Usage

commit-combobox-usage.tsx
import { CommitCombobox, type ComboOption } from "@/components/ui/commit-combobox"

<CommitCombobox label="Delivery city" options={CITIES} defaultInputValue="Banglore" />

What it catches

  • Typed text left without a pick when leaving the field
  • Misspellings, with a one-tap Did you mean
  • Two options with the same name, by asking which
  • A pick silently replaced by later typing

Props

CommitCombobox props
PropTypeDefault
label* (required)

Visible label.

string—
options

The options to pick from. Ignored when `loadOptions` is set.

readonly ComboOption[][]
loadOptions

Fetches options for a query (debounced, aborted and ignored once stale).

(query: string, signal: AbortSignal) => Promise<ComboOption[]>—
value

Controlled pick: the option, or null when nothing is picked.

ComboOption | null—
defaultValue

Initial pick when uncontrolled.

ComboOption | nullnull
onValueChange

Called with the picked option, or null when the pick is dropped.

(option: ComboOption | null) => void—
defaultInputValue

Unpicked text to start with (a restored draft). It is checked as if the user had just left the field.

string—
messages

Override any text (see `COMMIT_COMBOBOX_MESSAGES`).

Partial<CommitComboboxMessages>—

* required. Also accepts the native props of <input> (className, aria-*, data-*…), passed through to it.

Accessibility

  • role="combobox" with aria-autocomplete="list", aria-expanded, aria-controls and aria-activedescendant
  • Arrow keys move through options, Enter picks, Escape closes or undoes
  • Visible <label> tied to the input
  • Motion respects prefers-reduced-motion

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

  • Fuzzy matching is for suggestions only; it never picks a near match on its own
  • With loadOptions, matching only covers the options returned

What it stops

Typed text saved instead of a pick

Also known as

combobox · autocomplete · typeahead · select · searchable dropdown · city picker · react select · cmdk

Field type

Dependencies

Pairs well with