Skip to content

Commit 339eb60

Browse files
committed
🐛 Fix to prevent dropdown overflow when near viewport edge (#1907)
1 parent 96be393 commit 339eb60

File tree

1 file changed

+33
-7
lines changed

1 file changed

+33
-7
lines changed

src/lib/actions/handle_dropdown.ts

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,6 @@ export function handleDropdownBehavior(
7979

8080
// Recalculate the dropdown position on resize.
8181
const handleWindowResize = () => {
82-
if (options.isOpen) {
83-
options.closeDropdown();
84-
}
85-
8682
clearTimeout(resizeTimeout);
8783

8884
resizeTimeout = setTimeout(() => {
@@ -146,10 +142,11 @@ export function calculateDropdownPosition(event: MouseEvent): {
146142
} {
147143
lastTriggerElement = event.currentTarget as HTMLElement;
148144
const rect = (lastTriggerElement as HTMLElement).getBoundingClientRect();
145+
const { x, y } = preventDropdownOverflowWhenNearViewportEdge(rect.right, rect.bottom);
149146

150147
return {
151-
x: rect.right,
152-
y: rect.bottom,
148+
x: x,
149+
y: y,
153150
isLower: rect.top > window.innerHeight / 2,
154151
};
155152
}
@@ -182,7 +179,36 @@ export function recalculateDropdownPosition(options: {
182179
}
183180

184181
const rect = lastTriggerElement.getBoundingClientRect();
185-
options.updatePosition(rect.right, rect.bottom, rect.top > window.innerHeight / 2);
182+
const { x, y } = preventDropdownOverflowWhenNearViewportEdge(rect.right, rect.bottom);
183+
options.updatePosition(x, y, rect.top > window.innerHeight / 2);
184+
}
185+
186+
/**
187+
* Adjusts coordinates to prevent a dropdown from overflowing the viewport edge.
188+
*
189+
* @param x - The horizontal coordinate to adjust
190+
* @param y - The vertical coordinate to adjust
191+
* @returns An object containing adjusted x and y coordinates that ensure the dropdown
192+
* will have at least a 10px margin from the viewport edge
193+
*
194+
* @example
195+
* // Adjust coordinates for dropdown positioning
196+
* const adjustedPosition = preventDropdownOverflowWhenNearViewportEdge(mouseX, mouseY);
197+
*/
198+
function preventDropdownOverflowWhenNearViewportEdge(
199+
x: number,
200+
y: number,
201+
): { x: number; y: number } {
202+
const margin = 10; // minimal margin from viewport edge
203+
204+
if (x > window.innerWidth - margin) {
205+
x = window.innerWidth - margin;
206+
}
207+
if (y > window.innerHeight - margin) {
208+
y = window.innerHeight - margin;
209+
}
210+
211+
return { x, y };
186212
}
187213

188214
/**

0 commit comments

Comments
 (0)