added hook for handle flip side
This commit is contained in:
parent
3569bdc8d3
commit
9e29510711
@ -1,4 +1,4 @@
|
||||
import { useState, useMemo, useCallback, useEffect } from "react";
|
||||
import { useState, useMemo, useCallback, useEffect,useLayoutEffect } from "react";
|
||||
|
||||
/*
|
||||
options:
|
||||
@ -239,3 +239,75 @@ export function useGridCore({
|
||||
serverMode,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export function useDropdownPosition(btnRef, menuRef, isOpen, level = 0) {
|
||||
const [style, setStyle] = useState({});
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (!isOpen || !btnRef.current || !menuRef.current) return;
|
||||
|
||||
const updatePosition = () => {
|
||||
const btn = btnRef.current.getBoundingClientRect();
|
||||
const menu = menuRef.current;
|
||||
|
||||
const menuHeight = menu.offsetHeight;
|
||||
const menuWidth = menu.offsetWidth;
|
||||
|
||||
const vh = window.innerHeight;
|
||||
const vw = window.innerWidth;
|
||||
|
||||
const spaceBelow = vh - btn.bottom;
|
||||
const spaceAbove = btn.top;
|
||||
|
||||
// ------------ AUTO FLIP (top/bottom) ------------
|
||||
const openUp = menuHeight > spaceBelow && spaceAbove > spaceBelow;
|
||||
let top = openUp ? btn.top - menuHeight : btn.bottom;
|
||||
|
||||
if (top < 8) top = 8;
|
||||
if (top + menuHeight > vh - 8) top = vh - menuHeight - 8;
|
||||
|
||||
// ------------ AUTO FLIP (left/right) ------------
|
||||
let left = btn.left;
|
||||
|
||||
if (level === 0) {
|
||||
// Main menu
|
||||
if (left + menuWidth > vw - 8) left = vw - menuWidth - 8;
|
||||
} else {
|
||||
// Nested menu opens to right
|
||||
left = btn.right;
|
||||
if (left + menuWidth > vw - 8) {
|
||||
left = btn.left - menuWidth; // flip to left if overflow
|
||||
}
|
||||
}
|
||||
|
||||
setStyle({
|
||||
position: "fixed",
|
||||
top,
|
||||
left,
|
||||
zIndex: 99999,
|
||||
maxHeight: vh - 16,
|
||||
overflowY: "auto",
|
||||
});
|
||||
};
|
||||
|
||||
// RUN AFTER MENU RENDERS
|
||||
requestAnimationFrame(updatePosition);
|
||||
|
||||
// RUN AGAIN after potential layout changes
|
||||
setTimeout(updatePosition, 50);
|
||||
|
||||
window.addEventListener("resize", updatePosition);
|
||||
return () => window.removeEventListener("resize", updatePosition);
|
||||
}, [isOpen, level]);
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user