Menu
Preview appears after the next Storybook update.
<Menu />When to use
Use it for
- More than two or three actions on one item: show the main one as a button and the rest in a Menu.
- View options: checkable items for columns, a radio group for sort order.
- A submenu for one level of grouping (Move to group, then the groups).
- Leading icons when they help scanning (Rename, Duplicate, Delete): pass icon, a Lucide icon or an element like a brand mark. Put icons on every item of the menu or on none; labels stay aligned either way.
Not for
- Choosing a value for a form field: use Select or Combobox, which work with Field and forms.
- Navigation between pages: use links in the sidebar or tabs.
- Two actions: show both as buttons.
Do and don't
Every example is rendered with the real component, so it always matches what ships.
Destructive items last, after a separator
Distance from routine actions prevents slips. The danger tone backs up the verb.
Icons on all items or on none
Labels stay aligned either way, but a mix reads as noise.
Submenus inside submenus
Two levels deep loses keyboard and pointer users alike. Flatten with groups.
Accessibility
- Base UI Menu: the trigger has aria-haspopup and aria-expanded; the popup is role menu with menuitem, menuitemcheckbox and menuitemradio children.
- ArrowDown or Enter opens it and focuses the first item; arrows move, Home and End jump, typing a letter jumps to a matching item.
- Enter and Space activate; checkable items toggle aria-checked and keep the menu open.
- ArrowRight opens a submenu, ArrowLeft and Escape close it; Escape on the root returns focus to the trigger.
- Shortcut hints are visual only (aria-hidden); bind the shortcut yourself and document it elsewhere.
- Disabled items stay in the list so users learn the action exists, but cannot be activated.
Content guidelines
- Items are verbs in sentence case: "Rename", "Duplicate", "Delete token".
- Options are nouns: "Last updated", "Usage".
- Group labels are short nouns: "Columns", "Sort by".
- No ellipsis on items, even when they open a dialog: the dialog title says what happens next.
From the code Generated from the component, not editable here.
Anatomy and tokens
Read from packages/react/src/components/Menu/Menu.module.css at build time. Every value is a token: open one to see its alias chain in both themes.
- Positioning layer (layer.popover, above a Dialog)
.positioner - Surface (popup.*)
.popup - Surface (popup.*)
.popup[data-ending-style] - Item (menu.item.*, height from menu.item-height density token)
.item - Item (menu.item.*, height from menu.item-height density token)
.item[data-highlighted], .submenuTrigger[data-popup-open] - Item (menu.item.*, height from menu.item-height density token), focus
.item:focus-visible - Item (menu.item.*, height from menu.item-height density token)
.item[data-disabled] - Danger tone
.danger - Icon or indicator slot
.leading - Shortcut hint
.shortcut - Submenu chevron
.chevron - Check or radio indicator (ink)
.indicator - Radio dot
.radioDot - Group label
.groupLabel - Separator
.separator
Motion and interaction
Menu animates on open and close. Try it in the preview at the top.
| When | What changes | Duration | Easing |
|---|---|---|---|
| Open | Fade and movement | motion.duration.fast150 ms | motion.easing.enterstarts fast, lands softly |
| Close | Fade and movement | motion.duration.fast150 ms | motion.easing.exitstarts softly, leaves fast |
With reduced motion turned on, every change happens at once.
From the code Generated from the component, not editable here.
Props
Parsed from the TypeScript types in packages/react/src/components/Menu/Menu.tsx, so this table cannot drift from the code.
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | none | No description in the code yet. |
defaultOpen | boolean | none | No description in the code yet. |
onOpenChange | (open: boolean) => void | none | No description in the code yet. |
loopFocus | boolean | true | Wrap focus from the last item to the first. Default true. |
children | ReactNode | none | MenuTrigger and MenuContent. |
Comes with MenuRadioGroup, MenuGroup, MenuSeparator, MenuSubmenu, each accepting native <div> attributes.
Playground
Menu has no typed options to play with: it is a container. Compose it with MenuRadioGroup, MenuGroup, MenuSeparator, MenuSubmenu and any native attribute. Here it is in both themes.
Workbench
For contributors: every state with the accessibility panel, in the component workbench (Storybook). The stories double as visual test fixtures; the guidance on this page is the user documentation (open Menu in Storybook).
Embed Storybook stories here (5)
Loads from https://bridge-storybook.floriangouloubi.com (set STORYBOOK_URL at build time). If Storybook is not running, the frames stay empty.
Actions
RowOverflow
CheckableItems
AllStates
AllStatesCheckable
From the code Generated from the component, not editable here.
Changelog
- New
The measure now writes the Figma sets drawn under a component's folder as their own entries, so Claude can fix them: popups drawn open (Dialog/Popup, AlertDialog/Popup, Drawer/Popup, Menu/Popup, Popover/Popup, Tooltip/Popup, and Select/Popup or Combobox/Popup, measured open when the stories show them closed) and sets that fix a prop (Pagination/Full, Pagination/Compact, Progress/Linear)
v1.0.0, Nov 11, 2026
- New
Exploration page "..." menu: Rename (the pull request title and the exploration's name in its body, the branch and preview link unchanged) and Back to exploring (undoes Done exploring while no developer has pushed since: the developer section and the done marker leave the body, the
explorationlabel comes back,ready-for-devsgoes; a refused label write still succeeds through the body)v1.0.0, Nov 11, 2026
- New
Overlays: Dialog (sizes, scrolling body, footer, close last in focus order), AlertDialog (destructive confirmations, async confirm), Drawer (start, end, bottom with swipe), Popover, Tooltip with TooltipProvider, Menu (icons, shortcuts, groups, submenus, checkbox and radio items, danger items)
v1.0.0, Nov 11, 2026
- New
Invite collaborators: a dialog from the team menu and Settings that takes several work emails, a role picker (Can view, Can edit, Reviewer as Designer or Developer, Admin) and lists who has access with Resend
v1.0.0, Nov 11, 2026
- New
Studio: "Create a new team" in the team chip menu now opens a dialog over the page instead of leaving for the launcher on Studio home, so you keep your place
v1.0.0, Nov 11, 2026
- New
Studio Branches is all the work: the summary banner, the tabs and the status menu are gone
v1.0.0, Nov 11, 2026
- Fix
bridge specs --measuremeasures the item, not its group: when a story renders a set's component inside its parent (a radio in its fieldset, a menu item in its open menu), the measure reads the element with the Figma set's root class, opening the popup if neededv1.0.0, Nov 11, 2026
- Fix
Component specs match the code in two places the generator misread: menu parts drawn alone take the popup's snug line height, and the page header title takes its desktop (h1) size, as width media queries are now read at the 1200 px the code images use
v1.0.0, Nov 11, 2026
- Fix
Select and Combobox: the highlighted option's corners now follow the popup's corners, like Menu items
v1.0.0, Nov 11, 2026
- Fix
Menu: the item highlight is concentric with the popup corners
v1.0.0, Nov 11, 2026
- Fix
Studio: the account menu and other dropdown menus no longer make their button jump when they open
v1.0.0, Nov 11, 2026
- Fix
Exploration page: the More actions menu has icons, and Archive sits last, apart, in the danger tone
v1.0.0, Nov 11, 2026
- Fix
Invite collaborators, role picker (board I2): "They review as" now stacks its two cards, each one line with its drawing, name and what it reviews (Designer, How it looks and works; Developer, How it is built), in a slightly wider menu
v1.0.0, Nov 11, 2026
- Fix
Design lead is a box under the roles in Settings, Members, where people look for it, not an item of the row's menu
v1.0.0, Nov 11, 2026
- Fix
A team whose repository was renamed or moved to another owner now shows once, by its current name and with the higher role, in "Your teams" (the team menu), the "Use Bridge in Claude" and "Connect Figma" pickers, and the account's teams
v1.0.0, Nov 11, 2026
- Fix
One face per email member everywhere: the account menu, the header, Members, the invite dialog, exploration cards and rows, the review page and an exploration's activity all draw the face of the member's name (
~name), never their email, a row index, the Bridge app's avatar or a GitHub account that happens to share their namev1.0.0, Nov 11, 2026
- Fix
Studio shows the theme switch in the top bar again, in the same place as the Library, instead of hiding it in the account menu
v1.0.0, Nov 11, 2026
- Fix
Studio Components: one family menu instead of nine chips (17 interactive elements on the first screen)
v1.0.0, Nov 11, 2026
- Fix
Click targets: token rows (name, copy, menu, uses chip), the Studio row menu, the logo link, changelog refs and Quality actions are at least 32px tall; standalone links at least 24px
v1.0.0, Nov 11, 2026
- Fix
Studio Tokens: a page header and one toolbar row (filter field "Filter N tokens", type chips with counts, one Options menu for collections, usage, brand and modes, columns and exact match, then New token), and the table at full width with Name, Light and Dark
v1.0.0, Nov 11, 2026