UNPKG

monaco-editor

Version:
140 lines (139 loc) 7 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { ActionBar } from '../actionbar/actionbar.js'; import { DropdownMenuActionViewItem } from '../dropdown/dropdownActionViewItem.js'; import { Action, SubmenuAction } from '../../../common/actions.js'; import { Codicon } from '../../../common/codicons.js'; import { ThemeIcon } from '../../../common/themables.js'; import { EventMultiplexer } from '../../../common/event.js'; import { Disposable, DisposableStore } from '../../../common/lifecycle.js'; import './toolbar.css'; import * as nls from '../../../../nls.js'; import { createInstantHoverDelegate } from '../hover/hoverDelegateFactory.js'; /** * A widget that combines an action bar for primary actions and a dropdown for secondary actions. */ export class ToolBar extends Disposable { constructor(container, contextMenuProvider, options = { orientation: 0 /* ActionsOrientation.HORIZONTAL */ }) { super(); this.submenuActionViewItems = []; this.hasSecondaryActions = false; this._onDidChangeDropdownVisibility = this._register(new EventMultiplexer()); this.onDidChangeDropdownVisibility = this._onDidChangeDropdownVisibility.event; this.disposables = this._register(new DisposableStore()); options.hoverDelegate = options.hoverDelegate ?? this._register(createInstantHoverDelegate()); this.options = options; this.toggleMenuAction = this._register(new ToggleMenuAction(() => this.toggleMenuActionViewItem?.show(), options.toggleMenuTitle)); this.element = document.createElement('div'); this.element.className = 'monaco-toolbar'; container.appendChild(this.element); this.actionBar = this._register(new ActionBar(this.element, { orientation: options.orientation, ariaLabel: options.ariaLabel, actionRunner: options.actionRunner, allowContextMenu: options.allowContextMenu, highlightToggledItems: options.highlightToggledItems, hoverDelegate: options.hoverDelegate, actionViewItemProvider: (action, viewItemOptions) => { if (action.id === ToggleMenuAction.ID) { this.toggleMenuActionViewItem = new DropdownMenuActionViewItem(action, action.menuActions, contextMenuProvider, { actionViewItemProvider: this.options.actionViewItemProvider, actionRunner: this.actionRunner, keybindingProvider: this.options.getKeyBinding, classNames: ThemeIcon.asClassNameArray(options.moreIcon ?? Codicon.toolBarMore), anchorAlignmentProvider: this.options.anchorAlignmentProvider, menuAsChild: !!this.options.renderDropdownAsChildElement, skipTelemetry: this.options.skipTelemetry, isMenu: true, hoverDelegate: this.options.hoverDelegate }); this.toggleMenuActionViewItem.setActionContext(this.actionBar.context); this.disposables.add(this._onDidChangeDropdownVisibility.add(this.toggleMenuActionViewItem.onDidChangeVisibility)); return this.toggleMenuActionViewItem; } if (options.actionViewItemProvider) { const result = options.actionViewItemProvider(action, viewItemOptions); if (result) { return result; } } if (action instanceof SubmenuAction) { const result = new DropdownMenuActionViewItem(action, action.actions, contextMenuProvider, { actionViewItemProvider: this.options.actionViewItemProvider, actionRunner: this.actionRunner, keybindingProvider: this.options.getKeyBinding, classNames: action.class, anchorAlignmentProvider: this.options.anchorAlignmentProvider, menuAsChild: !!this.options.renderDropdownAsChildElement, skipTelemetry: this.options.skipTelemetry, hoverDelegate: this.options.hoverDelegate }); result.setActionContext(this.actionBar.context); this.submenuActionViewItems.push(result); this.disposables.add(this._onDidChangeDropdownVisibility.add(result.onDidChangeVisibility)); return result; } return undefined; } })); } set actionRunner(actionRunner) { this.actionBar.actionRunner = actionRunner; } get actionRunner() { return this.actionBar.actionRunner; } getElement() { return this.element; } getItemAction(indexOrElement) { return this.actionBar.getAction(indexOrElement); } setActions(primaryActions, secondaryActions) { this.clear(); const primaryActionsToSet = primaryActions ? primaryActions.slice(0) : []; // Inject additional action to open secondary actions if present this.hasSecondaryActions = !!(secondaryActions && secondaryActions.length > 0); if (this.hasSecondaryActions && secondaryActions) { this.toggleMenuAction.menuActions = secondaryActions.slice(0); primaryActionsToSet.push(this.toggleMenuAction); } primaryActionsToSet.forEach(action => { this.actionBar.push(action, { icon: this.options.icon ?? true, label: this.options.label ?? false, keybinding: this.getKeybindingLabel(action) }); }); } getKeybindingLabel(action) { const key = this.options.getKeyBinding?.(action); return key?.getLabel() ?? undefined; } clear() { this.submenuActionViewItems = []; this.disposables.clear(); this.actionBar.clear(); } dispose() { this.clear(); this.disposables.dispose(); super.dispose(); } } export class ToggleMenuAction extends Action { static { this.ID = 'toolbar.toggle.more'; } constructor(toggleDropdownMenu, title) { title = title || nls.localize('moreActions', "More Actions..."); super(ToggleMenuAction.ID, title, undefined, true); this._menuActions = []; this.toggleDropdownMenu = toggleDropdownMenu; } async run() { this.toggleDropdownMenu(); } get menuActions() { return this._menuActions; } set menuActions(actions) { this._menuActions = actions; } }