fix(nav): add delay to hamburger menu hover to prevent premature closing
Added 150ms delay when mouse leaves the hamburger button or menu to allow smooth transition between them without the menu closing. This fixes the issue where the menu would immediately close when moving the mouse from the button to the dropdown content. Implementation: - useRef to track timeout - handleMouseEnter: cancels any pending close timeout - handleMouseLeave: sets 150ms delay before closing - Applied to both button and menu content - Cleanup effect to clear timeout on unmount The menu now stays open while hovering either the button or the dropdown, providing smooth UX for both hover and click interactions. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -3,8 +3,7 @@
|
||||
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
||||
import Link from 'next/link'
|
||||
import { usePathname, useRouter } from 'next/navigation'
|
||||
import type React from 'react'
|
||||
import { useState } from 'react'
|
||||
import React, { useState } from 'react'
|
||||
import { css } from '../../styled-system/css'
|
||||
import { container, hstack } from '../../styled-system/patterns'
|
||||
import { useFullscreen } from '../contexts/FullscreenContext'
|
||||
@@ -33,17 +32,41 @@ function HamburgerMenu({
|
||||
}) {
|
||||
const [open, setOpen] = useState(false)
|
||||
const [hovered, setHovered] = useState(false)
|
||||
const hoverTimeoutRef = React.useRef<NodeJS.Timeout | null>(null)
|
||||
|
||||
// Open on hover or click
|
||||
const isOpen = open || hovered
|
||||
|
||||
const handleMouseEnter = () => {
|
||||
if (hoverTimeoutRef.current) {
|
||||
clearTimeout(hoverTimeoutRef.current)
|
||||
hoverTimeoutRef.current = null
|
||||
}
|
||||
setHovered(true)
|
||||
}
|
||||
|
||||
const handleMouseLeave = () => {
|
||||
// Delay closing to allow moving from button to menu
|
||||
hoverTimeoutRef.current = setTimeout(() => {
|
||||
setHovered(false)
|
||||
}, 150)
|
||||
}
|
||||
|
||||
React.useEffect(() => {
|
||||
return () => {
|
||||
if (hoverTimeoutRef.current) {
|
||||
clearTimeout(hoverTimeoutRef.current)
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<DropdownMenu.Root open={isOpen} onOpenChange={setOpen}>
|
||||
<DropdownMenu.Trigger asChild>
|
||||
<button
|
||||
type="button"
|
||||
onMouseEnter={() => setHovered(true)}
|
||||
onMouseLeave={() => setHovered(false)}
|
||||
onMouseEnter={handleMouseEnter}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
@@ -76,8 +99,8 @@ function HamburgerMenu({
|
||||
side="bottom"
|
||||
align="start"
|
||||
sideOffset={8}
|
||||
onMouseEnter={() => setHovered(true)}
|
||||
onMouseLeave={() => setHovered(false)}
|
||||
onMouseEnter={handleMouseEnter}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
style={{
|
||||
background: 'linear-gradient(135deg, rgba(17, 24, 39, 0.97), rgba(31, 41, 55, 0.97))',
|
||||
backdropFilter: 'blur(12px)',
|
||||
|
||||
Reference in New Issue
Block a user