Menubar
A desktop application menu bar presenting a horizontal strip of top-level menus with full keyboard navigation.
import { Menubar, MenubarMenu } from "@glint/components/menubar.slint";import { Tokens } from "@glint/theme/tokens.slint";import { IconSet } from "@lucide";
export component Demo inherits Window { width: 560px; height: 320px; background: Tokens.color-background;
in-out property <string> last-action: "None";
VerticalLayout { alignment: start; spacing: 24px; padding: 16px;
Menubar { menus: [ { label: "File", items: [ { label: "New Window", icon: IconSet.AppWindow, shortcut: "Ctrl+Shift+N" }, { label: "New File", icon: IconSet.FilePlus, shortcut: "Ctrl+N" }, { label: "Open Recent", separator-before: true, children: [ { label: "project-a" }, { label: "workspace-b" }, ]}, { label: "Exit", separator-before: true, shortcut: "Ctrl+Q" } ] }, { label: "Edit", items: [ { label: "Undo", icon: IconSet.Undo, shortcut: "Ctrl+Z" }, { label: "Redo", icon: IconSet.Redo, shortcut: "Ctrl+Y" }, { label: "Cut", separator-before: true, icon: IconSet.Scissors, shortcut: "Ctrl+X" }, { label: "Copy", icon: IconSet.Copy, shortcut: "Ctrl+C" }, { label: "Paste", icon: IconSet.Clipboard, shortcut: "Ctrl+V" }, ] }, { label: "View", items: [ { label: "Full Screen", shortcut: "F11", checkable: true, checked: false }, { label: "Show Minimap", checkable: true, checked: true }, ] } ]; selected(menu, item, child) => { root.last-action = "Menu " + menu + ", Item " + item + (child >= 0 ? (", Subitem " + child) : ""); } }
VerticalLayout { alignment: center; spacing: 8px;
Text { text: "Desktop Application Menu Bar"; color: Tokens.color-foreground; font-size: Tokens.typography-body-size; horizontal-alignment: center; }
Text { text: "Last action: " + root.last-action; color: Tokens.color-muted-foreground; font-size: Tokens.typography-body-sm-size; horizontal-alignment: center; } } }}Usage
import { Menubar, MenubarMenu } from "@glint/components/menubar.slint";
export component AppWindow inherits Window { Menubar { menus: [ { label: "File", items: [ { label: "New File", shortcut: "Ctrl+N" }, { label: "Save", shortcut: "Ctrl+S" }, ] }, { label: "Edit", items: [ { label: "Undo", shortcut: "Ctrl+Z" }, { label: "Redo", shortcut: "Ctrl+Y" }, ] } ]; selected(menu, item, child) => { // handle selection } }}Menubar renders a top-level application menu bar from an array of MenubarMenu structs.
Each menu item contains a label for the top bar and an array of MenuEntry items for the popup menu, powered by MenuPanel and following the grouped rows model.
The keyboard traversal matches desktop standards: Tab enters the menu bar, ←/→ step across top-level triggers (and switch between open menus if one is expanded), ↓ or Enter opens the focused menu, and Escape closes the active menu.
Examples
Nested submenus and positioning
Submenus cascade beside the parent item when children are present. Use submenu-side (PanelSide.right, PanelSide.left) and submenu-align (PanelAlign.start, PanelAlign.center, PanelAlign.end) to position nested panels.
import { Menubar } from "@glint/components/menubar.slint";import { PanelSide, PanelAlign } from "@glint/components/panel.slint";import { Tokens } from "@glint/theme/tokens.slint";import { IconSet } from "@lucide";
export component Demo inherits Window { width: 560px; height: 320px; background: Tokens.color-background;
VerticalLayout { padding: 16px;
Menubar { submenu-side: PanelSide.right; submenu-align: PanelAlign.start; menus: [ { label: "Preferences", items: [ { label: "Themes", icon: IconSet.Palette, children: [ { label: "Dark Modern" }, { label: "Light Plus" }, { label: "High Contrast" }, ] }, { label: "Font Size", icon: IconSet.Type, children: [ { label: "Small (12px)" }, { label: "Medium (14px)" }, { label: "Large (16px)" }, ] } ] } ]; } }}Checkbox and radio options across menus
Menu rows can hold independent checkable toggles or grouped radio options. Changes update the menus property reactively.
import { Menubar, MenubarMenu } from "@glint/components/menubar.slint";import { Tokens } from "@glint/theme/tokens.slint";
export component Demo inherits Window { width: 560px; height: 320px; background: Tokens.color-background;
in-out property <[MenubarMenu]> app-menus: [ { label: "Layout", items: [ { label: "Single Column", checkable: true, checked: true, radio-group: "layout" }, { label: "Two Columns", checkable: true, checked: false, radio-group: "layout" }, { label: "Grid View", checkable: true, checked: false, radio-group: "layout" }, { label: "Show Status Bar", separator-before: true, checkable: true, checked: true }, ] } ];
VerticalLayout { padding: 16px;
Menubar { menus <=> root.app-menus; } }}Custom menu width floor
Use min-content-width to establish the minimum width for dropdown panels across all top-level menus. Panels automatically grow wider if any row requires more horizontal space.
import { Menubar } from "@glint/components/menubar.slint";import { Tokens } from "@glint/theme/tokens.slint";
export component Demo inherits Window { width: 560px; height: 320px; background: Tokens.color-background;
VerticalLayout { padding: 16px;
Menubar { min-content-width: 260px; menus: [ { label: "Navigation", items: [ { label: "Go to Symbol in Workspace…", shortcut: "Ctrl+T" }, { label: "Go to Line / Column…", shortcut: "Ctrl+G" }, ] } ]; } }}API Reference
Properties
| Property | Type | Default | Description |
|---|---|---|---|
menus | in-out [MenubarMenu] | no default | Top-level menus (File / Edit / View / …), each with its own items. in-out because activating a checkbox or radio row writes its new checked back here. |
min-content-width | in length | 200px | The floor under every open menu's panel width; a panel grows past it to fit its widest row, icon and shortcut hint included. |
submenu-side | in PanelSide | PanelSide.right | Where a row's submenu panel opens: which side of the menu, and how it lines up against the row it hangs off. A submenu opens beside its row, so top and bottom read as right. |
submenu-align | in PanelAlign | PanelAlign.start | |
highlighted-index | in-out int | 0 | Row highlighted by ↑/↓ inside the currently-open popup. |
focused-index | in-out int | 0 | Trigger the keyboard stands on; consumers rarely set this. |
Callbacks
| Callback | Description |
|---|---|
selected(int , int , int) | Fired with the menu index, the chosen row's index, and the index of the submenu leaf that was taken or -1 when the row itself was; the popup closes. |
Enums
| Enum | Values |
|---|---|
PanelSide | top, right, bottom, left |
PanelAlign | start, center, end |
Accessibility
- Top-level menu bar semantics. Each trigger in the horizontal bar is an accessible button announcing the menu label and whether that menu is expanded (
accessible-expanded). - Menu item semantics. Open menus render as accessible list structures where items carry their index, name, checkable state, and shortcut descriptions.
- Keyboard navigation. Tab navigates into the bar. ←/→ move focus between menu triggers, automatically opening adjacent menus if a menu is already open. ↑/↓ navigate within an open menu. Escape closes open submenus and top-level menus.
- Focus ring. Menu triggers display a standard theme focus ring when navigated via keyboard.