Fix popup overflow
Fix pulldowns overflow
Update extra popus
Update UTCI/SunSoak - Show variant selected
This commit is contained in:
Fraxle
2026-05-26 13:15:26 +01:00
parent f8a220b325
commit 1509ddb78d
8 changed files with 95 additions and 16 deletions
+35 -2
View File
@@ -37,7 +37,10 @@ export function useColumnPopup() {
const calcPopupPos = (thEl) => {
const rect = thEl.getBoundingClientRect();
const popupW = 260, popupH = 110, margin = 8, gap = 6;
// Use a generous height estimate so tall (text-heavy) popups prefer going
// below rather than overflowing the top. The post-render clamp effect
// catches any remaining overflow after the real height is known.
const popupW = 260, popupH = 220, margin = 8, gap = 6;
let x = rect.left + rect.width / 2;
x = Math.max(popupW / 2 + margin, Math.min(x, window.innerWidth - popupW / 2 - margin));
const below = rect.top < popupH + gap + margin;
@@ -103,10 +106,26 @@ export function useColumnPopup() {
};
}, [colPopup]);
// Post-render clamp: after the popup actually paints, measure its real
// bounding rect and nudge y if it overflows the viewport top or bottom.
// The >1 guard prevents floating-point micro-loops.
useEffect(() => {
if (!colPopup || !colPopupRef.current) return;
const rect = colPopupRef.current.getBoundingClientRect();
const MARGIN = 8;
if (!colPopup.below && rect.top < MARGIN) {
const delta = MARGIN - rect.top;
if (delta > 1) setColPopup(prev => prev ? { ...prev, y: prev.y + delta } : prev);
} else if (colPopup.below && rect.bottom > window.innerHeight - MARGIN) {
const delta = rect.bottom - (window.innerHeight - MARGIN);
if (delta > 1) setColPopup(prev => prev ? { ...prev, y: prev.y - delta } : prev);
}
}, [colPopup]);
// --- Event tag popup helpers -----------------------------------------
const calcEventPopupPos = (spanEl) => {
const rect = spanEl.getBoundingClientRect();
const popupW = 260, popupH = 80, margin = 8, gap = 6;
const popupW = 260, popupH = 160, margin = 8, gap = 6;
let x = rect.left + rect.width / 2;
x = Math.max(popupW / 2 + margin, Math.min(x, window.innerWidth - popupW / 2 - margin));
const below = rect.top < popupH + gap + margin;
@@ -206,6 +225,20 @@ export function useColumnPopup() {
};
}, [eventTagPopup]);
// Post-render clamp for event-tag popup (same logic as col popup above).
useEffect(() => {
if (!eventTagPopup || !eventTagPopupRef.current) return;
const rect = eventTagPopupRef.current.getBoundingClientRect();
const MARGIN = 8;
if (!eventTagPopup.below && rect.top < MARGIN) {
const delta = MARGIN - rect.top;
if (delta > 1) setEventTagPopup(prev => prev ? { ...prev, y: prev.y + delta } : prev);
} else if (eventTagPopup.below && rect.bottom > window.innerHeight - MARGIN) {
const delta = rect.bottom - (window.innerHeight - MARGIN);
if (delta > 1) setEventTagPopup(prev => prev ? { ...prev, y: prev.y - delta } : prev);
}
}, [eventTagPopup]);
return {
// column-header popup
colPopup, colPopupRef,