"use client"; import Link from "next/link"; import { usePathname } from "next/navigation"; import { useEffect, useState } from "react"; import { AnimatePresence, motion } from "framer-motion"; import { Logo } from "../ui/Logo"; import { ScrollProgress } from "../ui/ScrollProgress"; import { NAV_LINKS, STUDIO } from "@/lib/site"; import { EASE_OUT_EXPO } from "@/lib/motion"; export function Navbar() { const pathname = usePathname(); const [scrolled, setScrolled] = useState(false); // The drawer stores the route it was opened on, so any navigation closes it // by derivation — no effect syncing state to the router. const [openedOn, setOpenedOn] = useState(null); const open = openedOn === pathname; const close = () => setOpenedOn(null); useEffect(() => { const onScroll = () => setScrolled(window.scrollY > 20); onScroll(); window.addEventListener("scroll", onScroll, { passive: true }); return () => window.removeEventListener("scroll", onScroll); }, []); // Lock the page and allow Escape to dismiss while the drawer is open. useEffect(() => { if (!open) return; const onKeyDown = (event: KeyboardEvent) => { if (event.key === "Escape") setOpenedOn(null); }; document.addEventListener("keydown", onKeyDown); const previousOverflow = document.body.style.overflow; document.body.style.overflow = "hidden"; return () => { document.removeEventListener("keydown", onKeyDown); document.body.style.overflow = previousOverflow; }; }, [open]); const isActive = (href: string) => pathname === href || pathname.startsWith(`${href}/`); return (
{open && ( {/* The rows deal out one by one. The drawer is the only place on the site where a whole navigation appears at once, and a block of four identical lines arriving together reads as a flash. */} {NAV_LINKS.map((link) => ( {link.label.toUpperCase()} ))} )}
); }