Skip to content

Commit

Permalink
fix: Context menu overflows out of the window
Browse files Browse the repository at this point in the history
  • Loading branch information
NriotHrreion committed Oct 4, 2024
1 parent 245a748 commit ede821d
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 36 deletions.
13 changes: 0 additions & 13 deletions src/ui/canvas/canvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,19 +74,6 @@ export class Canvas extends Component<HTMLCanvasElement, CanvasOptions> implemen
{
text: "力",
icon: ArrowRightFromLine,
},
{
text: "test item",
subItems: [
{
text: "test item",
subItems: [
{
text: "hello world"
}
]
}
]
}
]
}
Expand Down
58 changes: 37 additions & 21 deletions src/ui/contextMenu/contextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ const defaultOptions: ContextMenuOptions = {
};

export interface IContextMenu extends IComponent {
setPosition(position: ContextMenuPosition): void

id?: string
}

Expand Down Expand Up @@ -73,27 +75,7 @@ export class ContextMenu extends Component<HTMLDivElement, ContextMenuOptions> 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) => {
Expand Down Expand Up @@ -127,6 +109,40 @@ export class ContextMenu extends Component<HTMLDivElement, ContextMenuOptions> 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;
}
Expand Down
24 changes: 22 additions & 2 deletions src/ui/contextMenu/contextMenuProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,30 @@ class ContextMenuProvider extends Provider<ContextMenu> implements IContextMenuP
e.stopPropagation();

this.clearContextMenus();
this.createContextMenu(items, {

// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
type TopOrBottom<P = ContextMenuPosition> = P extends `${infer A}-${infer _B}` ? A : never;
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
type LeftOrRight<P = ContextMenuPosition> = 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}`);
});
}

Expand Down

0 comments on commit ede821d

Please sign in to comment.