Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 44 additions & 4 deletions torchci/components/layout/NavBarGroupDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down Expand Up @@ -54,21 +54,61 @@ export function NavBarGroupDropdown({
}) {
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
const open = Boolean(anchorEl);
const boxRef = useRef<HTMLDivElement>(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 (
<Box
onMouseEnter={(e) => setAnchorEl(e.currentTarget)}
onMouseLeave={() => setAnchorEl(null)}
ref={boxRef}
onMouseEnter={(e) => setDropdownIfNotTouch(e.currentTarget)}
onMouseLeave={() => setDropdownIfNotTouch(null)}
>
<Button
id="grouped-menu-button"
aria-controls={open ? "grouped-menu" : undefined}
aria-haspopup="true"
aria-expanded={open ? "true" : undefined}
onClick={(e) => {
if (isTouchDevice) {
// Toggle dropdown on touch devices
setAnchorEl(anchorEl ? null : e.currentTarget);
}
}}
sx={{
textTransform: "none",
cursor: "pointer",
Expand Down Expand Up @@ -103,7 +143,7 @@ export function NavBarGroupDropdown({
))}

{/* Multi-item groups next, sorted by group label; each group header + its sorted items */}
{multis.map((group, gi) => (
{multis.map((group) => (
<Fragment key={`multi-${group.label}`}>
<ListSubheader
disableSticky
Expand Down