refactor(ui): auto-detect dropdown position from last click

This commit is contained in:
Joan
2026-02-07 23:01:34 +01:00
parent 6f1e8c56f2
commit 2e9a833a1a
2 changed files with 18 additions and 14 deletions

View File

@@ -5,12 +5,22 @@ import './GameDropdown.css';
interface GameDropdownProps {
isOpen: boolean;
onClose: () => void;
position: { x: number; y: number };
position?: { x: number; y: number }; // Made optional
children: React.ReactNode;
className?: string;
width?: string;
}
// Track last click position globally to avoid passing it every time
let lastClickPos = { x: 0, y: 0 };
if (typeof window !== 'undefined') {
// Capture usage of mouse down to update position before component renders
window.addEventListener('mousedown', (e) => {
lastClickPos = { x: e.clientX, y: e.clientY };
}, { capture: true });
}
/**
* GameDropdown
*
@@ -56,10 +66,13 @@ export const GameDropdown: React.FC<GameDropdownProps> = ({
if (!isOpen) return null;
// Adjust position to keep within viewport
// Use passed position or fallback to last click position
// Default offset of -10 to center mouse over menu
let x = position.x - 10;
let y = position.y - 10;
const targetX = position ? position.x : lastClickPos.x;
const targetY = position ? position.y : lastClickPos.y;
let x = targetX - 10;
let y = targetY - 10;
let flipUp = false;
// Simple adjustment logic (can be improved with measuring ref)

View File

@@ -94,7 +94,6 @@ function LocationView({
// Dropdown State
const [activeDropdown, setActiveDropdown] = useState<string | null>(null)
const [dropdownPos, setDropdownPos] = useState({ x: 0, y: 0 })
// Handle dropdown toggle
const handleDropdownClick = (e: React.MouseEvent, id: string) => {
@@ -102,11 +101,7 @@ function LocationView({
if (activeDropdown === id) {
setActiveDropdown(null)
} else {
// Use mouse position for grid-like dropdown behavior
setDropdownPos({
x: e.clientX,
y: e.clientY
})
// GameDropdown now auto-detects mouse position if we don't pass it
setActiveDropdown(id)
}
}
@@ -244,7 +239,6 @@ function LocationView({
<GameDropdown
isOpen={true}
onClose={() => setActiveDropdown(null)}
position={dropdownPos}
width="160px"
>
<div className="game-dropdown-header">{getTranslatedText(enemy.name)}</div>
@@ -295,7 +289,6 @@ function LocationView({
<GameDropdown
isOpen={true}
onClose={() => setActiveDropdown(null)}
position={dropdownPos}
width="160px"
>
<div className="game-dropdown-header">{getTranslatedText(corpse.name)}</div>
@@ -345,7 +338,6 @@ function LocationView({
<GameDropdown
isOpen={true}
onClose={() => setActiveDropdown(null)}
position={dropdownPos}
>
<div className="game-dropdown-header">{getTranslatedText(npc.name)}</div>
<GameButton variant="primary" size="sm" style={{ width: '100%', justifyContent: 'flex-start' }}>
@@ -439,7 +431,6 @@ function LocationView({
<GameDropdown
isOpen={true}
onClose={() => setActiveDropdown(null)}
position={dropdownPos}
width="160px"
>
<div className="game-dropdown-header">{getTranslatedText(item.name)}</div>