11import { cn } from "@/lib/utils" ;
2- import {
3- AnimatePresence ,
4- motion ,
5- useScroll ,
6- useMotionValueEvent ,
7- } from "motion/react" ;
2+ import { AnimatePresence , motion } from "motion/react" ;
83import { Cross as HamburgerCross } from "hamburger-react" ;
94import { useEffect , useState , useRef } from "react" ;
105
@@ -25,10 +20,48 @@ export const HoverNavigation = ({
2520 className ?: string ;
2621} ) => {
2722 const [ hoveredIndex , setHoveredIndex ] = useState < number | null > ( null ) ;
23+ const [ activeIndex , setActiveIndex ] = useState < number | null > ( null ) ;
2824 const [ hamburgerOpen , setHamburgerOpen ] = useState ( false ) ;
2925 const hamburgerRef = useRef < HTMLDivElement > ( null ) ;
3026 const menuRef = useRef < HTMLDivElement > ( null ) ;
3127
28+ // Track which section is in view
29+ useEffect ( ( ) => {
30+ const sectionIds = items . map ( ( item ) => {
31+ const url = new URL ( item . link , window . location . origin ) ;
32+ return url . hash . replace ( "#" , "" ) ;
33+ } ) ;
34+
35+ const observers : IntersectionObserver [ ] = [ ] ;
36+
37+ sectionIds . forEach ( ( id , idx ) => {
38+ if ( ! id ) return ;
39+
40+ const element = document . getElementById ( id ) ;
41+ if ( ! element ) return ;
42+
43+ const observer = new IntersectionObserver (
44+ ( entries ) => {
45+ entries . forEach ( ( entry ) => {
46+ if ( entry . isIntersecting ) {
47+ setActiveIndex ( idx ) ;
48+ }
49+ } ) ;
50+ } ,
51+ {
52+ rootMargin : "-20% 0px -50% 0px" ,
53+ } ,
54+ ) ;
55+
56+ observer . observe ( element ) ;
57+ observers . push ( observer ) ;
58+ } ) ;
59+
60+ return ( ) => {
61+ observers . forEach ( ( observer ) => observer . disconnect ( ) ) ;
62+ } ;
63+ } , [ items ] ) ;
64+
3265 useEffect ( ( ) => {
3366 const handleClickOutside = ( event : MouseEvent ) => {
3467 if (
@@ -48,6 +81,9 @@ export const HoverNavigation = ({
4881 } ;
4982 } , [ hamburgerOpen ] ) ;
5083
84+ // Use hoveredIndex when hovering, otherwise use activeIndex
85+ const displayIndex = hoveredIndex !== null ? hoveredIndex : activeIndex ;
86+
5187 return (
5288 < >
5389 < div className = "bg-secondary/50 fixed top-5 left-1/2 z-30 box-border hidden -translate-x-1/2 items-center justify-center overflow-auto rounded-[40px] border-2 border-solid border-gray-700 px-5 py-3 backdrop-blur-md md:flex md:w-11/12 lg:w-2/3 xl:w-auto" >
@@ -76,7 +112,7 @@ export const HoverNavigation = ({
76112 }
77113 >
78114 < AnimatePresence >
79- { hoveredIndex === idx && (
115+ { displayIndex === idx && (
80116 < motion . span
81117 className = "absolute inset-0 z-10 block h-full w-full rounded-3xl bg-neutral-100"
82118 layoutId = "hoverBackground"
0 commit comments