"use client"; import { LazyMotion, domAnimation, m } from "motion/react"; import { useEffect, useRef, useState } from "react"; import { NAV_ITEMS } from "@/content/site"; import { Logo } from "./Logo"; const LEFT = NAV_ITEMS.slice(0, 3); const RIGHT = NAV_ITEMS.slice(3); type NavItem = (typeof NAV_ITEMS)[number]; /** * Kopfzeile wie bei der Filmcamp-Referenz: Logo mittig, Abschnitte links und * rechts. Ueber dem Headerbild transparent mit heller Schrift, nach dem * Scrollen auf hellem Grund. */ export function SiteHeader({ logoLight, logoDark }: { logoLight: string | null; logoDark: string | null }) { const [active, setActive] = useState(null); const [scrolled, setScrolled] = useState(false); const [menuOpen, setMenuOpen] = useState(false); const menuButton = useRef(null); const firstLink = useRef(null); useEffect(() => { const onScroll = () => setScrolled(window.scrollY > 24); onScroll(); window.addEventListener("scroll", onScroll, { passive: true }); return () => window.removeEventListener("scroll", onScroll); }, []); // Markiert den Abschnitt, der gerade die Bildschirmmitte kreuzt. useEffect(() => { const sections = NAV_ITEMS.map((item) => document.getElementById(item.id)).filter(Boolean) as HTMLElement[]; const observer = new IntersectionObserver( (entries) => { for (const entry of entries) if (entry.isIntersecting) setActive(entry.target.id); }, { rootMargin: "-45% 0px -50% 0px" }, ); sections.forEach((s) => observer.observe(s)); return () => observer.disconnect(); }, []); useEffect(() => { if (!menuOpen) return; firstLink.current?.focus(); const onKey = (e: KeyboardEvent) => { if (e.key === "Escape") { setMenuOpen(false); menuButton.current?.focus(); } }; document.addEventListener("keydown", onKey); return () => document.removeEventListener("keydown", onKey); }, [menuOpen]); const solid = scrolled || menuOpen; const navList = (items: readonly NavItem[], align: string) => ( ); return (
Zum Inhalt springen
Platz sichern
{menuOpen && ( )}
); }