CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-theia--core

Core framework for building cloud and desktop IDE applications using modern web technologies with TypeScript and dependency injection.

Pending
Overview
Eval results
Files

menus.mddocs/

Menus

Theia's menu system provides hierarchical menu management with dynamic contributions, context menus, and command integration for building comprehensive application interfaces.

Capabilities

Menu Model Registry

Central registry for menu structure and menu items.

/**
 * Registry for menu models and actions
 */
interface MenuModelRegistry {
    /**
     * Register menu action
     * @param menuPath - Path to menu location
     * @param item - Menu action to register
     * @returns Disposable to unregister
     */
    registerMenuAction(menuPath: MenuPath, item: MenuAction): Disposable;
    
    /**
     * Register submenu
     * @param menuPath - Path to parent menu
     * @param label - Submenu label
     * @returns Menu path for the new submenu
     */
    registerSubmenu(menuPath: MenuPath, label: string): MenuPath;
    
    /**
     * Get menu model for path
     * @param menuPath - Menu path
     * @returns Menu model
     */
    getMenu(menuPath: MenuPath): CompositeMenuNode;
    
    /**
     * Get all menu paths
     * @returns Array of menu paths
     */
    getMenuPaths(): MenuPath[];
}

/**
 * Service token for MenuModelRegistry
 */
const MenuModelRegistry: symbol;

Menu Paths

Hierarchical menu location identifiers.

/**
 * Menu path array for identifying menu locations
 */
type MenuPath = string[];

/**
 * Common menu paths
 */
namespace MenuPaths {
    /** File menu */
    const File: MenuPath;
    
    /** Edit menu */
    const Edit: MenuPath;
    
    /** View menu */
    const View: MenuPath;
    
    /** Help menu */
    const Help: MenuPath;
}

Menu Actions

Individual menu items that execute commands.

/**
 * Menu action definition
 */
interface MenuAction {
    /** Command to execute */
    commandId: string;
    
    /** Display label (overrides command label) */
    label?: string;
    
    /** Icon CSS class */
    icon?: string;
    
    /** Menu item order/priority */
    order?: string;
    
    /** Alt text for accessibility */
    alt?: string;
    
    /** When clause for conditional display */
    when?: string;
    
    /** Group for menu organization */
    group?: string;
}

Usage Example:

import { injectable, inject } from "@theia/core";
import { MenuModelRegistry, MenuAction } from "@theia/core/lib/common";

@injectable()
export class MyMenuContribution {
    constructor(
        @inject(MenuModelRegistry) 
        private readonly menus: MenuModelRegistry
    ) {}
    
    registerMenus(): void {
        // Register action in File menu
        const openAction: MenuAction = {
            commandId: 'my-extension.open-file',
            label: 'Open Special File',
            icon: 'fa fa-file-o',
            order: '1',
            group: 'file'
        };
        
        this.menus.registerMenuAction(['file'], openAction);
        
        // Create submenu
        const mySubmenu = this.menus.registerSubmenu(['view'], 'My Extension');
        
        // Add actions to submenu
        this.menus.registerMenuAction(mySubmenu, {
            commandId: 'my-extension.show-panel',
            label: 'Show Panel',
            order: '1'
        });
        
        this.menus.registerMenuAction(mySubmenu, {
            commandId: 'my-extension.settings', 
            label: 'Settings',
            order: '2'
        });
    }
}

Menu Nodes

Menu structure representation.

/**
 * Base menu node interface
 */
interface MenuNode {
    /** Node identifier */
    readonly id: string;
    
    /** Display label */
    readonly label?: string;
    
    /** Icon CSS class */
    readonly icon?: string;
    
    /** Sort string for ordering */
    readonly sortString?: string;
    
    /** When clause for visibility */
    readonly when?: string;
}

/**
 * Composite menu node containing child nodes
 */
interface CompositeMenuNode extends MenuNode {
    /** Child menu nodes */
    readonly children: MenuNode[];
    
    /** True if node has children */
    readonly hasChildren: boolean;
}

/**
 * Action menu node that executes commands
 */
interface ActionMenuNode extends MenuNode {
    /** Command to execute */
    readonly command: string;
    
    /** Command arguments */
    readonly args?: any[];
    
    /** Alt text */
    readonly alt?: string;
}

Context Menus

Dynamic context menus for widgets and UI elements.

/**
 * Context menu renderer interface
 */
interface ContextMenuRenderer {
    /**
     * Render context menu
     * @param menuPath - Menu path
     * @param anchor - Anchor element or coordinates
     * @param onHide - Callback when menu hides
     */
    render(
        menuPath: MenuPath,
        anchor: Element | { x: number; y: number },
        onHide?: () => void
    ): Promise<void>;
}

/**
 * Service token for ContextMenuRenderer
 */
const ContextMenuRenderer: symbol;

Usage Example:

import { inject, injectable } from "@theia/core";
import { ContextMenuRenderer } from "@theia/core/lib/browser";

@injectable()
export class MyWidget {
    constructor(
        @inject(ContextMenuRenderer)
        private readonly contextMenuRenderer: ContextMenuRenderer
    ) {}
    
    private handleContextMenu(event: MouseEvent): void {
        event.preventDefault();
        
        // Render context menu at mouse position
        this.contextMenuRenderer.render(
            ['my-widget-context'],
            { x: event.clientX, y: event.clientY }
        );
    }
    
    private setupContextMenu(): void {
        // Register context menu items
        this.menus.registerMenuAction(['my-widget-context'], {
            commandId: 'my-widget.copy',
            label: 'Copy',
            order: '1'
        });
        
        this.menus.registerMenuAction(['my-widget-context'], {
            commandId: 'my-widget.paste',
            label: 'Paste', 
            order: '2'
        });
    }
}

Menu Contribution

Extension point for contributing menus.

/**
 * Menu contribution interface
 */
interface MenuContribution {
    /**
     * Register menus
     * @param menus - Menu model registry
     */
    registerMenus(menus: MenuModelRegistry): void;
}

/**
 * Service token for MenuContribution
 */
const MenuContribution: symbol;

Advanced Features

Conditional Menus

Menus that appear based on context conditions.

// Register conditional menu action
this.menus.registerMenuAction(['edit'], {
    commandId: 'editor.action.rename',
    label: 'Rename Symbol',
    when: 'editorHasRenameProvider && editorTextFocus'
});

Menu Groups

Organize menu items into logical groups with separators.

// Actions in same group appear together
this.menus.registerMenuAction(['file'], {
    commandId: 'file.new',
    group: 'new',
    order: '1'
});

this.menus.registerMenuAction(['file'], {
    commandId: 'file.open',
    group: 'new', 
    order: '2'
});

// Different group creates separator
this.menus.registerMenuAction(['file'], {
    commandId: 'file.save',
    group: 'save',
    order: '1'
});

Types

/**
 * Menu-related type definitions
 */
type MenuItemRole = 'normal' | 'separator' | 'submenu';

interface MenuOptions {
    role?: MenuItemRole;
    type?: 'normal' | 'separator' | 'submenu' | 'checkbox' | 'radio';
    checked?: boolean;
    enabled?: boolean;
    visible?: boolean;
}

type MenuCallback = () => void;

Install with Tessl CLI

npx tessl i tessl/npm-theia--core

docs

application-framework.md

commands.md

dependency-injection.md

events-messaging.md

index.md

keybindings.md

menus.md

preferences-configuration.md

resources-files.md

widgets-ui.md

tile.json