@etsoo/react 1.8.50 → 1.8.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__tests__/ScrollerGrid.tsx +95 -0
- package/__tests__/ScrollerList.tsx +85 -0
- package/lib/cjs/components/GridLoader.d.ts +2 -2
- package/lib/cjs/components/GridMethodRef.d.ts +12 -7
- package/lib/cjs/components/ScrollerGrid.d.ts +26 -51
- package/lib/cjs/components/ScrollerGrid.js +67 -101
- package/lib/cjs/components/ScrollerList.d.ts +16 -41
- package/lib/cjs/components/ScrollerList.js +33 -52
- package/lib/cjs/custom/CustomFieldReact.d.ts +1 -1
- package/lib/cjs/index.d.ts +0 -1
- package/lib/mjs/components/GridLoader.d.ts +2 -2
- package/lib/mjs/components/GridMethodRef.d.ts +12 -7
- package/lib/mjs/components/ScrollerGrid.d.ts +26 -51
- package/lib/mjs/components/ScrollerGrid.js +68 -102
- package/lib/mjs/components/ScrollerList.d.ts +16 -41
- package/lib/mjs/components/ScrollerList.js +35 -54
- package/lib/mjs/custom/CustomFieldReact.d.ts +1 -1
- package/lib/mjs/index.d.ts +0 -1
- package/package.json +13 -13
- package/setupTests.ts +13 -0
- package/src/components/GridLoader.ts +2 -2
- package/src/components/GridMethodRef.ts +14 -8
- package/src/components/ScrollerGrid.tsx +163 -251
- package/src/components/ScrollerList.tsx +71 -152
- package/src/custom/CustomFieldReact.ts +1 -1
- package/src/index.ts +0 -5
- package/vite.config.mts +1 -0
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
import { DataTypes } from "@etsoo/shared";
|
|
2
2
|
import React from "react";
|
|
3
|
-
import {
|
|
4
|
-
Align,
|
|
5
|
-
GridChildComponentProps,
|
|
6
|
-
GridOnItemsRenderedProps,
|
|
7
|
-
VariableSizeGrid,
|
|
8
|
-
VariableSizeGridProps
|
|
9
|
-
} from "react-window";
|
|
3
|
+
import { Grid, GridProps, useGridRef } from "react-window";
|
|
10
4
|
import {
|
|
11
5
|
GridJsonData,
|
|
12
6
|
GridLoadDataProps,
|
|
@@ -14,32 +8,20 @@ import {
|
|
|
14
8
|
GridLoaderPartialStates,
|
|
15
9
|
GridLoaderStates
|
|
16
10
|
} from "./GridLoader";
|
|
17
|
-
import { GridMethodRef } from "./GridMethodRef";
|
|
11
|
+
import { GridMethodRef, ScrollToRowParam } from "./GridMethodRef";
|
|
12
|
+
import { useCombinedRefs } from "../uses/useCombinedRefs";
|
|
18
13
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Selected items
|
|
25
|
-
*/
|
|
26
|
-
selectedItems: T[];
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Set items for rerenderer
|
|
30
|
-
* @param callback Callback
|
|
31
|
-
*/
|
|
32
|
-
setItems: (
|
|
33
|
-
callback: (
|
|
34
|
-
items: T[],
|
|
35
|
-
ref: ScrollerGridForwardRef<T>
|
|
36
|
-
) => T[] | undefined | void
|
|
37
|
-
) => void;
|
|
14
|
+
type ScrollerGridCellrops<T extends object> = {
|
|
15
|
+
rows: T[];
|
|
16
|
+
states: GridLoaderStates<T>;
|
|
17
|
+
};
|
|
38
18
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
19
|
+
export type ScrollToCellParam = {
|
|
20
|
+
behavior?: ScrollToRowParam["behavior"];
|
|
21
|
+
columnAlign?: ScrollToRowParam["align"];
|
|
22
|
+
columnIndex: number;
|
|
23
|
+
rowAlign?: ScrollToRowParam["align"];
|
|
24
|
+
rowIndex: number;
|
|
43
25
|
};
|
|
44
26
|
|
|
45
27
|
/**
|
|
@@ -49,7 +31,10 @@ export type ScrollerGridProps<
|
|
|
49
31
|
T extends object,
|
|
50
32
|
P extends GridJsonData = GridLoadDataProps
|
|
51
33
|
> = GridLoader<T, P> &
|
|
52
|
-
Omit<
|
|
34
|
+
Omit<
|
|
35
|
+
GridProps<ScrollerGridCellrops<T>>,
|
|
36
|
+
"cellProps" | "overscanCount" | "rowCount"
|
|
37
|
+
> & {
|
|
53
38
|
/**
|
|
54
39
|
* Footer renderer
|
|
55
40
|
*/
|
|
@@ -64,16 +49,14 @@ export type ScrollerGridProps<
|
|
|
64
49
|
headerRenderer?: (states: GridLoaderStates<T>) => React.ReactNode;
|
|
65
50
|
|
|
66
51
|
/**
|
|
67
|
-
*
|
|
52
|
+
* Height of the grid
|
|
68
53
|
*/
|
|
69
|
-
|
|
54
|
+
height?: number | string;
|
|
70
55
|
|
|
71
56
|
/**
|
|
72
|
-
*
|
|
57
|
+
* Id field
|
|
73
58
|
*/
|
|
74
|
-
|
|
75
|
-
props: ScrollerGridItemRendererProps<T>
|
|
76
|
-
) => React.ReactElement;
|
|
59
|
+
idField?: DataTypes.Keys<T>;
|
|
77
60
|
|
|
78
61
|
/**
|
|
79
62
|
* Methods
|
|
@@ -86,9 +69,9 @@ export type ScrollerGridProps<
|
|
|
86
69
|
onSelectChange?: (selectedItems: T[]) => void;
|
|
87
70
|
|
|
88
71
|
/**
|
|
89
|
-
*
|
|
72
|
+
* Width of the grid
|
|
90
73
|
*/
|
|
91
|
-
|
|
74
|
+
width?: number | string;
|
|
92
75
|
};
|
|
93
76
|
|
|
94
77
|
/**
|
|
@@ -96,24 +79,16 @@ export type ScrollerGridProps<
|
|
|
96
79
|
*/
|
|
97
80
|
export interface ScrollerGridForwardRef<T> extends GridMethodRef<T> {
|
|
98
81
|
/**
|
|
99
|
-
* Scroll to the
|
|
82
|
+
* Scroll to the cell
|
|
83
|
+
* @param param Parameters to control
|
|
100
84
|
*/
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
scrollToItem(params: {
|
|
104
|
-
align?: Align | undefined;
|
|
105
|
-
columnIndex?: number | undefined;
|
|
106
|
-
rowIndex?: number | undefined;
|
|
107
|
-
}): void;
|
|
85
|
+
scrollToCell(param: ScrollToCellParam): void;
|
|
108
86
|
|
|
109
87
|
/**
|
|
110
|
-
* Scroll to the
|
|
88
|
+
* Scroll to the cell
|
|
89
|
+
* @param param Parameters to control
|
|
111
90
|
*/
|
|
112
|
-
|
|
113
|
-
align?: Align | undefined;
|
|
114
|
-
columnIndex?: number | undefined;
|
|
115
|
-
rowIndex?: number | undefined;
|
|
116
|
-
}): void;
|
|
91
|
+
scrollToColumn(param: ScrollToRowParam): void;
|
|
117
92
|
|
|
118
93
|
/**
|
|
119
94
|
* Select the item
|
|
@@ -133,21 +108,6 @@ export interface ScrollerGridForwardRef<T> extends GridMethodRef<T> {
|
|
|
133
108
|
* @param checked Checked
|
|
134
109
|
*/
|
|
135
110
|
selectItem(item: any, checked: boolean): void;
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
*
|
|
139
|
-
* @param index
|
|
140
|
-
* @param shouldForceUpdate
|
|
141
|
-
*/
|
|
142
|
-
resetAfterColumnIndex(index: number, shouldForceUpdate?: boolean): void;
|
|
143
|
-
|
|
144
|
-
resetAfterIndices(params: {
|
|
145
|
-
columnIndex: number;
|
|
146
|
-
rowIndex: number;
|
|
147
|
-
shouldForceUpdate?: boolean | undefined;
|
|
148
|
-
}): void;
|
|
149
|
-
|
|
150
|
-
resetAfterRowIndex(index: number, shouldForceUpdate?: boolean): void;
|
|
151
111
|
}
|
|
152
112
|
|
|
153
113
|
/**
|
|
@@ -162,32 +122,45 @@ export const ScrollerGrid = <T extends object>(props: ScrollerGridProps<T>) => {
|
|
|
162
122
|
defaultOrderBy,
|
|
163
123
|
footerRenderer,
|
|
164
124
|
headerRenderer,
|
|
165
|
-
|
|
125
|
+
height = "100%",
|
|
126
|
+
gridRef,
|
|
127
|
+
width = "100%",
|
|
128
|
+
style = {},
|
|
166
129
|
idField = "id" as DataTypes.Keys<T>,
|
|
167
130
|
loadBatchSize,
|
|
168
131
|
loadData,
|
|
169
132
|
mRef,
|
|
170
|
-
|
|
133
|
+
onCellsRendered,
|
|
171
134
|
onSelectChange,
|
|
172
135
|
rowHeight = 53,
|
|
173
|
-
threshold =
|
|
174
|
-
width,
|
|
136
|
+
threshold = 3,
|
|
175
137
|
onInitLoad,
|
|
176
138
|
onUpdateRows,
|
|
177
139
|
...rest
|
|
178
140
|
} = props;
|
|
179
141
|
|
|
142
|
+
// Style
|
|
143
|
+
Object.assign(style, {
|
|
144
|
+
width,
|
|
145
|
+
height,
|
|
146
|
+
overflowX: "hidden"
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// Refs
|
|
150
|
+
const localRef = useGridRef(null);
|
|
151
|
+
const refs = useCombinedRefs(gridRef, localRef);
|
|
152
|
+
|
|
180
153
|
// Rows
|
|
181
154
|
const [rows, updateRows] = React.useState<T[]>([]);
|
|
182
155
|
const setRows = (rows: T[], reset: boolean = false) => {
|
|
183
|
-
|
|
156
|
+
stateRefs.current.loadedItems = rows.length;
|
|
184
157
|
updateRows(rows);
|
|
185
158
|
|
|
186
|
-
if (!reset && onUpdateRows) onUpdateRows(rows,
|
|
159
|
+
if (!reset && onUpdateRows) onUpdateRows(rows, stateRefs.current);
|
|
187
160
|
};
|
|
188
161
|
|
|
189
|
-
// Refs
|
|
190
|
-
const
|
|
162
|
+
// State Refs
|
|
163
|
+
const stateRefs = React.useRef<GridLoaderStates<T>>({
|
|
191
164
|
queryPaging: {
|
|
192
165
|
currentPage: 0,
|
|
193
166
|
orderBy: defaultOrderBy,
|
|
@@ -201,72 +174,71 @@ export const ScrollerGrid = <T extends object>(props: ScrollerGridProps<T>) => {
|
|
|
201
174
|
idCache: {}
|
|
202
175
|
});
|
|
203
176
|
|
|
204
|
-
const ref = React.useRef<VariableSizeGrid<T>>(null);
|
|
205
|
-
|
|
206
177
|
// Load data
|
|
207
178
|
const loadDataLocal = (pageAdd: number = 1) => {
|
|
208
179
|
// Prevent multiple loadings
|
|
209
180
|
if (
|
|
210
|
-
!
|
|
211
|
-
|
|
212
|
-
|
|
181
|
+
!stateRefs.current.hasNextPage ||
|
|
182
|
+
stateRefs.current.isNextPageLoading ||
|
|
183
|
+
stateRefs.current.isMounted === false
|
|
213
184
|
)
|
|
214
185
|
return;
|
|
215
186
|
|
|
216
187
|
// Update state
|
|
217
|
-
|
|
188
|
+
stateRefs.current.isNextPageLoading = true;
|
|
218
189
|
|
|
219
190
|
// Parameters
|
|
220
|
-
const { queryPaging, data } =
|
|
191
|
+
const { queryPaging, data } = stateRefs.current;
|
|
221
192
|
|
|
222
193
|
const loadProps: GridLoadDataProps = {
|
|
223
194
|
queryPaging,
|
|
224
195
|
data
|
|
225
196
|
};
|
|
226
197
|
|
|
227
|
-
loadData(loadProps,
|
|
228
|
-
if (result == null ||
|
|
198
|
+
loadData(loadProps, stateRefs.current.lastItem).then((result) => {
|
|
199
|
+
if (result == null || stateRefs.current.isMounted === false) {
|
|
229
200
|
return;
|
|
230
201
|
}
|
|
231
|
-
|
|
202
|
+
stateRefs.current.isMounted = true;
|
|
232
203
|
|
|
233
204
|
const newItems = result.length;
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
205
|
+
stateRefs.current.lastLoadedItems = newItems;
|
|
206
|
+
stateRefs.current.lastItem = result.at(-1);
|
|
207
|
+
stateRefs.current.isNextPageLoading = false;
|
|
208
|
+
stateRefs.current.hasNextPage =
|
|
209
|
+
newItems >= stateRefs.current.queryPaging.batchSize;
|
|
238
210
|
|
|
239
211
|
if (pageAdd === 0) {
|
|
240
212
|
// New items
|
|
241
|
-
const newRows =
|
|
213
|
+
const newRows = stateRefs.current.lastLoadedItems
|
|
242
214
|
? [...rows]
|
|
243
215
|
.splice(
|
|
244
|
-
rows.length -
|
|
245
|
-
|
|
216
|
+
rows.length - stateRefs.current.lastLoadedItems,
|
|
217
|
+
stateRefs.current.lastLoadedItems
|
|
246
218
|
)
|
|
247
219
|
.concat(result)
|
|
248
220
|
: result;
|
|
249
221
|
|
|
250
|
-
|
|
222
|
+
stateRefs.current.idCache = {};
|
|
251
223
|
for (const row of newRows) {
|
|
252
224
|
const id = row[idField] as any;
|
|
253
|
-
|
|
225
|
+
stateRefs.current.idCache[id] = null;
|
|
254
226
|
}
|
|
255
227
|
|
|
256
228
|
// Update rows
|
|
257
229
|
setRows(newRows);
|
|
258
230
|
} else {
|
|
259
231
|
// Set current page
|
|
260
|
-
if (
|
|
261
|
-
|
|
262
|
-
else
|
|
232
|
+
if (stateRefs.current.queryPaging.currentPage == null)
|
|
233
|
+
stateRefs.current.queryPaging.currentPage = pageAdd;
|
|
234
|
+
else stateRefs.current.queryPaging.currentPage += pageAdd;
|
|
263
235
|
|
|
264
236
|
// Update rows, avoid duplicate items
|
|
265
237
|
const newRows = [...rows];
|
|
266
238
|
|
|
267
239
|
for (const item of result) {
|
|
268
240
|
const id = item[idField] as any;
|
|
269
|
-
if (
|
|
241
|
+
if (stateRefs.current.idCache[id] === undefined) {
|
|
270
242
|
newRows.push(item);
|
|
271
243
|
}
|
|
272
244
|
}
|
|
@@ -276,44 +248,6 @@ export const ScrollerGrid = <T extends object>(props: ScrollerGridProps<T>) => {
|
|
|
276
248
|
});
|
|
277
249
|
};
|
|
278
250
|
|
|
279
|
-
// Item renderer
|
|
280
|
-
const itemRendererLocal = (
|
|
281
|
-
itemProps: GridChildComponentProps<T>,
|
|
282
|
-
state: GridLoaderStates<T>
|
|
283
|
-
) => {
|
|
284
|
-
// Custom render
|
|
285
|
-
const data =
|
|
286
|
-
itemProps.rowIndex < rows.length ? rows[itemProps.rowIndex] : undefined;
|
|
287
|
-
return itemRenderer({
|
|
288
|
-
...itemProps,
|
|
289
|
-
data,
|
|
290
|
-
selectedItems: state.selectedItems,
|
|
291
|
-
setItems: (
|
|
292
|
-
callback: (
|
|
293
|
-
items: T[],
|
|
294
|
-
ref: ScrollerGridForwardRef<T>
|
|
295
|
-
) => T[] | undefined | void
|
|
296
|
-
) => {
|
|
297
|
-
const result = callback(rows, instance);
|
|
298
|
-
if (result == null) return;
|
|
299
|
-
setRows(result);
|
|
300
|
-
}
|
|
301
|
-
});
|
|
302
|
-
};
|
|
303
|
-
|
|
304
|
-
// Local items renderer callback
|
|
305
|
-
const onItemsRenderedLocal = (props: GridOnItemsRenderedProps) => {
|
|
306
|
-
// No items, means no necessary to load more data during reset
|
|
307
|
-
const itemCount = rows.length;
|
|
308
|
-
if (itemCount > 0 && props.visibleRowStopIndex + threshold > itemCount) {
|
|
309
|
-
// Auto load next page
|
|
310
|
-
loadDataLocal();
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
// Custom
|
|
314
|
-
if (onItemsRendered) onItemsRendered(props);
|
|
315
|
-
};
|
|
316
|
-
|
|
317
251
|
// Reset the state and load again
|
|
318
252
|
const reset = (add?: GridLoaderPartialStates<T>, items: T[] = []) => {
|
|
319
253
|
const { queryPaging, ...rest } = add ?? {};
|
|
@@ -326,124 +260,99 @@ export const ScrollerGrid = <T extends object>(props: ScrollerGridProps<T>) => {
|
|
|
326
260
|
lastItem: undefined,
|
|
327
261
|
...rest
|
|
328
262
|
};
|
|
329
|
-
Object.assign(
|
|
330
|
-
Object.assign(
|
|
263
|
+
Object.assign(stateRefs.current, resetState);
|
|
264
|
+
Object.assign(stateRefs.current.queryPaging, {
|
|
331
265
|
currentPage: 0,
|
|
332
266
|
...queryPaging
|
|
333
267
|
});
|
|
334
268
|
|
|
335
269
|
// Reset items
|
|
336
|
-
if (
|
|
270
|
+
if (stateRefs.current.isMounted !== false) setRows(items, true);
|
|
337
271
|
};
|
|
338
272
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
273
|
+
React.useImperativeHandle(
|
|
274
|
+
mRef,
|
|
275
|
+
() => ({
|
|
276
|
+
delete(index) {
|
|
277
|
+
const item = rows.at(index);
|
|
278
|
+
if (item) {
|
|
279
|
+
const newRows = [...rows];
|
|
280
|
+
newRows.splice(index, 1);
|
|
281
|
+
setRows(newRows);
|
|
282
|
+
}
|
|
283
|
+
return item;
|
|
284
|
+
},
|
|
285
|
+
insert(item, start) {
|
|
343
286
|
const newRows = [...rows];
|
|
344
|
-
newRows.splice(
|
|
287
|
+
newRows.splice(start, 0, item);
|
|
345
288
|
setRows(newRows);
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
rowIndex
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
289
|
+
},
|
|
290
|
+
refresh(): void {
|
|
291
|
+
loadDataLocal(0);
|
|
292
|
+
},
|
|
293
|
+
reset,
|
|
294
|
+
scrollToCell(param: ScrollToCellParam): void {
|
|
295
|
+
localRef.current?.scrollToCell(param);
|
|
296
|
+
},
|
|
297
|
+
scrollToColumn(param: ScrollToRowParam): void {
|
|
298
|
+
localRef.current?.scrollToColumn(param);
|
|
299
|
+
},
|
|
300
|
+
scrollToRow(param: ScrollToRowParam): void {
|
|
301
|
+
localRef.current?.scrollToRow(param);
|
|
302
|
+
},
|
|
303
|
+
select(rowIndex: number) {
|
|
304
|
+
// Select only one item
|
|
305
|
+
const selectedItems = stateRefs.current.selectedItems;
|
|
306
|
+
selectedItems[0] = rows[rowIndex];
|
|
307
|
+
|
|
308
|
+
if (onSelectChange) onSelectChange(selectedItems);
|
|
309
|
+
},
|
|
310
|
+
selectAll(checked: boolean) {
|
|
311
|
+
const selectedItems = stateRefs.current.selectedItems;
|
|
312
|
+
|
|
313
|
+
rows.forEach((row) => {
|
|
314
|
+
const index = selectedItems.findIndex(
|
|
315
|
+
(selectedItem) => selectedItem[idField] === row[idField]
|
|
316
|
+
);
|
|
317
|
+
|
|
318
|
+
if (checked) {
|
|
319
|
+
if (index === -1) selectedItems.push(row);
|
|
320
|
+
} else if (index !== -1) {
|
|
321
|
+
selectedItems.splice(index, 1);
|
|
322
|
+
}
|
|
323
|
+
});
|
|
380
324
|
|
|
381
|
-
|
|
325
|
+
if (onSelectChange) onSelectChange(selectedItems);
|
|
326
|
+
},
|
|
327
|
+
selectItem(item: T, checked: boolean) {
|
|
328
|
+
const selectedItems = stateRefs.current.selectedItems;
|
|
382
329
|
const index = selectedItems.findIndex(
|
|
383
|
-
(selectedItem) => selectedItem[idField] ===
|
|
330
|
+
(selectedItem) => selectedItem[idField] === item[idField]
|
|
384
331
|
);
|
|
385
332
|
|
|
386
333
|
if (checked) {
|
|
387
|
-
if (index === -1) selectedItems.push(
|
|
388
|
-
} else
|
|
389
|
-
selectedItems.splice(index, 1);
|
|
334
|
+
if (index === -1) selectedItems.push(item);
|
|
335
|
+
} else {
|
|
336
|
+
if (index !== -1) selectedItems.splice(index, 1);
|
|
390
337
|
}
|
|
391
|
-
});
|
|
392
338
|
|
|
393
|
-
|
|
394
|
-
},
|
|
395
|
-
selectItem(item: T, checked: boolean) {
|
|
396
|
-
const selectedItems = refs.current.selectedItems;
|
|
397
|
-
const index = selectedItems.findIndex(
|
|
398
|
-
(selectedItem) => selectedItem[idField] === item[idField]
|
|
399
|
-
);
|
|
400
|
-
|
|
401
|
-
if (checked) {
|
|
402
|
-
if (index === -1) selectedItems.push(item);
|
|
403
|
-
} else {
|
|
404
|
-
if (index !== -1) selectedItems.splice(index, 1);
|
|
339
|
+
if (onSelectChange) onSelectChange(selectedItems);
|
|
405
340
|
}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
reset,
|
|
410
|
-
resetAfterColumnIndex(index: number, shouldForceUpdate?: boolean) {
|
|
411
|
-
ref.current?.resetAfterColumnIndex(index, shouldForceUpdate);
|
|
412
|
-
},
|
|
413
|
-
resetAfterIndices(params: {
|
|
414
|
-
columnIndex: number;
|
|
415
|
-
rowIndex: number;
|
|
416
|
-
shouldForceUpdate?: boolean | undefined;
|
|
417
|
-
}) {
|
|
418
|
-
ref.current?.resetAfterIndices(params);
|
|
419
|
-
},
|
|
420
|
-
resetAfterRowIndex(index: number, shouldForceUpdate?: boolean) {
|
|
421
|
-
ref.current?.resetAfterRowIndex(index, shouldForceUpdate);
|
|
422
|
-
}
|
|
423
|
-
};
|
|
424
|
-
|
|
425
|
-
React.useImperativeHandle(mRef, () => instance, [rows]);
|
|
426
|
-
|
|
427
|
-
// Force update to work with the new width and rowHeight
|
|
428
|
-
React.useEffect(() => {
|
|
429
|
-
ref.current?.resetAfterIndices({
|
|
430
|
-
columnIndex: 0,
|
|
431
|
-
rowIndex: 0,
|
|
432
|
-
shouldForceUpdate: true
|
|
433
|
-
});
|
|
434
|
-
}, [width, rowHeight]);
|
|
341
|
+
}),
|
|
342
|
+
[rows]
|
|
343
|
+
);
|
|
435
344
|
|
|
436
345
|
// Rows
|
|
437
|
-
const
|
|
438
|
-
|
|
439
|
-
// Row count
|
|
440
|
-
const rowCount = refs.current.hasNextPage ? rowLength + 1 : rowLength;
|
|
346
|
+
const rowCount = rows.length;
|
|
441
347
|
|
|
442
348
|
React.useEffect(() => {
|
|
443
349
|
// Auto load data when current page is 0
|
|
444
|
-
if (
|
|
350
|
+
if (
|
|
351
|
+
stateRefs.current.queryPaging.currentPage === 0 &&
|
|
352
|
+
stateRefs.current.autoLoad
|
|
353
|
+
) {
|
|
445
354
|
const initItems =
|
|
446
|
-
onInitLoad == null ? undefined : onInitLoad(
|
|
355
|
+
onInitLoad == null ? undefined : onInitLoad(stateRefs.current);
|
|
447
356
|
if (initItems) reset(initItems[1], initItems[0]);
|
|
448
357
|
else loadDataLocal();
|
|
449
358
|
}
|
|
@@ -451,33 +360,36 @@ export const ScrollerGrid = <T extends object>(props: ScrollerGridProps<T>) => {
|
|
|
451
360
|
|
|
452
361
|
React.useEffect(() => {
|
|
453
362
|
return () => {
|
|
454
|
-
|
|
363
|
+
stateRefs.current.isMounted = false;
|
|
455
364
|
};
|
|
456
365
|
}, []);
|
|
457
366
|
|
|
458
367
|
// Layout
|
|
459
368
|
return (
|
|
460
369
|
<React.Fragment>
|
|
461
|
-
{headerRenderer && headerRenderer(
|
|
462
|
-
<
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
370
|
+
{headerRenderer && headerRenderer(stateRefs.current)}
|
|
371
|
+
<Grid<ScrollerGridCellrops<T>>
|
|
372
|
+
cellProps={{ rows, states: stateRefs.current }}
|
|
373
|
+
gridRef={refs}
|
|
374
|
+
onCellsRendered={(visibleCells, allCells) => {
|
|
375
|
+
// No items, means no necessary to load more data during reset
|
|
376
|
+
if (
|
|
377
|
+
rowCount > 0 &&
|
|
378
|
+
visibleCells.rowStopIndex + threshold > rowCount
|
|
379
|
+
) {
|
|
380
|
+
// Auto load next page
|
|
381
|
+
loadDataLocal();
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
onCellsRendered?.(visibleCells, allCells);
|
|
467
385
|
}}
|
|
468
|
-
|
|
469
|
-
|
|
386
|
+
overscanCount={threshold}
|
|
387
|
+
rowHeight={rowHeight}
|
|
470
388
|
rowCount={rowCount}
|
|
471
|
-
|
|
472
|
-
typeof rowHeight === "function" ? rowHeight : () => rowHeight
|
|
473
|
-
}
|
|
474
|
-
style={{ overflowX: "hidden" }}
|
|
475
|
-
width={width}
|
|
389
|
+
style={style}
|
|
476
390
|
{...rest}
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
</VariableSizeGrid>
|
|
480
|
-
{footerRenderer && footerRenderer(rows, refs.current)}
|
|
391
|
+
/>
|
|
392
|
+
{footerRenderer && footerRenderer(rows, stateRefs.current)}
|
|
481
393
|
</React.Fragment>
|
|
482
394
|
);
|
|
483
395
|
};
|