Skip to content
LuoForge/Tungsten
Components/Combobox·

Combobox

since v8.4.0

Searchable single/multi value selector wrapping react-aria (ADR-0006). See

{@link ComboboxProps}.

Install

Add the package and import the component.

pnpm add @hey-mike/tungsten
pnpm add @hey-mike/tungsten
import { Combobox } from '@hey-mike/tungsten';
import { Combobox } from '@hey-mike/tungsten';

Preview

Same fixtures used by the visual-regression suite.

Usage

apps/docs/app/snapshots/combobox/page.tsx

'use client';

import { Combobox } from '@hey-mike/tungsten';
import { VariantGrid } from '../_components/VariantGrid';

const FRUITS = [
  { id: 'apple', label: 'Apple' },
  { id: 'banana', label: 'Banana' },
  { id: 'cherry', label: 'Cherry' },
  { id: 'date', label: 'Date' },
];

export default function ComboboxSnapshot() {
  return (
    <VariantGrid
      title="Combobox"
      variants={[
        {
          label: 'empty',
          node: (
            <div className="w-64">
              <Combobox label="Fruit" options={FRUITS} placeholder="Search fruit…" />
            </div>
          ),
        },
        {
          label: 'single (selected)',
          node: (
            <div className="w-64">
              <Combobox label="Fruit" options={FRUITS} defaultSelectedKey="cherry" />
            </div>
          ),
        },
        {
          label: 'multi (chips)',
          node: (
            <div className="w-72">
              <Combobox
                mode="multiple"
                label="Fruit"
                options={FRUITS}
                defaultSelectedKeys={['apple', 'cherry']}
                placeholder="Add fruit…"
              />
            </div>
          ),
        },
      ]}
    />
  );
}
'use client';

import { Combobox } from '@hey-mike/tungsten';
import { VariantGrid } from '../_components/VariantGrid';

const FRUITS = [
  { id: 'apple', label: 'Apple' },
  { id: 'banana', label: 'Banana' },
  { id: 'cherry', label: 'Cherry' },
  { id: 'date', label: 'Date' },
];

export default function ComboboxSnapshot() {
  return (
    <VariantGrid
      title="Combobox"
      variants={[
        {
          label: 'empty',
          node: (
            <div className="w-64">
              <Combobox label="Fruit" options={FRUITS} placeholder="Search fruit…" />
            </div>
          ),
        },
        {
          label: 'single (selected)',
          node: (
            <div className="w-64">
              <Combobox label="Fruit" options={FRUITS} defaultSelectedKey="cherry" />
            </div>
          ),
        },
        {
          label: 'multi (chips)',
          node: (
            <div className="w-72">
              <Combobox
                mode="multiple"
                label="Fruit"
                options={FRUITS}
                defaultSelectedKeys={['apple', 'cherry']}
                placeholder="Add fruit…"
              />
            </div>
          ),
        },
      ]}
    />
  );
}

Props

Surface specific to <Combobox />.

PropTypeDefaultDescription
mode"single" | "multiple"
selectedKeystring | nullControlled selected option id. Pair with onSelectionChange.
defaultSelectedKeystring | nullUncontrolled initial selection.
onSelectionChange((id: string | null) => void) | ((ids: string[]) => void)Fires when the selection changes (or clears → null). Fires with the full selected-id array on every add/remove.
options*ComboboxOption[]The full option list (already filtered if shouldFilter={false}).
inputValuestringControlled input text. Pair with onInputChange.
onInputChange((value: string) => void)Fires on every keystroke — the hook for server-side/async filtering.
shouldFilterbooleanFilter options client-side by the query (default). Set false for server-side.
isLoadingbooleanShow a loading row in the listbox (async in-flight).
errorstringError message shown in the listbox when option loading failed.
emptyMessagestringMessage when there are zero options.
labelstringAccessible name for the input when not inside a FormField.
placeholderstringPlaceholder shown in the empty input.
isDisabledbooleanDisable the control.
isRequiredbooleanMark required (also read from FieldContext).
classNamestringClass on the input.
aria-labelstring
selectedKeysstring[]Controlled selected ids. Pair with onSelectionChange.
defaultSelectedKeysstring[]Uncontrolled initial selection.
maxSelectionsnumberCap the number of selections; further picks are blocked once reached.

Used in recipes

Compositions from the /recipes reference that use this component.

Source