-
Notifications
You must be signed in to change notification settings - Fork 240
Expand file tree
/
Copy pathuse-visibility-calculation.ts
More file actions
79 lines (72 loc) · 2.2 KB
/
use-visibility-calculation.ts
File metadata and controls
79 lines (72 loc) · 2.2 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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import useElementResize from "@/components/hooks/useElementResize";
import { useCallback, useEffect, useState } from "react";
import { OptimizeTableHeaderWithIndexProps } from ".";
import { getVisibleCellRange } from "./helper";
import OptimizeTableState from "./optimize-table-state";
export default function useTableVisibilityRecalculation({
containerRef,
totalRowCount,
rowHeight,
renderAhead,
headers,
state,
}: {
containerRef: React.RefObject<HTMLDivElement>;
totalRowCount: number;
rowHeight: number;
renderAhead: number;
headers: OptimizeTableHeaderWithIndexProps[];
state: OptimizeTableState;
}) {
const [visibleDebounce, setVisibleDebounce] = useState<{
rowStart: number;
rowEnd: number;
colStart: number;
colEnd: number;
}>({
rowStart: 0,
rowEnd: 0,
colStart: 0,
colEnd: 0,
});
const recalculateVisible = useCallback(
(e: HTMLDivElement) => {
const headerSizes = state.getHeaderWidth();
setVisibleDebounce(
getVisibleCellRange(
e,
headers.map((header) => headerSizes[header.index]) as number[],
totalRowCount,
rowHeight,
renderAhead,
state.gutterColumnWidth
)
);
},
[setVisibleDebounce, totalRowCount, rowHeight, renderAhead, headers, state]
);
const onHeaderResize = useCallback(
(idx: number, newWidth: number) => {
if (containerRef.current) {
state.setHeaderWidth(idx, newWidth);
recalculateVisible(containerRef.current);
}
},
[state, recalculateVisible, containerRef]
);
// Recalculate the visibility again when we scroll the container
useEffect(() => {
const ref = containerRef.current;
if (ref) {
const onContainerScroll = (e: Event) => {
recalculateVisible(e.currentTarget as HTMLDivElement);
e.preventDefault();
e.stopPropagation();
};
containerRef.current.addEventListener("scroll", onContainerScroll);
return () => ref.removeEventListener("scroll", onContainerScroll);
}
}, [containerRef, recalculateVisible]);
useElementResize<HTMLDivElement>(recalculateVisible, containerRef);
return { visibileRange: visibleDebounce, onHeaderResize };
}