'use client'; import { Suspense, useState, useEffect, useCallback } from 'react'; import { StaticLink } from '@/components/ui/static-link'; import Image from 'next/image'; import { usePathname } from 'next/navigation'; import { Menu, X } from 'lucide-react'; import { AnimatePresence, motion } from 'framer-motion'; import { Button } from '@/components/ui/button'; import { COMPANY_INFO, NAVIGATION, type NavigationItem } from '@/lib/constants'; import { useFocusTrap } from '@/hooks/use-focus-trap'; function HeaderContent() { const [isOpen, setIsOpen] = useState(false); const [isScrolled, setIsScrolled] = useState(false); const [headerTheme, setHeaderTheme] = useState<'light' | 'dark'>('light'); const pathname = usePathname(); const focusTrapRef = useFocusTrap(isOpen); // 监听 data-header-theme 属性变化(产品落地页控制导航栏颜色) useEffect(() => { const handleThemeChange = () => { const theme = document.documentElement.getAttribute('data-header-theme'); setHeaderTheme(theme === 'dark' ? 'dark' : 'light'); }; handleThemeChange(); const observer = new MutationObserver(handleThemeChange); observer.observe(document.documentElement, { attributes: true, attributeFilter: ['data-header-theme'], }); return () => observer.disconnect(); }, []); useEffect(() => { const handleScroll = () => { setIsScrolled(window.scrollY > 20); }; const handleGlobalKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape' && isOpen) { setIsOpen(false); } }; window.addEventListener('scroll', handleScroll, { passive: true }); window.addEventListener('keydown', handleGlobalKeyDown); return () => { window.removeEventListener('scroll', handleScroll); window.removeEventListener('keydown', handleGlobalKeyDown); }; }, [isOpen]); const handleKeyDown = useCallback((e: React.KeyboardEvent) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setIsOpen(!isOpen); } if (e.key === 'Escape' && isOpen) { setIsOpen(false); } }, [isOpen]); const handleNavClick = useCallback((href: string) => { // Close mobile menu, then navigate (StaticLink delegates navigation to onClick when present) setIsOpen(false); window.location.href = href; }, []); const isActive = useCallback((item: NavigationItem) => { if (item.id === 'contact') { return pathname === '/contact'; } if (item.id === 'home') { return pathname === '/'; } return pathname === `/${item.id}`; }, [pathname]); const navigationItems = NAVIGATION; return ( <>
{COMPANY_INFO.shortName}
{isOpen && (
setIsOpen(false)} aria-hidden="true" /> )} ); } function HeaderFallback() { return (
); } export function Header() { return ( }> ); }