or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

app-lifecycle.mddevelopment.mdindex.mdipc.mdmenu-system.mdnetwork-protocols.mdplatform-features.mdsecurity.mdsystem-integration.mdwindow-management.md
tile.json

menu-system.mddocs/

Menu System

Native menu system, including application menus, context menus, and platform-specific UI components like Touch Bar.

Capabilities

Menu

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
    });
  });
}

MenuItem

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;
}

TouchBar (macOS)

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);
}

Types

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;