Menu holds a short list of actions behind a key. Rows are 40 px with an optional glyph at the start and a Kbd shortcut at the end; the highlighted row takes the hover face and a 4 px ink bar, so it reads without colour. Checkbox and radio items, group labels, separators and submenus are parts of the same file.
Example#
Usage#
Use a menu for a short list of actions behind one key: duplicate, flag, archive. The trigger is a Button or an IconButton; rows are 40 px with an optional glyph and a keyboard shortcut.
- Parts.
MenuItem,MenuCheckboxItem,MenuRadioGroupwithMenuRadioItem,MenuGroupwithMenuLabel,MenuSeparatorandMenuSubmenufor one level of nesting. - Keyboard. Arrows move, letters jump, Enter or Space activates, the right arrow opens a submenu and Escape closes.
- The highlighted row takes the hover face and a 4 px ink bar at its start, so it reads without colour.
- Navigation is a list of links or the Navbar, not a menu. Choosing a value in a form is a
Selector aCombobox.
Recipe: view settings with check and radio items#
"use client";
import {
Menu, MenuCheckboxItem, MenuContent, MenuGroup, MenuLabel,
MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuTrigger,
} from "@maxgrits/overprint-react/menu";
export function ViewMenu() {
return (
<Menu>
<MenuTrigger size="sm">View</MenuTrigger>
<MenuContent>
<MenuGroup>
<MenuLabel>Show</MenuLabel>
<MenuCheckboxItem defaultChecked>Archived projects</MenuCheckboxItem>
<MenuCheckboxItem>Private notes</MenuCheckboxItem>
</MenuGroup>
<MenuSeparator />
<MenuRadioGroup defaultValue="week">
<MenuLabel>Group by</MenuLabel>
<MenuRadioItem value="week">Week</MenuRadioItem>
<MenuRadioItem value="client">Client</MenuRadioItem>
</MenuRadioGroup>
</MenuContent>
</Menu>
);
}Check and radio items keep the menu open after a press, so several settings can change in one visit; Escape or a press outside closes it.
Anatomy#
- PlateRaised surface, 2 px rule, 200 px at least.
.mk-menu-popup - Group labelLabel role in the second ink.
.mk-menu-label - GlyphOptional, 18 px, from the shape alphabet.
.mk-menu-item-start - LabelRow-title type, a verb.
.mk-menu-item-label - ShortcutKbd caps for the keys.
.mk-menu-item-end - Separator2 px soft rule between groups.
.mk-menu-separator
Volume#
Reading layer: identical at every volume.
Quiet
Studio
Press
Rave
Content#
- Items are verbs: "Duplicate", "Archive", "Flag for review".
- Put the most common action first and destructive ones last, after a separator.
- An action that cannot be undone says so in a confirming dialog, not in the menu label.
Do and don't#
Do
Don't
A menu of twelve items in three submenus.
Accessibility#
- The APG menu pattern through Base UI: arrows, Home and End, typeahead, Enter and Space, Escape back to the trigger, Tab closes and moves on.
- The trigger carries
aria-haspopup="menu"; checkbox and radio items carryaria-checked. - It portals with its trigger's scope; reduced motion keeps only the fade.
| Keys | What happens |
|---|---|
| EnterorSpaceorArrow Down | On the trigger: opens the menu on its first item |
| Arrow UporArrow Down | Moves between items |
| HomeorEnd | First or last item |
| A letter | Moves to the next item starting with it |
| EnterorSpace | Chooses the item |
| Arrow RightorArrow Left | Opens or closes a submenu |
| Escape | Closes the menu; focus returns to the trigger |
| Tab | Closes the menu and moves on |
The colour pairs it prints, with their contrast on both papers:
| Text | Surface | Role | Bone | Night |
|---|---|---|---|---|
--mk-text | --mk-surface-raised | ui | not in this look | not in this look |
--mk-text | --mk-hover | ui | not in this look | not in this look |
Props#
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | none | |
defaultOpen | boolean | none | |
onOpenChange | ((open: boolean) => void) | none | |
modal | boolean | true | A modal menu locks the page while open (default true, Base UI's). |
children required | ReactNode | none |
Tokens#
System tokens (18)
--mk-border--mk-dur-menu--mk-dur-reduced--mk-ease-out--mk-font-text--mk-hover--mk-radius-plate--mk-rule--mk-rule-soft--mk-shadow-menu--mk-space-1--mk-space-2--mk-space-3--mk-surface-raised--mk-text--mk-text-disabled--mk-type-body-ui-size--mk-z-popover
Its own properties (5)
--mk-menu-leading--mk-menu-pad--mk-menu-row--mk-menu-start--mk-menu-start-gap
Changelog#
Arrived in 0.9.0.
ComboboxandComboboxItem(a case- and accent-insensitive filter by default, groups, chips formultiple, "Searching…", an empty message, a live result count, andinlinefor a list printed in place),PopoverwithPopoverTrigger,PopoverContentandPopoverClose,Menuwith its eleven parts (shortcuts asKbdcaps, checkbox and radio items, group labels, separators, submenus), andToastProviderwithuseToast(a slab pill, one at a time with three waiting, 5.2 s with a drain bar that holds while the region is hovered, focused or the window is away). Read the whole entry