@etsoo/react 1.8.51 → 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/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/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/index.ts +0 -5
- package/vite.config.mts +1 -0
|
@@ -1,66 +1,41 @@
|
|
|
1
1
|
import { DataTypes } from "@etsoo/shared";
|
|
2
2
|
import React from "react";
|
|
3
|
-
import {
|
|
3
|
+
import { ListProps } from "react-window";
|
|
4
4
|
import { GridLoader } from "./GridLoader";
|
|
5
5
|
import { GridMethodRef } from "./GridMethodRef";
|
|
6
|
+
type ScrollerListRowProps<T extends object> = {
|
|
7
|
+
items: T[];
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Scroller list forward ref
|
|
11
|
+
*/
|
|
12
|
+
export interface ScrollerListForwardRef<T> extends GridMethodRef<T> {
|
|
13
|
+
}
|
|
6
14
|
/**
|
|
7
15
|
* Scroller vertical list props
|
|
8
16
|
*/
|
|
9
|
-
export type ScrollerListProps<T extends object> = GridLoader<T> & Omit<ListProps<T
|
|
10
|
-
/**
|
|
11
|
-
* Methods ref
|
|
12
|
-
*/
|
|
13
|
-
mRef?: React.Ref<ScrollerListForwardRef<T>>;
|
|
14
|
-
/**
|
|
15
|
-
* Outer div ref
|
|
16
|
-
*/
|
|
17
|
-
oRef?: React.Ref<HTMLDivElement>;
|
|
17
|
+
export type ScrollerListProps<T extends object> = GridLoader<T> & Omit<ListProps<ScrollerListRowProps<T>>, "rowCount" | "rowProps" | "overscanCount"> & {
|
|
18
18
|
/**
|
|
19
19
|
* Height of the list
|
|
20
20
|
*/
|
|
21
|
-
height?: number;
|
|
22
|
-
/**
|
|
23
|
-
* Width of the list
|
|
24
|
-
*/
|
|
25
|
-
width?: number | string;
|
|
21
|
+
height?: number | string;
|
|
26
22
|
/**
|
|
27
23
|
* Id field
|
|
28
24
|
*/
|
|
29
25
|
idField?: DataTypes.Keys<T>;
|
|
30
26
|
/**
|
|
31
|
-
*
|
|
27
|
+
* Methods ref
|
|
32
28
|
*/
|
|
33
|
-
|
|
29
|
+
mRef?: React.Ref<ScrollerListForwardRef<T>>;
|
|
34
30
|
/**
|
|
35
|
-
*
|
|
31
|
+
* Width of the list
|
|
36
32
|
*/
|
|
37
|
-
|
|
33
|
+
width?: number | string;
|
|
38
34
|
};
|
|
39
|
-
/**
|
|
40
|
-
* Scroller list ref
|
|
41
|
-
*/
|
|
42
|
-
export interface ScrollerListRef {
|
|
43
|
-
/**
|
|
44
|
-
* Scroll to the specified offset (scrollTop or scrollLeft, depending on the direction prop).
|
|
45
|
-
*/
|
|
46
|
-
scrollTo(scrollOffset: number): void;
|
|
47
|
-
/**
|
|
48
|
-
* Scroll to the specified item.
|
|
49
|
-
*/
|
|
50
|
-
scrollToItem(index: number, align?: Align): void;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Scroller list forward ref
|
|
54
|
-
*/
|
|
55
|
-
export interface ScrollerListForwardRef<T> extends GridMethodRef<T> {
|
|
56
|
-
/**
|
|
57
|
-
* Refresh latest page data
|
|
58
|
-
*/
|
|
59
|
-
refresh(): void;
|
|
60
|
-
}
|
|
61
35
|
/**
|
|
62
36
|
* Scroller vertical list
|
|
63
37
|
* @param props Props
|
|
64
38
|
* @returns Component
|
|
65
39
|
*/
|
|
66
40
|
export declare const ScrollerList: <T extends object>(props: ScrollerListProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
41
|
+
export {};
|
|
@@ -9,11 +9,14 @@ const shared_1 = require("@etsoo/shared");
|
|
|
9
9
|
const react_1 = __importDefault(require("react"));
|
|
10
10
|
const react_window_1 = require("react-window");
|
|
11
11
|
const useCombinedRefs_1 = require("../uses/useCombinedRefs");
|
|
12
|
-
const GridLoader_1 = require("./GridLoader");
|
|
13
12
|
// Calculate loadBatchSize
|
|
14
|
-
const calculateBatchSize = (height,
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
const calculateBatchSize = (height, rowHeight) => {
|
|
14
|
+
if (typeof height === "number" &&
|
|
15
|
+
typeof rowHeight === "number" &&
|
|
16
|
+
rowHeight > 0) {
|
|
17
|
+
return 1 + Math.ceil(height / rowHeight);
|
|
18
|
+
}
|
|
19
|
+
return 10;
|
|
17
20
|
};
|
|
18
21
|
/**
|
|
19
22
|
* Scroller vertical list
|
|
@@ -22,18 +25,14 @@ const calculateBatchSize = (height, itemSize) => {
|
|
|
22
25
|
*/
|
|
23
26
|
const ScrollerList = (props) => {
|
|
24
27
|
// Destruct
|
|
25
|
-
const { autoLoad = true, defaultOrderBy, height =
|
|
28
|
+
const { autoLoad = true, defaultOrderBy, height = "100%", width = "100%", mRef, style = {}, idField = "id", rowHeight, listRef, loadBatchSize = calculateBatchSize(height, rowHeight), loadData, threshold = 3, onRowsRendered, onInitLoad, onUpdateRows, ...rest } = props;
|
|
26
29
|
// Style
|
|
27
30
|
Object.assign(style, {
|
|
28
|
-
width
|
|
29
|
-
height
|
|
30
|
-
display: "inline-block"
|
|
31
|
+
width,
|
|
32
|
+
height
|
|
31
33
|
});
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
const outerRef = react_1.default.useRef(null);
|
|
35
|
-
const refs = (0, useCombinedRefs_1.useCombinedRefs)(oRef, outerRef);
|
|
36
|
-
// Rows
|
|
34
|
+
const localRef = (0, react_window_1.useListRef)(null);
|
|
35
|
+
const refs = (0, useCombinedRefs_1.useCombinedRefs)(listRef, localRef);
|
|
37
36
|
const [rows, updateRows] = react_1.default.useState([]);
|
|
38
37
|
const setRows = (rows, reset = false) => {
|
|
39
38
|
stateRefs.current.loadedItems = rows.length;
|
|
@@ -41,8 +40,7 @@ const ScrollerList = (props) => {
|
|
|
41
40
|
if (!reset && onUpdateRows)
|
|
42
41
|
onUpdateRows(rows, stateRefs.current);
|
|
43
42
|
};
|
|
44
|
-
|
|
45
|
-
const batchSize = (0, GridLoader_1.GridSizeGet)(loadBatchSize, height);
|
|
43
|
+
const batchSize = shared_1.Utils.getResult(loadBatchSize, height);
|
|
46
44
|
const stateRefs = react_1.default.useRef({
|
|
47
45
|
queryPaging: {
|
|
48
46
|
currentPage: 0,
|
|
@@ -113,13 +111,6 @@ const ScrollerList = (props) => {
|
|
|
113
111
|
}
|
|
114
112
|
});
|
|
115
113
|
};
|
|
116
|
-
const itemRendererLocal = (itemProps) => {
|
|
117
|
-
// Custom render
|
|
118
|
-
return itemRenderer({
|
|
119
|
-
...itemProps,
|
|
120
|
-
data: rows[itemProps.index]
|
|
121
|
-
});
|
|
122
|
-
};
|
|
123
114
|
// Reset the state and load again
|
|
124
115
|
const reset = (add, items = []) => {
|
|
125
116
|
const { queryPaging, ...rest } = add ?? {};
|
|
@@ -142,7 +133,6 @@ const ScrollerList = (props) => {
|
|
|
142
133
|
setRows(items, true);
|
|
143
134
|
};
|
|
144
135
|
react_1.default.useImperativeHandle(mRef, () => {
|
|
145
|
-
const refMethods = listRef.current;
|
|
146
136
|
return {
|
|
147
137
|
delete(index) {
|
|
148
138
|
const item = rows.at(index);
|
|
@@ -162,48 +152,39 @@ const ScrollerList = (props) => {
|
|
|
162
152
|
loadDataLocal(0);
|
|
163
153
|
},
|
|
164
154
|
reset,
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
},
|
|
168
|
-
scrollToItemRef(index, align) {
|
|
169
|
-
refMethods.scrollToItem(index, align);
|
|
155
|
+
scrollToRow(param) {
|
|
156
|
+
localRef.current?.scrollToRow(param);
|
|
170
157
|
}
|
|
171
158
|
};
|
|
172
159
|
}, []);
|
|
173
|
-
//
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
loadDataLocal();
|
|
181
|
-
}
|
|
182
|
-
// Custom
|
|
183
|
-
if (onItemsRendered)
|
|
184
|
-
onItemsRendered(props);
|
|
185
|
-
};
|
|
186
|
-
// Item count
|
|
187
|
-
const itemCount = stateRefs.current.hasNextPage ? rowCount + 1 : rowCount;
|
|
160
|
+
// When layout ready
|
|
161
|
+
react_1.default.useEffect(() => {
|
|
162
|
+
// Return clear function
|
|
163
|
+
return () => {
|
|
164
|
+
stateRefs.current.isMounted = false;
|
|
165
|
+
};
|
|
166
|
+
}, []);
|
|
188
167
|
react_1.default.useEffect(() => {
|
|
189
168
|
// Auto load data when current page is 0
|
|
190
169
|
if (stateRefs.current.queryPaging?.currentPage === 0 &&
|
|
191
170
|
stateRefs.current.autoLoad) {
|
|
192
|
-
const initItems = onInitLoad == null ? undefined : onInitLoad(
|
|
171
|
+
const initItems = onInitLoad == null ? undefined : onInitLoad(localRef.current);
|
|
193
172
|
if (initItems)
|
|
194
173
|
reset(initItems[1], initItems[0]);
|
|
195
174
|
else
|
|
196
175
|
loadDataLocal();
|
|
197
176
|
}
|
|
198
177
|
}, [onInitLoad, loadDataLocal]);
|
|
199
|
-
//
|
|
200
|
-
|
|
201
|
-
// Return clear function
|
|
202
|
-
return () => {
|
|
203
|
-
stateRefs.current.isMounted = false;
|
|
204
|
-
};
|
|
205
|
-
}, []);
|
|
178
|
+
// Row count
|
|
179
|
+
const rowCount = rows.length;
|
|
206
180
|
// Layout
|
|
207
|
-
return
|
|
181
|
+
return ((0, jsx_runtime_1.jsx)(react_window_1.List, { listRef: refs, onRowsRendered: (visibleCells, allCells) => {
|
|
182
|
+
// No items, means no necessary to load more data during reset
|
|
183
|
+
if (rowCount > 0 && visibleCells.stopIndex + threshold > rowCount) {
|
|
184
|
+
// Auto load next page
|
|
185
|
+
loadDataLocal();
|
|
186
|
+
}
|
|
187
|
+
onRowsRendered?.(visibleCells, allCells);
|
|
188
|
+
}, overscanCount: threshold, rowHeight: rowHeight, rowCount: rowCount, rowProps: { items: rows }, style: style, ...rest }));
|
|
208
189
|
};
|
|
209
190
|
exports.ScrollerList = ScrollerList;
|
package/lib/cjs/index.d.ts
CHANGED
|
@@ -10,7 +10,6 @@ export * from "./components/ListItemReact";
|
|
|
10
10
|
export * from "./components/ScrollerGrid";
|
|
11
11
|
export * from "./components/ScrollerList";
|
|
12
12
|
export * from "./components/ScrollRestoration";
|
|
13
|
-
export type { ListOnScrollProps, GridOnScrollProps, VariableSizeGrid } from "react-window";
|
|
14
13
|
export * from "./custom/CustomFieldReact";
|
|
15
14
|
export * from "./notifier/Notifier";
|
|
16
15
|
export * from "@etsoo/notificationbase";
|
|
@@ -3,7 +3,7 @@ import { DataTypes } from "@etsoo/shared";
|
|
|
3
3
|
/**
|
|
4
4
|
* Grid size
|
|
5
5
|
*/
|
|
6
|
-
export type GridSize = number | ((input: number) => number);
|
|
6
|
+
export type GridSize = number | ((input: number | string) => number);
|
|
7
7
|
/**
|
|
8
8
|
* Grid size calculation
|
|
9
9
|
* @param size Size
|
|
@@ -81,7 +81,7 @@ export type GridLoader<T extends object, P extends GridJsonData = GridLoadDataPr
|
|
|
81
81
|
*/
|
|
82
82
|
defaultOrderBy?: QueryPagingOrder[];
|
|
83
83
|
/**
|
|
84
|
-
* Batch size when load data, default will be calcuated with height and
|
|
84
|
+
* Batch size when load data, default will be calcuated with height and rowHeight
|
|
85
85
|
*/
|
|
86
86
|
loadBatchSize?: GridSize;
|
|
87
87
|
/**
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ListImperativeAPI } from "react-window";
|
|
2
2
|
import { GridLoaderPartialStates } from "./GridLoader";
|
|
3
|
+
/**
|
|
4
|
+
* Scroll to row parameter type
|
|
5
|
+
*/
|
|
6
|
+
export type ScrollToRowParam = Parameters<ListImperativeAPI["scrollToRow"]>[0];
|
|
3
7
|
/**
|
|
4
8
|
* Grid method ref
|
|
5
9
|
*/
|
|
@@ -15,17 +19,18 @@ export interface GridMethodRef<T> {
|
|
|
15
19
|
* @param start Start position
|
|
16
20
|
*/
|
|
17
21
|
insert(item: T, start: number): void;
|
|
22
|
+
/**
|
|
23
|
+
* Refresh latest page data
|
|
24
|
+
*/
|
|
25
|
+
refresh(): void;
|
|
18
26
|
/**
|
|
19
27
|
* Reset
|
|
20
28
|
* @param add Additional data
|
|
21
29
|
*/
|
|
22
30
|
reset(add?: GridLoaderPartialStates<T>): void;
|
|
23
31
|
/**
|
|
24
|
-
* Scroll to the
|
|
25
|
-
|
|
26
|
-
scrollToRef(scrollOffset: number): void;
|
|
27
|
-
/**
|
|
28
|
-
* Scroll to the specified item.
|
|
32
|
+
* Scroll to the row
|
|
33
|
+
* @param param Parameters to control
|
|
29
34
|
*/
|
|
30
|
-
|
|
35
|
+
scrollToRow(param: ScrollToRowParam): void;
|
|
31
36
|
}
|
|
@@ -1,27 +1,23 @@
|
|
|
1
1
|
import { DataTypes } from "@etsoo/shared";
|
|
2
2
|
import React from "react";
|
|
3
|
-
import {
|
|
3
|
+
import { GridProps } from "react-window";
|
|
4
4
|
import { GridJsonData, GridLoadDataProps, GridLoader, GridLoaderStates } from "./GridLoader";
|
|
5
|
-
import { GridMethodRef } from "./GridMethodRef";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Data
|
|
18
|
-
*/
|
|
19
|
-
data?: T;
|
|
5
|
+
import { GridMethodRef, ScrollToRowParam } from "./GridMethodRef";
|
|
6
|
+
type ScrollerGridCellrops<T extends object> = {
|
|
7
|
+
rows: T[];
|
|
8
|
+
states: GridLoaderStates<T>;
|
|
9
|
+
};
|
|
10
|
+
export type ScrollToCellParam = {
|
|
11
|
+
behavior?: ScrollToRowParam["behavior"];
|
|
12
|
+
columnAlign?: ScrollToRowParam["align"];
|
|
13
|
+
columnIndex: number;
|
|
14
|
+
rowAlign?: ScrollToRowParam["align"];
|
|
15
|
+
rowIndex: number;
|
|
20
16
|
};
|
|
21
17
|
/**
|
|
22
18
|
* Scroller vertical grid props
|
|
23
19
|
*/
|
|
24
|
-
export type ScrollerGridProps<T extends object, P extends GridJsonData = GridLoadDataProps> = GridLoader<T, P> & Omit<
|
|
20
|
+
export type ScrollerGridProps<T extends object, P extends GridJsonData = GridLoadDataProps> = GridLoader<T, P> & Omit<GridProps<ScrollerGridCellrops<T>>, "cellProps" | "overscanCount" | "rowCount"> & {
|
|
25
21
|
/**
|
|
26
22
|
* Footer renderer
|
|
27
23
|
*/
|
|
@@ -31,13 +27,13 @@ export type ScrollerGridProps<T extends object, P extends GridJsonData = GridLoa
|
|
|
31
27
|
*/
|
|
32
28
|
headerRenderer?: (states: GridLoaderStates<T>) => React.ReactNode;
|
|
33
29
|
/**
|
|
34
|
-
*
|
|
30
|
+
* Height of the grid
|
|
35
31
|
*/
|
|
36
|
-
|
|
32
|
+
height?: number | string;
|
|
37
33
|
/**
|
|
38
|
-
*
|
|
34
|
+
* Id field
|
|
39
35
|
*/
|
|
40
|
-
|
|
36
|
+
idField?: DataTypes.Keys<T>;
|
|
41
37
|
/**
|
|
42
38
|
* Methods
|
|
43
39
|
*/
|
|
@@ -47,34 +43,24 @@ export type ScrollerGridProps<T extends object, P extends GridJsonData = GridLoa
|
|
|
47
43
|
*/
|
|
48
44
|
onSelectChange?: (selectedItems: T[]) => void;
|
|
49
45
|
/**
|
|
50
|
-
*
|
|
46
|
+
* Width of the grid
|
|
51
47
|
*/
|
|
52
|
-
|
|
48
|
+
width?: number | string;
|
|
53
49
|
};
|
|
54
50
|
/**
|
|
55
51
|
* Scroller grid forward ref
|
|
56
52
|
*/
|
|
57
53
|
export interface ScrollerGridForwardRef<T> extends GridMethodRef<T> {
|
|
58
54
|
/**
|
|
59
|
-
* Scroll to the
|
|
55
|
+
* Scroll to the cell
|
|
56
|
+
* @param param Parameters to control
|
|
60
57
|
*/
|
|
61
|
-
|
|
62
|
-
scrollLeft: number;
|
|
63
|
-
scrollTop: number;
|
|
64
|
-
}): void;
|
|
65
|
-
scrollToItem(params: {
|
|
66
|
-
align?: Align | undefined;
|
|
67
|
-
columnIndex?: number | undefined;
|
|
68
|
-
rowIndex?: number | undefined;
|
|
69
|
-
}): void;
|
|
58
|
+
scrollToCell(param: ScrollToCellParam): void;
|
|
70
59
|
/**
|
|
71
|
-
* Scroll to the
|
|
60
|
+
* Scroll to the cell
|
|
61
|
+
* @param param Parameters to control
|
|
72
62
|
*/
|
|
73
|
-
|
|
74
|
-
align?: Align | undefined;
|
|
75
|
-
columnIndex?: number | undefined;
|
|
76
|
-
rowIndex?: number | undefined;
|
|
77
|
-
}): void;
|
|
63
|
+
scrollToColumn(param: ScrollToRowParam): void;
|
|
78
64
|
/**
|
|
79
65
|
* Select the item
|
|
80
66
|
* @param rowIndex Row index
|
|
@@ -91,18 +77,6 @@ export interface ScrollerGridForwardRef<T> extends GridMethodRef<T> {
|
|
|
91
77
|
* @param checked Checked
|
|
92
78
|
*/
|
|
93
79
|
selectItem(item: any, checked: boolean): void;
|
|
94
|
-
/**
|
|
95
|
-
*
|
|
96
|
-
* @param index
|
|
97
|
-
* @param shouldForceUpdate
|
|
98
|
-
*/
|
|
99
|
-
resetAfterColumnIndex(index: number, shouldForceUpdate?: boolean): void;
|
|
100
|
-
resetAfterIndices(params: {
|
|
101
|
-
columnIndex: number;
|
|
102
|
-
rowIndex: number;
|
|
103
|
-
shouldForceUpdate?: boolean | undefined;
|
|
104
|
-
}): void;
|
|
105
|
-
resetAfterRowIndex(index: number, shouldForceUpdate?: boolean): void;
|
|
106
80
|
}
|
|
107
81
|
/**
|
|
108
82
|
* Scroller vertical grid
|
|
@@ -110,3 +84,4 @@ export interface ScrollerGridForwardRef<T> extends GridMethodRef<T> {
|
|
|
110
84
|
* @returns Component
|
|
111
85
|
*/
|
|
112
86
|
export declare const ScrollerGrid: <T extends object>(props: ScrollerGridProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
87
|
+
export {};
|