Capítulo 19 de 51

Chapter 19: Combobox

Core Idea

A filterable Select — selection is restricted to predefined items (like Select), but the popup filters as you type; use it over Select when the item list is large enough to need filtering, and prefer Autocomplete instead when free-form text input must be allowed.

Key Concepts

  • Usage guidelines: "Combobox is a filterable Select" — pick it over Select once the item count is large enough to warrant filtering. Not for free-form search widgets (use Autocomplete). Not appropriate when you don't need to render an input at all (use Select — it has listbox-specific accessibility Combobox doesn't need).
  • Anatomy (largest in the library): RootLabel + InputGroup (Input, Trigger, Icon, Clear, Value, ChipsChipChipRemove) + PortalBackdrop, PositionerPopup (Arrow, Status, Empty, ListRowItemItemIndicator, Separator, GroupGroupLabel, Collection).
  • Two labeling patterns: input-as-form-control → label Combobox.Input with a native <label>/Field.Label; input-inside-popup pattern → Combobox.Label labels the Trigger instead, since the trigger (not the input) is the form control in that layout.
  • Multi-select with chips: multiple prop + the Chips/Chip/ChipRemove parts render selected items as removable chips inside the input group — a feature Select doesn't have.
  • TypeScript inference: item type is inferred from defaultValue/value passed to Root; the items array's element type must match Item's value type.
  • Filtering: same filter/filteredItems/useFilter/useFilteredItems machinery as Autocomplete (ch013); isItemEqualToValue customizes equality when items aren't primitives; itemToStringLabel/itemToStringValue control display vs. value string conversion.
  • autoComplete: browser autofill hint prop, separate from the component's own filtering.

Reference Tables

PartNotable propsNotable data attributes
Rootvalue/onValueChange, inputValue/onInputValueChange, open/onOpenChange, multiple, items, filter, isItemEqualToValue, itemToStringLabel/itemToStringValue, grid, virtualized, limit
Itemvalue, onClick, index, disableddata-selected, data-highlighted, data-disabled
ItemIndicatorkeepMounteddata-starting-style/data-ending-style
Chips/Chip/ChipRemovenativeButton (on ChipRemove)
Valueplaceholder
TriggernativeButton, disableddata-placeholder, data-popup-open, plus shared field-state attributes

Key Takeaways

  1. Choose Combobox over Select specifically when the list is long enough that scrolling to find an item beats typing to filter it — for short lists, Select's simpler interaction model is usually better UX.
  2. Choose Combobox over Autocomplete specifically when the value must be constrained to the item set — Autocomplete's whole point is allowing values outside that set.
  3. Label the right part: if the visible input is the form control, label Input; if the input lives inside the popup and the visible control is the trigger, label the Trigger via Combobox.Label instead — mislabeling here is the most common Combobox a11y bug.

Connects To

  • ch013 (Autocomplete): shares nearly the entire part tree and filtering API — the two chapters are best read together to see exactly where they diverge (selection constraint, chips, Label placement).
  • ch038 (Select): the non-filterable sibling for shorter item lists.
  • ch009 (Forms): naming/labeling rules referenced above.