monaco-editor-core
Version:
A browser based code editor
108 lines (107 loc) • 4.59 kB
JavaScript
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);
}
}