Getting StartedComponentsDesign TokensThemingTheme SynthesizerFrameworksAccessibilityUtilitiesServer RenderingBrowser SupportContributingChangelogApp ShellAspect GridAuth ShellCenterContainerDashboard GridFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbarAnchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkStepper NavTabsTop BarTree ViewAccordionAspect RatioAvatarAvatar GroupCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSkeletonSpinnerStackVideoVirtual ListActivity HeatmapAnimated NumberBadgeBar ListChartClockComparisonCountdown TimerData GridDescription ListDiffGaugeJSON TreeKanbanLevel MeterListMeterSparklineStatStepperTagTimelineUptimeValue CardWaveformBlockquoteCode BlockCode GroupGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriterButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerField ListFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree SelectAlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuHover CardLoading OverlayNotification PanelPopoverProgressSheetToastTooltip
ARC UIARC Radiant Components
v4.9DocsComponentsTokensSynthesizer
Getting StartedFrameworksServer RenderingDesign TokensThemingTheme SynthesizerTypographyUtilitiesAll ComponentsAccessibilityBrowser SupportChangelogContributingStatsApp ShellAspect GridAuth ShellCenterContainerDashboard GridFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbarAnchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkStepper NavTabsTop BarTree ViewAccordionAspect RatioAvatarAvatar GroupCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSkeletonSpinnerStackVideoVirtual ListActivity HeatmapAnimated NumberBadgeBar ListChartClockComparisonCountdown TimerData GridDescription ListDiffGaugeJSON TreeKanbanLevel MeterListMeterSparklineStatStepperTagTimelineUptimeValue CardWaveformBlockquoteCode BlockCode GroupGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriterButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerField ListFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree SelectAlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuHover CardLoading OverlayNotification PanelPopoverProgressSheetToastTooltip

Menubar

Desktop-application-style menu bar (File / Edit / View) with nested submenus, keyboard shortcuts display, and full WAI-ARIA menubar keyboard navigation.

ComponentsMenubar
navigationinteractivebeta
<arc-menubar>

Overview

Menubar renders the horizontal command bar familiar from desktop applications: a row of top-level menus like File, Edit, and View, each opening a vertical dropdown of commands. The entire structure is data-driven: assign an array to the `items` property via JavaScript and the component renders triggers, menus, submenus, dividers, and right-aligned keyboard shortcut hints. Menu entries can nest one further level: an item with its own `items` array becomes a submenu parent, rendered with a caret indicator. Submenus open to the right of their parent item and automatically flip to the left when they would overflow the viewport. Entries with `{ divider: true }` render as separator lines, `disabled` entries are skipped by keyboard navigation, and `shortcut` strings display in muted monospace (display only: the component does not bind global hotkeys). Interaction follows the WAI-ARIA menubar pattern faithfully. The bar exposes a single tab stop with roving focus: ArrowLeft/ArrowRight move across top-level items, ArrowDown or Enter opens a menu, ArrowUp opens it focused on the last item. Inside menus, arrows move and wrap past dividers and disabled items, ArrowRight enters a submenu, ArrowLeft steps back out (or over to the previous top-level menu), typeahead jumps to items by first letter, and Escape unwinds one level at a time, restoring focus to the trigger. With the pointer, clicking a trigger toggles its menu, hovering other triggers switches menus once one is open, and hovering a submenu parent opens it after a short delay. Activating a leaf fires `arc-select` with the full label path from root to leaf.

Guidelines

When to use

  • Assign `items` via JavaScript. It is a property, not an HTML attribute
  • Group related commands with `{ divider: true }` entries, mirroring desktop app conventions
  • Use `shortcut` strings that match your actual key bindings. The menubar displays them but you must register the hotkeys yourself
  • Keep top-level labels to single words (File, Edit, View) so the bar scans like a native app
  • Listen to `arc-select` and branch on the label path array to route commands

When not to use

  • Do not use Menubar for site navigation. Use navigation-menu or top-bar; menubars are for application commands
  • Do not nest submenus more than one level below a menu. Deep chains are hard to traverse with a pointer
  • Do not put destructive actions directly next to common ones without a divider between them
  • Do not rely on shortcut hints as functionality. They are display-only text
  • Avoid more than 7-8 top-level menus; consolidate rare commands into a submenu instead

Features

  • Data-driven: one `items` array describes triggers, menus, submenus, dividers, shortcuts, and disabled states
  • Faithful WAI-ARIA menubar pattern: `role="menubar"`, `role="menu"`, `role="menuitem"`, roving tabindex with a single tab stop
  • Full 2D keyboard navigation: arrows in both axes, Home/End, Enter/Space, Escape unwinding one level at a time
  • Typeahead: printable characters jump to the next matching item in the open menu, or across the menubar when closed
  • Standard menubar pointer behavior: click to toggle, hover to switch open menus, ~150ms hover-intent delay on submenus
  • Submenus flip from right to left automatically when they would overflow the viewport
  • `arc-select` event carries the full label path from root to leaf (e.g. `["File", "Export", "PNG"]`)
  • CSS parts for `bar`, `trigger`, `menu`, `item`, and `shortcut` enable external styling

Preview

selected: —

Usage

This component requires JavaScript. No pure HTML/CSS version is available. Use the Web Component directly or a framework wrapper.

<arc-menubar id="app-menubar"></arc-menubar>

<script>
  const menubar = document.getElementById('app-menubar');
  menubar.items = [
    { label: 'File', items: [
      { label: 'New File', shortcut: '⌘N' },
      { label: 'Open…', shortcut: '⌘O' },
      { divider: true },
      { label: 'Export', items: [
        { label: 'PNG' },
        { label: 'SVG' }
      ] }
    ] },
    { label: 'Edit', items: [
      { label: 'Undo', shortcut: '⌘Z' },
      { label: 'Redo', shortcut: '⇧⌘Z', disabled: true }
    ] }
  ];

  menubar.addEventListener('arc-select', (e) => {
    console.log('command:', e.detail.path); // e.g. ['File', 'Export', 'PNG']
  });
</script>

API

itemsArray<{label:string,disabled?:boolean,items:Array<{label?:string,shortcut?:string,disabled?:boolean,divider?:boolean,items?:Array<{label:string,shortcut?:string,disabled?:boolean}>}>}>[]
The menu structure. Entries with an items array become submenus (one further nesting level supported); { divider: true } renders a separator. Set as a property, or as a JSON attribute for a menu structure that is static.

Events

arc-select
Fired when a leaf menu item is activated. detail.path is the array of labels from the top-level menu to the selected leaf, e.g. ["File", "Export", "PNG"].

See Also