Skip to main content
The Menu class provides a way to create context menus and dropdown menus that can be displayed at specific positions or in response to mouse events.

Overview

Menus are commonly used for:
  • Right-click context menus
  • Dropdown menus in custom UI elements
  • Action menus with multiple options
  • File/folder context menus

Constructor

const menu = new Menu();
Creates a new menu instance. The menu starts empty and must be populated with items before being shown.

Methods

addItem

Add a menu item to the menu.
addItem(cb: (item: MenuItem) => any): this
cb
function
required
A callback function that receives a MenuItem instance to configure
return
Menu
Returns the menu instance for chaining

Example

const menu = new Menu();

menu.addItem((item) => {
  item
    .setTitle('Open in new tab')
    .setIcon('lucide-external-link')
    .onClick(() => {
      console.log('Opening in new tab');
    });
});

addSeparator

Add a visual separator between menu items.
addSeparator(): this
return
Menu
Returns the menu instance for chaining

Example

menu
  .addItem((item) => item.setTitle('Copy'))
  .addItem((item) => item.setTitle('Cut'))
  .addSeparator()
  .addItem((item) => item.setTitle('Delete').setWarning(true));

showAtMouseEvent

Display the menu at the position of a mouse event.
showAtMouseEvent(evt: MouseEvent): this
evt
MouseEvent
required
The mouse event to position the menu at (typically a right-click event)
return
Menu
Returns the menu instance for chaining

Example

class MyPlugin extends Plugin {
  onload() {
    this.registerDomEvent(document, 'contextmenu', (evt) => {
      const menu = new Menu();
      
      menu.addItem((item) => {
        item
          .setTitle('Custom action')
          .setIcon('lucide-star')
          .onClick(() => {
            new Notice('Custom action clicked!');
          });
      });
      
      menu.showAtMouseEvent(evt);
    });
  }
}

showAtPosition

Display the menu at a specific position on screen.
showAtPosition(position: MenuPositionDef, doc?: Document): this
position
MenuPositionDef
required
An object defining the position and display options for the menu
doc
Document
Optional document object (useful for popout windows)
return
Menu
Returns the menu instance for chaining
x
number
required
Horizontal position in pixels
y
number
required
Vertical position in pixels
width
number
Width of the menu in pixels
overlap
boolean
Whether the menu can overlap the target position
left
boolean
Whether to align the menu to the left

Example

const menu = new Menu();
menu.addItem((item) => item.setTitle('Option 1'));

menu.showAtPosition({ x: 100, y: 200 });

hide

Hide the menu.
hide(): this
return
Menu
Returns the menu instance for chaining

close

Close the menu (alias for hide).
close(): void

onHide

Register a callback to be called when the menu is hidden.
onHide(callback: () => any): void
callback
function
required
Function to call when the menu is hidden

Example

const menu = new Menu();
menu.onHide(() => {
  console.log('Menu was closed');
});

setNoIcon

Prevent icons from being displayed in menu items.
setNoIcon(): this
return
Menu
Returns the menu instance for chaining

setUseNativeMenu

Force the menu to use native or DOM rendering (desktop only).
setUseNativeMenu(useNativeMenu: boolean): this
useNativeMenu
boolean
required
Whether to use native menu rendering
return
Menu
Returns the menu instance for chaining

Static Methods

forEvent

Create a menu for a pointer or mouse event (since 1.6.0).
static forEvent(evt: PointerEvent | MouseEvent): Menu
evt
PointerEvent | MouseEvent
required
The event to create a menu for
return
Menu
A new Menu instance
Menu items are configured through the MenuItem class, which provides methods to customize their appearance and behavior.

setTitle

Set the title text of the menu item.
setTitle(title: string | DocumentFragment): this
title
string | DocumentFragment
required
The title text or DocumentFragment to display

setIcon

Set an icon for the menu item.
setIcon(icon: IconName | null): this
icon
IconName | null
required
The icon ID (from Lucide or custom icons), or null to remove the icon

setChecked

Set the checked state of the menu item.
setChecked(checked: boolean | null): this
checked
boolean | null
required
Whether the item should appear checked (true), unchecked (false), or neutral (null)

setDisabled

Disable or enable the menu item.
setDisabled(disabled: boolean): this
disabled
boolean
required
Whether the item should be disabled

setWarning

Set the warning state (typically displays in red).
setWarning(isWarning: boolean): this
isWarning
boolean
required
Whether to enable the warning state

setIsLabel

Set whether the item is a label (non-clickable).
setIsLabel(isLabel: boolean): this
isLabel
boolean
required
Whether the item should be a label

onClick

Set the click handler for the menu item.
onClick(callback: (evt: MouseEvent | KeyboardEvent) => any): this
callback
function
required
Function to call when the item is clicked or activated via keyboard

setSection

Set the section this menu item belongs to.
setSection(section: string): this
section
string
required
The section ID. Inspect DOM elements to find existing section IDs in Obsidian menus

Complete Example

class MyPlugin extends Plugin {
  onload() {
    // Add a command that shows a menu
    this.addCommand({
      id: 'show-custom-menu',
      name: 'Show custom menu',
      callback: () => {
        this.showCustomMenu();
      }
    });
    
    // Add right-click menu to files
    this.registerEvent(
      this.app.workspace.on('file-menu', (menu, file) => {
        menu.addItem((item) => {
          item
            .setTitle('Process file')
            .setIcon('lucide-zap')
            .onClick(async () => {
              await this.processFile(file);
            });
        });
      })
    );
  }
  
  showCustomMenu() {
    const menu = new Menu();
    
    menu.addItem((item) => {
      item
        .setTitle('Create note')
        .setIcon('lucide-file-plus')
        .onClick(() => {
          new Notice('Creating note...');
        });
    });
    
    menu.addItem((item) => {
      item
        .setTitle('Import data')
        .setIcon('lucide-download')
        .onClick(() => {
          new Notice('Importing data...');
        });
    });
    
    menu.addSeparator();
    
    menu.addItem((item) => {
      item
        .setTitle('Delete all')
        .setIcon('lucide-trash')
        .setWarning(true)
        .onClick(() => {
          new Notice('Deleting all...');
        });
    });
    
    menu.showAtMouseEvent(window.event as MouseEvent);
  }
  
  async processFile(file: TFile) {
    // Process the file
    new Notice(`Processing ${file.name}`);
  }
}

See Also

Build docs developers (and LLMs) love