Form

Combobox

A searchable select for long lists, single or `multiple`. The trigger matches Select; the popover has a search field above a filtered list. Type to filter, arrows to move, Enter to pick.

Where your company is registered.

Usage

  • Use for long lists (15+) where people know what they are looking for.
  • Use Select for short lists; scrolling a few options is faster than typing.
  • Don’t use it to create free-text values; it only picks from options.
  • Use multiple for labels, tags, assignees; for 2–6 independent on/off options use Checkboxes.

Installation

Install the package (React 19):

terminal
npm install @krackedui/motion

Import the styles once, in your app entry or root layout:

/src/main.tsx
import '@krackedui/motion/styles.css';

Use it anywhere inside your app's <Theme> (see Installation):

/src/ComboboxExample.tsx
import { useState } from 'react';
import { Combobox, Field } from '@krackedui/motion';

const countries = ['Argentina', 'Australia', 'Belgium', 'Brazil', 'Canada', 'France', 'Germany', 'Ghana', 'Rwanda']
  .map((c) => ({ value: c.toLowerCase(), label: c }));

export function CountryField() {
  const [country, setCountry] = useState('');
  return (
    <Field label="Country" description="Where your company is registered.">
      <Combobox
        options={countries}
        value={country}
        onValueChange={setCountry}
        placeholder="Choose a country"
        searchPlaceholder="Search countries"
        emptyText="No country matches"
      />
    </Field>
  );
}

Examples

People

Options can carry an icon and a second line. Filtering matches the label text, ignoring case and accents.

Invalid and disabled

Pick a project to file this under.

Multiple

multiple (Motion extra): value is a string[], chips show the selection, Enter or a click toggles an option and keeps the list open, Backspace in the empty search removes the last one.

Pick all that apply.

Dark theme

API Reference

Combobox

The ref goes to the trigger <button>.

PropTypeDefault
options
ControlOption[]
multiple
boolean
false
value / defaultValue
stringstring[]
onValueChange
(value: string) => void(value: string[]) => void
placeholder
string
"Select…"
searchPlaceholder
string
"Search…"
emptyText
ReactNode
"No results"
filter
(option, query) => boolean
size
"sm""md""lg"
"md"
invalid
boolean
false
disabled
boolean
false
required
boolean
false
name
string
open
boolean
defaultOpen
boolean
onOpenChange
(open: boolean) => void
id
string
className
string
style
CSSProperties
contentClassName
string
aria-label
string
aria-labelledby
string
aria-describedby
string

Accessibility

  • The trigger is a button with aria-haspopup="dialog" and aria-expanded; opening moves focus into the search field. It differs from Select on purpose (APG): Select's trigger is a select-only combobox because its popup is the listbox itself, while here the popup holds its own combobox search field, and two nested comboboxes would be ambiguous. The current value is the trigger's description, so it is announced after the label.
  • The search field is role="combobox" with aria-autocomplete="list", aria-controls (the listbox) and aria-activedescendant (the highlighted option), so focus stays in the field while arrows move.
  • ↓ / ↑ move (wrapping, skipping disabled), Page Up/Down jump 10, Enter picks, Escape closes; focus returns to the trigger. The result count is announced politely.
  • Typing a letter on the closed trigger opens it with that letter as the search.
  • With multiple: the listbox has aria-multiselectable="true" and each option aria-selected; Enter (or a click) toggles the highlighted option and keeps the list open; Backspace in the empty search (or Backspace / Delete on the trigger) removes the last value. The trigger is described by "Bug, Design selected" (the chips are hidden from assistive tech).
© 2026 Motion. Internal documentation.