Capítulo 27 de 51

Chapter 27: Menu

Core Idea

A click-triggered dropdown menu — the anatomy and item vocabulary (items, submenus, radio/checkbox items) that Context Menu (ch020) and Menubar (ch028) both reuse, with Viewport supporting content transitions between menu "screens" (e.g. drilling into a submenu in place).

Key Concepts

  • Anatomy: RootTrigger, PortalBackdrop, PositionerPopup (Arrow, Item, LinkItem, Separator, SubmenuRootSubmenuTrigger, GroupGroupLabel, RadioGroupRadioItemRadioItemIndicator, CheckboxItemCheckboxItemIndicator, Viewport).
  • Viewport: added in v1.3.0 for content transitions — exposes data-activation-direction, data-current/data-previous, data-transitioning for animating between menu levels as a submenu opens/closes in place instead of stacking popups.
  • Hover-opening: Trigger/SubmenuTrigger support openOnHover, delay, closeDelay — configure hover-intent timing per trigger.
  • Detached triggers: same Handle/createHandle()/handle prop/triggerId system as Dialog/AlertDialog, for opening a menu from a trigger that isn't its sibling.
  • Item variants: plain Item (action), LinkItem (renders as a link, closeOnClick), CheckboxItem/RadioItem (selection state within the menu, each with an ...Indicator sub-part), SubmenuTrigger (nested menu).
  • Roving tabindex: menu items share one Tab stop with internal arrow-key navigation — configure via loopFocus/orientation on Root, don't hand-roll.

Reference Tables

PartNotable propsNotable data attributes
Rootopen/onOpenChange, modal, loopFocus, orientation, handle, closeParentOnEsc
TriggeropenOnHover, delay, closeDelay, handle, payloaddata-popup-open, data-pressed
Itemlabel, onClick, closeOnClick, disableddata-highlighted, data-disabled
CheckboxItemchecked/onCheckedChange, closeOnClickdata-checked, data-unchecked, data-highlighted
RadioGroup/RadioItemvalue/onValueChange (group), value (item)data-checked, data-unchecked
Viewportdata-activation-direction, data-current, data-previous, data-transitioning

Key Takeaways

  1. Use Viewport when you want a "drill down into submenu, replace content in place" UX (mobile-app-style menu navigation) instead of the default stacked-popup submenu presentation.
  2. Configure openOnHover/delay/closeDelay deliberately per trigger — the defaults favor click-to-open; hover-opening is opt-in and needs sensible delay tuning to avoid accidental triggers.
  3. LinkItem vs. Item + render={<a/>}: prefer LinkItem when available — it's purpose-built for link semantics within a menu (vs. Radix's approach of overriding Item's render).

Connects To

  • ch020 (Context Menu): shares this entire item/submenu vocabulary; only the trigger mechanism differs.
  • ch028 (Menubar): multiple Menu.Roots coordinated under one horizontal bar.
  • ch007 (Composition): Handle/detached-trigger pattern shared with Dialog/AlertDialog.