1
1
"use client" ;
2
2
3
- import React from "react" ;
3
+ import React , { useEffect , useState } from "react" ;
4
4
import { getIntroductionDictionary } from "@/features/localization/services/language-dictionary.service" ;
5
5
import styles from "./sidebar-nav.module.scss" ;
6
- import { useRouter } from "next/navigation " ;
6
+ import clsx from "clsx " ;
7
7
8
8
interface SidebarNavComponentProps {
9
9
languageCode : string ;
@@ -21,7 +21,33 @@ export const SidebarNavComponent: React.FC<SidebarNavComponentProps> = ({
21
21
languageCode,
22
22
} ) => {
23
23
const introductionDictionary = getIntroductionDictionary ( languageCode ) ;
24
- const router = useRouter ( ) ;
24
+ const headings = introductionDictionary . content . headings ;
25
+ const [ activeId , setActiveId ] = useState < string | null > ( null ) ;
26
+
27
+ useEffect ( ( ) => {
28
+ const observer = new IntersectionObserver (
29
+ ( entries ) => {
30
+ entries . forEach ( ( entry ) => {
31
+ if ( entry . isIntersecting ) {
32
+ const id = entry . target . id ;
33
+ setActiveId ( id ) ;
34
+ history . replaceState ( null , "" , `#${ id } ` ) ;
35
+ }
36
+ } ) ;
37
+ } ,
38
+ {
39
+ threshold : 0 ,
40
+ }
41
+ ) ;
42
+ const elements = headings
43
+ . map ( ( heading ) => document . getElementById ( heading . id ) )
44
+ . filter ( Boolean ) as HTMLElement [ ] ;
45
+ elements . forEach ( ( el ) => observer . observe ( el ) ) ;
46
+ return ( ) => {
47
+ elements . forEach ( ( el ) => observer . unobserve ( el ) ) ;
48
+ } ;
49
+ } , [ headings ] ) ;
50
+
25
51
const handleClick = ( id : string ) => {
26
52
scrollToElementWithOffset ( id , - 120 ) ;
27
53
history . replaceState ( null , "" , `#${ id } ` ) ;
@@ -33,7 +59,10 @@ export const SidebarNavComponent: React.FC<SidebarNavComponentProps> = ({
33
59
{ introductionDictionary . content . headings . map ( ( heading , index ) => (
34
60
< li
35
61
key = { index }
36
- className = { styles . title }
62
+ className = { clsx (
63
+ styles . title ,
64
+ activeId === heading . id && styles . title__active
65
+ ) }
37
66
onClick = { ( ) => handleClick ( heading . id ) }
38
67
>
39
68
{ heading . title }
0 commit comments