"use client"; /** * MobileNav — hamburger button + slide-in drawer for narrow viewports. * * The desktop SiteHeader holds the full primary nav inline; on mobile that * cluster overflows past the viewport edge. This drawer keeps the brand * always visible and tucks the rest behind a hamburger. * * Behaviour: * - Opens on hamburger click, closes on backdrop click, ESC, link click, * or close button. * - Locks body scroll while open so the page underneath doesn't jiggle. * - Marks the active nav link via usePathname (mirrors NavLink). * - aria-modal="true" + dialog role + escape handling for screen readers. * * The locale toggle and auth pill live inside the panel so the mobile * surface offers every action the desktop navbar does. */ import Link from "next/link"; import { usePathname } from "next/navigation"; import { useEffect, useRef, useState } from "react"; import { Menu, X } from "lucide-react"; import { AuthBar } from "./auth-bar"; import { BrandMark } from "./brand-mark"; import { LocaleToggleClient } from "./locale-toggle-client"; interface NavItem { href: string; label: string; } const COPY = { "pt-br": { open: "Abrir menu", close: "Fechar menu", section: "Navegação" }, en: { open: "Open menu", close: "Close menu", section: "Navigation" }, } as const; export function MobileNav({ locale, items, }: { locale: "pt-br" | "en"; items: NavItem[] }) { const [open, setOpen] = useState(false); const pathname = usePathname() || "/"; const closeBtnRef = useRef(null); const t = COPY[locale]; useEffect(() => { if (!open) return; const onKey = (e: KeyboardEvent) => { if (e.key === "Escape") setOpen(false); }; window.addEventListener("keydown", onKey); // Lock body scroll while the panel is open. const prev = document.body.style.overflow; document.body.style.overflow = "hidden"; // Move focus to the close button so VoiceOver / TalkBack announce the // dialog and keyboard users can dismiss it with one press. closeBtnRef.current?.focus(); return () => { window.removeEventListener("keydown", onKey); document.body.style.overflow = prev; }; }, [open]); function isActive(href: string): boolean { return pathname === href || (href !== "/" && pathname.startsWith(`${href}/`)); } return ( <> {open && (
)} ); }