diff options
Diffstat (limited to 'src/client/views/ContextMenu.tsx')
-rw-r--r-- | src/client/views/ContextMenu.tsx | 89 |
1 files changed, 46 insertions, 43 deletions
diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx index cffcd0f17..c9908b4b0 100644 --- a/src/client/views/ContextMenu.tsx +++ b/src/client/views/ContextMenu.tsx @@ -1,10 +1,10 @@ -import React = require("react"); +import React = require('react'); import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, IReactionDisposer, observable } from "mobx"; -import { observer } from "mobx-react"; -import "./ContextMenu.scss"; -import { ContextMenuItem, ContextMenuProps, OriginalMenuProps } from "./ContextMenuItem"; -import { Utils } from "../../Utils"; +import { action, computed, IReactionDisposer, observable } from 'mobx'; +import { observer } from 'mobx-react'; +import './ContextMenu.scss'; +import { ContextMenuItem, ContextMenuProps, OriginalMenuProps } from './ContextMenuItem'; +import { Utils } from '../../Utils'; @observer export class ContextMenu extends React.Component { @@ -14,7 +14,7 @@ export class ContextMenu extends React.Component { @observable private _pageX: number = 0; @observable private _pageY: number = 0; @observable private _display: boolean = false; - @observable private _searchString: string = ""; + @observable private _searchString: string = ''; @observable private _showSearch: boolean = false; // afaik displaymenu can be called before all the items are added to the menu, so can't determine in displayMenu what the height of the menu will be @observable private _yRelativeToTop: boolean = true; @@ -43,9 +43,10 @@ export class ContextMenu extends React.Component { onPointerDown = (e: PointerEvent) => { this._mouseX = e.clientX; this._mouseY = e.clientY; - } + }; @action onPointerUp = (e: PointerEvent) => { + if (e.button !== 2 && !e.ctrlKey) return; const curX = e.clientX; const curY = e.clientY; if (this._ignoreUp) { @@ -63,27 +64,27 @@ export class ContextMenu extends React.Component { this._display = true; } } - } + }; componentWillUnmount() { - document.removeEventListener("pointerdown", this.onPointerDown); - document.removeEventListener("pointerup", this.onPointerUp); + document.removeEventListener('pointerdown', this.onPointerDown, true); + document.removeEventListener('pointerup', this.onPointerUp); this._reactionDisposer?.(); } @action componentDidMount = () => { - document.addEventListener("pointerdown", this.onPointerDown); - document.addEventListener("pointerup", this.onPointerUp); - } + document.addEventListener('pointerdown', this.onPointerDown, true); + document.addEventListener('pointerup', this.onPointerUp); + }; @action clearItems() { this._items = []; - this._defaultPrefix = ""; + this._defaultPrefix = ''; this._defaultItem = undefined; } - _defaultPrefix: string = ""; + _defaultPrefix: string = ''; _defaultItem: ((name: string) => void) | undefined; findByDescription = (target: string, toLowerCase = false) => { @@ -92,7 +93,7 @@ export class ContextMenu extends React.Component { toLowerCase && (reference = reference.toLowerCase()); return reference === target; }); - } + }; @action addItem(item: ContextMenuProps) { @@ -103,9 +104,9 @@ export class ContextMenu extends React.Component { @action moveAfter(item: ContextMenuProps, after: ContextMenuProps) { if (after && this.findByDescription(after.description)) { - const curInd = this._items.findIndex((i) => i.description === item.description); + const curInd = this._items.findIndex(i => i.description === item.description); this._items.splice(curInd, 1); - const afterInd = this._items.findIndex((i) => i.description === after.description); + const afterInd = this._items.findIndex(i => i.description === after.description); this._items.splice(afterInd + 1, 0, item); } } @@ -142,7 +143,7 @@ export class ContextMenu extends React.Component { _onDisplay?: () => void = undefined; @action - displayMenu = (x: number, y: number, initSearch = "", showSearch = false, onDisplay?: () => void) => { + displayMenu = (x: number, y: number, initSearch = '', showSearch = false, onDisplay?: () => void) => { //maxX and maxY will change if the UI/font size changes, but will work for any amount //of items added to the menu @@ -153,7 +154,7 @@ export class ContextMenu extends React.Component { this._shouldDisplay = true; this._onDisplay = onDisplay; this._display = !onDisplay; - } + }; @action closeMenu = () => { @@ -162,10 +163,10 @@ export class ContextMenu extends React.Component { this._display = false; this._shouldDisplay = false; return wasOpen; - } + }; @computed get filteredItems(): (OriginalMenuProps | string[])[] { - const searchString = this._searchString.toLowerCase().split(" "); + const searchString = this._searchString.toLowerCase().split(' '); const matches = (descriptions: string[]): boolean => { return searchString.every(s => descriptions.some(desc => desc.toLowerCase().includes(s))); }; @@ -176,7 +177,7 @@ export class ContextMenu extends React.Component { for (const item of items) { const description = item.description; const path = groupFunc(description); - if ("subitems" in item) { + if ('subitems' in item) { const children = flattenItems(item.subitems, name => [...groupFunc(description), name]); if (children.length || matches(path)) { eles.push(path); @@ -205,13 +206,14 @@ export class ContextMenu extends React.Component { if (!this._searchString) { return this._items.map((item, ind) => <ContextMenuItem {...item} noexpand={this.itemsNeedSearch ? true : (item as any).noexpand} key={ind + item.description} closeMenu={this.closeMenu} />); } - return this.filteredItems.map((value, index) => - Array.isArray(value) ? + return this.filteredItems.map((value, index) => + Array.isArray(value) ? ( <div className="contextMenu-group"> - <div className="contextMenu-description">{value.join(" -> ")}</div> + <div className="contextMenu-description">{value.join(' -> ')}</div> </div> - : - <ContextMenuItem {...value} key={index+value.description} closeMenu={this.closeMenu} selected={index === this.selectedIndex} /> + ) : ( + <ContextMenuItem {...value} key={index + value.description} closeMenu={this.closeMenu} selected={index === this.selectedIndex} /> + ) ); } @@ -220,32 +222,34 @@ export class ContextMenu extends React.Component { } render() { - return !this._display ? (null) : - <div className="contextMenu-cont" style={{left: this.pageX, ...(this._yRelativeToTop ? { top: this.pageY } : { bottom: this.pageY })}}> - {!this.itemsNeedSearch ? (null) : - <span className={"search-icon"}> + return !this._display ? null : ( + <div className="contextMenu-cont" style={{ left: this.pageX, ...(this._yRelativeToTop ? { top: this.pageY } : { bottom: this.pageY }) }}> + {!this.itemsNeedSearch ? null : ( + <span className={'search-icon'}> <span className="icon-background"> <FontAwesomeIcon icon="search" size="lg" /> </span> <input className="contextMenu-item contextMenu-description search" type="text" placeholder="Filter Menu..." value={this._searchString} onKeyDown={this.onKeyDown} onChange={this.onChange} autoFocus /> - </span>} + </span> + )} {this.menuItems} - </div>; + </div> + ); } @action onKeyDown = (e: React.KeyboardEvent) => { - if (e.key === "ArrowDown") { + if (e.key === 'ArrowDown') { if (this.selectedIndex < this.flatItems.length - 1) { this.selectedIndex++; } e.preventDefault(); - } else if (e.key === "ArrowUp") { + } else if (e.key === 'ArrowUp') { if (this.selectedIndex > 0) { this.selectedIndex--; } e.preventDefault(); - } else if (e.key === "Enter" || e.key === "Tab") { + } else if (e.key === 'Enter' || e.key === 'Tab') { const item = this.flatItems[this.selectedIndex]; if (item) { item.event({ x: this.pageX, y: this.pageY }); @@ -256,20 +260,19 @@ export class ContextMenu extends React.Component { e.preventDefault(); e.stopPropagation(); } - } + }; @action onChange = (e: React.ChangeEvent<HTMLInputElement>) => { this._searchString = e.target.value; if (!this._searchString) { this.selectedIndex = -1; - } - else { + } else { if (this.selectedIndex === -1) { this.selectedIndex = 0; } else { this.selectedIndex = Math.min(this.flatItems.length - 1, this.selectedIndex); } } - } -}
\ No newline at end of file + }; +} |