diff --git a/torchci/components/layout/NavBarGroupDropdown.tsx b/torchci/components/layout/NavBarGroupDropdown.tsx index b2bc2187ca..5493159355 100644 --- a/torchci/components/layout/NavBarGroupDropdown.tsx +++ b/torchci/components/layout/NavBarGroupDropdown.tsx @@ -9,7 +9,7 @@ import { } from "@mui/material"; import { Box } from "@mui/system"; import Link from "next/link"; -import { Fragment, useMemo, useState } from "react"; +import { Fragment, useEffect, useMemo, useRef, useState } from "react"; export type NavItem = { label: string; route: string }; export type NavCategory = { label: string; items: NavItem[]; type?: string }; @@ -54,21 +54,61 @@ export function NavBarGroupDropdown({ }) { const [anchorEl, setAnchorEl] = useState(null); const open = Boolean(anchorEl); + const boxRef = useRef(null); const { singles, multis, bottom } = useMemo( () => sortForMenu(groups), [groups] ); + // Check if device is touch-enabled + const isTouchDevice = useMemo( + () => + typeof window !== "undefined" && + ("ontouchstart" in window || navigator.maxTouchPoints > 0), + [] + ); + + // Set dropdown state only on non-touch devices + const setDropdownIfNotTouch = (value: HTMLElement | null) => { + if (!isTouchDevice) { + setAnchorEl(value); + } + }; + + // Close dropdown when clicking outside + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + const target = event.target as HTMLElement; + if (boxRef.current && !boxRef.current.contains(target)) { + setAnchorEl(null); + } + }; + + if (open) { + document.addEventListener("click", handleClickOutside); + return () => { + document.removeEventListener("click", handleClickOutside); + }; + } + }, [open]); + return ( setAnchorEl(e.currentTarget)} - onMouseLeave={() => setAnchorEl(null)} + ref={boxRef} + onMouseEnter={(e) => setDropdownIfNotTouch(e.currentTarget)} + onMouseLeave={() => setDropdownIfNotTouch(null)} >