Files
jakeandClaude Sonnet 5.5 a8c4a0a09e perf: render site header as a server component
Split the scroll shell, home link and theme toggle into small client
components so the contact popover markup and icon SVGs render on the
server instead of shipping in the client bundle.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-03 08:57:20 -04:00

50 lines
1.2 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import { cn } from "@/lib/utils";
/** Sticky header wrapper that gains a background once the page is scrolled. */
const HeaderShell = ({
className,
children,
}: {
className?: string;
children: React.ReactNode;
}) => {
const [isScrolled, setIsScrolled] = useState(false);
useEffect(() => {
const handleScroll = () => {
setIsScrolled(window.scrollY > 10);
};
// Check initial scroll position
handleScroll();
window.addEventListener("scroll", handleScroll, { passive: true });
return () => window.removeEventListener("scroll", handleScroll);
}, []);
return (
<div
data-scrolled={isScrolled}
style={{ viewTransitionName: "persistent-nav" }}
className={cn(
"sticky top-0 z-50 w-full",
"motion-safe:transition-[background-color,backdrop-filter,border-color]",
"motion-safe:duration-200",
"bg-background/0 backdrop-blur-none",
"data-[scrolled=true]:bg-background/80",
"data-[scrolled=true]:backdrop-blur-md",
"data-[scrolled=true]:border-b data-[scrolled=true]:border-border/70",
className,
)}
>
{children}
</div>
);
};
export { HeaderShell };