Files
blockly/core/menuitem.ts
dependabot[bot] 2546b01d70 chore(deps): Bump prettier from 2.8.8 to 3.0.0 (#7322)
* chore(deps): Bump prettier from 2.8.8 to 3.0.0

Bumps [prettier](https://github.com/prettier/prettier) from 2.8.8 to 3.0.0.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/2.8.8...3.0.0)

---
updated-dependencies:
- dependency-name: prettier
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore: Reformat using Prettier v3.0 defaults

The main change is to add trailing commas to the last line of
block-formatted function calls.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Christopher Allen <cpcallen+git@google.com>
2023-07-25 14:56:10 +00:00

253 lines
6.1 KiB
TypeScript

/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* Blockly menu item similar to Closure's goog.ui.MenuItem
*
* @class
*/
import * as goog from '../closure/goog/goog.js';
goog.declareModuleId('Blockly.MenuItem');
import * as aria from './utils/aria.js';
import * as dom from './utils/dom.js';
import * as idGenerator from './utils/idgenerator.js';
/**
* Class representing an item in a menu.
*/
export class MenuItem {
/** Is the menu item clickable, as opposed to greyed-out. */
private enabled = true;
/** The DOM element for the menu item. */
private element: HTMLDivElement | null = null;
/** Whether the menu item is rendered right-to-left. */
private rightToLeft = false;
/** ARIA name for this menu. */
private roleName: aria.Role | null = null;
/** Is this menu item checkable. */
private checkable = false;
/** Is this menu item currently checked. */
private checked = false;
/** Is this menu item currently highlighted. */
private highlight = false;
/** Bound function to call when this menu item is clicked. */
private actionHandler: Function | null = null;
/**
* @param content Text caption to display as the content of the item, or a
* HTML element to display.
* @param opt_value Data/model associated with the menu item.
*/
constructor(
private readonly content: string | HTMLElement,
private readonly opt_value?: string,
) {}
/**
* Creates the menuitem's DOM.
*
* @returns Completed DOM.
*/
createDom(): Element {
const element = document.createElement('div');
element.id = idGenerator.getNextUniqueId();
this.element = element;
// Set class and style
// goog-menuitem* is deprecated, use blocklyMenuItem*. May 2020.
element.className =
'blocklyMenuItem goog-menuitem ' +
(this.enabled ? '' : 'blocklyMenuItemDisabled goog-menuitem-disabled ') +
(this.checked ? 'blocklyMenuItemSelected goog-option-selected ' : '') +
(this.highlight
? 'blocklyMenuItemHighlight goog-menuitem-highlight '
: '') +
(this.rightToLeft ? 'blocklyMenuItemRtl goog-menuitem-rtl ' : '');
const content = document.createElement('div');
content.className = 'blocklyMenuItemContent goog-menuitem-content';
// Add a checkbox for checkable menu items.
if (this.checkable) {
const checkbox = document.createElement('div');
checkbox.className = 'blocklyMenuItemCheckbox goog-menuitem-checkbox';
content.appendChild(checkbox);
}
let contentDom: Node = this.content as HTMLElement;
if (typeof this.content === 'string') {
contentDom = document.createTextNode(this.content);
}
content.appendChild(contentDom);
element.appendChild(content);
// Initialize ARIA role and state.
if (this.roleName) {
aria.setRole(element, this.roleName);
}
aria.setState(
element,
aria.State.SELECTED,
(this.checkable && this.checked) || false,
);
aria.setState(element, aria.State.DISABLED, !this.enabled);
return element;
}
/** Dispose of this menu item. */
dispose() {
this.element = null;
}
/**
* Gets the menu item's element.
*
* @returns The DOM element.
* @internal
*/
getElement(): Element | null {
return this.element;
}
/**
* Gets the unique ID for this menu item.
*
* @returns Unique component ID.
* @internal
*/
getId(): string {
return this.element!.id;
}
/**
* Gets the value associated with the menu item.
*
* @returns value Value associated with the menu item.
* @internal
*/
getValue(): string | null {
return this.opt_value ?? null;
}
/**
* Set menu item's rendering direction.
*
* @param rtl True if RTL, false if LTR.
* @internal
*/
setRightToLeft(rtl: boolean) {
this.rightToLeft = rtl;
}
/**
* Set the menu item's accessibility role.
*
* @param roleName Role name.
* @internal
*/
setRole(roleName: aria.Role) {
this.roleName = roleName;
}
/**
* Sets the menu item to be checkable or not. Set to true for menu items
* that represent checkable options.
*
* @param checkable Whether the menu item is checkable.
* @internal
*/
setCheckable(checkable: boolean) {
this.checkable = checkable;
}
/**
* Checks or unchecks the component.
*
* @param checked Whether to check or uncheck the component.
* @internal
*/
setChecked(checked: boolean) {
this.checked = checked;
}
/**
* Highlights or unhighlights the component.
*
* @param highlight Whether to highlight or unhighlight the component.
* @internal
*/
setHighlighted(highlight: boolean) {
this.highlight = highlight;
const el = this.getElement();
if (el && this.isEnabled()) {
// goog-menuitem-highlight is deprecated, use blocklyMenuItemHighlight.
// May 2020.
const name = 'blocklyMenuItemHighlight';
const nameDep = 'goog-menuitem-highlight';
if (highlight) {
dom.addClass(el, name);
dom.addClass(el, nameDep);
} else {
dom.removeClass(el, name);
dom.removeClass(el, nameDep);
}
}
}
/**
* Returns true if the menu item is enabled, false otherwise.
*
* @returns Whether the menu item is enabled.
* @internal
*/
isEnabled(): boolean {
return this.enabled;
}
/**
* Enables or disables the menu item.
*
* @param enabled Whether to enable or disable the menu item.
* @internal
*/
setEnabled(enabled: boolean) {
this.enabled = enabled;
}
/**
* Performs the appropriate action when the menu item is activated
* by the user.
*
* @internal
*/
performAction() {
if (this.isEnabled() && this.actionHandler) {
this.actionHandler(this);
}
}
/**
* Set the handler that's called when the menu item is activated by the user.
* `obj` will be used as the 'this' object in the function when called.
*
* @param fn The handler.
* @param obj Used as the 'this' object in fn when called.
* @internal
*/
onAction(fn: (p1: MenuItem) => void, obj: object) {
this.actionHandler = fn.bind(obj);
}
}