Logo

Menubar

Persistent application menu built on dropdown-menu primitives with groups, checkbox and radio items, submenus, shortcuts, icons, and RTL support.

Preview

Usage

TS

import { FrMenubarModule } from '@frame-ui-ng/components/menubar';

HTML

<div frMenuBar>
  <div frMenuBarMenu>
    <button [frMenuBarTrigger]="fileMenu" type="button">File</button>

    <ng-template #fileMenu="frMenuBarContent" frMenuBarContent>
      <div frMenuBarPanel>
        <button frMenuBarItem type="button">
          New Tab
          <span frMenuBarShortcut>⌘T</span>
        </button>
        <button frMenuBarItem type="button">New Window</button>
        <div frMenuBarSeparator></div>
        <button frMenuBarItem type="button">Share</button>
        <button frMenuBarItem type="button">
          Print
          <span frMenuBarShortcut>⌘P</span>
        </button>
      </div>
    </ng-template>
  </div>
</div>

Examples

Basic

Use menubar menus for persistent desktop-style command groups such as File, Edit, View, and Profiles.

Checkbox

Use checkbox items for independent view or formatting toggles.

Radio

Use radio groups for exclusive selections such as profiles or themes.

Submenu

Use submenus for nested command branches that should stay attached to the active menubar panel.

With Icons

Add icons to menu rows when the actions benefit from fast scanning.

RTL support

Menubar triggers and overlay content inherit document direction and support aligned RTL panels.

Custom Styling

Override menubar tokens for the persistent shell and trigger state, and dropdown-menu tokens for the opened panels.

Token Inspector

Inspect the menubar shell and trigger tokens alongside the inherited dropdown-menu panel and item tokens.

File

Design Tokens

Menubar defines tokens for the persistent horizontal shell and trigger states. Opened panels intentionally reuse the dropdown-menu token contract.

SCSS


  --frame-menubar-bg: var(--frame-surface);
  --frame-menubar-color: var(--frame-surface-foreground);
  --frame-menubar-border: var(--frame-border);
  --frame-menubar-radius: var(--frame-radius-md);
  --frame-menubar-padding: 0.25rem;
  --frame-menubar-gap: 0.25rem;
  --frame-menubar-shadow: none;
  --frame-menubar-trigger-height: 2rem;
  --frame-menubar-trigger-padding-x: 0.75rem;
  --frame-menubar-trigger-gap: 0.375rem;
  --frame-menubar-trigger-radius: calc(var(--frame-menubar-radius) - 0.125rem);
  --frame-menubar-trigger-font-size: 0.875rem;
  --frame-menubar-trigger-font-weight: 500;
  --frame-menubar-trigger-bg: transparent;
  --frame-menubar-trigger-color: var(--frame-menubar-color);
  --frame-menubar-trigger-hover-bg: color-mix(in srgb, var(--frame-accent) 48%, transparent);
  --frame-menubar-trigger-hover-color: var(--frame-menubar-color);
  --frame-menubar-trigger-open-bg: var(--frame-accent);
  --frame-menubar-trigger-open-color: var(--frame-accent-foreground);
  --frame-menubar-trigger-focus-shadow: 0 0 0 3px color-mix(in srgb, var(--frame-ring) 24%, transparent);