Menu

Component for displaying lists of links or actions that the user can take.

Import#

import { Menu } from '@volue/wave-react';
// you may also access Menu's context via hook:
// import { useMenuContext } from '@volue/wave-react';

Menu is a compound component that consists of multiple parts to help you create all kinds of menus:

  • Menu: The wrapper that contains all the parts of a menu and provides context for its children.
  • Menu.Trigger: The trigger that toggles the menu.
  • Menu.Icon: The default chevron icon used as an open/close indicator.
  • Menu.ContextTrigger: A wrapper around the target area that opens the context menu upon right-clicking.
  • Menu.Content: The container that pops out when the menu is open.
  • Menu.Group: The container used to group multiple, related menu items.
  • Menu.Label: The component that renders the label of Menu.Group.
  • Menu.Item: A single item of the menu.
  • Menu.CheckboxItem: A single item of the menu that acts as a checkbox.
  • Menu.RadioGroup: A wrapper for a group of mutually exclusive radio menu items.
  • Menu.RadioItem: A single item of the menu that acts as a radio button and participates in a Menu.RadioGroup.
  • Menu.Separator: The component that renders a horizontal divider between menu items and groups.

Examples#

Basic#

Menu works in an uncontrolled way by default, meaning each Menu component instance is responsible for managing its own state internally.

Controlled Menu#

You can easily make the menu controlled, by passing your own state to isOpen prop. onIsOpenChange handler is called when the state of the menu changes, allowing you to sync state.

Menu items#

Use the Menu.Item component to configure Menu options.

By passing the startElement prop, you can add icon to each Menu.Item to help clarify the intent of the item's action. To add a command (or hotkey) to menu item, you can use the endElement prop.

Use onSelect handler that is triggered on click and enter + space key down to add interactivity to the Menu.Item.

To prevent the user from interacting with the Menu.Item, use isDisabled property. This will make the item unselectable via keyboard navigation, and it will be skipped when pressing the up/down arrows.

For destructive actions such as deleting something, you can set the menu item's intent to danger. When using this feature, you may want to consider providing a confirmation via a Dialog component.

Groups and labels#

Related items can be grouped inside Menu.Group. Use Menu.Label component, to render an accessible label for the menu group.

To visualy divide groups of items in the menu, use Menu.Separator .

With a custom trigger#

You can choose to have a different trigger for the Menu depending on the application's context.

Placement#

By default the menu will be placed below your trigger if it can fit, but this can be customised via the placement prop. For example, when the trigger is right-aligned within its container, you can set the placement to bottom right.

Menu is using Positioner internally to dynamically position it's content based on the available space. The passed position might get overwritten by smart positioning when necessary.

Sizes#

Use the size prop to control the size of the Menu.Content. medium and small sizes are available, with the medium size used by default

Item overflow#

When there are many items in a menu it will grow to a maximum height and the overflowing items will be scrollable.

You can use css prop to control the maxWidth of the menu content. Long labels will be truncated to avoid blowing out the content.

Typeahead search#

When focus is on the Menu.Trigger or within the Menu.Content and you type a letter key, a search begins. Focus will move to the first Menu.Item that starts with the letter you typed.

When user repeats typed character focus cycles among items that starts with the typed character. Try it with following example and repeatedly type character c.

If the content of Menu.Item is too complex or non-textual, pass the textValue property to Menu.Item to indicate that the text will be used for typeahead purposes.

Context menu#

To display a menu located at the pointer, triggered by a right-click or a long-press, wrap the area that should open the context menu with Menu.ContextTrigger.

Single selection#

You can render a list of menu items as radios to allow users to make a single selection. Menu radio items must be used inside Menu.RadioGroup.

Consider using specialized Single Select Menu component to handle selection.

Menu component is carrying accessibility/semantic of a WAI-ARIA Menu Button design pattern, while Single Select Menu follows WAI ARIA Listbox pattern.

Multiple selection#

You can render a list of menu items as checkboxes to allow users to select multiple items at a time.

Consider using specialized Multi Select Menu component to handle multi-selection.


Accessibility#

Menu implements the WAI-ARIA Menu Button design pattern.

  • All relevant ARIA attributes are automatically managed.

  • Menu trigger can be focused with Tab or Shift + Tab

  • Mouse click, Space, Enter or opens the menu.

  • After triggering the menu with keyboard, focus is set to the first menu item.

  • Clicking outside the menu content or pressing ESC closes the menu and sets focus to the menu trigger.

  • When menu is opened, and keys move the focus among non-disabled menu items. Focus movement is managed using roving focus technique.

  • When menu is opened, Home and Page Up moves focus to the first item.

  • When menu is opened, End and Page Down moves focus to the last item.

  • Enter or Space activates the menu item and closes the menu.
  • When menu is opened, typing any printable character moves focus to the first menu item that matches the typed character. Typing multiple keys in quick succession results in moving focus to the first item that matches the full string. If the same character is typed in succession, focus cycles among the items starting with that character.

  • When menu is opened and needs scrolling, scroll behavior is enclosed only to the opened menu.

  • The menu content is portaled (via Portal utility) to the end of document.body to break it out of the source order.


API Reference#

Menu#

Prop
Type
Default
isOpen
boolean
false
defaultIsOpen
boolean
No default value
onIsOpenChange
function
No default value

Menu.Trigger#

Prop
Type
Default
as
enum
button
css
StitchesCss
No default value

Menu.ContextTrigger#

Prop
Type
Default
as
enum
span
css
StitchesCss
No default value

Menu.Icon#

Prop
Type
Default
css
StitchesCss
No default value

Menu.Content#

Prop
Type
Default
as
enum
div
css
StitchesCss
No default value
placement
enum
"bottom_left"
size
enum
medium
anchorOffset
number
8
onExitComplete
function
() => void
onPointerDownOutside
function
No default value
loop
boolean
false

Menu.Group#

Prop
Type
Default
as
enum
div
css
StitchesCss
No default value

Menu.Label#

Prop
Type
Default
as
enum
div
css
StitchesCss
No default value

Menu.Item#

Prop
Type
Default
as
enum
div
css
StitchesCss
No default value
isDisabled
boolean
false
textValue
string
No default value
onSelect
function
No default value
startElement
React.ReactElement
No default value
endElement
React.ReactElement
No default value
intent
enum
No default value

Menu.CheckboxItem#

The Menu.CheckboxItem extends all the Menu.Item properties and adds the following ones:

Prop
Type
Default
isChecked
boolean
No default value
onIsCheckedChange
function
No default value

Menu.RadioGroup#

The Menu.RadioGroup extends all the Menu.Group properties and adds the following ones:

Prop
Type
Default
value
string
No default value
onValueChange
function
No default value

Menu.RadioItem#

The Menu.RadioItem extends all the Menu.Item properties and adds the following ones:

Prop
Type
Default
value*
string
No default value

Menu.Separator#

Prop
Type
Default
as
enum
div
css
StitchesCss
No default value