diff options
author | Kristóf Marussy <kristof@marussy.com> | 2024-03-15 18:01:48 +0100 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2024-03-15 19:19:33 +0100 |
commit | 0a16f36b8afc23f335c1146d6ea53329f9e27df7 (patch) | |
tree | 91a204a8f44f605042a8498a96f68dd02a5f1705 /src/components/TrackActiveSection.tsx | |
parent | chore(deps): bump dependencies (diff) | |
download | blog-0a16f36b8afc23f335c1146d6ea53329f9e27df7.tar.gz blog-0a16f36b8afc23f335c1146d6ea53329f9e27df7.tar.zst blog-0a16f36b8afc23f335c1146d6ea53329f9e27df7.zip |
Add landing page sections and update resume
Diffstat (limited to 'src/components/TrackActiveSection.tsx')
-rw-r--r-- | src/components/TrackActiveSection.tsx | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/components/TrackActiveSection.tsx b/src/components/TrackActiveSection.tsx new file mode 100644 index 0000000..bb1b2ee --- /dev/null +++ b/src/components/TrackActiveSection.tsx | |||
@@ -0,0 +1,47 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 Kristóf Marussy | ||
3 | * | ||
4 | * SPDX-License-Identifier: MIT | ||
5 | */ | ||
6 | |||
7 | import { type ReactNode, useEffect, useCallback, useRef } from 'react'; | ||
8 | |||
9 | import { useActiveSection } from './ActiveSectionProvider'; | ||
10 | |||
11 | export default function TrackActiveSection({ | ||
12 | children, | ||
13 | }: { | ||
14 | children: ReactNode; | ||
15 | }) { | ||
16 | const { setHash } = useActiveSection(); | ||
17 | const elementRef = useRef<HTMLDivElement | null>(null); | ||
18 | const callback = useCallback(() => { | ||
19 | const { current: element } = elementRef; | ||
20 | if (!element) { | ||
21 | return; | ||
22 | } | ||
23 | const currentID = Array.from(element.children) | ||
24 | .reverse() | ||
25 | .find((child) => child.getBoundingClientRect().top <= 60)?.id; | ||
26 | const currentHash = | ||
27 | currentID === undefined || currentID === '' ? '' : `#${currentID}`; | ||
28 | setHash(currentHash); | ||
29 | }, [setHash]); | ||
30 | const setElement = useCallback( | ||
31 | (element: HTMLDivElement | null) => { | ||
32 | elementRef.current = element; | ||
33 | if (element) { | ||
34 | callback(); | ||
35 | } else { | ||
36 | setHash(undefined); | ||
37 | } | ||
38 | }, | ||
39 | [setHash], | ||
40 | ); | ||
41 | useEffect(() => { | ||
42 | window.addEventListener('scroll', callback); | ||
43 | return () => window.removeEventListener('scroll', callback); | ||
44 | }); | ||
45 | |||
46 | return <div ref={setElement}>{children}</div>; | ||
47 | } | ||