Menu primitive
Headless Menu: the behavior, keyboard support and ARIA of the WAI-ARIA Menu pattern, with no styles.
@ndop/primitives/menu- WAI-ARIA: Menu
Import
Primitives ship in the @ndop/primitives package and have no styles. Their state is on data attributes for you to style.
import {
NdMenuContent,
NdMenuGroup,
NdMenuItemCheckbox,
NdMenuItemIndicator,
NdMenuLabel,
NdMenuRadioGroup,
NdMenuSeparator,
NdMenuItem,
NdMenuItemRadio,
NdMenuSubTrigger,
} from '@ndop/primitives/menu';Accessibility
Implements the Menu pattern of the WAI-ARIA Authoring Practices.
Keyboard
Keys the component handles.
| Key | Action |
|---|---|
| ArrowDownorArrowUp | Moves focus to the next or previous item, wrapping. |
| HomeorEnd | Moves focus to the first or last item. |
| Enter | Activates the focused item and closes the menu. |
| Space | Activates the focused item; checkbox and radio items keep the menu open. |
| ArrowRight | On a sub-trigger, opens its menu and focuses the first item. |
| ArrowLeft | In a submenu, closes it and focuses its sub-trigger. |
| Escape | Closes the current menu and returns focus to what opened it. |
| Tab | Closes every open menu and moves focus on from the trigger. |
| a | Typeahead: moves focus to the next item whose label starts with the typed letters. |
Focus
- Opened from the keyboard, a menu focuses its first item (its last with
ArrowUpon a Dropdown Menu trigger); opened with the pointer, the menu itself. - Closing returns focus to the trigger or sub-trigger.
Right-to-left
ArrowLeft opens submenus and ArrowRight closes them, and submenus open on the left. Direction comes from the app's Directionality: the document's dir, or a CDK [dir] directive.
API reference
NdMenuContent
[ndMenuContent]role menufrom @ndop/primitives/menuA menu: a list of actions in a role="menu" element, composing the CDK's
CdkMenu (ADR-0004, amendment 3). Put it in an ng-template that a
Dropdown Menu trigger, a Context Menu trigger or a ndMenuSubTrigger
renders. Arrow keys, Home, End and typeahead move between items; Escape
closes it and returns focus to what opened it.
Manages aria-orientation.
| NdMenuContent binding | Type | Default |
|---|---|---|
(closed)Emits when the menu closes. | void | — |
| Data attribute | Values |
|---|---|
data-state | open |
data-side | — |
NdMenuGroup
[ndMenuGroup]role groupfrom @ndop/primitives/menuGroups related items (role="group"). Name it with aria-labelledby
pointing at a ndMenuLabel.
NdMenuItemCheckbox
[ndMenuItemCheckbox]role menuitemcheckboxfrom @ndop/primitives/menuA menu item that is on or off (role="menuitemcheckbox"), composing
CdkMenuItemCheckbox. Activating it flips checked; Space keeps the
menu open.
Manages aria-checked, aria-disabled.
| NdMenuItemCheckbox binding | Type | Default |
|---|---|---|
[disabled]Makes it inert but focusable, with aria-disabled. | boolean | false |
[(checked)]Whether it's on. Two-way bindable with [(checked)]. | boolean | false |
(triggered)Emits when it's activated. | void | — |
| Data attribute | Values |
|---|---|
data-state | — |
data-disabled | — |
NdMenuItemIndicator
[ndMenuItemIndicator]from @ndop/primitives/menuThe check or dot of a checkbox or radio item. It has the hidden
attribute while its item is unchecked.
| Data attribute | Values |
|---|---|
data-state | — |
NdMenuLabel
[ndMenuLabel]from @ndop/primitives/menuA heading for a group of items, as plain text; point the group's
aria-labelledby at it.
NdMenuRadioGroup
[ndMenuRadioGroup]role groupfrom @ndop/primitives/menuGroups radio items (role="group") and holds which one is checked.
Name it with aria-labelledby pointing at a ndMenuLabel.
| NdMenuRadioGroup binding | Type | Default |
|---|---|---|
[(value)]The checked radio item's value, or null. Two-way bindable with
[(value)]. | string | null | null |
NdMenuSeparator
[ndMenuSeparator]role separatorfrom @ndop/primitives/menuA line between groups of items (role="separator").
NdMenuItem
[ndMenuItem]role menuitemfrom @ndop/primitives/menuOne action in a menu (role="menuitem"), composing CdkMenuItem.
Activating it with a click, Enter or Space emits triggered and closes
every open menu. disabled sets aria-disabled only, never the native
attribute: disabled items stay focusable and do nothing. Use a div, as
on a button browsers turn Space into a click, which closes the menu.
Manages aria-disabled.
| NdMenuItem binding | Type | Default |
|---|---|---|
[disabled]Makes it inert but focusable, with aria-disabled. | boolean | false |
(triggered)Emits when it's activated. | void | — |
| Data attribute | Values |
|---|---|
data-disabled | — |
NdMenuItemRadio
[ndMenuItemRadio]role menuitemradiofrom @ndop/primitives/menuOne choice in a NdMenuRadioGroup (role="menuitemradio"),
composing CdkMenuItemRadio. Activating it makes its value the
group's; Space keeps the menu open.
Manages aria-checked, aria-disabled.
| NdMenuItemRadio binding | Type | Default |
|---|---|---|
[value]requiredThe value its group takes when it's checked. | string | — |
[disabled]Makes it inert but focusable, with aria-disabled. | boolean | false |
(triggered)Emits when it's activated. | void | — |
| Data attribute | Values |
|---|---|
data-state | — |
data-disabled | — |
NdMenuSubTrigger
[ndMenuSubTrigger]role menuitemfrom @ndop/primitives/menuA menu item that opens the submenu in the ng-template it's given
(role="menuitem" with aria-haspopup="menu"): with a click, hover,
Enter, Space or the arrow key toward the end side.
Manages aria-haspopup, aria-expanded, aria-controls.
| NdMenuSubTrigger binding | Type | Default |
|---|---|---|
[ndMenuSubTrigger]The ng-template of the submenu. | TemplateRef<unknown> | null | null |
[disabled]Makes it inert but focusable, with aria-disabled. | boolean | false |
| Data attribute | Values |
|---|---|
data-state | — |
data-disabled | — |