diff --git a/src/ui/canvas/canvas.tsx b/src/ui/canvas/canvas.tsx index f7da1a9..c3b7e80 100644 --- a/src/ui/canvas/canvas.tsx +++ b/src/ui/canvas/canvas.tsx @@ -74,19 +74,6 @@ export class Canvas extends Component implemen { text: "力", icon: ArrowRightFromLine, - }, - { - text: "test item", - subItems: [ - { - text: "test item", - subItems: [ - { - text: "hello world" - } - ] - } - ] } ] } diff --git a/src/ui/contextMenu/contextMenu.tsx b/src/ui/contextMenu/contextMenu.tsx index 26b0ba4..befa410 100644 --- a/src/ui/contextMenu/contextMenu.tsx +++ b/src/ui/contextMenu/contextMenu.tsx @@ -42,6 +42,8 @@ const defaultOptions: ContextMenuOptions = { }; export interface IContextMenu extends IComponent { + setPosition(position: ContextMenuPosition): void + id?: string } @@ -73,27 +75,7 @@ export class ContextMenu extends Component i : this._createItem(info); } - const width = this.contextMenuElem.clientWidth; - const height = this.contextMenuElem.clientHeight; - - switch(this._options.position) { - case "top-left": - this.contextMenuElem.style.left = (this._options.anchor.x - width) +"px"; - this.contextMenuElem.style.top = (this._options.anchor.y - height) +"px"; - break; - case "top-right": - this.contextMenuElem.style.left = this._options.anchor.x +"px"; - this.contextMenuElem.style.top = (this._options.anchor.y - height) +"px"; - break; - case "bottom-left": - this.contextMenuElem.style.left = (this._options.anchor.x - width) +"px"; - this.contextMenuElem.style.top = this._options.anchor.y +"px"; - break; - case "bottom-right": - this.contextMenuElem.style.left = this._options.anchor.x +"px"; - this.contextMenuElem.style.top = this._options.anchor.y +"px"; - break; - } + this.setPosition(this._options.position); // Remove the context menu when the user clicks outside this._element.addEventListener("mousedown", (e) => { @@ -127,6 +109,40 @@ export class ContextMenu extends Component i this._register(item); } + public setPosition(position: ContextMenuPosition) { + this._options.position = position; + + const width = this.width; + const height = this.height; + + switch(position) { + case "top-left": + this.contextMenuElem.style.left = (this._options.anchor.x - width) +"px"; + this.contextMenuElem.style.top = (this._options.anchor.y - height) +"px"; + break; + case "top-right": + this.contextMenuElem.style.left = this._options.anchor.x +"px"; + this.contextMenuElem.style.top = (this._options.anchor.y - height) +"px"; + break; + case "bottom-left": + this.contextMenuElem.style.left = (this._options.anchor.x - width) +"px"; + this.contextMenuElem.style.top = this._options.anchor.y +"px"; + break; + case "bottom-right": + this.contextMenuElem.style.left = this._options.anchor.x +"px"; + this.contextMenuElem.style.top = this._options.anchor.y +"px"; + break; + } + } + + public get width() { + return this.contextMenuElem.clientWidth; + } + + public get height() { + return this.contextMenuElem.clientHeight; + } + public get id() { return this._options.id; } diff --git a/src/ui/contextMenu/contextMenuProvider.ts b/src/ui/contextMenu/contextMenuProvider.ts index 0fbb05d..4f3999b 100644 --- a/src/ui/contextMenu/contextMenuProvider.ts +++ b/src/ui/contextMenu/contextMenuProvider.ts @@ -52,10 +52,30 @@ class ContextMenuProvider extends Provider implements IContextMenuP e.stopPropagation(); this.clearContextMenus(); - this.createContextMenu(items, { + + // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars + type TopOrBottom

= P extends `${infer A}-${infer _B}` ? A : never; + // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars + type LeftOrRight

= P extends `${infer _A}-${infer B}` ? B : never; + + // default: "top-right" + let a: TopOrBottom = "top"; + let b: LeftOrRight = "right"; + + const menu = this.createContextMenu(items, { x: e.clientX, y: e.clientY - }, "top-right"); + }, `${a}-${b}`); + const { width, height } = menu; + + if(e.clientX + width > window.innerWidth) { + b = "left"; + } + if(e.clientY - height < 0) { + a = "bottom"; + } + + menu.setPosition(`${a}-${b}`); }); }