-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Expand file tree
/
Copy pathuseViewportColumns.ts
More file actions
122 lines (108 loc) · 3.32 KB
/
useViewportColumns.ts
File metadata and controls
122 lines (108 loc) · 3.32 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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import { useMemo } from 'react';
import { getColSpan } from '../utils';
import type { CalculatedColumn, Maybe } from '../types';
interface ViewportColumnsArgs<R, SR> {
columns: readonly CalculatedColumn<R, SR>[];
colSpanColumns: readonly CalculatedColumn<R, SR>[];
rows: readonly R[];
topSummaryRows: Maybe<readonly SR[]>;
bottomSummaryRows: Maybe<readonly SR[]>;
colOverscanStartIdx: number;
colOverscanEndIdx: number;
lastFrozenColumnIndex: number;
rightFrozenColumnCount: number;
rowOverscanStartIdx: number;
rowOverscanEndIdx: number;
}
export function useViewportColumns<R, SR>({
columns,
colSpanColumns,
rows,
topSummaryRows,
bottomSummaryRows,
colOverscanStartIdx,
colOverscanEndIdx,
lastFrozenColumnIndex,
rightFrozenColumnCount,
rowOverscanStartIdx,
rowOverscanEndIdx
}: ViewportColumnsArgs<R, SR>) {
// find the column that spans over a column within the visible columns range and adjust colOverscanStartIdx
const startIdx = useMemo(() => {
if (colOverscanStartIdx === 0) return 0;
let startIdx = colOverscanStartIdx;
const updateStartIdx = (colIdx: number, colSpan: number | undefined) => {
if (colSpan !== undefined && colIdx + colSpan > colOverscanStartIdx) {
// eslint-disable-next-line react-compiler/react-compiler
startIdx = colIdx;
return true;
}
return false;
};
for (const column of colSpanColumns) {
// check header row
const colIdx = column.idx;
if (colIdx >= startIdx) break;
if (updateStartIdx(colIdx, getColSpan(column, lastFrozenColumnIndex, { type: 'HEADER' }))) {
break;
}
// check viewport rows
for (let rowIdx = rowOverscanStartIdx; rowIdx <= rowOverscanEndIdx; rowIdx++) {
const row = rows[rowIdx];
if (
updateStartIdx(colIdx, getColSpan(column, lastFrozenColumnIndex, { type: 'ROW', row }))
) {
break;
}
}
// check summary rows
if (topSummaryRows != null) {
for (const row of topSummaryRows) {
if (
updateStartIdx(
colIdx,
getColSpan(column, lastFrozenColumnIndex, { type: 'SUMMARY', row })
)
) {
break;
}
}
}
if (bottomSummaryRows != null) {
for (const row of bottomSummaryRows) {
if (
updateStartIdx(
colIdx,
getColSpan(column, lastFrozenColumnIndex, { type: 'SUMMARY', row })
)
) {
break;
}
}
}
}
return startIdx;
}, [
rowOverscanStartIdx,
rowOverscanEndIdx,
rows,
topSummaryRows,
bottomSummaryRows,
colOverscanStartIdx,
lastFrozenColumnIndex,
colSpanColumns
]);
return useMemo((): readonly CalculatedColumn<R, SR>[] => {
const viewportColumns: CalculatedColumn<R, SR>[] = [];
for (let colIdx = 0; colIdx <= colOverscanEndIdx; colIdx++) {
const column = columns[colIdx];
if (colIdx < startIdx && !column.frozen) continue;
viewportColumns.push(column);
}
for(let colIdx = columns.length-rightFrozenColumnCount; colIdx<columns.length; colIdx++) {
const column = columns[colIdx];
viewportColumns.push(column);
}
return viewportColumns;
}, [startIdx, colOverscanEndIdx, columns]);
}