UNPKG

@jupyterlab/ui-components

Version:

JupyterLab - UI components written in React

297 lines 8.39 kB
// Copyright (c) Jupyter Development Team. // Distributed under the terms of the Modified BSD License. /* global WeakRef */ import { ArrayExt } from '@lumino/algorithm'; import { DisposableDelegate } from '@lumino/disposable'; import { Signal } from '@lumino/signaling'; import { Menu } from '@lumino/widgets'; /** * Namespace for JupyterLabMenu interfaces */ export var IRankedMenu; (function (IRankedMenu) { /** * Default menu item rank */ IRankedMenu.DEFAULT_RANK = 100; })(IRankedMenu || (IRankedMenu = {})); /** * An extensible menu for JupyterLab application menus. */ export class RankedMenu extends Menu { /** * Construct a new menu. * * @param options - Options for the lumino menu. */ constructor(options) { var _a; super(options); this._ranks = []; this.addClass('jp-ThemedContainer'); this._rank = options.rank; this._includeSeparators = (_a = options.includeSeparators) !== null && _a !== void 0 ? _a : true; } /** * Menu rank. */ get rank() { return this._rank; } /** * Add a group of menu items specific to a particular * plugin. * * The rank can be set for all items in the group using the * function argument or per item. * * @param items - the list of menu items to add. * @param rank - the default rank in the menu in which to insert the group. * @returns Disposable of the group */ addGroup(items, rank) { if (items.length === 0) { return new DisposableDelegate(() => void 0); } const defaultRank = rank !== null && rank !== void 0 ? rank : IRankedMenu.DEFAULT_RANK; const sortedItems = items .map(item => { var _a; return { ...item, rank: (_a = item.rank) !== null && _a !== void 0 ? _a : defaultRank }; }) .sort((a, b) => a.rank - b.rank); // Insert the plugin group into the menu. let insertIndex = this._ranks.findIndex(rank => sortedItems[0].rank < rank); if (insertIndex < 0) { insertIndex = this._ranks.length; // Insert at the end of the menu } // Keep an array of the menu items that have been created. const added = []; // Insert a separator before the group. // Lumino takes care of superfluous leading, // trailing, and duplicate separators. if (this._includeSeparators) { added.push(this.insertItem(insertIndex++, { type: 'separator', rank: defaultRank })); } // Insert the group. added.push(...sortedItems.map(item => { return this.insertItem(insertIndex++, item); })); // Insert a separator after the group. if (this._includeSeparators) { added.push(this.insertItem(insertIndex++, { type: 'separator', rank: defaultRank })); } return new DisposableDelegate(() => { added.forEach(i => i.dispose()); }); } /** * Add a menu item to the end of the menu. * * @param options - The options for creating the menu item. * * @returns The menu item added to the menu. */ addItem(options) { let insertIndex = -1; if (options.rank) { insertIndex = this._ranks.findIndex(rank => options.rank < rank); } if (insertIndex < 0) { insertIndex = this._ranks.length; // Insert at the end of the menu } return this.insertItem(insertIndex, options); } /** * Remove all menu items from the menu. */ clearItems() { this._ranks.length = 0; super.clearItems(); } /** * Dispose of the resources held by the menu. */ dispose() { this._ranks.length = 0; super.dispose(); } /** * Get the rank of the item at index. * * @param index Item index. * @returns Rank of the item. */ getRankAt(index) { return this._ranks[index]; } /** * Insert a menu item into the menu at the specified index. * * @param index - The index at which to insert the item. * * @param options - The options for creating the menu item. * * @returns The menu item added to the menu. * * #### Notes * The index will be clamped to the bounds of the items. */ insertItem(index, options) { var _a, _b; const clampedIndex = Math.max(0, Math.min(index, this._ranks.length)); ArrayExt.insert(this._ranks, clampedIndex, (_a = options.rank) !== null && _a !== void 0 ? _a : Math.max(IRankedMenu.DEFAULT_RANK, (_b = this._ranks[this._ranks.length - 1]) !== null && _b !== void 0 ? _b : IRankedMenu.DEFAULT_RANK)); const item = super.insertItem(clampedIndex, options); return new DisposableMenuItem(item, this); } /** * Remove the item at a given index from the menu. * * @param index - The index of the item to remove. * * #### Notes * This is a no-op if the index is out of range. */ removeItemAt(index) { ArrayExt.removeAt(this._ranks, index); super.removeItemAt(index); } } /** * Disposable Menu Item */ class DisposableMenuItem { /** * Create a disposable menu item from an item and the menu it belongs to * * @param item Menu item * @param menu Menu */ constructor(item, menu) { this._item = new WeakRef(item); this._menu = menu; // dispose this item if the parent menu is disposed const dispose = (menu) => { menu.disposed.disconnect(dispose, this); this.dispose(); }; this._menu.disposed.connect(dispose, this); } /** * Whether the menu item is disposed or not. */ get isDisposed() { return this._isDisposed; } /** * The type of the menu item. */ get type() { return this._item.deref().type; } /** * The command to execute when the item is triggered. */ get command() { return this._item.deref().command; } /** * The arguments for the command. */ get args() { return this._item.deref().args; } /** * The submenu for a `'submenu'` type item. */ get submenu() { return this._item.deref().submenu; } /** * The display label for the menu item. */ get label() { return this._item.deref().label; } /** * The mnemonic index for the menu item. */ get mnemonic() { return this._item.deref().mnemonic; } /** * The icon renderer for the menu item. */ get icon() { return this._item.deref().icon; } /** * The icon class for the menu item. */ get iconClass() { return this._item.deref().iconClass; } /** * The icon label for the menu item. */ get iconLabel() { return this._item.deref().iconLabel; } /** * The display caption for the menu item. */ get caption() { return this._item.deref().caption; } /** * The extra class name for the menu item. */ get className() { return this._item.deref().className; } /** * The dataset for the menu item. */ get dataset() { return this._item.deref().dataset; } /** * Whether the menu item is enabled. */ get isEnabled() { return this._item.deref().isEnabled; } /** * Whether the menu item is toggled. */ get isToggled() { return this._item.deref().isToggled; } /** * Whether the menu item is visible. */ get isVisible() { return this._item.deref().isVisible; } /** * The key binding for the menu item. */ get keyBinding() { return this._item.deref().keyBinding; } /** * Dispose the menu item by removing it from its menu. */ dispose() { if (this._isDisposed) { return; } this._isDisposed = true; const item = this._item.deref(); if (item && !this._menu.isDisposed) { this._menu.removeItem(item); } Signal.clearData(this); } } //# sourceMappingURL=menu.js.map