mirror of
https://github.com/arc53/DocsGPT.git
synced 2026-04-28 21:10:27 +00:00
(fix:menu) position smartly
This commit is contained in:
@@ -30,7 +30,17 @@ export default function ContextMenu({
|
|||||||
offset = { x: 0, y: 8 },
|
offset = { x: 0, y: 8 },
|
||||||
}: ContextMenuProps) {
|
}: ContextMenuProps) {
|
||||||
const menuRef = useRef<HTMLDivElement>(null);
|
const menuRef = useRef<HTMLDivElement>(null);
|
||||||
|
useEffect(() => {
|
||||||
|
if (isOpen && menuRef.current) {
|
||||||
|
const positionStyle = getMenuPosition();
|
||||||
|
if (menuRef.current) {
|
||||||
|
Object.assign(menuRef.current.style, {
|
||||||
|
top: positionStyle.top,
|
||||||
|
left: positionStyle.left,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [isOpen]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleClickOutside = (event: MouseEvent) => {
|
const handleClickOutside = (event: MouseEvent) => {
|
||||||
if (
|
if (
|
||||||
@@ -61,20 +71,45 @@ export default function ContextMenu({
|
|||||||
let top = rect.bottom + scrollY + offset.y;
|
let top = rect.bottom + scrollY + offset.y;
|
||||||
let left = rect.right + scrollX + offset.x;
|
let left = rect.right + scrollX + offset.x;
|
||||||
|
|
||||||
|
// Get menu dimensions (need ref to be available)
|
||||||
|
const menuWidth = menuRef.current?.offsetWidth || 144; // Default min-width
|
||||||
|
const menuHeight = menuRef.current?.offsetHeight || 0;
|
||||||
|
|
||||||
|
// Get viewport dimensions
|
||||||
|
const viewportWidth = window.innerWidth;
|
||||||
|
const viewportHeight = window.innerHeight;
|
||||||
|
|
||||||
|
// Adjust position based on specified position
|
||||||
switch (position) {
|
switch (position) {
|
||||||
case 'bottom-left':
|
case 'bottom-left':
|
||||||
left = rect.left + scrollX - offset.x;
|
left = rect.left + scrollX - offset.x;
|
||||||
break;
|
break;
|
||||||
case 'top-right':
|
case 'top-right':
|
||||||
top = rect.top + scrollY - offset.y;
|
top = rect.top + scrollY - offset.y - menuHeight;
|
||||||
break;
|
break;
|
||||||
case 'top-left':
|
case 'top-left':
|
||||||
top = rect.top + scrollY - offset.y;
|
top = rect.top + scrollY - offset.y - menuHeight;
|
||||||
left = rect.left + scrollX - offset.x;
|
left = rect.left + scrollX - offset.x;
|
||||||
break;
|
break;
|
||||||
// bottom-right is default
|
// bottom-right is default
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (left + menuWidth > viewportWidth) {
|
||||||
|
left = Math.max(5, viewportWidth - menuWidth - 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (left < 5) {
|
||||||
|
left = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (top + menuHeight > viewportHeight + scrollY) {
|
||||||
|
top = rect.top + scrollY - menuHeight - offset.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (top < scrollY + 5) {
|
||||||
|
top = rect.bottom + scrollY + offset.y;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
position: 'fixed',
|
position: 'fixed',
|
||||||
top: `${top}px`,
|
top: `${top}px`,
|
||||||
|
|||||||
Reference in New Issue
Block a user