From 7bf2c4149d02e098aa39f728a0f37927def0f8e2 Mon Sep 17 00:00:00 2001 From: gbanyan Date: Fri, 21 Nov 2025 01:20:48 +0800 Subject: [PATCH] Add hover delay to nav dropdown --- components/nav-menu.tsx | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/components/nav-menu.tsx b/components/nav-menu.tsx index 630591c..86ffd84 100644 --- a/components/nav-menu.tsx +++ b/components/nav-menu.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useState, FocusEvent } from 'react'; +import { useState, useRef, FocusEvent } from 'react'; import { FiMenu, FiX, @@ -61,6 +61,7 @@ interface NavMenuProps { export function NavMenu({ items }: NavMenuProps) { const [open, setOpen] = useState(false); const [activeDropdown, setActiveDropdown] = useState(null); + const closeTimer = useRef(null); const toggle = () => setOpen((val) => !val); const close = () => setOpen(false); @@ -70,6 +71,23 @@ export function NavMenu({ items }: NavMenuProps) { } }; + const clearCloseTimer = () => { + if (closeTimer.current) { + clearTimeout(closeTimer.current); + closeTimer.current = null; + } + }; + + const openDropdown = (key: string) => { + clearCloseTimer(); + setActiveDropdown(key); + }; + + const scheduleCloseDropdown = () => { + clearCloseTimer(); + closeTimer.current = window.setTimeout(() => setActiveDropdown(null), 180); + }; + const renderChild = (item: NavLinkItem) => { const Icon = ICON_MAP[item.iconKey] ?? FiFile; return item.href ? ( @@ -107,9 +125,9 @@ export function NavMenu({ items }: NavMenuProps) {
setActiveDropdown(item.key)} - onMouseLeave={() => setActiveDropdown(null)} - onFocus={() => setActiveDropdown(item.key)} + onMouseEnter={() => openDropdown(item.key)} + onMouseLeave={scheduleCloseDropdown} + onFocus={() => openDropdown(item.key)} onBlur={handleBlur} >