UNPKG

monaco-editor-core

Version:

A browser based code editor

108 lines (107 loc) 4.59 kB
import { $, append } from '../../dom.js'; import { BaseActionViewItem } from '../actionbar/actionViewItems.js'; import { DropdownMenu } from './dropdown.js'; import { Emitter } from '../../../common/event.js'; import './dropdown.css'; import { getDefaultHoverDelegate } from '../hover/hoverDelegateFactory.js'; import { getBaseLayerHoverDelegate } from '../hover/hoverDelegate2.js'; export class DropdownMenuActionViewItem extends BaseActionViewItem { constructor(action, menuActionsOrProvider, contextMenuProvider, options = Object.create(null)) { super(null, action, options); this.actionItem = null; this._onDidChangeVisibility = this._register(new Emitter()); this.onDidChangeVisibility = this._onDidChangeVisibility.event; this.menuActionsOrProvider = menuActionsOrProvider; this.contextMenuProvider = contextMenuProvider; this.options = options; if (this.options.actionRunner) { this.actionRunner = this.options.actionRunner; } } render(container) { this.actionItem = container; const labelRenderer = (el) => { this.element = append(el, $('a.action-label')); let classNames = []; if (typeof this.options.classNames === 'string') { classNames = this.options.classNames.split(/\s+/g).filter(s => !!s); } else if (this.options.classNames) { classNames = this.options.classNames; } // todo@aeschli: remove codicon, should come through `this.options.classNames` if (!classNames.find(c => c === 'icon')) { classNames.push('codicon'); } this.element.classList.add(...classNames); this.element.setAttribute('role', 'button'); this.element.setAttribute('aria-haspopup', 'true'); this.element.setAttribute('aria-expanded', 'false'); if (this._action.label) { this._register(getBaseLayerHoverDelegate().setupManagedHover(this.options.hoverDelegate ?? getDefaultHoverDelegate('mouse'), this.element, this._action.label)); } this.element.ariaLabel = this._action.label || ''; return null; }; const isActionsArray = Array.isArray(this.menuActionsOrProvider); const options = { contextMenuProvider: this.contextMenuProvider, labelRenderer: labelRenderer, menuAsChild: this.options.menuAsChild, actions: isActionsArray ? this.menuActionsOrProvider : undefined, actionProvider: isActionsArray ? undefined : this.menuActionsOrProvider, skipTelemetry: this.options.skipTelemetry }; this.dropdownMenu = this._register(new DropdownMenu(container, options)); this._register(this.dropdownMenu.onDidChangeVisibility(visible => { this.element?.setAttribute('aria-expanded', `${visible}`); this._onDidChangeVisibility.fire(visible); })); this.dropdownMenu.menuOptions = { actionViewItemProvider: this.options.actionViewItemProvider, actionRunner: this.actionRunner, getKeyBinding: this.options.keybindingProvider, context: this._context }; if (this.options.anchorAlignmentProvider) { const that = this; this.dropdownMenu.menuOptions = { ...this.dropdownMenu.menuOptions, get anchorAlignment() { return that.options.anchorAlignmentProvider(); } }; } this.updateTooltip(); this.updateEnabled(); } getTooltip() { let title = null; if (this.action.tooltip) { title = this.action.tooltip; } else if (this.action.label) { title = this.action.label; } return title ?? undefined; } setActionContext(newContext) { super.setActionContext(newContext); if (this.dropdownMenu) { if (this.dropdownMenu.menuOptions) { this.dropdownMenu.menuOptions.context = newContext; } else { this.dropdownMenu.menuOptions = { context: newContext }; } } } show() { this.dropdownMenu?.show(); } updateEnabled() { const disabled = !this.action.enabled; this.actionItem?.classList.toggle('disabled', disabled); this.element?.classList.toggle('disabled', disabled); } }