Context Menu
An accessible dropdown and context menu that is used to display a list of actions or options that a user can choose when a trigger element is right-clicked or long pressed.
Features
- Support for items, labels, groups of items.
- Focus is fully managed using
aria-activedescendantpattern. - Typeahead to allow focusing items by typing text.
- Keyboard navigation support including arrow keys, home/end, page up/down.
Installation
To use the menu machine in your project, run the following command in your command line:
This command will install the framework agnostic menu logic and the reactive utilities for your framework of choice.
Anatomy
To set up the menu correctly, you'll need to understand its anatomy and how we name its parts.
Each part includes a
data-partattribute to help identify them in the DOM.
On a high level, the menu consists of:
- Trigger: The element that toggles the menu.
- Positioner: The element that positions the menu dynamically.
- Content: The element that contains the menu items and groups.
- Item: The menu item used to trigger an action.
The optional parts include:
- Option Item: The menu item that acts as a radio or checkbox.
- Context Trigger: The trigger for the menu item.
- Separator: The element that is used to visually separate menu items.
Usage
First, import the menu package into your project
import * as menu from "@zag-js/menu"
The menu package exports two key functions:
machine— The state machine logic for the menu widget.connect— The function that translates the machine's state to JSX attributes and event handlers.
You'll need to provide a unique
idto theuseMachinehook. This is used to ensure that every part has a unique identifier.
Next, import the required hooks and functions for your framework and use the menu machine in your project 🔥
To show the menu when a trigger element is right-clicked, use the
contextTriggerProps provided by the menu's connect function.
Context menu's are also opened during a long-press of roughly 700ms when the
pointer is pen or touch.
Styling guide
Earlier, we mentioned that each menu part has a data-part attribute added to
them to select and style them in the DOM.
Focused item state
When an item is focused, via keyboard navigation or pointer, it is given a
data-focus attribute.
[data-part="item"][data-focus] { /* styles for focused state */ } [data-part="option-item"][data-focus] { /* styles for focused state */ }
Disabled item state
When an item or an option item is disabled, it is given a data-disabled
attribute.
[data-part="item"][data-disabled] { /* styles for disabled state */ } [data-part="option-item"][data-disabled] { /* styles for disabled state */ }
Using arrows
When using arrows within the menu, you can style it using css variables.
[data-part="arrow"] { --arrow-size: 20px; --arrow-background: red; }
Checked option item state
When an option item is checked, it is given a data-checked attribute.
[data-part="option-item"][data-checked] { /* styles for checked state */ }
Methods and Properties
The menu's api exposes the following methods:
isOpenbooleanWhether the menu is openopen() => voidFunction to open the menuclose() => voidFunction to close the menuhighlightedIdstringThe id of the currently highlighted menuitemsetHighlightedId(id: string) => voidFunction to set the highlighted menuitemsetParent(parent: Service) => voidFunction to register a parent menu. This is used for submenussetChild(child: Service) => voidFunction to register a child menu. This is used for submenusvalueRecord<string, string | string[]>The value of the menu options itemsetValue(name: string, value: any) => voidFunction to set the value of the menu options itemreposition(options?: Partial<PositioningOptions>) => voidFunction to reposition the popovergetOptionItemState(props: OptionItemProps) => OptionItemStateReturns the state of the option itemgetItemState(props: ItemProps) => ItemStateReturns the state of the menu item
Edit this page on GitHub