Skip to content

Commit 21ad34b

Browse files
shahryarjbKarlsonxD
andcommitted
Fix Misplaced dropdown when content has min-width
Fixed #447 Co-Authored-By: Hannes <42112359+karlsonxd@users.noreply.github.com>
1 parent 5ed8276 commit 21ad34b

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

priv/assets/js/floating.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,51 @@ const Floating = {
425425
content.style.transform = "none";
426426
}
427427

428+
// Clamp to viewport to prevent content from overflowing screen edges.
429+
// This runs regardless of smartPositioning to always keep content visible.
430+
const contentWidth = content.offsetWidth;
431+
const contentHeight = content.offsetHeight;
432+
const viewportLeft = window.scrollX;
433+
const viewportRight = window.scrollX + window.innerWidth;
434+
const viewportTop = window.scrollY;
435+
const viewportBottom = window.scrollY + window.innerHeight;
436+
437+
if (pos === "top" || pos === "bottom") {
438+
// left is the center point (CSS translateX(-50%) shifts it), so actual edges are:
439+
const actualLeft = left - contentWidth / 2;
440+
const actualRight = left + contentWidth / 2;
441+
442+
if (actualRight > viewportRight) {
443+
left = viewportRight - contentWidth - gap;
444+
content.style.transform = "none";
445+
} else if (actualLeft < viewportLeft) {
446+
left = viewportLeft + gap;
447+
content.style.transform = "none";
448+
}
449+
450+
// When content is wider than viewport, the right-edge clamp pushes left off-screen.
451+
// Always anchor to left edge so the start of content stays visible (LTR).
452+
if (left < viewportLeft + gap) {
453+
left = viewportLeft + gap;
454+
content.style.transform = "none";
455+
}
456+
} else if (pos === "left" || pos === "right") {
457+
if (top + contentHeight > viewportBottom) {
458+
top = viewportBottom - contentHeight - gap;
459+
}
460+
if (top < viewportTop) {
461+
top = viewportTop + gap;
462+
}
463+
464+
// Horizontal clamping for left/right positions
465+
if (left + contentWidth > viewportRight) {
466+
left = viewportRight - contentWidth - gap;
467+
}
468+
if (left < viewportLeft + gap) {
469+
left = viewportLeft + gap;
470+
}
471+
}
472+
428473
content.style.position = "absolute";
429474
content.style.top = `${top}px`;
430475
content.style.left = `${left}px`;

0 commit comments

Comments
 (0)