forked from nodejs/nodejs.org
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuseNavigationState.ts
More file actions
42 lines (33 loc) · 1.14 KB
/
useNavigationState.ts
File metadata and controls
42 lines (33 loc) · 1.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
'use client';
import { useContext, useEffect } from 'react';
import { NavigationStateContext } from '#site/providers/navigationStateProvider';
import { debounce } from '#site/util/objects';
import type { RefObject } from 'react';
const useNavigationState = <T extends HTMLElement>(
id: string,
ref: RefObject<T | null>,
debounceTime = 300
) => {
const navigationState = useContext(NavigationStateContext);
const handleScroll = debounce(() => {
if (ref.current) {
navigationState[id] = {
x: ref.current.scrollLeft,
y: ref.current.scrollTop,
};
}
}, debounceTime);
useEffect(() => {
const element = ref.current;
if (element) {
if (navigationState[id] && navigationState[id].y !== element.scrollTop) {
element.scroll({ top: navigationState[id].y, behavior: 'instant' });
}
element.addEventListener('scroll', handleScroll, { passive: true });
return () => element.removeEventListener('scroll', handleScroll);
}
// We need this effect to run only on mount
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
};
export default useNavigationState;