Add hover delay to nav dropdown

This commit is contained in:
2025-11-21 01:20:48 +08:00
parent 9d7a6757c9
commit 7bf2c4149d

View File

@@ -1,6 +1,6 @@
'use client'; 'use client';
import { useState, FocusEvent } from 'react'; import { useState, useRef, FocusEvent } from 'react';
import { import {
FiMenu, FiMenu,
FiX, FiX,
@@ -61,6 +61,7 @@ interface NavMenuProps {
export function NavMenu({ items }: NavMenuProps) { export function NavMenu({ items }: NavMenuProps) {
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const [activeDropdown, setActiveDropdown] = useState<string | null>(null); const [activeDropdown, setActiveDropdown] = useState<string | null>(null);
const closeTimer = useRef<number | null>(null);
const toggle = () => setOpen((val) => !val); const toggle = () => setOpen((val) => !val);
const close = () => setOpen(false); 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 renderChild = (item: NavLinkItem) => {
const Icon = ICON_MAP[item.iconKey] ?? FiFile; const Icon = ICON_MAP[item.iconKey] ?? FiFile;
return item.href ? ( return item.href ? (
@@ -107,9 +125,9 @@ export function NavMenu({ items }: NavMenuProps) {
<div <div
key={item.key} key={item.key}
className="group relative" className="group relative"
onMouseEnter={() => setActiveDropdown(item.key)} onMouseEnter={() => openDropdown(item.key)}
onMouseLeave={() => setActiveDropdown(null)} onMouseLeave={scheduleCloseDropdown}
onFocus={() => setActiveDropdown(item.key)} onFocus={() => openDropdown(item.key)}
onBlur={handleBlur} onBlur={handleBlur}
> >
<button <button