@etsoo/react 1.8.22 → 1.8.24
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/lib/cjs/app/CoreConstants.js +17 -0
- package/lib/cjs/app/EventWatcher.js +45 -0
- package/lib/cjs/app/InputDialogProps.js +2 -0
- package/lib/cjs/app/ReactUtils.js +173 -0
- package/lib/cjs/components/DnDList.js +136 -0
- package/lib/cjs/components/DynamicRouter.js +39 -0
- package/lib/cjs/components/GridColumn.js +46 -0
- package/lib/cjs/components/GridLoader.js +49 -0
- package/lib/cjs/components/GridMethodRef.js +2 -0
- package/lib/cjs/components/ListItemReact.js +2 -0
- package/lib/cjs/components/ScrollRestoration.js +37 -0
- package/lib/cjs/components/ScrollerGrid.js +254 -0
- package/lib/cjs/components/ScrollerList.js +205 -0
- package/lib/cjs/custom/CustomFieldReact.js +2 -0
- package/lib/cjs/index.js +54 -0
- package/lib/cjs/notifier/Notifier.js +82 -0
- package/lib/cjs/states/CultureState.js +46 -0
- package/lib/cjs/states/IState.js +2 -0
- package/lib/cjs/states/PageState.js +46 -0
- package/lib/cjs/states/State.js +48 -0
- package/lib/cjs/states/UserState.js +80 -0
- package/lib/cjs/uses/useAsyncState.js +39 -0
- package/lib/cjs/uses/useCombinedRefs.js +29 -0
- package/lib/cjs/uses/useDelayedExecutor.js +17 -0
- package/lib/cjs/uses/useDimensions.js +98 -0
- package/lib/cjs/uses/useParamsEx.js +15 -0
- package/lib/cjs/uses/useRefs.js +17 -0
- package/lib/cjs/uses/useRequiredContext.js +19 -0
- package/lib/cjs/uses/useSearchParamsEx.js +19 -0
- package/lib/cjs/uses/useTimeout.js +29 -0
- package/lib/cjs/uses/useWindowScroll.js +53 -0
- package/lib/cjs/uses/useWindowSize.js +53 -0
- package/lib/mjs/app/CoreConstants.d.ts +13 -0
- package/lib/mjs/app/EventWatcher.d.ts +35 -0
- package/lib/mjs/app/InputDialogProps.d.ts +19 -0
- package/lib/mjs/app/ReactUtils.d.ts +41 -0
- package/lib/mjs/components/DnDList.d.ts +74 -0
- package/lib/mjs/components/DynamicRouter.d.ts +24 -0
- package/lib/mjs/components/GridColumn.d.ts +193 -0
- package/lib/mjs/components/GridLoader.d.ts +155 -0
- package/lib/mjs/components/GridMethodRef.d.ts +31 -0
- package/lib/mjs/components/ListItemReact.d.ts +6 -0
- package/lib/mjs/components/ScrollRestoration.d.ts +4 -0
- package/lib/mjs/components/ScrollerGrid.d.ts +112 -0
- package/lib/mjs/components/ScrollerList.d.ts +66 -0
- package/lib/mjs/custom/CustomFieldReact.d.ts +22 -0
- package/lib/mjs/index.d.ts +33 -0
- package/lib/mjs/notifier/Notifier.d.ts +143 -0
- package/lib/mjs/states/CultureState.d.ts +41 -0
- package/lib/mjs/states/IState.d.ts +49 -0
- package/lib/mjs/states/PageState.d.ts +61 -0
- package/lib/mjs/states/State.d.ts +18 -0
- package/lib/mjs/states/UserState.d.ts +56 -0
- package/lib/mjs/uses/useAsyncState.d.ts +11 -0
- package/lib/mjs/uses/useCombinedRefs.d.ts +6 -0
- package/lib/mjs/uses/useDelayedExecutor.d.ts +5 -0
- package/lib/mjs/uses/useDimensions.d.ts +17 -0
- package/lib/mjs/uses/useParamsEx.d.ts +6 -0
- package/lib/mjs/uses/useRefs.d.ts +8 -0
- package/lib/mjs/uses/useRequiredContext.d.ts +7 -0
- package/lib/mjs/uses/useSearchParamsEx.d.ts +6 -0
- package/lib/mjs/uses/useTimeout.d.ts +8 -0
- package/lib/mjs/uses/useWindowScroll.d.ts +12 -0
- package/lib/mjs/uses/useWindowSize.d.ts +10 -0
- package/package.json +14 -9
- package/tsconfig.cjs.json +20 -0
- package/tsconfig.json +2 -2
- /package/lib/{app → cjs/app}/CoreConstants.d.ts +0 -0
- /package/lib/{app → cjs/app}/EventWatcher.d.ts +0 -0
- /package/lib/{app → cjs/app}/InputDialogProps.d.ts +0 -0
- /package/lib/{app → cjs/app}/ReactUtils.d.ts +0 -0
- /package/lib/{components → cjs/components}/DnDList.d.ts +0 -0
- /package/lib/{components → cjs/components}/DynamicRouter.d.ts +0 -0
- /package/lib/{components → cjs/components}/GridColumn.d.ts +0 -0
- /package/lib/{components → cjs/components}/GridLoader.d.ts +0 -0
- /package/lib/{components → cjs/components}/GridMethodRef.d.ts +0 -0
- /package/lib/{components → cjs/components}/ListItemReact.d.ts +0 -0
- /package/lib/{components → cjs/components}/ScrollRestoration.d.ts +0 -0
- /package/lib/{components → cjs/components}/ScrollerGrid.d.ts +0 -0
- /package/lib/{components → cjs/components}/ScrollerList.d.ts +0 -0
- /package/lib/{custom → cjs/custom}/CustomFieldReact.d.ts +0 -0
- /package/lib/{index.d.ts → cjs/index.d.ts} +0 -0
- /package/lib/{notifier → cjs/notifier}/Notifier.d.ts +0 -0
- /package/lib/{states → cjs/states}/CultureState.d.ts +0 -0
- /package/lib/{states → cjs/states}/IState.d.ts +0 -0
- /package/lib/{states → cjs/states}/PageState.d.ts +0 -0
- /package/lib/{states → cjs/states}/State.d.ts +0 -0
- /package/lib/{states → cjs/states}/UserState.d.ts +0 -0
- /package/lib/{uses → cjs/uses}/useAsyncState.d.ts +0 -0
- /package/lib/{uses → cjs/uses}/useCombinedRefs.d.ts +0 -0
- /package/lib/{uses → cjs/uses}/useDelayedExecutor.d.ts +0 -0
- /package/lib/{uses → cjs/uses}/useDimensions.d.ts +0 -0
- /package/lib/{uses → cjs/uses}/useParamsEx.d.ts +0 -0
- /package/lib/{uses → cjs/uses}/useRefs.d.ts +0 -0
- /package/lib/{uses → cjs/uses}/useRequiredContext.d.ts +0 -0
- /package/lib/{uses → cjs/uses}/useSearchParamsEx.d.ts +0 -0
- /package/lib/{uses → cjs/uses}/useTimeout.d.ts +0 -0
- /package/lib/{uses → cjs/uses}/useWindowScroll.d.ts +0 -0
- /package/lib/{uses → cjs/uses}/useWindowSize.d.ts +0 -0
- /package/lib/{app → mjs/app}/CoreConstants.js +0 -0
- /package/lib/{app → mjs/app}/EventWatcher.js +0 -0
- /package/lib/{app → mjs/app}/InputDialogProps.js +0 -0
- /package/lib/{app → mjs/app}/ReactUtils.js +0 -0
- /package/lib/{components → mjs/components}/DnDList.js +0 -0
- /package/lib/{components → mjs/components}/DynamicRouter.js +0 -0
- /package/lib/{components → mjs/components}/GridColumn.js +0 -0
- /package/lib/{components → mjs/components}/GridLoader.js +0 -0
- /package/lib/{components → mjs/components}/GridMethodRef.js +0 -0
- /package/lib/{components → mjs/components}/ListItemReact.js +0 -0
- /package/lib/{components → mjs/components}/ScrollRestoration.js +0 -0
- /package/lib/{components → mjs/components}/ScrollerGrid.js +0 -0
- /package/lib/{components → mjs/components}/ScrollerList.js +0 -0
- /package/lib/{custom → mjs/custom}/CustomFieldReact.js +0 -0
- /package/lib/{index.js → mjs/index.js} +0 -0
- /package/lib/{notifier → mjs/notifier}/Notifier.js +0 -0
- /package/lib/{states → mjs/states}/CultureState.js +0 -0
- /package/lib/{states → mjs/states}/IState.js +0 -0
- /package/lib/{states → mjs/states}/PageState.js +0 -0
- /package/lib/{states → mjs/states}/State.js +0 -0
- /package/lib/{states → mjs/states}/UserState.js +0 -0
- /package/lib/{uses → mjs/uses}/useAsyncState.js +0 -0
- /package/lib/{uses → mjs/uses}/useCombinedRefs.js +0 -0
- /package/lib/{uses → mjs/uses}/useDelayedExecutor.js +0 -0
- /package/lib/{uses → mjs/uses}/useDimensions.js +0 -0
- /package/lib/{uses → mjs/uses}/useParamsEx.js +0 -0
- /package/lib/{uses → mjs/uses}/useRefs.js +0 -0
- /package/lib/{uses → mjs/uses}/useRequiredContext.js +0 -0
- /package/lib/{uses → mjs/uses}/useSearchParamsEx.js +0 -0
- /package/lib/{uses → mjs/uses}/useTimeout.js +0 -0
- /package/lib/{uses → mjs/uses}/useWindowScroll.js +0 -0
- /package/lib/{uses → mjs/uses}/useWindowSize.js +0 -0
- /package/{vite.config.ts → vite.config.mts} +0 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ScrollerGrid = void 0;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const react_1 = __importDefault(require("react"));
|
|
9
|
+
const react_window_1 = require("react-window");
|
|
10
|
+
/**
|
|
11
|
+
* Scroller vertical grid
|
|
12
|
+
* @param props Props
|
|
13
|
+
* @returns Component
|
|
14
|
+
*/
|
|
15
|
+
const ScrollerGrid = (props) => {
|
|
16
|
+
// Destruct
|
|
17
|
+
const { autoLoad = true, defaultOrderBy, footerRenderer, headerRenderer, itemRenderer, idField = "id", loadBatchSize, loadData, mRef, onItemsRendered, onSelectChange, rowHeight = 53, threshold = 6, width, onInitLoad, onUpdateRows, ...rest } = props;
|
|
18
|
+
// Rows
|
|
19
|
+
const [rows, updateRows] = react_1.default.useState([]);
|
|
20
|
+
const setRows = (rows, reset = false) => {
|
|
21
|
+
refs.current.loadedItems = rows.length;
|
|
22
|
+
updateRows(rows);
|
|
23
|
+
if (!reset && onUpdateRows)
|
|
24
|
+
onUpdateRows(rows, refs.current);
|
|
25
|
+
};
|
|
26
|
+
// Refs
|
|
27
|
+
const refs = react_1.default.useRef({
|
|
28
|
+
queryPaging: {
|
|
29
|
+
currentPage: 0,
|
|
30
|
+
orderBy: defaultOrderBy,
|
|
31
|
+
batchSize: 10
|
|
32
|
+
},
|
|
33
|
+
autoLoad,
|
|
34
|
+
hasNextPage: true,
|
|
35
|
+
isNextPageLoading: false,
|
|
36
|
+
loadedItems: 0,
|
|
37
|
+
selectedItems: [],
|
|
38
|
+
idCache: {}
|
|
39
|
+
});
|
|
40
|
+
const ref = react_1.default.useRef(null);
|
|
41
|
+
// Load data
|
|
42
|
+
const loadDataLocal = (pageAdd = 1) => {
|
|
43
|
+
// Prevent multiple loadings
|
|
44
|
+
if (!refs.current.hasNextPage || refs.current.isNextPageLoading)
|
|
45
|
+
return;
|
|
46
|
+
// Update state
|
|
47
|
+
refs.current.isNextPageLoading = true;
|
|
48
|
+
// Parameters
|
|
49
|
+
const { queryPaging, data } = refs.current;
|
|
50
|
+
const loadProps = {
|
|
51
|
+
queryPaging,
|
|
52
|
+
data
|
|
53
|
+
};
|
|
54
|
+
loadData(loadProps, refs.current.lastItem).then((result) => {
|
|
55
|
+
if (result == null || refs.current.isMounted === false) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
refs.current.isMounted = true;
|
|
59
|
+
const newItems = result.length;
|
|
60
|
+
refs.current.lastLoadedItems = newItems;
|
|
61
|
+
refs.current.lastItem = result.at(-1);
|
|
62
|
+
refs.current.isNextPageLoading = false;
|
|
63
|
+
refs.current.hasNextPage = newItems >= refs.current.queryPaging.batchSize;
|
|
64
|
+
if (pageAdd === 0) {
|
|
65
|
+
// New items
|
|
66
|
+
const newRows = refs.current.lastLoadedItems
|
|
67
|
+
? [...rows]
|
|
68
|
+
.splice(rows.length - refs.current.lastLoadedItems, refs.current.lastLoadedItems)
|
|
69
|
+
.concat(result)
|
|
70
|
+
: result;
|
|
71
|
+
refs.current.idCache = {};
|
|
72
|
+
for (const row of newRows) {
|
|
73
|
+
const id = row[idField];
|
|
74
|
+
refs.current.idCache[id] = null;
|
|
75
|
+
}
|
|
76
|
+
// Update rows
|
|
77
|
+
setRows(newRows);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
// Set current page
|
|
81
|
+
if (refs.current.queryPaging.currentPage == null)
|
|
82
|
+
refs.current.queryPaging.currentPage = pageAdd;
|
|
83
|
+
else
|
|
84
|
+
refs.current.queryPaging.currentPage += pageAdd;
|
|
85
|
+
// Update rows, avoid duplicate items
|
|
86
|
+
const newRows = [...rows];
|
|
87
|
+
for (const item of result) {
|
|
88
|
+
const id = item[idField];
|
|
89
|
+
if (refs.current.idCache[id] === undefined) {
|
|
90
|
+
newRows.push(item);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
setRows(newRows);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
// Item renderer
|
|
98
|
+
const itemRendererLocal = (itemProps, state) => {
|
|
99
|
+
// Custom render
|
|
100
|
+
const data = itemProps.rowIndex < rows.length ? rows[itemProps.rowIndex] : undefined;
|
|
101
|
+
return itemRenderer({
|
|
102
|
+
...itemProps,
|
|
103
|
+
data,
|
|
104
|
+
selectedItems: state.selectedItems,
|
|
105
|
+
setItems: (callback) => {
|
|
106
|
+
const result = callback(rows, instance);
|
|
107
|
+
if (result == null)
|
|
108
|
+
return;
|
|
109
|
+
setRows(result);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
};
|
|
113
|
+
// Local items renderer callback
|
|
114
|
+
const onItemsRenderedLocal = (props) => {
|
|
115
|
+
// No items, means no necessary to load more data during reset
|
|
116
|
+
const itemCount = rows.length;
|
|
117
|
+
if (itemCount > 0 && props.visibleRowStopIndex + threshold > itemCount) {
|
|
118
|
+
// Auto load next page
|
|
119
|
+
loadDataLocal();
|
|
120
|
+
}
|
|
121
|
+
// Custom
|
|
122
|
+
if (onItemsRendered)
|
|
123
|
+
onItemsRendered(props);
|
|
124
|
+
};
|
|
125
|
+
// Reset the state and load again
|
|
126
|
+
const reset = (add, items = []) => {
|
|
127
|
+
const { queryPaging, ...rest } = add ?? {};
|
|
128
|
+
const resetState = {
|
|
129
|
+
autoLoad: true,
|
|
130
|
+
loadedItems: 0,
|
|
131
|
+
hasNextPage: true,
|
|
132
|
+
isNextPageLoading: false,
|
|
133
|
+
lastLoadedItems: undefined,
|
|
134
|
+
lastItem: undefined,
|
|
135
|
+
...rest
|
|
136
|
+
};
|
|
137
|
+
Object.assign(refs.current, resetState);
|
|
138
|
+
Object.assign(refs.current.queryPaging, {
|
|
139
|
+
currentPage: 0,
|
|
140
|
+
...queryPaging
|
|
141
|
+
});
|
|
142
|
+
// Reset items
|
|
143
|
+
if (refs.current.isMounted !== false)
|
|
144
|
+
setRows(items, true);
|
|
145
|
+
};
|
|
146
|
+
const instance = {
|
|
147
|
+
delete(index) {
|
|
148
|
+
const item = rows.at(index);
|
|
149
|
+
if (item) {
|
|
150
|
+
const newRows = [...rows];
|
|
151
|
+
newRows.splice(index, 1);
|
|
152
|
+
setRows(newRows);
|
|
153
|
+
}
|
|
154
|
+
return item;
|
|
155
|
+
},
|
|
156
|
+
insert(item, start) {
|
|
157
|
+
const newRows = [...rows];
|
|
158
|
+
newRows.splice(start, 0, item);
|
|
159
|
+
setRows(newRows);
|
|
160
|
+
},
|
|
161
|
+
scrollTo(params) {
|
|
162
|
+
ref.current?.scrollTo(params);
|
|
163
|
+
},
|
|
164
|
+
scrollToItem(params) {
|
|
165
|
+
ref.current?.scrollToItem(params);
|
|
166
|
+
},
|
|
167
|
+
scrollToRef(scrollOffset) {
|
|
168
|
+
ref.current?.scrollTo({ scrollLeft: 0, scrollTop: scrollOffset });
|
|
169
|
+
},
|
|
170
|
+
scrollToItemRef(index, align) {
|
|
171
|
+
ref.current?.scrollToItem({ rowIndex: index, align });
|
|
172
|
+
},
|
|
173
|
+
select(rowIndex) {
|
|
174
|
+
// Select only one item
|
|
175
|
+
const selectedItems = refs.current.selectedItems;
|
|
176
|
+
selectedItems[0] = rows[rowIndex];
|
|
177
|
+
if (onSelectChange)
|
|
178
|
+
onSelectChange(selectedItems);
|
|
179
|
+
},
|
|
180
|
+
selectAll(checked) {
|
|
181
|
+
const selectedItems = refs.current.selectedItems;
|
|
182
|
+
rows.forEach((row) => {
|
|
183
|
+
const index = selectedItems.findIndex((selectedItem) => selectedItem[idField] === row[idField]);
|
|
184
|
+
if (checked) {
|
|
185
|
+
if (index === -1)
|
|
186
|
+
selectedItems.push(row);
|
|
187
|
+
}
|
|
188
|
+
else if (index !== -1) {
|
|
189
|
+
selectedItems.splice(index, 1);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
if (onSelectChange)
|
|
193
|
+
onSelectChange(selectedItems);
|
|
194
|
+
},
|
|
195
|
+
selectItem(item, checked) {
|
|
196
|
+
const selectedItems = refs.current.selectedItems;
|
|
197
|
+
const index = selectedItems.findIndex((selectedItem) => selectedItem[idField] === item[idField]);
|
|
198
|
+
if (checked) {
|
|
199
|
+
if (index === -1)
|
|
200
|
+
selectedItems.push(item);
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
if (index !== -1)
|
|
204
|
+
selectedItems.splice(index, 1);
|
|
205
|
+
}
|
|
206
|
+
if (onSelectChange)
|
|
207
|
+
onSelectChange(selectedItems);
|
|
208
|
+
},
|
|
209
|
+
reset,
|
|
210
|
+
resetAfterColumnIndex(index, shouldForceUpdate) {
|
|
211
|
+
ref.current?.resetAfterColumnIndex(index, shouldForceUpdate);
|
|
212
|
+
},
|
|
213
|
+
resetAfterIndices(params) {
|
|
214
|
+
ref.current?.resetAfterIndices(params);
|
|
215
|
+
},
|
|
216
|
+
resetAfterRowIndex(index, shouldForceUpdate) {
|
|
217
|
+
ref.current?.resetAfterRowIndex(index, shouldForceUpdate);
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
react_1.default.useImperativeHandle(mRef, () => instance, [rows]);
|
|
221
|
+
react_1.default.useEffect(() => {
|
|
222
|
+
return () => {
|
|
223
|
+
refs.current.isMounted = false;
|
|
224
|
+
};
|
|
225
|
+
}, []);
|
|
226
|
+
// Force update to work with the new width and rowHeight
|
|
227
|
+
react_1.default.useEffect(() => {
|
|
228
|
+
ref.current?.resetAfterIndices({
|
|
229
|
+
columnIndex: 0,
|
|
230
|
+
rowIndex: 0,
|
|
231
|
+
shouldForceUpdate: true
|
|
232
|
+
});
|
|
233
|
+
}, [width, rowHeight]);
|
|
234
|
+
// Rows
|
|
235
|
+
const rowLength = rows.length;
|
|
236
|
+
// Row count
|
|
237
|
+
const rowCount = refs.current.hasNextPage ? rowLength + 1 : rowLength;
|
|
238
|
+
// Auto load data when current page is 0
|
|
239
|
+
if (refs.current.queryPaging.currentPage === 0 && refs.current.autoLoad) {
|
|
240
|
+
const initItems = onInitLoad == null ? undefined : onInitLoad(ref.current);
|
|
241
|
+
if (initItems)
|
|
242
|
+
reset(initItems[1], initItems[0]);
|
|
243
|
+
else
|
|
244
|
+
loadDataLocal();
|
|
245
|
+
}
|
|
246
|
+
// Layout
|
|
247
|
+
return ((0, jsx_runtime_1.jsxs)(react_1.default.Fragment, { children: [headerRenderer && headerRenderer(refs.current), (0, jsx_runtime_1.jsx)(react_window_1.VariableSizeGrid, { itemKey: ({ columnIndex, rowIndex, data }) => {
|
|
248
|
+
if (data == null)
|
|
249
|
+
return [rowIndex, columnIndex].join(",");
|
|
250
|
+
// ${data[idField]}-${rowIndex} always unique but no cache for the same item
|
|
251
|
+
return [`${data[idField]}`, columnIndex].join(",");
|
|
252
|
+
}, onItemsRendered: onItemsRenderedLocal, ref: ref, rowCount: rowCount, rowHeight: typeof rowHeight === "function" ? rowHeight : () => rowHeight, style: { overflowX: "hidden" }, width: width, ...rest, children: (props) => itemRendererLocal(props, refs.current) }), footerRenderer && footerRenderer(rows, refs.current)] }));
|
|
253
|
+
};
|
|
254
|
+
exports.ScrollerGrid = ScrollerGrid;
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ScrollerList = void 0;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const shared_1 = require("@etsoo/shared");
|
|
9
|
+
const react_1 = __importDefault(require("react"));
|
|
10
|
+
const react_window_1 = require("react-window");
|
|
11
|
+
const useCombinedRefs_1 = require("../uses/useCombinedRefs");
|
|
12
|
+
const GridLoader_1 = require("./GridLoader");
|
|
13
|
+
// Calculate loadBatchSize
|
|
14
|
+
const calculateBatchSize = (height, itemSize) => {
|
|
15
|
+
const size = shared_1.Utils.getResult(itemSize, 0);
|
|
16
|
+
return 2 + Math.ceil(height / size);
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Scroller vertical list
|
|
20
|
+
* @param props Props
|
|
21
|
+
* @returns Component
|
|
22
|
+
*/
|
|
23
|
+
const ScrollerList = (props) => {
|
|
24
|
+
// Destruct
|
|
25
|
+
const { autoLoad = true, defaultOrderBy, height = document.documentElement.clientHeight, width = "100%", mRef, oRef, style = {}, idField = "id", itemRenderer, itemSize, loadBatchSize = calculateBatchSize(height, itemSize), loadData, threshold = (0, GridLoader_1.GridSizeGet)(loadBatchSize, height) / 2, onItemsRendered, onInitLoad, onUpdateRows, ...rest } = props;
|
|
26
|
+
// Style
|
|
27
|
+
Object.assign(style, {
|
|
28
|
+
width: "100%",
|
|
29
|
+
height: "100%",
|
|
30
|
+
display: "inline-block"
|
|
31
|
+
});
|
|
32
|
+
// Refs
|
|
33
|
+
const listRef = react_1.default.useRef();
|
|
34
|
+
const outerRef = react_1.default.useRef();
|
|
35
|
+
const refs = (0, useCombinedRefs_1.useCombinedRefs)(oRef, outerRef);
|
|
36
|
+
// Rows
|
|
37
|
+
const [rows, updateRows] = react_1.default.useState([]);
|
|
38
|
+
const setRows = (rows, reset = false) => {
|
|
39
|
+
stateRefs.current.loadedItems = rows.length;
|
|
40
|
+
updateRows(rows);
|
|
41
|
+
if (!reset && onUpdateRows)
|
|
42
|
+
onUpdateRows(rows, stateRefs.current);
|
|
43
|
+
};
|
|
44
|
+
// States
|
|
45
|
+
const batchSize = (0, GridLoader_1.GridSizeGet)(loadBatchSize, height);
|
|
46
|
+
const stateRefs = react_1.default.useRef({
|
|
47
|
+
queryPaging: {
|
|
48
|
+
currentPage: 0,
|
|
49
|
+
orderBy: defaultOrderBy,
|
|
50
|
+
batchSize
|
|
51
|
+
},
|
|
52
|
+
autoLoad,
|
|
53
|
+
loadedItems: 0,
|
|
54
|
+
hasNextPage: true,
|
|
55
|
+
isNextPageLoading: false,
|
|
56
|
+
selectedItems: [],
|
|
57
|
+
idCache: {}
|
|
58
|
+
});
|
|
59
|
+
// Load data
|
|
60
|
+
const loadDataLocal = (pageAdd = 1) => {
|
|
61
|
+
// Prevent multiple loadings
|
|
62
|
+
if (!stateRefs.current.hasNextPage || stateRefs.current.isNextPageLoading)
|
|
63
|
+
return;
|
|
64
|
+
// Update state
|
|
65
|
+
stateRefs.current.isNextPageLoading = true;
|
|
66
|
+
// Parameters
|
|
67
|
+
const { queryPaging, data } = stateRefs.current;
|
|
68
|
+
const loadProps = {
|
|
69
|
+
queryPaging,
|
|
70
|
+
data
|
|
71
|
+
};
|
|
72
|
+
loadData(loadProps, stateRefs.current.lastItem).then((result) => {
|
|
73
|
+
if (result == null || stateRefs.current.isMounted === false) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
stateRefs.current.isMounted = true;
|
|
77
|
+
const newItems = result.length;
|
|
78
|
+
stateRefs.current.lastLoadedItems = newItems;
|
|
79
|
+
stateRefs.current.lastItem = result.at(-1);
|
|
80
|
+
stateRefs.current.hasNextPage = newItems >= batchSize;
|
|
81
|
+
stateRefs.current.isNextPageLoading = false;
|
|
82
|
+
if (pageAdd === 0) {
|
|
83
|
+
// New items
|
|
84
|
+
const newRows = stateRefs.current.lastLoadedItems
|
|
85
|
+
? [...rows]
|
|
86
|
+
.splice(rows.length - stateRefs.current.lastLoadedItems, stateRefs.current.lastLoadedItems)
|
|
87
|
+
.concat(result)
|
|
88
|
+
: result;
|
|
89
|
+
stateRefs.current.idCache = {};
|
|
90
|
+
for (const row of newRows) {
|
|
91
|
+
const id = row[idField];
|
|
92
|
+
stateRefs.current.idCache[id] = null;
|
|
93
|
+
}
|
|
94
|
+
// Update rows
|
|
95
|
+
setRows(newRows);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
if (stateRefs.current.queryPaging.currentPage == null)
|
|
99
|
+
stateRefs.current.queryPaging.currentPage = pageAdd;
|
|
100
|
+
else
|
|
101
|
+
stateRefs.current.queryPaging.currentPage += pageAdd;
|
|
102
|
+
// Update rows, avoid duplicate items
|
|
103
|
+
const newRows = [...rows];
|
|
104
|
+
for (const item of result) {
|
|
105
|
+
const id = item[idField];
|
|
106
|
+
if (stateRefs.current.idCache[id] === undefined) {
|
|
107
|
+
newRows.push(item);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
setRows(newRows);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
};
|
|
114
|
+
const itemRendererLocal = (itemProps) => {
|
|
115
|
+
// Custom render
|
|
116
|
+
return itemRenderer({
|
|
117
|
+
...itemProps,
|
|
118
|
+
data: rows[itemProps.index]
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
// Reset the state and load again
|
|
122
|
+
const reset = (add, items = []) => {
|
|
123
|
+
const { queryPaging, ...rest } = add ?? {};
|
|
124
|
+
const resetState = {
|
|
125
|
+
autoLoad: true,
|
|
126
|
+
loadedItems: 0,
|
|
127
|
+
hasNextPage: true,
|
|
128
|
+
isNextPageLoading: false,
|
|
129
|
+
lastLoadedItems: undefined,
|
|
130
|
+
lastItem: undefined,
|
|
131
|
+
...rest
|
|
132
|
+
};
|
|
133
|
+
Object.assign(stateRefs.current, resetState);
|
|
134
|
+
Object.assign(stateRefs.current.queryPaging, {
|
|
135
|
+
currentPage: 0,
|
|
136
|
+
...queryPaging
|
|
137
|
+
});
|
|
138
|
+
// Reset
|
|
139
|
+
if (stateRefs.current.isMounted !== false)
|
|
140
|
+
setRows(items, true);
|
|
141
|
+
};
|
|
142
|
+
react_1.default.useImperativeHandle(mRef, () => {
|
|
143
|
+
const refMethods = listRef.current;
|
|
144
|
+
return {
|
|
145
|
+
delete(index) {
|
|
146
|
+
const item = rows.at(index);
|
|
147
|
+
if (item) {
|
|
148
|
+
const newRows = [...rows];
|
|
149
|
+
newRows.splice(index, 1);
|
|
150
|
+
setRows(newRows);
|
|
151
|
+
}
|
|
152
|
+
return item;
|
|
153
|
+
},
|
|
154
|
+
insert(item, start) {
|
|
155
|
+
const newRows = [...rows];
|
|
156
|
+
newRows.splice(start, 0, item);
|
|
157
|
+
setRows(newRows);
|
|
158
|
+
},
|
|
159
|
+
refresh() {
|
|
160
|
+
loadDataLocal(0);
|
|
161
|
+
},
|
|
162
|
+
reset,
|
|
163
|
+
scrollToRef(scrollOffset) {
|
|
164
|
+
refMethods.scrollTo(scrollOffset);
|
|
165
|
+
},
|
|
166
|
+
scrollToItemRef(index, align) {
|
|
167
|
+
refMethods.scrollToItem(index, align);
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
}, []);
|
|
171
|
+
// When layout ready
|
|
172
|
+
react_1.default.useEffect(() => {
|
|
173
|
+
// Return clear function
|
|
174
|
+
return () => {
|
|
175
|
+
stateRefs.current.isMounted = false;
|
|
176
|
+
};
|
|
177
|
+
}, []);
|
|
178
|
+
// Row count
|
|
179
|
+
const rowCount = rows.length;
|
|
180
|
+
// Local items renderer callback
|
|
181
|
+
const onItemsRenderedLocal = (props) => {
|
|
182
|
+
// No items, means no necessary to load more data during reset
|
|
183
|
+
if (rowCount > 0 && props.visibleStopIndex + threshold > rowCount) {
|
|
184
|
+
// Auto load next page
|
|
185
|
+
loadDataLocal();
|
|
186
|
+
}
|
|
187
|
+
// Custom
|
|
188
|
+
if (onItemsRendered)
|
|
189
|
+
onItemsRendered(props);
|
|
190
|
+
};
|
|
191
|
+
// Item count
|
|
192
|
+
const itemCount = stateRefs.current.hasNextPage ? rowCount + 1 : rowCount;
|
|
193
|
+
// Auto load data when current page is 0
|
|
194
|
+
if (stateRefs.current.queryPaging?.currentPage === 0 &&
|
|
195
|
+
stateRefs.current.autoLoad) {
|
|
196
|
+
const initItems = onInitLoad == null ? undefined : onInitLoad(listRef.current);
|
|
197
|
+
if (initItems)
|
|
198
|
+
reset(initItems[1], initItems[0]);
|
|
199
|
+
else
|
|
200
|
+
loadDataLocal();
|
|
201
|
+
}
|
|
202
|
+
// Layout
|
|
203
|
+
return typeof itemSize === "function" ? ((0, jsx_runtime_1.jsx)(react_window_1.VariableSizeList, { height: height, width: width, itemCount: itemCount, itemKey: (index, data) => shared_1.DataTypes.getIdValue1(data, idField) ?? index, itemSize: itemSize, outerRef: refs, ref: listRef, style: style, onItemsRendered: onItemsRenderedLocal, ...rest, children: itemRendererLocal })) : ((0, jsx_runtime_1.jsx)(react_window_1.FixedSizeList, { height: height, width: width, itemCount: itemCount, itemKey: (index, data) => shared_1.DataTypes.getIdValue1(data, idField) ?? index, itemSize: itemSize, outerRef: refs, ref: listRef, style: style, onItemsRendered: onItemsRenderedLocal, ...rest, children: itemRendererLocal }));
|
|
204
|
+
};
|
|
205
|
+
exports.ScrollerList = ScrollerList;
|
package/lib/cjs/index.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
// app
|
|
18
|
+
__exportStar(require("./app/CoreConstants"), exports);
|
|
19
|
+
__exportStar(require("./app/EventWatcher"), exports);
|
|
20
|
+
__exportStar(require("./app/InputDialogProps"), exports);
|
|
21
|
+
__exportStar(require("./app/ReactUtils"), exports);
|
|
22
|
+
// components
|
|
23
|
+
__exportStar(require("./components/DnDList"), exports);
|
|
24
|
+
__exportStar(require("./components/DynamicRouter"), exports);
|
|
25
|
+
__exportStar(require("./components/GridColumn"), exports);
|
|
26
|
+
__exportStar(require("./components/GridLoader"), exports);
|
|
27
|
+
__exportStar(require("./components/GridMethodRef"), exports);
|
|
28
|
+
__exportStar(require("./components/ListItemReact"), exports);
|
|
29
|
+
__exportStar(require("./components/ScrollerGrid"), exports);
|
|
30
|
+
__exportStar(require("./components/ScrollerList"), exports);
|
|
31
|
+
__exportStar(require("./components/ScrollRestoration"), exports);
|
|
32
|
+
// custom
|
|
33
|
+
__exportStar(require("./custom/CustomFieldReact"), exports);
|
|
34
|
+
// notifier
|
|
35
|
+
__exportStar(require("./notifier/Notifier"), exports);
|
|
36
|
+
__exportStar(require("@etsoo/notificationbase"), exports);
|
|
37
|
+
// states
|
|
38
|
+
__exportStar(require("./states/CultureState"), exports);
|
|
39
|
+
__exportStar(require("./states/IState"), exports);
|
|
40
|
+
__exportStar(require("./states/PageState"), exports);
|
|
41
|
+
__exportStar(require("./states/State"), exports);
|
|
42
|
+
__exportStar(require("./states/UserState"), exports);
|
|
43
|
+
// uses
|
|
44
|
+
__exportStar(require("./uses/useAsyncState"), exports);
|
|
45
|
+
__exportStar(require("./uses/useCombinedRefs"), exports);
|
|
46
|
+
__exportStar(require("./uses/useDelayedExecutor"), exports);
|
|
47
|
+
__exportStar(require("./uses/useDimensions"), exports);
|
|
48
|
+
__exportStar(require("./uses/useParamsEx"), exports);
|
|
49
|
+
__exportStar(require("./uses/useRefs"), exports);
|
|
50
|
+
__exportStar(require("./uses/useRequiredContext"), exports);
|
|
51
|
+
__exportStar(require("./uses/useSearchParamsEx"), exports);
|
|
52
|
+
__exportStar(require("./uses/useTimeout"), exports);
|
|
53
|
+
__exportStar(require("./uses/useWindowScroll"), exports);
|
|
54
|
+
__exportStar(require("./uses/useWindowSize"), exports);
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.NotifierReact = exports.NotificationReact = void 0;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const notificationbase_1 = require("@etsoo/notificationbase");
|
|
9
|
+
const State_1 = require("../states/State");
|
|
10
|
+
/**
|
|
11
|
+
* React notification
|
|
12
|
+
*/
|
|
13
|
+
class NotificationReact extends notificationbase_1.Notification {
|
|
14
|
+
}
|
|
15
|
+
exports.NotificationReact = NotificationReact;
|
|
16
|
+
/**
|
|
17
|
+
* Notifier for React
|
|
18
|
+
*/
|
|
19
|
+
class NotifierReact extends notificationbase_1.NotificationContainer {
|
|
20
|
+
/**
|
|
21
|
+
* Singleton instance
|
|
22
|
+
*/
|
|
23
|
+
static get instance() {
|
|
24
|
+
return NotifierReact._instance;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Update notifier
|
|
28
|
+
* @param notifier Notifier
|
|
29
|
+
*/
|
|
30
|
+
static updateInstance(notifier) {
|
|
31
|
+
NotifierReact._instance = notifier;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Constructor
|
|
35
|
+
*/
|
|
36
|
+
constructor() {
|
|
37
|
+
super((notification, dismiss) => {
|
|
38
|
+
// Debug
|
|
39
|
+
if (this.debug) {
|
|
40
|
+
console.debug("NotifierReact.updateCallback", notification, dismiss, this.loadingCount);
|
|
41
|
+
}
|
|
42
|
+
// Make sure the state update is set
|
|
43
|
+
if (this.stateUpdate)
|
|
44
|
+
this.stateUpdate({ notification, dismiss });
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Create state provider
|
|
49
|
+
* @param className Style class name
|
|
50
|
+
* @returns Provider
|
|
51
|
+
*/
|
|
52
|
+
createProvider(className, debug) {
|
|
53
|
+
// Custom creator
|
|
54
|
+
const creator = (state, update, props) => {
|
|
55
|
+
// Hold the current state update
|
|
56
|
+
this.stateUpdate = update;
|
|
57
|
+
// Aligns collection
|
|
58
|
+
const aligns = [];
|
|
59
|
+
for (const align in state) {
|
|
60
|
+
// Notifications under the align
|
|
61
|
+
const notifications = state[align];
|
|
62
|
+
// UI collections
|
|
63
|
+
const ui = notifications.map((notification) => notification.render(props, className ? className + "-item" : className));
|
|
64
|
+
// Add to the collection
|
|
65
|
+
aligns.push(this.createContainer(Number(align), ui));
|
|
66
|
+
}
|
|
67
|
+
// Debug
|
|
68
|
+
if (debug) {
|
|
69
|
+
console.debug("NotifierReact.createProvider", className, state, aligns);
|
|
70
|
+
}
|
|
71
|
+
// Generate the component
|
|
72
|
+
return react_1.default.createElement("div", { className }, aligns);
|
|
73
|
+
};
|
|
74
|
+
// Create state
|
|
75
|
+
const { provider } = State_1.State.create((state, _action) => {
|
|
76
|
+
// Collection update is done with NotificationContainer
|
|
77
|
+
return { ...state };
|
|
78
|
+
}, this.notifications, {}, creator);
|
|
79
|
+
return provider;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
exports.NotifierReact = NotifierReact;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CultureState = void 0;
|
|
4
|
+
const State_1 = require("./State");
|
|
5
|
+
// Calls
|
|
6
|
+
const calls = {
|
|
7
|
+
/**
|
|
8
|
+
* Key value
|
|
9
|
+
* @param key Item key
|
|
10
|
+
*/
|
|
11
|
+
get(key) {
|
|
12
|
+
const resources = this.state.resources;
|
|
13
|
+
const value = typeof resources === "object" ? resources[key] : undefined;
|
|
14
|
+
if (value == null)
|
|
15
|
+
return undefined;
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Culture state
|
|
21
|
+
* Creator for culture context and provider globally, not inside a component to avoid problem:
|
|
22
|
+
* Cannot update a component (`provider`) while rendering a different component
|
|
23
|
+
*/
|
|
24
|
+
class CultureState {
|
|
25
|
+
/**
|
|
26
|
+
* Constructor
|
|
27
|
+
*/
|
|
28
|
+
constructor(item) {
|
|
29
|
+
// Default
|
|
30
|
+
const defaultItem = item ?? {};
|
|
31
|
+
// Load resources
|
|
32
|
+
if (item != null && typeof item.resources !== "object")
|
|
33
|
+
item.resources().then((result) => (item.resources = result));
|
|
34
|
+
// Act
|
|
35
|
+
const { context, provider } = State_1.State.create((state, action) => {
|
|
36
|
+
// Language reducer
|
|
37
|
+
if (state.name !== action.name) {
|
|
38
|
+
return { ...action };
|
|
39
|
+
}
|
|
40
|
+
return state;
|
|
41
|
+
}, defaultItem, calls);
|
|
42
|
+
this.context = context;
|
|
43
|
+
this.provider = provider;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
exports.CultureState = CultureState;
|