Skip to content

Early previewhamur is not on npm yet. The components are being built in the open, follow along on GitHub.

MenusReact

Menubar

A menu bar with commands and options for your application, as in a desktop app.

Rendered by React 19.3.1

import { Menu } from '@hamur/react/menu'
import { Menubar } from '@hamur/react/menubar'

const menus = [
  { label: 'File', items: ['New file', 'Open...', 'Save'] },
  { label: 'Edit', items: ['Undo', 'Redo', 'Cut', 'Copy', 'Paste'] },
  { label: 'View', items: ['Zoom in', 'Zoom out', 'Full screen'] },
]

export default function MenubarExample() {
  return (
    <Menubar style={{ display: 'flex', gap: 4 }}>
      {menus.map((menu) => (
        <Menu.Root key={menu.label}>
          <Menu.Trigger className="button">{menu.label}</Menu.Trigger>
          <Menu.Portal>
            <Menu.Positioner sideOffset={6}>
              <Menu.Popup className="menu">
                {menu.items.map((item) => (
                  <Menu.Item key={item} className="menu-item">
                    {item}
                  </Menu.Item>
                ))}
              </Menu.Popup>
            </Menu.Positioner>
          </Menu.Portal>
        </Menu.Root>
      ))}
    </Menubar>
  )
}
198Tests passing in React · 0 failing
8.0 KiBSize
Not measured yetMemory
Not measured yetSpeed
productdevbook and 13 upstream authors8 commits · last

Installation

npm i @hamur/react

Not on npm yet. The package goes out under the chosen name.

Anatomy

Import the component and assemble its parts:

<Menubar />

Examples

The demo at the top is the one example this component has so far.

API reference

4 props across 1 parts, in React syntax. className, style, render are listed once, under Shared props.

MenubarMenubar

The container for menus.

Menubar props
PropTypeDefault
loopFocusWhether to loop keyboard focus back to the first itembooleantrue
modalWhether the menubar is modal.booleantrue
disabledWhether the whole menubar is disabled.booleanfalse
orientationThe orientation of the menubar.MenuRootOrientation'horizontal'
Menubar data attributes
Data attributeDescription
data-modalPresent when the corresponding menubar is modal.
data-orientationDetermines the orientation of the menubar.
data-has-submenu-openPresent when any submenu within the menubar is open.

Shared props

Every part that renders an element takes these.

Shared props
PropType
classNameCSS class applied to the element, or a function that returns a class based on the component's state.string | ((state: State) => string | undefined)
styleStyle applied to the element, or a function that returns a style object based on the component's state.React.CSSProperties | ((state: State) => React.CSSProperties | undefined)
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, State>

Keyboard and accessibility

Keyboard

Keyboard
KeysDoesPart
ArrowLeftArrowRightMoves between the menus' triggersMenubar
HomeEndMoves to the first or last triggerMenubar
SpaceOpens the focused menuMenubar
ArrowDownArrowUpMoves through the open menu's itemsMenubar
ArrowLeftArrowRightWith a menu open, opens the previous or next menu insteadMenubar
ArrowRightOpens a submenuMenubar
ArrowLeftCloses a submenu and returns focus to its triggerMenubar
EscapeCloses the open menuMenubar

Accessibility

What the parts set
PartSetsSo that
Menubarrole="menubar", aria-orientationa screen reader announces a menu bar and which arrow keys move in it
Menubargives each Menu trigger inside role="menuitem"the triggers are read as the bar's items

Focus order

  1. The menubar is one tab stop: the last focused trigger, or the first.
  2. Arrow keys move between triggers; with a menu open, they move into and across menus.
  3. Escape closes the menu and leaves focus on its trigger.