refactor(ui): auto-detect dropdown position from last click
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user