Native menu system, including application menus, context menus, and platform-specific UI components like Touch Bar.
Application and context menu management.
/**
* Create native application menus and context menus
*/
class Menu {
/** Sets the application menu in macOS. On Windows and Linux, the menu will be set as each window's top menu */
static setApplicationMenu(menu: Menu | null): void;
/** Returns the application menu, if set, or null, if not set */
static getApplicationMenu(): Menu | null;
/** Sends the action to the first responder of application. This is used for emulating default macOS menu behaviors */
static sendActionToFirstResponder(action: string): void;
/** Generally, the template is an array of options for constructing a MenuItem */
static buildFromTemplate(template: Array<MenuItemConstructorOptions | MenuItem>): Menu;
/** Pops up this menu as a context menu in the BrowserWindow */
popup(options?: PopupOptions): void;
/** Closes the context menu in the browserWindow */
closePopup(browserWindow?: BrowserWindow): void;
/** Appends the menuItem to the menu */
append(menuItem: MenuItem): void;
/** Returns the item with the specified id */
getMenuItemById(id: string): MenuItem | null;
/** Inserts the menuItem to the pos position of the menu */
insert(pos: number, menuItem: MenuItem): void;
/** A MenuItem[] array containing the menu's items */
readonly items: MenuItem[];
}Usage Examples:
const { Menu, MenuItem, BrowserWindow, app } = require('electron');
// Create application menu
function createApplicationMenu() {
const template = [
{
label: 'File',
submenu: [
{
label: 'New',
accelerator: 'CmdOrCtrl+N',
click: () => {
createNewDocument();
}
},
{
label: 'Open',
accelerator: 'CmdOrCtrl+O',
click: async () => {
await openFile();
}
},
{
label: 'Save',
accelerator: 'CmdOrCtrl+S',
click: () => {
saveFile();
}
},
{ type: 'separator' },
{
label: 'Exit',
accelerator: process.platform === 'darwin' ? 'Cmd+Q' : 'Ctrl+Q',
click: () => {
app.quit();
}
}
]
},
{
label: 'Edit',
submenu: [
{ role: 'undo' },
{ role: 'redo' },
{ type: 'separator' },
{ role: 'cut' },
{ role: 'copy' },
{ role: 'paste' },
{ role: 'selectall' }
]
},
{
label: 'View',
submenu: [
{ role: 'reload' },
{ role: 'forcereload' },
{ role: 'toggledevtools' },
{ type: 'separator' },
{ role: 'resetzoom' },
{ role: 'zoomin' },
{ role: 'zoomout' },
{ type: 'separator' },
{ role: 'togglefullscreen' }
]
},
{
label: 'Window',
submenu: [
{ role: 'minimize' },
{ role: 'close' }
]
}
];
// macOS specific menu adjustments
if (process.platform === 'darwin') {
template.unshift({
label: app.getName(),
submenu: [
{ role: 'about' },
{ type: 'separator' },
{ role: 'services' },
{ type: 'separator' },
{ role: 'hide' },
{ role: 'hideothers' },
{ role: 'unhide' },
{ type: 'separator' },
{ role: 'quit' }
]
});
// Window menu
template[4].submenu = [
{ role: 'close' },
{ role: 'minimize' },
{ role: 'zoom' },
{ type: 'separator' },
{ role: 'front' }
];
}
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
}
// Create context menu
function createContextMenu() {
const contextMenu = Menu.buildFromTemplate([
{
label: 'Copy',
accelerator: 'CmdOrCtrl+C',
click: () => {
clipboard.writeText(getSelectedText());
}
},
{
label: 'Paste',
accelerator: 'CmdOrCtrl+V',
click: () => {
insertText(clipboard.readText());
}
},
{ type: 'separator' },
{
label: 'Select All',
accelerator: 'CmdOrCtrl+A',
click: () => {
selectAll();
}
},
{ type: 'separator' },
{
label: 'Inspect Element',
click: (menuItem, browserWindow, event) => {
browserWindow.webContents.inspectElement(event.x, event.y);
}
}
]);
return contextMenu;
}
// Show context menu on right click
function setupContextMenu(window) {
window.webContents.on('context-menu', (event, params) => {
const contextMenu = createContextMenu();
contextMenu.popup({
window: window,
x: params.x,
y: params.y
});
});
}Individual menu items with various types and behaviors.
/**
* Add items to native application menus and context menus
*/
class MenuItem {
/** Create a new menu item */
constructor(options: MenuItemConstructorOptions);
/** A string indicating the visibility of the item */
enabled: boolean;
/** A boolean indicating whether the item is visible */
visible: boolean;
/** A boolean indicating whether the item is checked */
checked: boolean;
/** A string representing the menu items label */
label: string;
/** A function that is fired when the MenuItem receives a click event */
click: (menuItem: MenuItem, browserWindow: BrowserWindow | undefined, event: KeyboardEvent) => void;
/** A Menu that the item is a part of */
menu: Menu;
/** A Menu (optional) containing the menu item's submenu, if present */
submenu: Menu | undefined;
/** A string representing the menu item's type */
type: 'normal' | 'separator' | 'submenu' | 'checkbox' | 'radio';
/** A string (optional) representing the menu item's role */
role: MenuItemRole | undefined;
/** A string (optional) representing the menu item's accelerator */
accelerator: string | undefined;
/** A NativeImage (optional) that is displayed on the left of the menu item */
icon: NativeImage | undefined;
/** A string representing the item's sublabel */
sublabel: string;
/** A string representing the item's tooltip */
toolTip: string;
/** A string representing the item's id */
id: string;
}macOS Touch Bar support for MacBook Pro models.
/**
* Create TouchBar layouts for native macOS applications
*/
class TouchBar {
/** Create a new TouchBar with the specified items */
constructor(options: TouchBarConstructorOptions);
/** A string representing the description of the TouchBar */
static TouchBarButton: typeof TouchBarButton;
static TouchBarColorPicker: typeof TouchBarColorPicker;
static TouchBarGroup: typeof TouchBarGroup;
static TouchBarLabel: typeof TouchBarLabel;
static TouchBarPopover: typeof TouchBarPopover;
static TouchBarScrubber: typeof TouchBarScrubber;
static TouchBarSegmentedControl: typeof TouchBarSegmentedControl;
static TouchBarSlider: typeof TouchBarSlider;
static TouchBarSpacer: typeof TouchBarSpacer;
/** The escape item to replace the "esc" button on the touch bar */
escapeItem: TouchBarButton | TouchBarColorPicker | TouchBarGroup | TouchBarLabel | TouchBarPopover | TouchBarScrubber | TouchBarSegmentedControl | TouchBarSlider | TouchBarSpacer | null;
}
class TouchBarButton {
constructor(options: TouchBarButtonConstructorOptions);
label: string;
accessibilityLabel: string;
backgroundColor: string;
icon: NativeImage | undefined;
iconPosition: 'left' | 'right' | 'overlay';
enabled: boolean;
}
class TouchBarLabel {
constructor(options: TouchBarLabelConstructorOptions);
label: string;
accessibilityLabel: string;
textColor: string;
}
class TouchBarSpacer {
constructor(options: TouchBarSpacerConstructorOptions);
size: 'small' | 'large' | 'flexible';
}Usage Examples:
// macOS TouchBar setup
const { TouchBar } = require('electron');
const { TouchBarLabel, TouchBarButton, TouchBarSpacer } = TouchBar;
function setupTouchBar(window) {
if (process.platform !== 'darwin') return;
const touchBar = new TouchBar({
items: [
new TouchBarButton({
label: 'π Search',
backgroundColor: '#7851A9',
click: () => {
openSearchDialog();
}
}),
new TouchBarSpacer({ size: 'small' }),
new TouchBarButton({
label: 'π Open',
click: () => {
openFile();
}
}),
new TouchBarButton({
label: 'πΎ Save',
click: () => {
saveFile();
}
}),
new TouchBarSpacer({ size: 'flexible' }),
new TouchBarLabel({
label: 'Ready',
textColor: '#00FF00'
})
]
});
window.setTouchBar(touchBar);
}
// Dynamic TouchBar updates
function updateTouchBarStatus(window, status) {
const statusLabel = new TouchBarLabel({
label: status,
textColor: status === 'Error' ? '#FF0000' : '#00FF00'
});
const touchBar = new TouchBar({
items: [
new TouchBarButton({
label: 'π Refresh',
click: () => {
window.webContents.reload();
}
}),
new TouchBarSpacer({ size: 'flexible' }),
statusLabel
]
});
window.setTouchBar(touchBar);
}interface MenuItemConstructorOptions {
click?: (menuItem: MenuItem, browserWindow: BrowserWindow | undefined, event: KeyboardEvent) => void;
role?: MenuItemRole;
type?: 'normal' | 'separator' | 'submenu' | 'checkbox' | 'radio';
label?: string;
sublabel?: string;
toolTip?: string;
accelerator?: Accelerator;
icon?: NativeImage | string;
enabled?: boolean;
acceleratorWorksWhenHidden?: boolean;
visible?: boolean;
checked?: boolean;
registerAccelerator?: boolean;
sharingItem?: SharingItem;
submenu?: Array<MenuItemConstructorOptions | MenuItem> | Menu;
id?: string;
before?: string[];
after?: string[];
beforeGroupContaining?: string[];
afterGroupContaining?: string[];
}
type MenuItemRole =
| 'undo'
| 'redo'
| 'cut'
| 'copy'
| 'paste'
| 'pasteandmatchstyle'
| 'delete'
| 'selectall'
| 'reload'
| 'forcereload'
| 'toggledevtools'
| 'resetzoom'
| 'zoomin'
| 'zoomout'
| 'toggleSpellChecker'
| 'togglefullscreen'
| 'window'
| 'minimize'
| 'close'
| 'help'
| 'about'
| 'services'
| 'hide'
| 'hideothers'
| 'unhide'
| 'quit'
| 'startSpeaking'
| 'stopSpeaking'
| 'zoom'
| 'front'
| 'appMenu'
| 'fileMenu'
| 'editMenu'
| 'viewMenu'
| 'recentDocuments'
| 'toggleTabBar'
| 'selectNextTab'
| 'selectPreviousTab'
| 'mergeAllWindows'
| 'clearRecentDocuments'
| 'moveTabToNewWindow'
| 'windowMenu';
interface PopupOptions {
window?: BrowserWindow;
x?: number;
y?: number;
positioningItem?: number;
callback?: () => void;
}
interface SharingItem {
texts?: string[];
filePaths?: string[];
urls?: string[];
}
interface TouchBarConstructorOptions {
items?: Array<TouchBarButton | TouchBarColorPicker | TouchBarGroup | TouchBarLabel | TouchBarPopover | TouchBarScrubber | TouchBarSegmentedControl | TouchBarSlider | TouchBarSpacer>;
escapeItem?: TouchBarButton | TouchBarColorPicker | TouchBarGroup | TouchBarLabel | TouchBarPopover | TouchBarScrubber | TouchBarSegmentedControl | TouchBarSlider | TouchBarSpacer;
}
interface TouchBarButtonConstructorOptions {
label?: string;
accessibilityLabel?: string;
backgroundColor?: string;
icon?: NativeImage | string;
iconPosition?: 'left' | 'right' | 'overlay';
enabled?: boolean;
click?: () => void;
}
interface TouchBarLabelConstructorOptions {
label?: string;
accessibilityLabel?: string;
textColor?: string;
}
interface TouchBarSpacerConstructorOptions {
size?: 'small' | 'large' | 'flexible';
}
type Accelerator = string;