import React, { useEffect, useState, useRef } from 'react';
import { Link, NavLink } from 'react-router-dom';
import clsx from 'clsx';
import ScrollProgress from './ScrollProgress.jsx';
import ImageFlex from './ImageFlex.jsx';
export default function Header() {
const [scrolled, setScrolled] = useState(false);
const [menuOpen, setMenuOpen] = useState(false);
const [projectsOpen, setProjectsOpen] = useState(false);
const [headerVisible, setHeaderVisible] = useState(false);
const [isHovered, setIsHovered] = useState(false);
const closeTimerRef = useRef(null);
const headerRef = useRef(null);
useEffect(() => {
const onScroll = () => {
const scrollY = window.scrollY;
setScrolled(scrollY > 24);
// Show header when scrolled
setHeaderVisible(scrollY > 50);
};
onScroll();
window.addEventListener('scroll', onScroll, { passive: true });
return () => window.removeEventListener('scroll', onScroll);
}, []);
useEffect(() => {
// Show header on hover or when menu is open, regardless of scroll position
if (isHovered || menuOpen) {
setHeaderVisible(true);
} else {
// Only hide if not scrolled
const scrollY = window.scrollY;
if (scrollY <= 50) {
setHeaderVisible(false);
}
}
}, [isHovered, menuOpen]);
useEffect(() => {
document.body.style.overflow = menuOpen ? 'hidden' : '';
}, [menuOpen]);
const navLink = (to, label) => (
clsx(
'relative px-3 py-2 text-sm font-medium transition',
// Animated underline (temporary) from right -> left on hover
'after:content-[""] after:absolute after:left-3 after:right-3 after:-bottom-1 after:h-[2px] after:bg-brand-600',
'after:transform after:scale-x-0 after:origin-right after:transition-transform after:duration-300',
'hover:after:origin-left hover:after:scale-x-100',
isActive ? 'text-brand-700' : 'text-slate-700 hover:text-brand-700'
)
}
>
{label}
);
return (
<>
{/* Invisible hover area at top of page to reveal header */}
setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
aria-hidden="true"
/>
setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
className={clsx(
'fixed inset-x-0 top-0 z-50 bg-white transition-all duration-300',
scrolled ? 'shadow' : '',
headerVisible
? 'translate-y-0 opacity-100 pointer-events-auto'
: '-translate-y-full opacity-0 pointer-events-none'
)}
role="banner"
style={{
transform: headerVisible ? 'translateY(0)' : 'translateY(-100%)',
}}
>
Skip to content
Jade Infra
>
);
}