fix(nav): close hamburger menu when nested dropdown closes and mouse not hovering

Fixed issue where hamburger menu would stay open after:
1. Hover over hamburger (opens)
2. Click style dropdown (opens)
3. Click outside to close style dropdown
4. Hamburger stays open until clicked

Solution:
- Track hover state with useRef to know real-time mouse position
- When nested dropdown closes, check if mouse is still hovering
- If not hovering, close hamburger immediately

Also cleaned up debug console.log statements now that the issue is resolved.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Thomas Hallock
2025-10-11 20:35:20 -05:00
parent a204c83afc
commit 7d652126d0
2 changed files with 14 additions and 27 deletions

View File

@@ -19,10 +19,7 @@ export function AbacusDisplayDropdown({ isFullscreen = false, onOpenChange: onOp
const [open, setOpen] = useState(false)
const { config, updateConfig, resetToDefaults } = useAbacusDisplay()
console.log('[AbacusDisplayDropdown] State:', { open })
const handleOpenChange = (isOpen: boolean) => {
console.log('[AbacusDisplayDropdown] onOpenChange called with:', isOpen, 'current open:', open)
setOpen(isOpen)
// Notify parent component
onOpenChangeProp?.(isOpen)
@@ -81,12 +78,6 @@ export function AbacusDisplayDropdown({ isFullscreen = false, onOpenChange: onOp
<DropdownMenu.Portal>
<DropdownMenu.Content
onInteractOutside={(e) => {
const target = e.target as HTMLElement
console.log('[AbacusDisplayDropdown] onInteractOutside triggered')
console.log('[AbacusDisplayDropdown] Target element:', target)
console.log('[AbacusDisplayDropdown] Target tagName:', target.tagName)
}}
className={css({
bg: isFullscreen ? 'rgba(0, 0, 0, 0.85)' : 'white',
rounded: 'xl',

View File

@@ -35,14 +35,13 @@ function HamburgerMenu({
const [hovered, setHovered] = useState(false)
const [nestedDropdownOpen, setNestedDropdownOpen] = useState(false)
const hoverTimeoutRef = React.useRef<NodeJS.Timeout | null>(null)
const isCurrentlyHovering = React.useRef(false)
// Open on hover or click OR if nested dropdown is open
const isOpen = open || hovered || nestedDropdownOpen
console.log('[HamburgerMenu] State:', { open, hovered, nestedDropdownOpen, isOpen })
const handleMouseEnter = () => {
console.log('[HamburgerMenu] Mouse enter')
isCurrentlyHovering.current = true
if (hoverTimeoutRef.current) {
clearTimeout(hoverTimeoutRef.current)
hoverTimeoutRef.current = null
@@ -51,25 +50,32 @@ function HamburgerMenu({
}
const handleMouseLeave = () => {
console.log('[HamburgerMenu] Mouse leave, nestedDropdownOpen:', nestedDropdownOpen)
isCurrentlyHovering.current = false
// Don't close if nested dropdown is open
if (nestedDropdownOpen) {
console.log('[HamburgerMenu] Skipping close - nested dropdown is open')
return
}
// Delay closing to allow moving from button to menu
hoverTimeoutRef.current = setTimeout(() => {
console.log('[HamburgerMenu] Mouse leave timeout fired')
setHovered(false)
}, 150)
}
const handleOpenChange = (newOpen: boolean) => {
console.log('[HamburgerMenu] onOpenChange called with:', newOpen, 'current open:', open)
setOpen(newOpen)
}
const handleNestedDropdownChange = (isNestedOpen: boolean) => {
setNestedDropdownOpen(isNestedOpen)
// When nested dropdown closes, also close hamburger if mouse is not hovering
if (!isNestedOpen && !isCurrentlyHovering.current) {
setHovered(false)
setOpen(false)
}
}
React.useEffect(() => {
return () => {
if (hoverTimeoutRef.current) {
@@ -122,18 +128,8 @@ function HamburgerMenu({
onInteractOutside={(e) => {
// Don't close the hamburger menu when clicking inside the nested style dropdown
const target = e.target as HTMLElement
console.log('[HamburgerMenu] onInteractOutside triggered')
console.log('[HamburgerMenu] Target element:', target)
console.log('[HamburgerMenu] Target tagName:', target.tagName)
console.log('[HamburgerMenu] Target className:', target.className)
console.log('[HamburgerMenu] Has [role="dialog"]:', !!target.closest('[role="dialog"]'))
console.log('[HamburgerMenu] Has [data-radix-popper-content-wrapper]:', !!target.closest('[data-radix-popper-content-wrapper]'))
if (target.closest('[role="dialog"]') || target.closest('[data-radix-popper-content-wrapper]')) {
console.log('[HamburgerMenu] Preventing close - nested dropdown interaction')
e.preventDefault()
} else {
console.log('[HamburgerMenu] Allowing close - outside interaction')
}
}}
style={{
@@ -385,7 +381,7 @@ function HamburgerMenu({
<div style={{ padding: '0 6px' }}>
<AbacusDisplayDropdown
isFullscreen={isFullscreen}
onOpenChange={setNestedDropdownOpen}
onOpenChange={handleNestedDropdownChange}
/>
</div>
</DropdownMenu.Content>