Capítulo 38 de 51

Chapter 38: Select

Core Idea

A non-filterable (keyboard-typeahead only) listbox select whose popup, by default, overlaps the trigger so the selected item's text lines up exactly with the trigger's displayed value (alignItemWithTrigger) — the single most distinctive and easy-to-misconfigure behavior in the component.

Key Concepts

  • Usage guideline — vs. Combobox: Select has no filtering beyond keyboard typeahead; switch to Combobox (ch019) once the item list is long enough to need real filtering.
  • Anatomy: RootLabel, Trigger (Value, Icon), PortalBackdrop, PositionerPopup (ScrollUpArrow, Arrow, ListItemItemText/ItemIndicator, Separator, GroupGroupLabel, ScrollDownArrow).
  • alignItemWithTrigger (default true): makes the popup overlap the trigger so the selected item aligns with the trigger's value text — data-side="none" on Popup/Positioner while this mode is active. Falls back to standard positioning automatically when: opened via touch, insufficient viewport space (tune the threshold via min-height on Positioner), or the trigger sits within 20px of the top/bottom viewport edge. All other positioning props (side, align, ...) are ignored while this mode is active — set alignItemWithTrigger={false} if you need side/align to take effect.
  • Multi-select: multiple prop on Root.
  • Scroll arrows: ScrollUpArrow/ScrollDownArrow replace a generic scrollbar for long option lists inside the popup, with data-visible reflecting whether more content exists in that direction.
  • Labeling: prefer Select.Label; fall back to aria-label on Trigger only when no visible label renders.

Reference Tables

PartNotable propsNotable data attributes
Rootvalue/onValueChange, multiple, items, isItemEqualToValue, itemToStringLabel/itemToStringValue, modal
PositioneralignItemWithTrigger (default true), side/align (ignored while active)data-side="none" when overlap mode active
Itemlabel, value, disableddata-selected, data-highlighted, data-disabled
ScrollUpArrow/ScrollDownArrowkeepMounteddata-direction, data-visible, data-starting-style/data-ending-style

Key Takeaways

  1. If a side/align prop appears to have no effect, check alignItemWithTrigger first — it's true by default and silently overrides normal positioning until it falls back or is disabled.
  2. Set alignItemWithTrigger={false} explicitly for any select whose popup must never overlap the trigger (e.g. a compact toolbar select where overlap looks broken) rather than fighting the automatic fallback conditions.
  3. Move to Combobox the moment users start scrolling through more than roughly a screenful of options — Select's typeahead is not a substitute for real filtering at scale.

Connects To

  • ch019 (Combobox): the filterable sibling — read together to decide which one a given list needs.
  • ch006 (Animation): the Select-specific Motion animation pattern (hybrid unmounted/kept-mounted) documented there.
  • ch037 (Scroll Area): a related but separate mechanism from this component's own ScrollUpArrow/ScrollDownArrow.