|Kit

Combobox

The kit's composable search-select primitive — a thin styled layer over Ark UI's Combobox. The engine Autocomplete and MultiSelect build on, and the escape hatch for fully custom pickers.

Combobox is the low-level, composable building block for searchable selects. It's a thin styled layer over Ark UI's Combobox, exposing the parts so you assemble the control and dropdown yourself. The data-driven Autocomplete and MultiSelect are built on it — reach for Combobox directly only when those don't fit.

Want "just pass data"? Use Autocomplete / MultiSelect / Select. Combobox is the composition layer underneath.

Playground

Combobox

Loading preview

Props

Code

<Combobox size="md" placeholder="Search frameworks…" />

Anatomy

You own the collection and the filtering — Ark's contract. Build a collection with createListCollection (re-exported from the module), filter your source list on input change, and render a Combobox.Item per option. size / variant / color set once on Root flow to the parts.

'use client';
import { useMemo, useState } from 'react';
import { Combobox, createListCollection } from '@42/ui-react/combobox';

const PROJECTS = ['Libft', 'ft_printf', 'Get Next Line', 'Minishell', 'ft_transcendence'];

export function ProjectPicker() {
  const [items, setItems] = useState(PROJECTS);
  const collection = useMemo(
    () => createListCollection({ items, itemToValue: (i) => i, itemToString: (i) => i }),
    [items],
  );

  return (
    <Combobox.Root
      collection={collection}
      openOnClick
      onInputValueChange={({ inputValue }) => {
        const q = inputValue.toLowerCase().trim();
        setItems(q ? PROJECTS.filter((f) => f.toLowerCase().includes(q)) : PROJECTS);
      }}
    >
      <Combobox.Control>
        <Combobox.Input placeholder="Search projects…" />
        <Combobox.ClearTrigger />
        <Combobox.Trigger />
      </Combobox.Control>

      <Combobox.Content>
        {items.map((item) => (
          <Combobox.Item key={item} item={item}>{item}</Combobox.Item>
        ))}
        <Combobox.Empty>Nothing found</Combobox.Empty>
      </Combobox.Content>
    </Combobox.Root>
  );
}

Parts

PartWraps (Ark)Notes
Combobox.RootCombobox.RootTakes the collection. Adds size / variant / color; defaults the dropdown to the control's width (positioning.sameWidth). All Ark root props (value, inputValue, multiple, onValueChange, onInputValueChange, …) pass through.
Combobox.ControlCombobox.ControlThe input shell (same chrome as Input). Holds the input + triggers. Accepts startSlot / endSlot for inline-start / -end adornments, laid out like Input's slots.
Combobox.InputCombobox.InputThe search <input>.
Combobox.TriggerCombobox.TriggerChevron toggle; rotates when open.
Combobox.ClearTriggerCombobox.ClearTriggerClears the value; auto-hidden when empty.
Combobox.ContentPositioner + ContentThe floating panel (positioner + scroll container in one).
Combobox.ItemItem + ItemText + ItemIndicatorAn option. Pass item={collectionItem}; renders a check when selected.
Combobox.GroupItemGroup + ItemGroupLabelPass label to head a group of options.
Combobox.EmptyEmptyShown when the collection is empty (e.g. no matches).
Combobox.ContextCombobox.ContextRender-prop access to the live machine api.

Grouped options

Wrap options in Combobox.Group with a label:

<Combobox.Content>
  <Combobox.Group label="Common Core">
    <Combobox.Item item="libft">Libft</Combobox.Item>
    <Combobox.Item item="ft_printf">ft_printf</Combobox.Item>
  </Combobox.Group>
  <Combobox.Group label="Outer Core">
    <Combobox.Item item="ft_transcendence">ft_transcendence</Combobox.Item>
    <Combobox.Item item="inception">Inception</Combobox.Item>
  </Combobox.Group>
</Combobox.Content>

Multiple selection

Pass multiple to Combobox.Root and pair it with a PillsInput target to show selected values as pills — this is exactly what MultiSelect assembles for you.

Field integration

Combobox consumes Ark's Field context, so wrapping it in Field wires the label, description, error, and aria-* automatically:

<Field label="Project" description="Pick a project">
  <ProjectPicker />
</Field>

Accessibility

  • Full combobox keyboard model from Ark: type to filter, / to move, Enter to select, Esc to close, Home / End to jump.
  • role="combobox" / listbox / option and the aria-activedescendant / aria-expanded wiring are handled by the Ark machine.
  • RTL is honored via the document dir. Filtering, custom values, and selection behavior are all Ark-owned — see the Ark Combobox docs for the full prop surface forwarded through Combobox.Root.

On this page