@etsoo/react 1.4.20 → 1.4.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/components/GridLoader.d.ts +6 -2
- package/lib/components/ScrollerGrid.d.ts +1 -1
- package/lib/components/ScrollerGrid.js +50 -43
- package/lib/components/ScrollerList.js +30 -32
- package/lib/mu/DataGridEx.d.ts +1 -1
- package/lib/mu/DataGridEx.js +25 -51
- package/lib/mu/DataGridRenderers.d.ts +4 -2
- package/lib/mu/DataGridRenderers.js +15 -11
- package/lib/mu/GridMethodRef.d.ts +2 -1
- package/lib/mu/ResponsibleContainer.d.ts +16 -0
- package/lib/mu/ResponsibleContainer.js +84 -36
- package/lib/mu/ScrollerListEx.js +1 -2
- package/lib/mu/SearchBar.js +3 -3
- package/lib/mu/TableEx.js +27 -25
- package/lib/mu/pages/CommonPage.d.ts +1 -2
- package/lib/uses/useDimensions.js +0 -8
- package/package.json +9 -9
- package/src/components/GridLoader.ts +7 -2
- package/src/components/ScrollerGrid.tsx +69 -63
- package/src/components/ScrollerList.tsx +44 -48
- package/src/mu/DataGridEx.tsx +53 -93
- package/src/mu/DataGridRenderers.tsx +19 -17
- package/src/mu/GridMethodRef.ts +3 -1
- package/src/mu/ResponsibleContainer.tsx +130 -42
- package/src/mu/ScrollerListEx.tsx +1 -2
- package/src/mu/SearchBar.tsx +3 -3
- package/src/mu/TableEx.tsx +40 -46
- package/src/uses/useDimensions.ts +0 -11
|
@@ -40,7 +40,10 @@ export interface ScrollerGridProps<T>
|
|
|
40
40
|
/**
|
|
41
41
|
* Footer renderer
|
|
42
42
|
*/
|
|
43
|
-
footerRenderer?: (
|
|
43
|
+
footerRenderer?: (
|
|
44
|
+
rows: T[],
|
|
45
|
+
states: GridLoaderStates<T>
|
|
46
|
+
) => React.ReactNode;
|
|
44
47
|
|
|
45
48
|
/**
|
|
46
49
|
* Header renderer
|
|
@@ -163,29 +166,28 @@ export const ScrollerGrid = <T extends Record<string, unknown>>(
|
|
|
163
166
|
...rest
|
|
164
167
|
} = props;
|
|
165
168
|
|
|
166
|
-
//
|
|
167
|
-
const [
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
return { ...currentState, ...newState };
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
autoLoad,
|
|
176
|
-
currentPage: 0,
|
|
177
|
-
hasNextPage: true,
|
|
178
|
-
isNextPageLoading: false,
|
|
179
|
-
orderBy: defaultOrderBy,
|
|
180
|
-
orderByAsc: defaultOrderByAsc,
|
|
181
|
-
rows: [],
|
|
182
|
-
batchSize: 10,
|
|
183
|
-
selectedItems: []
|
|
184
|
-
}
|
|
185
|
-
);
|
|
186
|
-
const isMounted = React.useRef(true);
|
|
169
|
+
// Rows
|
|
170
|
+
const [rows, updateRows] = React.useState<T[]>([]);
|
|
171
|
+
const setRows = (rows: T[]) => {
|
|
172
|
+
state.loadedItems = rows.length;
|
|
173
|
+
updateRows(rows);
|
|
174
|
+
};
|
|
187
175
|
|
|
188
|
-
|
|
176
|
+
// Refs
|
|
177
|
+
const refs = React.useRef<GridLoaderStates<T>>({
|
|
178
|
+
autoLoad,
|
|
179
|
+
currentPage: 0,
|
|
180
|
+
hasNextPage: true,
|
|
181
|
+
isNextPageLoading: false,
|
|
182
|
+
orderBy: defaultOrderBy,
|
|
183
|
+
orderByAsc: defaultOrderByAsc,
|
|
184
|
+
batchSize: 10,
|
|
185
|
+
loadedItems: 0,
|
|
186
|
+
selectedItems: []
|
|
187
|
+
});
|
|
188
|
+
const state = refs.current;
|
|
189
|
+
|
|
190
|
+
const ref = React.useRef<VariableSizeGrid<T>>(null);
|
|
189
191
|
|
|
190
192
|
// Load data
|
|
191
193
|
const loadDataLocal = (pageAdd: number = 1) => {
|
|
@@ -194,10 +196,10 @@ export const ScrollerGrid = <T extends Record<string, unknown>>(
|
|
|
194
196
|
|
|
195
197
|
// Update state
|
|
196
198
|
state.isNextPageLoading = true;
|
|
197
|
-
// stateUpdate({ isNextPageLoading: true });
|
|
198
199
|
|
|
199
200
|
// Parameters
|
|
200
|
-
const { currentPage, batchSize, orderBy, orderByAsc, data } =
|
|
201
|
+
const { currentPage, batchSize, orderBy, orderByAsc, data, isMounted } =
|
|
202
|
+
state;
|
|
201
203
|
|
|
202
204
|
const loadProps: GridLoadDataProps = {
|
|
203
205
|
currentPage,
|
|
@@ -208,38 +210,36 @@ export const ScrollerGrid = <T extends Record<string, unknown>>(
|
|
|
208
210
|
};
|
|
209
211
|
|
|
210
212
|
loadData(loadProps).then((result) => {
|
|
211
|
-
|
|
213
|
+
state.isMounted = true;
|
|
214
|
+
|
|
215
|
+
if (result == null || isMounted === false) {
|
|
212
216
|
return;
|
|
213
217
|
}
|
|
214
218
|
|
|
215
219
|
const newItems = result.length;
|
|
220
|
+
state.lastLoadedItems = newItems;
|
|
221
|
+
state.isNextPageLoading = false;
|
|
222
|
+
state.hasNextPage = newItems >= batchSize;
|
|
216
223
|
|
|
217
224
|
if (pageAdd === 0) {
|
|
218
225
|
// New items
|
|
219
|
-
const
|
|
220
|
-
?
|
|
226
|
+
const newRows = state.lastLoadedItems
|
|
227
|
+
? [...rows]
|
|
221
228
|
.splice(
|
|
222
|
-
|
|
229
|
+
rows.length - state.lastLoadedItems,
|
|
223
230
|
state.lastLoadedItems
|
|
224
231
|
)
|
|
225
232
|
.concat(result)
|
|
226
233
|
: result;
|
|
227
234
|
|
|
228
|
-
//
|
|
229
|
-
|
|
230
|
-
rows,
|
|
231
|
-
lastLoadedItems: newItems,
|
|
232
|
-
isNextPageLoading: false,
|
|
233
|
-
hasNextPage: newItems >= batchSize
|
|
234
|
-
});
|
|
235
|
+
// Update rows
|
|
236
|
+
setRows(newRows);
|
|
235
237
|
} else {
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
hasNextPage: newItems >= batchSize
|
|
242
|
-
});
|
|
238
|
+
// Set current page
|
|
239
|
+
state.currentPage = state.currentPage + pageAdd;
|
|
240
|
+
|
|
241
|
+
// Update rows
|
|
242
|
+
setRows([...rows, ...result]);
|
|
243
243
|
}
|
|
244
244
|
});
|
|
245
245
|
};
|
|
@@ -251,8 +251,8 @@ export const ScrollerGrid = <T extends Record<string, unknown>>(
|
|
|
251
251
|
) => {
|
|
252
252
|
// Custom render
|
|
253
253
|
const data =
|
|
254
|
-
itemProps.rowIndex <
|
|
255
|
-
?
|
|
254
|
+
itemProps.rowIndex < rows.length
|
|
255
|
+
? rows[itemProps.rowIndex]
|
|
256
256
|
: undefined;
|
|
257
257
|
return itemRenderer({
|
|
258
258
|
...itemProps,
|
|
@@ -264,7 +264,7 @@ export const ScrollerGrid = <T extends Record<string, unknown>>(
|
|
|
264
264
|
// Local items renderer callback
|
|
265
265
|
const onItemsRenderedLocal = (props: GridOnItemsRenderedProps) => {
|
|
266
266
|
// No items, means no necessary to load more data during reset
|
|
267
|
-
const itemCount =
|
|
267
|
+
const itemCount = rows.length;
|
|
268
268
|
if (
|
|
269
269
|
itemCount > 0 &&
|
|
270
270
|
props.visibleRowStopIndex + threshold > itemCount
|
|
@@ -278,17 +278,20 @@ export const ScrollerGrid = <T extends Record<string, unknown>>(
|
|
|
278
278
|
};
|
|
279
279
|
|
|
280
280
|
// Reset the state and load again
|
|
281
|
-
const reset = (add?:
|
|
282
|
-
const
|
|
281
|
+
const reset = (add?: Partial<GridLoaderStates<T>>) => {
|
|
282
|
+
const resetState: Partial<GridLoaderStates<T>> = {
|
|
283
283
|
autoLoad: true,
|
|
284
284
|
currentPage: 0,
|
|
285
|
+
loadedItems: 0,
|
|
285
286
|
hasNextPage: true,
|
|
286
287
|
isNextPageLoading: false,
|
|
287
288
|
lastLoadedItems: undefined,
|
|
288
|
-
rows: [],
|
|
289
289
|
...add
|
|
290
290
|
};
|
|
291
|
-
|
|
291
|
+
Object.assign(state, resetState);
|
|
292
|
+
|
|
293
|
+
// Reset items
|
|
294
|
+
setRows([]);
|
|
292
295
|
};
|
|
293
296
|
|
|
294
297
|
React.useImperativeHandle(
|
|
@@ -307,16 +310,14 @@ export const ScrollerGrid = <T extends Record<string, unknown>>(
|
|
|
307
310
|
select(rowIndex: number) {
|
|
308
311
|
// Select only one item
|
|
309
312
|
const selectedItems = state.selectedItems;
|
|
310
|
-
selectedItems[0] =
|
|
313
|
+
selectedItems[0] = rows[rowIndex];
|
|
311
314
|
|
|
312
315
|
if (onSelectChange) onSelectChange(selectedItems);
|
|
313
|
-
|
|
314
|
-
stateUpdate({ selectedItems });
|
|
315
316
|
},
|
|
316
317
|
selectAll(checked: boolean) {
|
|
317
318
|
const selectedItems = state.selectedItems;
|
|
318
319
|
|
|
319
|
-
|
|
320
|
+
rows.forEach((row) => {
|
|
320
321
|
const index = selectedItems.findIndex(
|
|
321
322
|
(selectedItem) => selectedItem[idField] === row[idField]
|
|
322
323
|
);
|
|
@@ -329,8 +330,6 @@ export const ScrollerGrid = <T extends Record<string, unknown>>(
|
|
|
329
330
|
});
|
|
330
331
|
|
|
331
332
|
if (onSelectChange) onSelectChange(selectedItems);
|
|
332
|
-
|
|
333
|
-
stateUpdate({ selectedItems });
|
|
334
333
|
},
|
|
335
334
|
selectItem(item: T, checked: boolean) {
|
|
336
335
|
const selectedItems = state.selectedItems;
|
|
@@ -345,8 +344,6 @@ export const ScrollerGrid = <T extends Record<string, unknown>>(
|
|
|
345
344
|
}
|
|
346
345
|
|
|
347
346
|
if (onSelectChange) onSelectChange(selectedItems);
|
|
348
|
-
|
|
349
|
-
stateUpdate({ selectedItems });
|
|
350
347
|
},
|
|
351
348
|
reset,
|
|
352
349
|
resetAfterColumnIndex(index: number, shouldForceUpdate?: boolean) {
|
|
@@ -363,17 +360,26 @@ export const ScrollerGrid = <T extends Record<string, unknown>>(
|
|
|
363
360
|
ref.current?.resetAfterRowIndex(index, shouldForceUpdate);
|
|
364
361
|
}
|
|
365
362
|
}),
|
|
366
|
-
[
|
|
363
|
+
[rows]
|
|
367
364
|
);
|
|
368
365
|
|
|
369
366
|
React.useEffect(() => {
|
|
370
367
|
return () => {
|
|
371
|
-
isMounted
|
|
368
|
+
state.isMounted = false;
|
|
372
369
|
};
|
|
373
370
|
}, []);
|
|
374
371
|
|
|
372
|
+
// Force update to work with the new width
|
|
373
|
+
React.useEffect(() => {
|
|
374
|
+
ref.current?.resetAfterIndices({
|
|
375
|
+
columnIndex: 0,
|
|
376
|
+
rowIndex: 0,
|
|
377
|
+
shouldForceUpdate: true
|
|
378
|
+
});
|
|
379
|
+
}, [width]);
|
|
380
|
+
|
|
375
381
|
// Destruct state
|
|
376
|
-
const { autoLoad: stateAutoLoad,
|
|
382
|
+
const { autoLoad: stateAutoLoad, hasNextPage, currentPage } = state;
|
|
377
383
|
const rowLength = rows.length;
|
|
378
384
|
|
|
379
385
|
// Row count
|
|
@@ -388,7 +394,7 @@ export const ScrollerGrid = <T extends Record<string, unknown>>(
|
|
|
388
394
|
{headerRenderer && headerRenderer(state)}
|
|
389
395
|
<VariableSizeGrid<T>
|
|
390
396
|
itemKey={({ columnIndex, rowIndex }) => {
|
|
391
|
-
const data =
|
|
397
|
+
const data = rows[rowIndex];
|
|
392
398
|
if (data == null) return [rowIndex, columnIndex].join(',');
|
|
393
399
|
return [data[idField], columnIndex].join(',');
|
|
394
400
|
}}
|
|
@@ -406,7 +412,7 @@ export const ScrollerGrid = <T extends Record<string, unknown>>(
|
|
|
406
412
|
>
|
|
407
413
|
{(props) => itemRendererLocal(props, state)}
|
|
408
414
|
</VariableSizeGrid>
|
|
409
|
-
{footerRenderer && footerRenderer(state)}
|
|
415
|
+
{footerRenderer && footerRenderer(rows, state)}
|
|
410
416
|
</React.Fragment>
|
|
411
417
|
);
|
|
412
418
|
};
|
|
@@ -133,27 +133,26 @@ export const ScrollerList = <T extends Record<string, any>>(
|
|
|
133
133
|
|
|
134
134
|
const refs = useCombinedRefs(oRef, outerRef);
|
|
135
135
|
|
|
136
|
+
// Rows
|
|
137
|
+
const [rows, updateRows] = React.useState<T[]>([]);
|
|
138
|
+
const setRows = (rows: T[]) => {
|
|
139
|
+
state.loadedItems = rows.length;
|
|
140
|
+
updateRows(rows);
|
|
141
|
+
};
|
|
142
|
+
|
|
136
143
|
// States
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
orderBy: defaultOrderBy,
|
|
150
|
-
orderByAsc: defaultOrderByAsc,
|
|
151
|
-
rows: [],
|
|
152
|
-
batchSize: GridSizeGet(loadBatchSize, height),
|
|
153
|
-
selectedItems: []
|
|
154
|
-
}
|
|
155
|
-
);
|
|
156
|
-
const isMounted = React.useRef(true);
|
|
144
|
+
const stateRefs = React.useRef<GridLoaderStates<T>>({
|
|
145
|
+
autoLoad,
|
|
146
|
+
currentPage: 0,
|
|
147
|
+
loadedItems: 0,
|
|
148
|
+
hasNextPage: true,
|
|
149
|
+
isNextPageLoading: false,
|
|
150
|
+
orderBy: defaultOrderBy,
|
|
151
|
+
orderByAsc: defaultOrderByAsc,
|
|
152
|
+
batchSize: GridSizeGet(loadBatchSize, height),
|
|
153
|
+
selectedItems: []
|
|
154
|
+
});
|
|
155
|
+
const state = stateRefs.current;
|
|
157
156
|
|
|
158
157
|
// Load data
|
|
159
158
|
const loadDataLocal = (pageAdd: number = 1) => {
|
|
@@ -162,10 +161,10 @@ export const ScrollerList = <T extends Record<string, any>>(
|
|
|
162
161
|
|
|
163
162
|
// Update state
|
|
164
163
|
state.isNextPageLoading = true;
|
|
165
|
-
// stateUpdate({ isNextPageLoading: true });
|
|
166
164
|
|
|
167
165
|
// Parameters
|
|
168
|
-
const { currentPage, batchSize, orderBy, orderByAsc, data } =
|
|
166
|
+
const { currentPage, batchSize, orderBy, orderByAsc, data, isMounted } =
|
|
167
|
+
state;
|
|
169
168
|
|
|
170
169
|
const loadProps: GridLoadDataProps = {
|
|
171
170
|
currentPage,
|
|
@@ -176,38 +175,35 @@ export const ScrollerList = <T extends Record<string, any>>(
|
|
|
176
175
|
};
|
|
177
176
|
|
|
178
177
|
loadData(loadProps).then((result) => {
|
|
179
|
-
|
|
178
|
+
state.isMounted = true;
|
|
179
|
+
|
|
180
|
+
if (result == null || isMounted === false) {
|
|
180
181
|
return;
|
|
181
182
|
}
|
|
182
183
|
|
|
183
184
|
const newItems = result.length;
|
|
185
|
+
state.lastLoadedItems = newItems;
|
|
186
|
+
state.hasNextPage = newItems >= loadBatchSize;
|
|
187
|
+
state.isNextPageLoading = false;
|
|
184
188
|
|
|
185
189
|
if (pageAdd === 0) {
|
|
186
190
|
// New items
|
|
187
|
-
const
|
|
188
|
-
?
|
|
191
|
+
const newRows = state.lastLoadedItems
|
|
192
|
+
? [...rows]
|
|
189
193
|
.splice(
|
|
190
|
-
|
|
194
|
+
rows.length - state.lastLoadedItems,
|
|
191
195
|
state.lastLoadedItems
|
|
192
196
|
)
|
|
193
197
|
.concat(result)
|
|
194
198
|
: result;
|
|
195
199
|
|
|
196
|
-
//
|
|
197
|
-
|
|
198
|
-
rows,
|
|
199
|
-
lastLoadedItems: newItems,
|
|
200
|
-
hasNextPage: newItems >= loadBatchSize,
|
|
201
|
-
isNextPageLoading: false
|
|
202
|
-
});
|
|
200
|
+
// Update rows
|
|
201
|
+
setRows(newRows);
|
|
203
202
|
} else {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
hasNextPage: newItems >= loadBatchSize,
|
|
209
|
-
isNextPageLoading: false
|
|
210
|
-
});
|
|
203
|
+
state.currentPage = state.currentPage + pageAdd;
|
|
204
|
+
|
|
205
|
+
// Update rows
|
|
206
|
+
setRows([...rows, ...result]);
|
|
211
207
|
}
|
|
212
208
|
});
|
|
213
209
|
};
|
|
@@ -216,7 +212,7 @@ export const ScrollerList = <T extends Record<string, any>>(
|
|
|
216
212
|
// Custom render
|
|
217
213
|
return itemRenderer({
|
|
218
214
|
...itemProps,
|
|
219
|
-
data:
|
|
215
|
+
data: rows[itemProps.index]
|
|
220
216
|
});
|
|
221
217
|
};
|
|
222
218
|
|
|
@@ -241,17 +237,17 @@ export const ScrollerList = <T extends Record<string, any>>(
|
|
|
241
237
|
loadDataLocal(0);
|
|
242
238
|
},
|
|
243
239
|
|
|
244
|
-
reset(add?:
|
|
245
|
-
|
|
246
|
-
stateUpdate({
|
|
240
|
+
reset(add?: Partial<GridLoaderStates<T>>): void {
|
|
241
|
+
const resetState: Partial<GridLoaderStates<T>> = {
|
|
247
242
|
autoLoad: true,
|
|
248
|
-
rows: [],
|
|
249
243
|
lastLoadedItems: undefined,
|
|
244
|
+
loadedItems: 0,
|
|
250
245
|
currentPage: 0,
|
|
251
246
|
hasNextPage: true,
|
|
252
247
|
isNextPageLoading: false,
|
|
253
248
|
...add
|
|
254
|
-
}
|
|
249
|
+
};
|
|
250
|
+
Object.assign(state, resetState);
|
|
255
251
|
},
|
|
256
252
|
|
|
257
253
|
scrollTo(scrollOffset: number): void {
|
|
@@ -298,12 +294,12 @@ export const ScrollerList = <T extends Record<string, any>>(
|
|
|
298
294
|
// Remove scroll event
|
|
299
295
|
window.removeEventListener('scroll', handleWindowScroll);
|
|
300
296
|
|
|
301
|
-
isMounted
|
|
297
|
+
state.isMounted = false;
|
|
302
298
|
};
|
|
303
299
|
}, []);
|
|
304
300
|
|
|
305
301
|
// Destruct state
|
|
306
|
-
const { autoLoad: stateAutoLoad,
|
|
302
|
+
const { autoLoad: stateAutoLoad, hasNextPage, currentPage } = state;
|
|
307
303
|
const rowCount = rows.length;
|
|
308
304
|
|
|
309
305
|
// Local items renderer callback
|
package/src/mu/DataGridEx.tsx
CHANGED
|
@@ -24,8 +24,6 @@ import {
|
|
|
24
24
|
ScrollerGridProps
|
|
25
25
|
} from '../components/ScrollerGrid';
|
|
26
26
|
import useCombinedRefs from '../uses/useCombinedRefs';
|
|
27
|
-
import { useDimensions } from '../uses/useDimensions';
|
|
28
|
-
import { useWindowSize } from '../uses/useWindowSize';
|
|
29
27
|
import { DataGridRenderers } from './DataGridRenderers';
|
|
30
28
|
|
|
31
29
|
/**
|
|
@@ -79,6 +77,7 @@ export interface DataGridExProps<T extends Record<string, any>>
|
|
|
79
77
|
* Footer item renderer
|
|
80
78
|
*/
|
|
81
79
|
footerItemRenderer?: (
|
|
80
|
+
rows: T[],
|
|
82
81
|
props: DataGridExFooterItemRendererProps<T>
|
|
83
82
|
) => React.ReactNode;
|
|
84
83
|
|
|
@@ -152,11 +151,6 @@ const createGridStyle = (
|
|
|
152
151
|
});
|
|
153
152
|
};
|
|
154
153
|
|
|
155
|
-
interface States {
|
|
156
|
-
gridWidth?: number;
|
|
157
|
-
ref?: ScrollerGridForwardRef;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
154
|
const rowItems = (
|
|
161
155
|
div: HTMLDivElement,
|
|
162
156
|
callback: (div: HTMLDivElement) => void
|
|
@@ -247,7 +241,7 @@ export function DataGridEx<T extends Record<string, any>>(
|
|
|
247
241
|
sortLabel = headerCellRenderer({
|
|
248
242
|
cellProps,
|
|
249
243
|
column,
|
|
250
|
-
columnIndex: index,
|
|
244
|
+
columnIndex: checkable ? index - 1 : index, // Ignore the checkbox case,
|
|
251
245
|
states
|
|
252
246
|
});
|
|
253
247
|
} else if (sortable && field != null) {
|
|
@@ -290,7 +284,7 @@ export function DataGridEx<T extends Record<string, any>>(
|
|
|
290
284
|
);
|
|
291
285
|
};
|
|
292
286
|
|
|
293
|
-
function defaultFooterRenderer(states: GridLoaderStates<T>) {
|
|
287
|
+
function defaultFooterRenderer(rows: T[], states: GridLoaderStates<T>) {
|
|
294
288
|
return (
|
|
295
289
|
<Box
|
|
296
290
|
className="DataGridEx-Footer"
|
|
@@ -310,9 +304,9 @@ export function DataGridEx<T extends Record<string, any>>(
|
|
|
310
304
|
|
|
311
305
|
// Cell
|
|
312
306
|
const cell = footerItemRenderer
|
|
313
|
-
? footerItemRenderer({
|
|
307
|
+
? footerItemRenderer(rows, {
|
|
314
308
|
column,
|
|
315
|
-
index,
|
|
309
|
+
index: checkable ? index - 1 : index, // Ignore the checkbox case
|
|
316
310
|
states,
|
|
317
311
|
cellProps,
|
|
318
312
|
checkable
|
|
@@ -383,7 +377,7 @@ export function DataGridEx<T extends Record<string, any>>(
|
|
|
383
377
|
color="primary"
|
|
384
378
|
checked={selected}
|
|
385
379
|
onChange={(_event, checked) => {
|
|
386
|
-
|
|
380
|
+
refs.current.ref?.selectItem(data, checked);
|
|
387
381
|
}}
|
|
388
382
|
/>
|
|
389
383
|
);
|
|
@@ -403,11 +397,11 @@ export function DataGridEx<T extends Record<string, any>>(
|
|
|
403
397
|
color="primary"
|
|
404
398
|
indeterminate={
|
|
405
399
|
states.selectedItems.length > 0 &&
|
|
406
|
-
states.selectedItems.length < states.
|
|
400
|
+
states.selectedItems.length < states.loadedItems
|
|
407
401
|
}
|
|
408
402
|
checked={states.selectedItems.length > 0}
|
|
409
403
|
onChange={(_event, checked) =>
|
|
410
|
-
|
|
404
|
+
refs.current.ref?.selectAll(checked)
|
|
411
405
|
}
|
|
412
406
|
/>
|
|
413
407
|
);
|
|
@@ -422,19 +416,11 @@ export function DataGridEx<T extends Record<string, any>>(
|
|
|
422
416
|
}
|
|
423
417
|
}
|
|
424
418
|
|
|
425
|
-
|
|
426
|
-
const [state, stateUpdate] = React.useReducer(
|
|
427
|
-
(currentState: States, newState: Partial<States>) => {
|
|
428
|
-
return { ...currentState, ...newState };
|
|
429
|
-
},
|
|
430
|
-
{
|
|
431
|
-
gridWidth: width
|
|
432
|
-
}
|
|
433
|
-
);
|
|
419
|
+
const refs = React.useRef<{ ref?: ScrollerGridForwardRef }>({});
|
|
434
420
|
|
|
435
|
-
const
|
|
421
|
+
const mRefLocal = useCombinedRefs(mRef, (ref: ScrollerGridForwardRef) => {
|
|
436
422
|
if (ref == null) return;
|
|
437
|
-
|
|
423
|
+
refs.current.ref = ref;
|
|
438
424
|
});
|
|
439
425
|
|
|
440
426
|
// New sort
|
|
@@ -442,8 +428,9 @@ export function DataGridEx<T extends Record<string, any>>(
|
|
|
442
428
|
reset({ orderBy: field, orderByAsc: asc });
|
|
443
429
|
};
|
|
444
430
|
|
|
431
|
+
// Reset
|
|
445
432
|
const reset = (add: {}) => {
|
|
446
|
-
|
|
433
|
+
refs.current.ref?.reset(add);
|
|
447
434
|
};
|
|
448
435
|
|
|
449
436
|
// Show hover tooltip for trucated text
|
|
@@ -594,14 +581,11 @@ export function DataGridEx<T extends Record<string, any>>(
|
|
|
594
581
|
[columns]
|
|
595
582
|
);
|
|
596
583
|
|
|
597
|
-
// Grid width
|
|
598
|
-
const { gridWidth } = state;
|
|
599
|
-
|
|
600
584
|
// Column width
|
|
601
585
|
const columnWidth = React.useCallback(
|
|
602
586
|
(index: number) => {
|
|
603
587
|
// Ignore null case
|
|
604
|
-
if (
|
|
588
|
+
if (width == null) return 0;
|
|
605
589
|
|
|
606
590
|
// Column
|
|
607
591
|
const column = columns[index];
|
|
@@ -609,9 +593,9 @@ export function DataGridEx<T extends Record<string, any>>(
|
|
|
609
593
|
|
|
610
594
|
// More space
|
|
611
595
|
const leftWidth =
|
|
612
|
-
|
|
596
|
+
width -
|
|
613
597
|
widthCalculator.total -
|
|
614
|
-
(
|
|
598
|
+
(width < 800 ? 0 : scrollbarSize);
|
|
615
599
|
|
|
616
600
|
// Shared width
|
|
617
601
|
const sharedWidth =
|
|
@@ -619,74 +603,50 @@ export function DataGridEx<T extends Record<string, any>>(
|
|
|
619
603
|
|
|
620
604
|
return (column.minWidth || minWidth) + sharedWidth;
|
|
621
605
|
},
|
|
622
|
-
[columns,
|
|
606
|
+
[columns, width]
|
|
623
607
|
);
|
|
624
608
|
|
|
625
609
|
// Table
|
|
626
610
|
const table = React.useMemo(() => {
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
?.sortAsc
|
|
631
|
-
: undefined;
|
|
632
|
-
|
|
633
|
-
return (
|
|
634
|
-
<ScrollerGrid<T>
|
|
635
|
-
className={Utils.mergeClasses(
|
|
636
|
-
'DataGridEx-Body',
|
|
637
|
-
'DataGridEx-CustomBar',
|
|
638
|
-
className,
|
|
639
|
-
createGridStyle(
|
|
640
|
-
alternatingColors,
|
|
641
|
-
selectedColor,
|
|
642
|
-
hoverColor
|
|
643
|
-
)
|
|
644
|
-
)}
|
|
645
|
-
columnCount={columns.length}
|
|
646
|
-
columnWidth={columnWidth}
|
|
647
|
-
defaultOrderBy={defaultOrderBy}
|
|
648
|
-
defaultOrderByAsc={defaultOrderByAsc}
|
|
649
|
-
height={
|
|
650
|
-
height -
|
|
651
|
-
headerHeight -
|
|
652
|
-
(hideFooter ? 0 : bottomHeight + 1) -
|
|
653
|
-
scrollbarSize
|
|
654
|
-
}
|
|
655
|
-
headerRenderer={headerRenderer}
|
|
656
|
-
idField={idField}
|
|
657
|
-
itemRenderer={itemRenderer}
|
|
658
|
-
footerRenderer={hideFooter ? undefined : footerRenderer}
|
|
659
|
-
width={Math.max(gridWidth, widthCalculator.total)}
|
|
660
|
-
mRef={refs}
|
|
661
|
-
{...rest}
|
|
662
|
-
/>
|
|
663
|
-
);
|
|
664
|
-
}
|
|
665
|
-
}, [gridWidth]);
|
|
611
|
+
const defaultOrderByAsc = defaultOrderBy
|
|
612
|
+
? columns.find((column) => column.field === defaultOrderBy)?.sortAsc
|
|
613
|
+
: undefined;
|
|
666
614
|
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
615
|
+
return (
|
|
616
|
+
<ScrollerGrid<T>
|
|
617
|
+
className={Utils.mergeClasses(
|
|
618
|
+
'DataGridEx-Body',
|
|
619
|
+
'DataGridEx-CustomBar',
|
|
620
|
+
className,
|
|
621
|
+
createGridStyle(
|
|
622
|
+
alternatingColors,
|
|
623
|
+
selectedColor,
|
|
624
|
+
hoverColor
|
|
625
|
+
)
|
|
626
|
+
)}
|
|
627
|
+
columnCount={columns.length}
|
|
628
|
+
columnWidth={columnWidth}
|
|
629
|
+
defaultOrderBy={defaultOrderBy}
|
|
630
|
+
defaultOrderByAsc={defaultOrderByAsc}
|
|
631
|
+
height={
|
|
632
|
+
height -
|
|
633
|
+
headerHeight -
|
|
634
|
+
(hideFooter ? 0 : bottomHeight + 1) -
|
|
635
|
+
scrollbarSize
|
|
636
|
+
}
|
|
637
|
+
headerRenderer={headerRenderer}
|
|
638
|
+
idField={idField}
|
|
639
|
+
itemRenderer={itemRenderer}
|
|
640
|
+
footerRenderer={hideFooter ? undefined : footerRenderer}
|
|
641
|
+
width={Math.max(width ?? 0, widthCalculator.total)}
|
|
642
|
+
mRef={mRefLocal}
|
|
643
|
+
{...rest}
|
|
644
|
+
/>
|
|
645
|
+
);
|
|
646
|
+
}, [width]);
|
|
686
647
|
|
|
687
648
|
return (
|
|
688
649
|
<Paper
|
|
689
|
-
ref={dimensions[0][0]}
|
|
690
650
|
sx={{
|
|
691
651
|
fontSize: '0.875rem',
|
|
692
652
|
height,
|
|
@@ -720,7 +680,7 @@ export function DataGridEx<T extends Record<string, any>>(
|
|
|
720
680
|
<div
|
|
721
681
|
className="DataGridEx-CustomBar"
|
|
722
682
|
style={{
|
|
723
|
-
width
|
|
683
|
+
width,
|
|
724
684
|
overflowX: 'auto',
|
|
725
685
|
overflowY: 'hidden'
|
|
726
686
|
}}
|