Skip to content

Commit 364e446

Browse files
committed
add styling and logic for active state in scrolling
1 parent 7985c13 commit 364e446

File tree

2 files changed

+53
-21
lines changed

2 files changed

+53
-21
lines changed

src/features/introduction/components/sidebar-nav/sidebar-nav.component.tsx

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
"use client";
22

3-
import React from "react";
3+
import React, { useEffect, useState } from "react";
44
import { getIntroductionDictionary } from "@/features/localization/services/language-dictionary.service";
55
import styles from "./sidebar-nav.module.scss";
6-
import { useRouter } from "next/navigation";
6+
import clsx from "clsx";
77

88
interface SidebarNavComponentProps {
99
languageCode: string;
@@ -21,7 +21,33 @@ export const SidebarNavComponent: React.FC<SidebarNavComponentProps> = ({
2121
languageCode,
2222
}) => {
2323
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+
2551
const handleClick = (id: string) => {
2652
scrollToElementWithOffset(id, -120);
2753
history.replaceState(null, "", `#${id}`);
@@ -33,7 +59,10 @@ export const SidebarNavComponent: React.FC<SidebarNavComponentProps> = ({
3359
{introductionDictionary.content.headings.map((heading, index) => (
3460
<li
3561
key={index}
36-
className={styles.title}
62+
className={clsx(
63+
styles.title,
64+
activeId === heading.id && styles.title__active
65+
)}
3766
onClick={() => handleClick(heading.id)}
3867
>
3968
{heading.title}
Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
1+
@use "@/libs/theme/styles/variables" as *;
2+
13
.container {
2-
position: sticky;
3-
color: white;
4-
height: 100vh;
5-
flex-shrink: 0;
6-
top: 0;
7-
padding: 100px 30px 0px;
8-
border-right: 1px solid white;
9-
max-width: 250px;
10-
overflow-y: auto
4+
display:none;
5+
@media #{$breakpoint-dimension-sm} {
6+
display: inline-block;
7+
height: 100vh;
8+
position: sticky;
9+
color: var(--color_fg_link);
10+
flex-shrink: 0;
11+
top: 0;
12+
padding: 100px 30px 0px;
13+
border-right: 1px solid var(--color_fg_link);
14+
max-width: 250px;
15+
overflow-y: auto;
16+
}
1117
}
1218

1319
.title {
@@ -16,14 +22,11 @@
1622
cursor: pointer;
1723
}
1824

19-
.list {
20-
list-style-type: none;
25+
.title__active {
26+
color: var(--color_fg_selected);
27+
border-bottom: 1px solid var(--color_border_selected);
2128
}
2229

23-
@media (max-width: 768px) {
24-
.container {
25-
width: 100%;
26-
height: auto;
27-
position: relative;
28-
}
30+
.list {
31+
list-style-type: none;
2932
}

0 commit comments

Comments
 (0)