From 565b27cca8953a60067de367cae4c0a99beb3cab Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Wed, 19 Jun 2019 16:21:03 -0400 Subject: started adding selection to context menu --- src/client/views/ContextMenu.scss | 4 +++ src/client/views/ContextMenu.tsx | 58 +++++++++++++++++++++++------------- src/client/views/ContextMenuItem.tsx | 6 ++-- 3 files changed, 45 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/client/views/ContextMenu.scss b/src/client/views/ContextMenu.scss index a1a2b06f1..254163b53 100644 --- a/src/client/views/ContextMenu.scss +++ b/src/client/views/ContextMenu.scss @@ -53,6 +53,10 @@ font-size: 20px; } +.contextMenu-itemSelected { + background: rgb(136, 136, 136) +} + .contextMenu-group { // width: 11vw; //10vw height: 30px; //2vh diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx index 1133f70a1..33de57cfa 100644 --- a/src/client/views/ContextMenu.tsx +++ b/src/client/views/ContextMenu.tsx @@ -1,5 +1,5 @@ import React = require("react"); -import { ContextMenuItem, ContextMenuProps } from "./ContextMenuItem"; +import { ContextMenuItem, ContextMenuProps, OriginalMenuProps } from "./ContextMenuItem"; import { observable, action, computed } from "mobx"; import { observer } from "mobx-react"; import "./ContextMenu.scss"; @@ -21,6 +21,7 @@ export class ContextMenu extends React.Component { @observable private _searchString: string = ""; // 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; + @observable selectedIndex = -1; private _searchRef = React.createRef(); @@ -75,49 +76,63 @@ export class ContextMenu extends React.Component { this._display = false; } - @computed get filteredItems() { + @computed get filteredItems(): (OriginalMenuProps | string[])[] { const searchString = this._searchString.toLowerCase().split(" "); const matches = (descriptions: string[]): boolean => { - return searchString.every(s => descriptions.some(desc => desc.includes(s))); + return searchString.every(s => descriptions.some(desc => desc.toLowerCase().includes(s))); }; - const createGroupHeader = (contents: any) => { - return ( -
-
{contents}
-
- ); - }; - const createItem = (item: ContextMenuProps) => ; - const flattenItems = (items: ContextMenuProps[], groupFunc: (contents: any) => JSX.Element, getPath: () => string[]) => { - let eles: JSX.Element[] = []; + const flattenItems = (items: ContextMenuProps[], groupFunc: (groupName: any) => string[]) => { + let eles: (OriginalMenuProps | string[])[] = []; + const leaves: OriginalMenuProps[] = []; for (const item of items) { - const description = item.description.toLowerCase(); - const path = [...getPath(), description]; + const description = item.description; + const path = groupFunc(description); if ("subitems" in item) { - const children = flattenItems(item.subitems, contents => groupFunc(<>{item.description} -> {contents}), () => path); + const children = flattenItems(item.subitems, name => [...groupFunc(description), name]); if (children.length || matches(path)) { - eles.push(groupFunc(item.description)); + eles.push(path); eles = eles.concat(children); } } else { if (!matches(path)) { continue; } - eles.push(createItem(item)); + leaves.push(item); } } + eles = [...leaves, ...eles]; + return eles; }; - return flattenItems(this._items, createGroupHeader, () => []); + return flattenItems(this._items, name => [name]); + } + + @computed get filteredViews() { + const createGroupHeader = (contents: any) => { + return ( +
+
{contents}
+
+ ); + }; + const createItem = (item: ContextMenuProps, selected: boolean) => ; + let itemIndex = 0; + return this.filteredItems.map(value => { + if (Array.isArray(value)) { + return createGroupHeader(value.join(" -> ")); + } else { + return createItem(value, ++itemIndex === this.selectedIndex); + } + }); } @computed get menuItems() { if (!this._searchString) { return this._items.map(item => ); } - return this.filteredItems; + return this.filteredViews; } render() { @@ -143,5 +158,8 @@ export class ContextMenu extends React.Component { @action onChange = (e: React.ChangeEvent) => { this._searchString = e.target.value; + if (this._searchString && this.selectedIndex === -1) { + this.selectedIndex = 0; + } } } \ No newline at end of file diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx index 88ebd95bc..ebcac7428 100644 --- a/src/client/views/ContextMenuItem.tsx +++ b/src/client/views/ContextMenuItem.tsx @@ -24,7 +24,7 @@ export interface SubmenuProps { export type ContextMenuProps = OriginalMenuProps | SubmenuProps; @observer -export class ContextMenuItem extends React.Component { +export class ContextMenuItem extends React.Component { @observable private _items: Array = []; @observable private overItem = false; @@ -69,7 +69,7 @@ export class ContextMenuItem extends React.Component { render() { if ("event" in this.props) { return ( -
+
{this.props.icon ? ( @@ -86,7 +86,7 @@ export class ContextMenuItem extends React.Component { {this._items.map(prop => )}
; return ( -
+
{this.props.icon ? ( -- cgit v1.2.3-70-g09d2