Horizon / src /components /MobileMenu.jsx
NKessler's picture
Upload 6270 files
4083225 verified
Raw
History Blame Contribute Delete
1.94 kB
import { useEffect } from "react";
import { NavLink } from "react-router-dom";
import { X } from "lucide-react";
import { NAV_ITEMS } from "./Sidebar.jsx";
import "./MobileMenu.css";
export default function MobileMenu({ open, onClose }) {
useEffect(() => {
if (!open) return undefined;
const previousOverflow = document.body.style.overflow;
document.body.style.overflow = "hidden";
const onKeyDown = (event) => {
if (event.key === "Escape") onClose();
};
window.addEventListener("keydown", onKeyDown);
return () => {
document.body.style.overflow = previousOverflow;
window.removeEventListener("keydown", onKeyDown);
};
}, [open, onClose]);
if (!open) return null;
return (
<div className="mobile-menu" role="dialog" aria-modal="true" aria-label="Visualization menu">
<button
className="mobile-menu__backdrop"
onClick={onClose}
aria-label="Close visualization menu"
/>
<section className="mobile-menu__panel">
<header className="mobile-menu__header">
<div>
<p className="label">Navigation</p>
<h2 className="mobile-menu__title">Visualizations</h2>
</div>
<button className="ghost mobile-menu__close" onClick={onClose} aria-label="Close menu">
<X size={18} />
</button>
</header>
<nav className="mobile-menu__nav" aria-label="Visualization links">
{NAV_ITEMS.map(({ to, label, Icon }) => (
<NavLink
key={to}
to={to}
className={({ isActive }) =>
`mobile-menu__link ${isActive ? "mobile-menu__link--active" : ""}`
}
onClick={onClose}
>
<Icon size={18} strokeWidth={1.6} />
<span>{label}</span>
</NavLink>
))}
</nav>
</section>
</div>
);
}