ensure contextMenu doesn't overflow viewport (#364)
This commit is contained in:
parent
d2a3ed7931
commit
8104c8525d
@ -18,7 +18,12 @@ type Props = {
|
||||
|
||||
function ContextMenu({ options, onCloseRequest, top, left }: Props) {
|
||||
return (
|
||||
<Popover onCloseRequest={onCloseRequest} top={top} left={left}>
|
||||
<Popover
|
||||
onCloseRequest={onCloseRequest}
|
||||
top={top}
|
||||
left={left}
|
||||
fitInViewport={true}
|
||||
>
|
||||
<ul className="context-menu" onContextMenu={e => e.preventDefault()}>
|
||||
{options.map((option, idx) => (
|
||||
<li
|
||||
|
@ -1,15 +1,41 @@
|
||||
import React from "react";
|
||||
import React, { useLayoutEffect, useRef } from "react";
|
||||
|
||||
type Props = {
|
||||
top?: number;
|
||||
left?: number;
|
||||
children?: React.ReactNode;
|
||||
onCloseRequest?(): void;
|
||||
fitInViewport?: boolean;
|
||||
};
|
||||
|
||||
export function Popover({ children, left, onCloseRequest, top }: Props) {
|
||||
export function Popover({
|
||||
children,
|
||||
left,
|
||||
top,
|
||||
onCloseRequest,
|
||||
fitInViewport = false
|
||||
}: Props) {
|
||||
const popoverRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// ensure the popover doesn't overflow the viewport
|
||||
useLayoutEffect(() => {
|
||||
if (fitInViewport && popoverRef.current) {
|
||||
const element = popoverRef.current;
|
||||
const { x, y, width, height } = element.getBoundingClientRect();
|
||||
|
||||
const viewportWidth = window.innerWidth;
|
||||
if (x + width > viewportWidth) {
|
||||
element.style.left = viewportWidth - width + "px";
|
||||
}
|
||||
const viewportHeight = window.innerHeight;
|
||||
if (y + height > viewportHeight) {
|
||||
element.style.top = viewportHeight - height + "px";
|
||||
}
|
||||
}
|
||||
}, [fitInViewport]);
|
||||
|
||||
return (
|
||||
<div className="popover" style={{ top: top, left: left }}>
|
||||
<div className="popover" style={{ top: top, left: left }} ref={popoverRef}>
|
||||
<div
|
||||
className="cover"
|
||||
onClick={onCloseRequest}
|
||||
|
Loading…
x
Reference in New Issue
Block a user