Menu
An accessible dropdown / action menu anchored to a trigger. It follows the WAI-ARIA menu button pattern: role="menu" content with role="menuitem" children, arrow-key navigation, typeahead, and submenu support.
Last action: —
Anatomy
Menu.Root shares open state and the trigger reference. Menu.Content renders the role="menu" panel in a portal, positioned against the trigger (default placement bottom-start). Items take an onAction handler and can be disabled.
<script>
import { Menu } from '@human-kit/ui';
</script>
<Menu.Root>
<Menu.Trigger>Options</Menu.Trigger>
<Menu.Content>
<Menu.Item onAction={edit}>Edit</Menu.Item>
<Menu.Item disabled>Duplicate</Menu.Item>
<Menu.Separator />
<Menu.Group>
<Menu.GroupLabel>Share</Menu.GroupLabel>
<Menu.Item onAction={copyLink}>Copy link</Menu.Item>
</Menu.Group>
</Menu.Content>
</Menu.Root>Groups and separators
Group related items with Menu.Group + Menu.GroupLabel — the group renders role="group" labelled by its label — and divide sections with Menu.Separator.
Submenus
Nest a Menu.SubmenuRoot containing a Menu.SubmenuTrigger and its own Menu.Content (default placement right-start). Submenus use a "safe triangle" pointer intent: while the pointer moves diagonally toward an open submenu, hovering the sibling items it passes over does not close it.
Usage guidelines
- Use
Menu.Rootto share open state and the trigger reference, and placeMenu.TriggerandMenu.Contentinside it. - Use
Menu.Itemfor actions. ProvideonAction, and optionallydisabled,closeOnSelect, ortextValue(for typeahead). closeOnSelect(onMenu.Root, overridable perMenu.Item) controls whether activating an item closes the menu. Defaulttrue.loop(defaulttrue) wraps arrow navigation;typeahead(defaulttrue) focuses items by typed text.- Group related items with
Menu.Group+Menu.GroupLabel, and divide sections withMenu.Separator. onOpenChange(open, details)reports why the state changed (details.reason) and supportsdetails.cancel()to prevent the transition.
Accessibility
Menu.Triggerrenders a button witharia-haspopup="menu"andaria-expanded;ArrowDown/Enter/Spaceopen the menu and focus the first item,ArrowUpopens and focuses the last item.Menu.Contentrendersrole="menu"and items renderrole="menuitem"; arrow keys move the highlight, and typeahead focuses items by typed text.- Escape closes the current (topmost) menu and returns focus to its trigger;
Taband outside interaction close the whole menu chain. - Within a submenu,
ArrowLeftcloses just that level;ArrowRighton a submenu trigger opens it.
API reference
Root
State container for the menu. Shares open state, the trigger reference, and navigation settings (loop, typeahead, closeOnSelect) with all parts.
* required. Native HTML attributes of the underlying element are also accepted.
Trigger
Button that opens the menu (aria-haspopup="menu", aria-expanded). ArrowDown/Enter/Space open and focus the first item; ArrowUp opens and focuses the last item.
* required. Native HTML attributes of the underlying element are also accepted.
Content
The floating role="menu" panel. Renders in a portal and positions itself against the trigger; also used as the panel of a submenu.
* required. Native HTML attributes of the underlying element are also accepted.
Overlay
Optional backdrop rendered behind the menu. Place it as a sibling of Menu.Content inside Menu.Root; in a submenu chain only the root menu should render one.
* required. Native HTML attributes of the underlying element are also accepted.
Item
An interactive role="menuitem" action. Accepts `onAction`, `disabled`, `closeOnSelect` (overrides the Root default), `textValue` for typeahead, and an optional stable `value`.
* required. Native HTML attributes of the underlying element are also accepted.
Separator
A visual divider between menu items (role="separator").
* required. Native HTML attributes of the underlying element are also accepted.
Group
Groups related items (role="group"), labelled by an optional Menu.GroupLabel via aria-labelledby.
* required. Native HTML attributes of the underlying element are also accepted.
GroupLabel
Accessible label for a Menu.Group. The surrounding group references it through aria-labelledby.
* required. Native HTML attributes of the underlying element are also accepted.
SubmenuRoot
State container for a nested submenu. Place it inside a Menu.Content with a Menu.SubmenuTrigger and its own Menu.Content; navigation settings inherit from the parent menu.
* required. Native HTML attributes of the underlying element are also accepted.
SubmenuTrigger
A role="menuitem" that opens its submenu on hover, ArrowRight, Enter, or Space. Behaves as a navigable item of the parent menu.
* required. Native HTML attributes of the underlying element are also accepted.