From 05136e97087a88a570e62897230e01750e3bf7a0 Mon Sep 17 00:00:00 2001 From: Joan Date: Sat, 7 Feb 2026 23:08:17 +0100 Subject: [PATCH] fix(ui): ensure dropdown position stays sticky on interaction --- pwa/src/components/common/GameDropdown.tsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/pwa/src/components/common/GameDropdown.tsx b/pwa/src/components/common/GameDropdown.tsx index 09c3dfb..529f8bf 100644 --- a/pwa/src/components/common/GameDropdown.tsx +++ b/pwa/src/components/common/GameDropdown.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useRef } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; import './GameDropdown.css'; @@ -38,6 +38,10 @@ export const GameDropdown: React.FC = ({ }) => { const dropdownRef = useRef(null); + // Capture position ONCE on mount (or first render) if not provided + // This prevents the menu from jumping if the user clicks inside it (changing lastClickPos) + const [capturedPos] = useState(() => position || lastClickPos); + // Handle click outside useEffect(() => { if (!isOpen) return; @@ -52,7 +56,6 @@ export const GameDropdown: React.FC = ({ document.addEventListener('mousedown', handleClickOutside); // Handle scroll to update position or close? - // For now, simpler to just close on scroll or let it float (fixed pos) const handleScroll = () => { // Optional: onClose(); }; @@ -66,9 +69,10 @@ export const GameDropdown: React.FC = ({ if (!isOpen) return null; - // Use passed position or fallback to last click position - const targetX = position ? position.x : lastClickPos.x; - const targetY = position ? position.y : lastClickPos.y; + // Use passed position (if updated dynamically) or fall back to the captured sticky position + const target = position || capturedPos; + const targetX = target.x; + const targetY = target.y; let x = targetX - 10;