Skip to main content

Combobox

Filters a list of options as the user types.

import { Combobox } from "@/fragments/ui";Source

Preview

<StatefulCombobox placeholder="Select a fruit">
  <Combobox.Input />
  <Combobox.Content>
    <Combobox.Item value="apple">Apple</Combobox.Item>
    <Combobox.Item value="banana">Banana</Combobox.Item>
    <Combobox.Item value="orange">Orange</Combobox.Item>

Installation

npx @usefragments/cli add combobox

Writes src/fragments/ui/components/Combobox plus what it imports, the globals stylesheet, and .fragments/registry-lock.json, then prints the packages to add. No account, no key.

Your own registry: publish from Fragments Cloud and add --registry org/name. Connect a workspace.

Anatomy

Combobox is a compound: import the root and reach its parts through dot notation.

  • Combobox.Input
  • Combobox.Trigger
  • Combobox.Content
  • Combobox.Item
  • Combobox.ItemIndicator
  • Combobox.Empty
  • Combobox.Group
  • Combobox.GroupLabel

Type to narrow the list; unmatched queries show a no-results row.

<StatefulCombobox placeholder="Select a fruit">
  <Combobox.Input />
  <Combobox.Content>
    <Combobox.Item value="apple">Apple</Combobox.Item>
    <Combobox.Item value="banana">Banana</Combobox.Item>
    <Combobox.Item value="orange">Orange</Combobox.Item>
    <Combobox.Item value="grape">Grape</Combobox.Item>
  </Combobox.Content>
</StatefulCombobox>

Examples

Multiple Selection

Each pick becomes a removable chip in the field.

<StatefulCombobox multiple placeholder="Select fruits...">
  <Combobox.Input />
  <Combobox.Content>
    <Combobox.Item value="apple">Apple</Combobox.Item>
    <Combobox.Item value="banana">Banana</Combobox.Item>
    <Combobox.Item value="orange">Orange</Combobox.Item>

With Label and Helper Text

Helper text tells the user the field is searchable.

<StatefulCombobox
  label="Assignee"
  placeholder="Search assignees..."
  helperText="Type to filter the list of available assignees."
>
  <Combobox.Input />

Error State

Red border, and the message replaces helper text.

<Combobox
  label="Reviewer"
  placeholder="Search reviewers..."
  error="Please select a reviewer"
>
  <Combobox.Input />

With Groups

Headed sections stay intact while filtering.

<StatefulCombobox placeholder="Search countries...">
  <Combobox.Input />
  <Combobox.Content>
    <>
      <Combobox.Group>
        <Combobox.GroupLabel>North America</Combobox.GroupLabel>

With Empty State

Combobox.Empty replaces the default no-results wording.

<StatefulCombobox placeholder="Filter languages...">
  <Combobox.Input />
  <Combobox.Content>
    <Combobox.Empty>No language matches that search</Combobox.Empty>
    <Combobox.Item value="js">JavaScript</Combobox.Item>
    <Combobox.Item value="ts">TypeScript</Combobox.Item>

Scrollable List

Caps at four rows and half-shows the fifth as a scroll hint.

<StatefulCombobox placeholder="Search languages...">
  <Combobox.Input />
  <Combobox.Content>
    <Combobox.Empty>No results found</Combobox.Empty>
    <Combobox.Item value="js">JavaScript</Combobox.Item>
    <Combobox.Item value="ts">TypeScript</Combobox.Item>

Custom Max Visible Items

maxVisibleItems raises the cap to six rows.

<StatefulCombobox placeholder="Search cities...">
  <Combobox.Input />
  <Combobox.Content maxVisibleItems={6}>
    <Combobox.Empty>No results found</Combobox.Empty>
    <Combobox.Item value="nyc">New York</Combobox.Item>
    <Combobox.Item value="lon">London</Combobox.Item>

Disabled

Dimmed and unfocusable.

<Combobox disabled placeholder="Search...">
  <Combobox.Input />
  <Combobox.Content>
    <Combobox.Item value="1">Option 1</Combobox.Item>
  </Combobox.Content>
</Combobox>

Explicit Trigger

showTrigger={false} hands the open control to your own Combobox.Trigger.

<StatefulCombobox placeholder="Search assignees...">
  <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
    <Combobox.Input showTrigger={false} />
    <Combobox.Trigger aria-label="Open assignee list" />
  </div>
  <Combobox.Content>

API

Component props
Prop
Type
Default
Description
multiplebooleanfalseAllow multiple selections with chips
valueunionNot setControlled selected value (string for single, string[] for multiple)
defaultValueunionNot setDefault selected value (uncontrolled)
onValueChangeunionNot setCalled when selection changes
onChangeunionNot setAlias for onValueChange
childrenRequirednodeNot setCombobox input and content
openbooleanNot setControlled open state of the dropdown
defaultOpenbooleanfalseInitial open state for uncontrolled usage
onOpenChangefunctionNot setCalled when dropdown open state changes
requiredbooleanNot set
namestringNot set
placeholderstringNot setPlaceholder text for the input
autoHighlightbooleantrueAuto-highlight first matching item while filtering
sizeenumsmmdlg"md"Size variant
classNamestringNot setWrapper class name
labelstringNot setVisible label text above the combobox
helperTextstringNot setHelper text shown below the combobox
errorunionNot setShow error styling. When a string is provided, it is displayed as an error message.
disabledbooleanfalseDisable the combobox
autoCompletestringNot set
formstringNot set
inputRefunionNot set
readOnlybooleanNot set

Accessibility

  • Arrow keys, Enter, and Escape all work
  • Typing filters the list in place
  • Correct ARIA combobox roles and attributes
  • Filtered result counts are announced
  • Chips can be removed from the keyboard

Guidance

Use when

  • Lists too long to scan by eye
  • The user roughly knows the value they want
  • Autocomplete or typeahead
  • Multi-select from a searchable list

Avoid when

  • Under five options (use Select or RadioGroup)
  • Free-form text with no known options (use Input)
  • Short list nobody needs to search (use Select)
  • Actions rather than values (use Menu)
  • SelectalternativeUse Select when search/filtering is not needed
  • InputsiblingUse Input for free-form text entry
  • ListboxsiblingUse Listbox for inline option lists

Next steps