@mui/x-data-grid 8.18.0 → 8.19.0
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/CHANGELOG.md +113 -0
- package/DataGrid/useDataGridComponent.js +4 -3
- package/components/GridRow.js +1 -1
- package/components/cell/GridActionsCell.d.ts +9 -0
- package/components/cell/GridActionsCell.js +54 -34
- package/components/cell/GridBooleanCell.js +0 -10
- package/components/cell/GridCell.js +4 -10
- package/components/columnHeaders/GridColumnHeaderItem.js +2 -2
- package/components/columnSelection/GridCellCheckboxRenderer.js +37 -22
- package/components/containers/GridRootStyles.js +1 -1
- package/components/toolbarV8/Toolbar.js +1 -1
- package/components/virtualization/GridVirtualScrollbar.d.ts +1 -0
- package/components/virtualization/GridVirtualScrollbar.js +13 -8
- package/components/virtualization/GridVirtualScroller.js +2 -1
- package/components/virtualization/GridVirtualScrollerRenderZone.js +1 -1
- package/constants/dataGridPropsDefaultValues.js +2 -1
- package/esm/DataGrid/useDataGridComponent.js +5 -4
- package/esm/components/GridRow.js +1 -1
- package/esm/components/cell/GridActionsCell.d.ts +9 -0
- package/esm/components/cell/GridActionsCell.js +55 -34
- package/esm/components/cell/GridBooleanCell.js +0 -10
- package/esm/components/cell/GridCell.js +4 -10
- package/esm/components/columnHeaders/GridColumnHeaderItem.js +2 -2
- package/esm/components/columnSelection/GridCellCheckboxRenderer.js +37 -22
- package/esm/components/containers/GridRootStyles.js +1 -1
- package/esm/components/toolbarV8/Toolbar.js +1 -1
- package/esm/components/virtualization/GridVirtualScrollbar.d.ts +1 -0
- package/esm/components/virtualization/GridVirtualScrollbar.js +12 -7
- package/esm/components/virtualization/GridVirtualScroller.js +2 -1
- package/esm/components/virtualization/GridVirtualScrollerRenderZone.js +1 -1
- package/esm/constants/dataGridPropsDefaultValues.js +2 -1
- package/esm/hooks/core/gridPropsSelectors.d.ts +2 -1
- package/esm/hooks/core/gridPropsSelectors.js +3 -0
- package/esm/hooks/core/useGridProps.js +8 -2
- package/esm/hooks/core/useGridVirtualizer.d.ts +80 -6
- package/esm/hooks/core/useGridVirtualizer.js +27 -12
- package/esm/hooks/features/columnGrouping/useGridColumnGrouping.js +6 -1
- package/esm/hooks/features/columnMenu/useGridColumnMenu.js +14 -4
- package/esm/hooks/features/columns/useGridColumnSpanning.js +9 -4
- package/esm/hooks/features/dimensions/useGridDimensions.js +12 -6
- package/esm/hooks/features/export/useGridPrintExport.js +18 -18
- package/esm/hooks/features/filter/useGridFilter.d.ts +1 -1
- package/esm/hooks/features/filter/useGridFilter.js +3 -1
- package/esm/hooks/features/focus/useGridFocus.js +0 -1
- package/esm/hooks/features/keyboardNavigation/useGridKeyboardNavigation.d.ts +1 -1
- package/esm/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +189 -25
- package/esm/hooks/features/pagination/useGridPaginationMeta.js +3 -3
- package/esm/hooks/features/pagination/useGridPaginationModel.js +7 -4
- package/esm/hooks/features/pagination/useGridRowCount.js +31 -15
- package/esm/hooks/features/rowSelection/useGridRowSelection.js +8 -7
- package/esm/hooks/features/rowSelection/utils.d.ts +1 -0
- package/esm/hooks/features/rowSelection/utils.js +17 -4
- package/esm/hooks/features/rows/useGridRowSpanning.js +23 -60
- package/esm/hooks/features/scroll/useGridScroll.js +2 -3
- package/esm/hooks/features/sorting/useGridSorting.d.ts +1 -1
- package/esm/hooks/features/sorting/useGridSorting.js +3 -1
- package/esm/hooks/features/virtualization/useGridVirtualization.js +24 -5
- package/esm/hooks/utils/useGridEvent.js +6 -2
- package/esm/hooks/utils/useRunOncePerLoop.d.ts +4 -1
- package/esm/hooks/utils/useRunOncePerLoop.js +28 -18
- package/esm/index.js +1 -1
- package/esm/models/colDef/gridColDef.d.ts +14 -0
- package/esm/models/events/gridEventLookup.d.ts +5 -0
- package/esm/models/gridStateCommunity.d.ts +1 -1
- package/esm/models/params/gridCellParams.d.ts +0 -10
- package/esm/models/props/DataGridProps.d.ts +13 -6
- package/esm/utils/keyboardUtils.d.ts +1 -8
- package/esm/utils/keyboardUtils.js +0 -7
- package/hooks/core/gridPropsSelectors.d.ts +2 -1
- package/hooks/core/gridPropsSelectors.js +4 -1
- package/hooks/core/useGridProps.js +8 -2
- package/hooks/core/useGridVirtualizer.d.ts +80 -6
- package/hooks/core/useGridVirtualizer.js +26 -11
- package/hooks/features/columnGrouping/useGridColumnGrouping.js +6 -1
- package/hooks/features/columnMenu/useGridColumnMenu.js +14 -4
- package/hooks/features/columns/useGridColumnSpanning.js +9 -4
- package/hooks/features/dimensions/useGridDimensions.js +12 -6
- package/hooks/features/export/useGridPrintExport.js +18 -18
- package/hooks/features/filter/useGridFilter.d.ts +1 -1
- package/hooks/features/filter/useGridFilter.js +3 -1
- package/hooks/features/focus/useGridFocus.js +0 -1
- package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.d.ts +1 -1
- package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +189 -25
- package/hooks/features/pagination/useGridPaginationMeta.js +2 -2
- package/hooks/features/pagination/useGridPaginationModel.js +7 -4
- package/hooks/features/pagination/useGridRowCount.js +30 -14
- package/hooks/features/rowSelection/useGridRowSelection.js +8 -7
- package/hooks/features/rowSelection/utils.d.ts +1 -0
- package/hooks/features/rowSelection/utils.js +16 -3
- package/hooks/features/rows/useGridRowSpanning.js +23 -60
- package/hooks/features/scroll/useGridScroll.js +2 -3
- package/hooks/features/sorting/useGridSorting.d.ts +1 -1
- package/hooks/features/sorting/useGridSorting.js +3 -1
- package/hooks/features/virtualization/useGridVirtualization.js +24 -5
- package/hooks/utils/useGridEvent.js +6 -2
- package/hooks/utils/useRunOncePerLoop.d.ts +4 -1
- package/hooks/utils/useRunOncePerLoop.js +27 -18
- package/index.js +1 -1
- package/models/colDef/gridColDef.d.ts +14 -0
- package/models/events/gridEventLookup.d.ts +5 -0
- package/models/gridStateCommunity.d.ts +1 -1
- package/models/params/gridCellParams.d.ts +0 -10
- package/models/props/DataGridProps.d.ts +13 -6
- package/package.json +3 -3
- package/utils/keyboardUtils.d.ts +1 -8
- package/utils/keyboardUtils.js +1 -13
|
@@ -106,15 +106,32 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
|
|
|
106
106
|
// There is one exception for the checkBoxHeader
|
|
107
107
|
return;
|
|
108
108
|
}
|
|
109
|
+
if (!isNavigationKey(event.key) && event.key !== 'Tab') {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Tab key is only allowed if tabbing is enabled for header/all, or if we are tabbing to the content area while `tabNavigation` is enabled for content only
|
|
114
|
+
if (event.key === 'Tab' && (props.tabNavigation === 'none' || props.tabNavigation === 'content' && event.shiftKey)) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
109
117
|
const currentPageRows = getCurrentPageRows();
|
|
110
118
|
const viewportPageSize = apiRef.current.getViewportPageSize();
|
|
111
119
|
const colIndexBefore = params.field ? apiRef.current.getColumnIndex(params.field) : 0;
|
|
112
120
|
const firstRowIndexInPage = currentPageRows.length > 0 ? 0 : null;
|
|
113
|
-
const lastRowIndexInPage = currentPageRows.length - 1;
|
|
121
|
+
const lastRowIndexInPage = currentPageRows.length > 0 ? currentPageRows.length - 1 : null;
|
|
114
122
|
const firstColIndex = 0;
|
|
115
|
-
const lastColIndex = gridVisibleColumnDefinitionsSelector(apiRef).length - 1;
|
|
123
|
+
const lastColIndex = Math.max(0, gridVisibleColumnDefinitionsSelector(apiRef).length - 1);
|
|
116
124
|
const columnGroupMaxDepth = gridColumnGroupsHeaderMaxDepthSelector(apiRef);
|
|
117
125
|
let shouldPreventDefault = true;
|
|
126
|
+
|
|
127
|
+
// If we are tabbing inside the header area while only content `tabNavigation` is enabled, go to the first cell
|
|
128
|
+
if (event.key === 'Tab' && props.tabNavigation === 'content' && !event.shiftKey) {
|
|
129
|
+
if (firstRowIndexInPage !== null) {
|
|
130
|
+
goToCell(firstColIndex, getRowIdFromIndex(firstRowIndexInPage));
|
|
131
|
+
event.preventDefault();
|
|
132
|
+
}
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
118
135
|
switch (event.key) {
|
|
119
136
|
case 'ArrowDown':
|
|
120
137
|
{
|
|
@@ -182,6 +199,36 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
|
|
|
182
199
|
}
|
|
183
200
|
break;
|
|
184
201
|
}
|
|
202
|
+
case 'Tab':
|
|
203
|
+
{
|
|
204
|
+
if (event.shiftKey) {
|
|
205
|
+
// if the key is pressed on the first column header, Shift+Tab should go to the group header if it is there or allow default behavior
|
|
206
|
+
if (colIndexBefore === firstColIndex) {
|
|
207
|
+
if (columnGroupMaxDepth > 0) {
|
|
208
|
+
goToGroupHeader(lastColIndex, columnGroupMaxDepth - 1, event);
|
|
209
|
+
} else {
|
|
210
|
+
shouldPreventDefault = false;
|
|
211
|
+
}
|
|
212
|
+
} else {
|
|
213
|
+
goToHeader(colIndexBefore - 1, event);
|
|
214
|
+
}
|
|
215
|
+
} else if (colIndexBefore === lastColIndex) {
|
|
216
|
+
// the key is pressed at the last column header. go to the first header filter or the first cell
|
|
217
|
+
if (headerFilteringEnabled) {
|
|
218
|
+
goToHeaderFilter(firstColIndex, event);
|
|
219
|
+
}
|
|
220
|
+
// this point can be reached if tabbing is enabled for all content or just header.
|
|
221
|
+
// if it is not enabled for all content or there is no data, then do not focus on the first cell
|
|
222
|
+
else if (props.tabNavigation === 'all' && firstRowIndexInPage !== null) {
|
|
223
|
+
goToCell(firstColIndex, getRowIdFromIndex(firstRowIndexInPage));
|
|
224
|
+
} else {
|
|
225
|
+
shouldPreventDefault = false;
|
|
226
|
+
}
|
|
227
|
+
} else {
|
|
228
|
+
goToHeader(colIndexBefore + 1, event);
|
|
229
|
+
}
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
185
232
|
case ' ':
|
|
186
233
|
{
|
|
187
234
|
// prevent Space event from scrolling
|
|
@@ -195,27 +242,43 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
|
|
|
195
242
|
if (shouldPreventDefault) {
|
|
196
243
|
event.preventDefault();
|
|
197
244
|
}
|
|
198
|
-
}, [apiRef, getCurrentPageRows, headerFilteringEnabled, goToHeaderFilter, goToCell, getRowIdFromIndex, isRtl, goToHeader, goToGroupHeader]);
|
|
245
|
+
}, [apiRef, props.tabNavigation, getCurrentPageRows, headerFilteringEnabled, goToHeaderFilter, goToCell, getRowIdFromIndex, isRtl, goToHeader, goToGroupHeader]);
|
|
199
246
|
const handleHeaderFilterKeyDown = React.useCallback((params, event) => {
|
|
200
247
|
const isEditing = gridHeaderFilteringEditFieldSelector(apiRef) === params.field;
|
|
201
248
|
const isHeaderMenuOpen = gridHeaderFilteringMenuSelector(apiRef) === params.field;
|
|
202
|
-
if (
|
|
249
|
+
if (isHeaderMenuOpen || isEditing && event.key !== 'Tab') {
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
if (!isNavigationKey(event.key) && event.key !== 'Tab') {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Tab key is only allowed if tabbing is enabled for header/all, or if we are tabbing to the content area while `tabNavigation` is enabled for content only
|
|
257
|
+
if (event.key === 'Tab' && (props.tabNavigation === 'none' || props.tabNavigation === 'content' && event.shiftKey)) {
|
|
203
258
|
return;
|
|
204
259
|
}
|
|
205
260
|
const currentPageRows = getCurrentPageRows();
|
|
206
261
|
const viewportPageSize = apiRef.current.getViewportPageSize();
|
|
207
262
|
const colIndexBefore = params.field ? apiRef.current.getColumnIndex(params.field) : 0;
|
|
208
|
-
const firstRowIndexInPage = 0;
|
|
209
|
-
const lastRowIndexInPage = currentPageRows.length - 1;
|
|
263
|
+
const firstRowIndexInPage = currentPageRows.length > 0 ? 0 : null;
|
|
264
|
+
const lastRowIndexInPage = currentPageRows.length > 0 ? currentPageRows.length - 1 : null;
|
|
210
265
|
const firstColIndex = 0;
|
|
211
|
-
const lastColIndex = gridVisibleColumnDefinitionsSelector(apiRef).length - 1;
|
|
266
|
+
const lastColIndex = Math.max(0, gridVisibleColumnDefinitionsSelector(apiRef).length - 1);
|
|
212
267
|
let shouldPreventDefault = true;
|
|
268
|
+
|
|
269
|
+
// If we are tabbing inside the header area while only content `tabNavigation` is enabled, go to the first cell
|
|
270
|
+
if (event.key === 'Tab' && props.tabNavigation === 'content' && !event.shiftKey) {
|
|
271
|
+
if (firstRowIndexInPage !== null) {
|
|
272
|
+
goToCell(firstColIndex, getRowIdFromIndex(firstRowIndexInPage));
|
|
273
|
+
event.preventDefault();
|
|
274
|
+
}
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
213
277
|
switch (event.key) {
|
|
214
278
|
case 'ArrowDown':
|
|
215
279
|
{
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
goToCell(colIndexBefore, rowId);
|
|
280
|
+
if (firstRowIndexInPage !== null) {
|
|
281
|
+
goToCell(colIndexBefore, getRowIdFromIndex(firstRowIndexInPage));
|
|
219
282
|
}
|
|
220
283
|
break;
|
|
221
284
|
}
|
|
@@ -269,6 +332,29 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
|
|
|
269
332
|
goToHeaderFilter(lastColIndex, event);
|
|
270
333
|
break;
|
|
271
334
|
}
|
|
335
|
+
case 'Tab':
|
|
336
|
+
{
|
|
337
|
+
if (event.shiftKey) {
|
|
338
|
+
// if the key is pressed on the first header filter, Shift+Tab should go to the column header
|
|
339
|
+
if (colIndexBefore === firstColIndex) {
|
|
340
|
+
goToHeader(lastColIndex, event);
|
|
341
|
+
} else {
|
|
342
|
+
goToHeaderFilter(colIndexBefore - 1, event);
|
|
343
|
+
}
|
|
344
|
+
} else if (colIndexBefore === lastColIndex) {
|
|
345
|
+
// the key is pressed at the last header filter.
|
|
346
|
+
// this point can be reached if `tabNavigation` is enabled for all content or just header.
|
|
347
|
+
// if it is not enabled for all content or there is no data, then do not focus on the first cell
|
|
348
|
+
if (props.tabNavigation === 'all' && firstRowIndexInPage !== null) {
|
|
349
|
+
goToCell(firstColIndex, getRowIdFromIndex(firstRowIndexInPage));
|
|
350
|
+
} else {
|
|
351
|
+
shouldPreventDefault = false;
|
|
352
|
+
}
|
|
353
|
+
} else {
|
|
354
|
+
goToHeaderFilter(colIndexBefore + 1, event);
|
|
355
|
+
}
|
|
356
|
+
break;
|
|
357
|
+
}
|
|
272
358
|
case ' ':
|
|
273
359
|
{
|
|
274
360
|
// prevent Space event from scrolling
|
|
@@ -282,7 +368,7 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
|
|
|
282
368
|
if (shouldPreventDefault) {
|
|
283
369
|
event.preventDefault();
|
|
284
370
|
}
|
|
285
|
-
}, [apiRef, getCurrentPageRows, goToHeaderFilter, isRtl, goToHeader, goToCell, getRowIdFromIndex]);
|
|
371
|
+
}, [apiRef, props.tabNavigation, getCurrentPageRows, goToHeaderFilter, isRtl, goToHeader, goToCell, getRowIdFromIndex]);
|
|
286
372
|
const handleColumnGroupHeaderKeyDown = React.useCallback((params, event) => {
|
|
287
373
|
const focusedColumnGroup = gridFocusColumnGroupHeaderSelector(apiRef);
|
|
288
374
|
if (focusedColumnGroup === null) {
|
|
@@ -297,15 +383,32 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
|
|
|
297
383
|
depth,
|
|
298
384
|
maxDepth
|
|
299
385
|
} = params;
|
|
386
|
+
if (!isNavigationKey(event.key) && event.key !== 'Tab') {
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// Tab key is only allowed if tabbing is enabled for header/all, or if we are tabbing to the content area while `tabNavigation` is enabled for content only
|
|
391
|
+
if (event.key === 'Tab' && (props.tabNavigation === 'none' || props.tabNavigation === 'content' && event.shiftKey)) {
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
300
394
|
const currentPageRows = getCurrentPageRows();
|
|
301
395
|
const viewportPageSize = apiRef.current.getViewportPageSize();
|
|
302
396
|
const currentColIndex = apiRef.current.getColumnIndex(currentField);
|
|
303
397
|
const colIndexBefore = currentField ? apiRef.current.getColumnIndex(currentField) : 0;
|
|
304
|
-
const firstRowIndexInPage = 0;
|
|
305
|
-
const lastRowIndexInPage = currentPageRows.length - 1;
|
|
398
|
+
const firstRowIndexInPage = currentPageRows.length > 0 ? 0 : null;
|
|
399
|
+
const lastRowIndexInPage = currentPageRows.length > 0 ? currentPageRows.length - 1 : null;
|
|
306
400
|
const firstColIndex = 0;
|
|
307
|
-
const lastColIndex = gridVisibleColumnDefinitionsSelector(apiRef).length - 1;
|
|
401
|
+
const lastColIndex = Math.max(0, gridVisibleColumnDefinitionsSelector(apiRef).length - 1);
|
|
308
402
|
let shouldPreventDefault = true;
|
|
403
|
+
|
|
404
|
+
// If we are tabbing inside the header area while only content `tabNavigation` is enabled, go to the first cell
|
|
405
|
+
if (event.key === 'Tab' && props.tabNavigation === 'content' && !event.shiftKey) {
|
|
406
|
+
if (firstRowIndexInPage !== null) {
|
|
407
|
+
goToCell(firstColIndex, getRowIdFromIndex(firstRowIndexInPage));
|
|
408
|
+
event.preventDefault();
|
|
409
|
+
}
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
309
412
|
switch (event.key) {
|
|
310
413
|
case 'ArrowDown':
|
|
311
414
|
{
|
|
@@ -356,6 +459,37 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
|
|
|
356
459
|
goToGroupHeader(lastColIndex, currentDepth, event);
|
|
357
460
|
break;
|
|
358
461
|
}
|
|
462
|
+
case 'Tab':
|
|
463
|
+
{
|
|
464
|
+
if (event.shiftKey) {
|
|
465
|
+
const remainingLeftColumns = fields.indexOf(currentField);
|
|
466
|
+
const targetColIndex = currentColIndex - remainingLeftColumns - 1;
|
|
467
|
+
if (targetColIndex < firstColIndex) {
|
|
468
|
+
if (depth === 0) {
|
|
469
|
+
// if the key is pressed on the first column group header at the top level, Shift+Tab should allow default behavior
|
|
470
|
+
shouldPreventDefault = false;
|
|
471
|
+
} else {
|
|
472
|
+
// Navigate to last column group header at the previous depth
|
|
473
|
+
goToGroupHeader(lastColIndex, currentDepth - 1, event);
|
|
474
|
+
}
|
|
475
|
+
} else {
|
|
476
|
+
goToGroupHeader(targetColIndex, currentDepth, event);
|
|
477
|
+
}
|
|
478
|
+
} else {
|
|
479
|
+
const remainingRightColumns = fields.length - fields.indexOf(currentField) - 1;
|
|
480
|
+
const targetColIndex = currentColIndex + remainingRightColumns + 1;
|
|
481
|
+
if (targetColIndex > lastColIndex && depth === maxDepth - 1) {
|
|
482
|
+
// the key is pressed at the last column group header at the deepest level. go to the first column header
|
|
483
|
+
goToHeader(firstColIndex, event);
|
|
484
|
+
} else if (targetColIndex > lastColIndex) {
|
|
485
|
+
// go down a depth level
|
|
486
|
+
goToGroupHeader(firstColIndex, currentDepth + 1, event);
|
|
487
|
+
} else {
|
|
488
|
+
goToGroupHeader(targetColIndex, currentDepth, event);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
break;
|
|
492
|
+
}
|
|
359
493
|
case ' ':
|
|
360
494
|
{
|
|
361
495
|
// prevent Space event from scrolling
|
|
@@ -369,7 +503,7 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
|
|
|
369
503
|
if (shouldPreventDefault) {
|
|
370
504
|
event.preventDefault();
|
|
371
505
|
}
|
|
372
|
-
}, [apiRef, getCurrentPageRows, goToHeader, goToGroupHeader, goToCell, getRowIdFromIndex]);
|
|
506
|
+
}, [apiRef, props.tabNavigation, getCurrentPageRows, goToHeader, goToGroupHeader, goToCell, getRowIdFromIndex]);
|
|
373
507
|
const handleCellKeyDown = React.useCallback((params, event) => {
|
|
374
508
|
// Ignore portal
|
|
375
509
|
if (isEventTargetInPortal(event)) {
|
|
@@ -378,7 +512,12 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
|
|
|
378
512
|
|
|
379
513
|
// Get the most recent params because the cell mode may have changed by another listener
|
|
380
514
|
const cellParams = apiRef.current.getCellParams(params.id, params.field);
|
|
381
|
-
if (cellParams.cellMode === GridCellModes.Edit || !isNavigationKey(event.key)) {
|
|
515
|
+
if (cellParams.cellMode === GridCellModes.Edit || !isNavigationKey(event.key) && event.key !== 'Tab') {
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// Tab key is only allowed if tabbing is enabled or if we are tabbing to the header area while `tabNavigation` is enabled for header only (with Shift+Tab)
|
|
520
|
+
if (event.key === 'Tab' && (props.tabNavigation === 'none' || props.tabNavigation === 'header' && !event.shiftKey)) {
|
|
382
521
|
return;
|
|
383
522
|
}
|
|
384
523
|
const canUpdateFocus = apiRef.current.unstable_applyPipeProcessors('canUpdateFocus', true, {
|
|
@@ -392,14 +531,22 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
|
|
|
392
531
|
if (currentPageRows.length === 0) {
|
|
393
532
|
return;
|
|
394
533
|
}
|
|
534
|
+
const previousAreaNavigationFn = headerFilteringEnabled ? goToHeaderFilter : goToHeader;
|
|
395
535
|
const viewportPageSize = apiRef.current.getViewportPageSize();
|
|
396
536
|
const colIndexBefore = params.field ? apiRef.current.getColumnIndex(params.field) : 0;
|
|
397
537
|
const rowIndexBefore = currentPageRows.findIndex(row => row.id === params.id);
|
|
398
538
|
const firstRowIndexInPage = 0;
|
|
399
539
|
const lastRowIndexInPage = currentPageRows.length - 1;
|
|
400
540
|
const firstColIndex = 0;
|
|
401
|
-
const lastColIndex = gridVisibleColumnDefinitionsSelector(apiRef).length - 1;
|
|
541
|
+
const lastColIndex = Math.max(0, gridVisibleColumnDefinitionsSelector(apiRef).length - 1);
|
|
402
542
|
let shouldPreventDefault = true;
|
|
543
|
+
|
|
544
|
+
// If we are tabbing inside the content area while only header `tabNavigation` is enabled, go to the last header filter or column header
|
|
545
|
+
if (event.key === 'Tab' && props.tabNavigation === 'header' && event.shiftKey) {
|
|
546
|
+
previousAreaNavigationFn(lastColIndex, event);
|
|
547
|
+
event.preventDefault();
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
403
550
|
switch (event.key) {
|
|
404
551
|
case 'ArrowDown':
|
|
405
552
|
{
|
|
@@ -413,10 +560,8 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
|
|
|
413
560
|
{
|
|
414
561
|
if (rowIndexBefore > firstRowIndexInPage) {
|
|
415
562
|
goToCell(colIndexBefore, getRowIdFromIndex(rowIndexBefore - 1));
|
|
416
|
-
} else if (headerFilteringEnabled) {
|
|
417
|
-
goToHeaderFilter(colIndexBefore, event);
|
|
418
563
|
} else {
|
|
419
|
-
|
|
564
|
+
previousAreaNavigationFn(colIndexBefore, event);
|
|
420
565
|
}
|
|
421
566
|
break;
|
|
422
567
|
}
|
|
@@ -448,10 +593,29 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
|
|
|
448
593
|
}
|
|
449
594
|
case 'Tab':
|
|
450
595
|
{
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
596
|
+
if (event.shiftKey) {
|
|
597
|
+
// if the key is pressed on the first cell, Shift+Tab should go to the last column header
|
|
598
|
+
// same is if `tabNavigation` is enabled for header only
|
|
599
|
+
if (colIndexBefore === firstColIndex && rowIndexBefore === firstRowIndexInPage) {
|
|
600
|
+
if (props.tabNavigation === 'all') {
|
|
601
|
+
previousAreaNavigationFn(lastColIndex, event);
|
|
602
|
+
} else {
|
|
603
|
+
shouldPreventDefault = false;
|
|
604
|
+
}
|
|
605
|
+
} else if (colIndexBefore === firstColIndex) {
|
|
606
|
+
goToCell(lastColIndex, getRowIdFromIndex(rowIndexBefore - 1));
|
|
607
|
+
} else {
|
|
608
|
+
goToCell(colIndexBefore - 1, getRowIdFromIndex(rowIndexBefore), 'left');
|
|
609
|
+
}
|
|
610
|
+
} else if (colIndexBefore === lastColIndex) {
|
|
611
|
+
// the key is pressed at the last column. if it is also the last row, do not to anything to allow the default behavior
|
|
612
|
+
// otherwise, go to the first column of the next row
|
|
613
|
+
if (rowIndexBefore !== lastRowIndexInPage) {
|
|
614
|
+
goToCell(firstColIndex, getRowIdFromIndex(rowIndexBefore + 1));
|
|
615
|
+
} else {
|
|
616
|
+
shouldPreventDefault = false;
|
|
617
|
+
}
|
|
618
|
+
} else {
|
|
455
619
|
goToCell(colIndexBefore + 1, getRowIdFromIndex(rowIndexBefore), 'right');
|
|
456
620
|
}
|
|
457
621
|
break;
|
|
@@ -515,7 +679,7 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
|
|
|
515
679
|
if (shouldPreventDefault) {
|
|
516
680
|
event.preventDefault();
|
|
517
681
|
}
|
|
518
|
-
}, [apiRef, getCurrentPageRows, isRtl, goToCell, getRowIdFromIndex, headerFilteringEnabled, goToHeaderFilter, goToHeader]);
|
|
682
|
+
}, [apiRef, props.tabNavigation, getCurrentPageRows, isRtl, goToCell, getRowIdFromIndex, headerFilteringEnabled, goToHeaderFilter, goToHeader]);
|
|
519
683
|
const checkIfCanStartEditing = React.useCallback((initialValue, {
|
|
520
684
|
event
|
|
521
685
|
}) => {
|
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
4
4
|
import * as React from 'react';
|
|
5
|
-
import { useGridLogger,
|
|
5
|
+
import { useGridLogger, useGridApiMethod } from "../../utils/index.js";
|
|
6
6
|
import { useGridRegisterPipeProcessor } from "../../core/pipeProcessing/index.js";
|
|
7
7
|
import { gridPaginationMetaSelector } from "./gridPaginationSelector.js";
|
|
8
8
|
export const useGridPaginationMeta = (apiRef, props) => {
|
|
9
9
|
const logger = useGridLogger(apiRef, 'useGridPaginationMeta');
|
|
10
|
-
const paginationMeta = useGridSelector(apiRef, gridPaginationMetaSelector);
|
|
11
10
|
apiRef.current.registerControlState({
|
|
12
11
|
stateId: 'paginationMeta',
|
|
13
12
|
propModel: props.paginationMeta,
|
|
@@ -20,6 +19,7 @@ export const useGridPaginationMeta = (apiRef, props) => {
|
|
|
20
19
|
* API METHODS
|
|
21
20
|
*/
|
|
22
21
|
const setPaginationMeta = React.useCallback(newPaginationMeta => {
|
|
22
|
+
const paginationMeta = gridPaginationMetaSelector(apiRef);
|
|
23
23
|
if (paginationMeta === newPaginationMeta) {
|
|
24
24
|
return;
|
|
25
25
|
}
|
|
@@ -29,7 +29,7 @@ export const useGridPaginationMeta = (apiRef, props) => {
|
|
|
29
29
|
meta: newPaginationMeta
|
|
30
30
|
})
|
|
31
31
|
}));
|
|
32
|
-
}, [apiRef, logger
|
|
32
|
+
}, [apiRef, logger]);
|
|
33
33
|
const paginationMetaApi = {
|
|
34
34
|
setPaginationMeta
|
|
35
35
|
};
|
|
@@ -60,6 +60,7 @@ export const useGridPaginationModel = (apiRef, props) => {
|
|
|
60
60
|
pageSize: currentModel.pageSize
|
|
61
61
|
});
|
|
62
62
|
}, [apiRef, logger]);
|
|
63
|
+
const debouncedSetPage = React.useMemo(() => debounce(setPage, 0), [setPage]);
|
|
63
64
|
const setPageSize = React.useCallback(pageSize => {
|
|
64
65
|
const currentModel = gridPaginationModelSelector(apiRef);
|
|
65
66
|
if (pageSize === currentModel.pageSize) {
|
|
@@ -154,9 +155,11 @@ export const useGridPaginationModel = (apiRef, props) => {
|
|
|
154
155
|
}
|
|
155
156
|
const pageCount = gridPageCountSelector(apiRef);
|
|
156
157
|
if (paginationModel.page > pageCount - 1) {
|
|
157
|
-
|
|
158
|
+
queueMicrotask(() => {
|
|
159
|
+
debouncedSetPage(Math.max(0, pageCount - 1));
|
|
160
|
+
});
|
|
158
161
|
}
|
|
159
|
-
}, [apiRef]);
|
|
162
|
+
}, [apiRef, debouncedSetPage]);
|
|
160
163
|
|
|
161
164
|
/**
|
|
162
165
|
* Goes to the first row of the grid
|
|
@@ -164,7 +167,7 @@ export const useGridPaginationModel = (apiRef, props) => {
|
|
|
164
167
|
const navigateToStart = React.useCallback(() => {
|
|
165
168
|
const paginationModel = gridPaginationModelSelector(apiRef);
|
|
166
169
|
if (paginationModel.page !== 0) {
|
|
167
|
-
|
|
170
|
+
debouncedSetPage(0);
|
|
168
171
|
}
|
|
169
172
|
|
|
170
173
|
// If the page was not changed it might be needed to scroll to the top
|
|
@@ -174,7 +177,7 @@ export const useGridPaginationModel = (apiRef, props) => {
|
|
|
174
177
|
top: 0
|
|
175
178
|
});
|
|
176
179
|
}
|
|
177
|
-
}, [apiRef]);
|
|
180
|
+
}, [apiRef, debouncedSetPage]);
|
|
178
181
|
const debouncedNavigateToStart = React.useMemo(() => debounce(navigateToStart, 0), [navigateToStart]);
|
|
179
182
|
|
|
180
183
|
/**
|
|
@@ -3,16 +3,13 @@
|
|
|
3
3
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import useLazyRef from '@mui/utils/useLazyRef';
|
|
6
|
+
import { useStoreEffect } from '@mui/x-internals/store';
|
|
6
7
|
import { gridFilteredTopLevelRowCountSelector } from "../filter/index.js";
|
|
7
|
-
import { useGridLogger,
|
|
8
|
+
import { useGridLogger, useGridApiMethod, useGridEvent } from "../../utils/index.js";
|
|
8
9
|
import { useGridRegisterPipeProcessor } from "../../core/pipeProcessing/index.js";
|
|
9
10
|
import { gridPaginationRowCountSelector, gridPaginationMetaSelector, gridPaginationModelSelector } from "./gridPaginationSelector.js";
|
|
10
11
|
export const useGridRowCount = (apiRef, props) => {
|
|
11
12
|
const logger = useGridLogger(apiRef, 'useGridRowCount');
|
|
12
|
-
const visibleTopLevelRowCount = useGridSelector(apiRef, gridFilteredTopLevelRowCountSelector);
|
|
13
|
-
const rowCountState = useGridSelector(apiRef, gridPaginationRowCountSelector);
|
|
14
|
-
const paginationMeta = useGridSelector(apiRef, gridPaginationMetaSelector);
|
|
15
|
-
const paginationModel = useGridSelector(apiRef, gridPaginationModelSelector);
|
|
16
13
|
const previousPageSize = useLazyRef(() => gridPaginationModelSelector(apiRef).pageSize);
|
|
17
14
|
apiRef.current.registerControlState({
|
|
18
15
|
stateId: 'paginationRowCount',
|
|
@@ -26,6 +23,7 @@ export const useGridRowCount = (apiRef, props) => {
|
|
|
26
23
|
* API METHODS
|
|
27
24
|
*/
|
|
28
25
|
const setRowCount = React.useCallback(newRowCount => {
|
|
26
|
+
const rowCountState = gridPaginationRowCountSelector(apiRef);
|
|
29
27
|
if (rowCountState === newRowCount) {
|
|
30
28
|
return;
|
|
31
29
|
}
|
|
@@ -35,7 +33,7 @@ export const useGridRowCount = (apiRef, props) => {
|
|
|
35
33
|
rowCount: newRowCount
|
|
36
34
|
})
|
|
37
35
|
}));
|
|
38
|
-
}, [apiRef, logger
|
|
36
|
+
}, [apiRef, logger]);
|
|
39
37
|
const paginationRowCountApi = {
|
|
40
38
|
setRowCount
|
|
41
39
|
};
|
|
@@ -83,28 +81,46 @@ export const useGridRowCount = (apiRef, props) => {
|
|
|
83
81
|
}
|
|
84
82
|
if (model.pageSize !== previousPageSize.current) {
|
|
85
83
|
previousPageSize.current = model.pageSize;
|
|
84
|
+
const rowCountState = gridPaginationRowCountSelector(apiRef);
|
|
86
85
|
if (rowCountState === -1) {
|
|
87
86
|
// Row count unknown and page size changed, reset the page
|
|
88
87
|
apiRef.current.setPage(0);
|
|
89
88
|
}
|
|
90
89
|
}
|
|
91
|
-
}, [props.paginationMode, previousPageSize,
|
|
90
|
+
}, [props.paginationMode, previousPageSize, apiRef]);
|
|
92
91
|
useGridEvent(apiRef, 'paginationModelChange', handlePaginationModelChange);
|
|
93
92
|
|
|
94
93
|
/**
|
|
95
94
|
* EFFECTS
|
|
96
95
|
*/
|
|
97
96
|
React.useEffect(() => {
|
|
98
|
-
if (props.paginationMode === '
|
|
99
|
-
apiRef.current.setRowCount(visibleTopLevelRowCount);
|
|
100
|
-
} else if (props.rowCount != null) {
|
|
97
|
+
if (props.paginationMode === 'server' && props.rowCount != null) {
|
|
101
98
|
apiRef.current.setRowCount(props.rowCount);
|
|
102
99
|
}
|
|
103
|
-
}, [apiRef, props.paginationMode,
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
100
|
+
}, [apiRef, props.paginationMode, props.rowCount]);
|
|
101
|
+
useStoreEffect(
|
|
102
|
+
// typings not supported currently, but methods work
|
|
103
|
+
apiRef.current.store, () => {
|
|
104
|
+
const isLastPage = gridPaginationMetaSelector(apiRef).hasNextPage === false;
|
|
105
|
+
if (isLastPage) {
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
if (props.paginationMode === 'client') {
|
|
109
|
+
return gridFilteredTopLevelRowCountSelector(apiRef);
|
|
110
|
+
}
|
|
111
|
+
return undefined;
|
|
112
|
+
}, (_, isLastPageOrRowCount) => {
|
|
113
|
+
if (isLastPageOrRowCount === true && gridPaginationRowCountSelector(apiRef) !== -1) {
|
|
114
|
+
const visibleTopLevelRowCount = gridFilteredTopLevelRowCountSelector(apiRef);
|
|
115
|
+
const paginationModel = gridPaginationModelSelector(apiRef);
|
|
107
116
|
apiRef.current.setRowCount(paginationModel.pageSize * paginationModel.page + visibleTopLevelRowCount);
|
|
117
|
+
} else if (typeof isLastPageOrRowCount === 'number') {
|
|
118
|
+
apiRef.current.setRowCount(isLastPageOrRowCount);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
React.useEffect(() => {
|
|
122
|
+
if (props.paginationMode === 'client') {
|
|
123
|
+
apiRef.current.setRowCount(gridFilteredTopLevelRowCountSelector(apiRef));
|
|
108
124
|
}
|
|
109
|
-
}, [apiRef,
|
|
125
|
+
}, [apiRef, props.paginationMode]);
|
|
110
126
|
};
|
|
@@ -62,7 +62,6 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
62
62
|
isRowSelectable: propIsRowSelectable
|
|
63
63
|
} = props;
|
|
64
64
|
const canHaveMultipleSelection = isMultipleRowSelectionEnabled(props);
|
|
65
|
-
const tree = useGridSelector(apiRef, gridRowTreeSelector);
|
|
66
65
|
const expandMouseRowRangeSelection = React.useCallback(id => {
|
|
67
66
|
let endId = id;
|
|
68
67
|
const startId = lastRowToggled.current ?? id;
|
|
@@ -128,6 +127,7 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
128
127
|
if (!apiRef.current.isRowSelectable(id)) {
|
|
129
128
|
return;
|
|
130
129
|
}
|
|
130
|
+
const tree = gridRowTreeSelector(apiRef);
|
|
131
131
|
lastRowToggled.current = id;
|
|
132
132
|
if (resetSelection) {
|
|
133
133
|
logger.debug(`Setting selection for row ${id}`);
|
|
@@ -173,12 +173,13 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
173
173
|
apiRef.current.setRowSelectionModel(newSelectionModel, 'singleRowSelection');
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
|
-
}, [apiRef, logger, applyAutoSelection,
|
|
176
|
+
}, [apiRef, logger, applyAutoSelection, props.rowSelectionPropagation?.descendants, props.rowSelectionPropagation?.parents, canHaveMultipleSelection]);
|
|
177
177
|
const selectRows = React.useCallback((ids, isSelected = true, resetSelection = false) => {
|
|
178
178
|
logger.debug(`Setting selection for several rows`);
|
|
179
179
|
if (props.rowSelection === false) {
|
|
180
180
|
return;
|
|
181
181
|
}
|
|
182
|
+
const tree = gridRowTreeSelector(apiRef);
|
|
182
183
|
const selectableIds = new Set();
|
|
183
184
|
for (let i = 0; i < ids.length; i += 1) {
|
|
184
185
|
const id = ids[i];
|
|
@@ -239,7 +240,7 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
239
240
|
if (isSelectionValid) {
|
|
240
241
|
apiRef.current.setRowSelectionModel(newSelectionModel, 'multipleRowsSelection');
|
|
241
242
|
}
|
|
242
|
-
}, [logger, applyAutoSelection, canHaveMultipleSelection, apiRef,
|
|
243
|
+
}, [logger, applyAutoSelection, canHaveMultipleSelection, apiRef, props.rowSelectionPropagation?.descendants, props.rowSelectionPropagation?.parents, props.rowSelection]);
|
|
243
244
|
const getPropagatedRowSelectionModel = React.useCallback(inputSelectionModel => {
|
|
244
245
|
if (!isNestedData || !applyAutoSelection || inputSelectionModel.type === 'exclude' || inputSelectionModel.ids.size === 0 && inputSelectionModel.type === 'include') {
|
|
245
246
|
return inputSelectionModel;
|
|
@@ -248,6 +249,7 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
248
249
|
type: inputSelectionModel.type,
|
|
249
250
|
ids: new Set(inputSelectionModel.ids)
|
|
250
251
|
};
|
|
252
|
+
const tree = gridRowTreeSelector(apiRef);
|
|
251
253
|
const selectionManager = createRowSelectionManager(propagatedSelectionModel);
|
|
252
254
|
const addRow = rowId => {
|
|
253
255
|
selectionManager.select(rowId);
|
|
@@ -256,7 +258,7 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
256
258
|
findRowsToSelect(apiRef, tree, id, props.rowSelectionPropagation?.descendants ?? false, props.rowSelectionPropagation?.parents ?? false, addRow, selectionManager);
|
|
257
259
|
}
|
|
258
260
|
return propagatedSelectionModel;
|
|
259
|
-
}, [apiRef,
|
|
261
|
+
}, [apiRef, props.rowSelectionPropagation?.descendants, props.rowSelectionPropagation?.parents, isNestedData, applyAutoSelection]);
|
|
260
262
|
const selectRowRange = React.useCallback(({
|
|
261
263
|
startId,
|
|
262
264
|
endId
|
|
@@ -325,7 +327,7 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
325
327
|
if (!props.rowSelectionPropagation?.parents) {
|
|
326
328
|
continue;
|
|
327
329
|
}
|
|
328
|
-
const node =
|
|
330
|
+
const node = rowTree[id];
|
|
329
331
|
if (node?.type === 'group') {
|
|
330
332
|
const isAutoGenerated = node.isAutoGenerated;
|
|
331
333
|
if (isAutoGenerated) {
|
|
@@ -366,7 +368,7 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
366
368
|
apiRef.current.setRowSelectionModel(newSelectionModel, 'multipleRowsSelection');
|
|
367
369
|
}
|
|
368
370
|
}
|
|
369
|
-
}, [apiRef, isNestedData, props.rowSelectionPropagation?.parents, props.keepNonExistentRowsSelected, props.filterMode,
|
|
371
|
+
}, [apiRef, isNestedData, props.rowSelectionPropagation?.parents, props.keepNonExistentRowsSelected, props.filterMode, getRowsToBeSelected]);
|
|
370
372
|
const handleSingleRowSelection = React.useCallback((id, event) => {
|
|
371
373
|
const hasCtrlKey = event.metaKey || event.ctrlKey;
|
|
372
374
|
|
|
@@ -530,7 +532,6 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
530
532
|
}
|
|
531
533
|
apiRef.current.setRowSelectionModel(propRowSelectionModel);
|
|
532
534
|
});
|
|
533
|
-
useGridEvent(apiRef, 'sortedRowsSet', runIfRowSelectionIsEnabled(() => removeOutdatedSelection(true)));
|
|
534
535
|
useGridEvent(apiRef, 'filteredRowsSet', runIfRowSelectionIsEnabled(() => removeOutdatedSelection()));
|
|
535
536
|
useGridEvent(apiRef, 'rowClick', runIfRowSelectionIsEnabled(handleRowClick));
|
|
536
537
|
useGridEvent(apiRef, 'rowSelectionCheckboxChange', runIfRowSelectionIsEnabled(handleRowSelectionCheckboxChange));
|
|
@@ -13,6 +13,7 @@ export declare const checkboxPropsSelector: (args_0: import("react").RefObject<{
|
|
|
13
13
|
}) => {
|
|
14
14
|
isIndeterminate: boolean;
|
|
15
15
|
isChecked: boolean;
|
|
16
|
+
isSelectable: boolean;
|
|
16
17
|
};
|
|
17
18
|
export declare function isMultipleRowSelectionEnabled(props: Pick<DataGridProcessedProps, 'signature' | 'disableMultipleRowSelection' | 'checkboxSelection'>): boolean;
|
|
18
19
|
export declare const findRowsToSelect: (apiRef: RefObject<GridPrivateApiCommunity>, tree: GridRowTreeConfig, selectedRow: GridRowId, autoSelectDescendants: boolean, autoSelectParents: boolean, addRow: (rowId: GridRowId) => void, rowSelectionManager?: RowSelectionManager) => void;
|
|
@@ -3,8 +3,10 @@ import { GRID_ROOT_GROUP_ID } from "../rows/gridRowsUtils.js";
|
|
|
3
3
|
import { gridFilteredRowsLookupSelector } from "../filter/gridFilterSelector.js";
|
|
4
4
|
import { gridSortedRowIdsSelector } from "../sorting/gridSortingSelector.js";
|
|
5
5
|
import { gridRowSelectionManagerSelector } from "./gridRowSelectionSelector.js";
|
|
6
|
-
import { gridRowTreeSelector } from "../rows/gridRowsSelector.js";
|
|
6
|
+
import { gridRowsLookupSelector, gridRowTreeSelector } from "../rows/gridRowsSelector.js";
|
|
7
7
|
import { createSelector } from "../../../utils/createSelector.js";
|
|
8
|
+
import { gridColumnDefinitionsSelector } from "../columns/index.js";
|
|
9
|
+
import { gridRowSelectableSelector } from "../../core/gridPropsSelectors.js";
|
|
8
10
|
export const ROW_SELECTION_PROPAGATION_DEFAULT = {
|
|
9
11
|
parents: true,
|
|
10
12
|
descendants: true
|
|
@@ -27,15 +29,25 @@ function getGridRowGroupSelectableDescendants(apiRef, groupId) {
|
|
|
27
29
|
}
|
|
28
30
|
return descendants;
|
|
29
31
|
}
|
|
30
|
-
export const checkboxPropsSelector = createSelector(gridRowTreeSelector, gridFilteredRowsLookupSelector, gridRowSelectionManagerSelector, (rowTree, filteredRowsLookup, rowSelectionManager, {
|
|
32
|
+
export const checkboxPropsSelector = createSelector(gridColumnDefinitionsSelector, gridRowTreeSelector, gridFilteredRowsLookupSelector, gridRowSelectionManagerSelector, gridRowsLookupSelector, gridRowSelectableSelector, (columns, rowTree, filteredRowsLookup, rowSelectionManager, rowsLookup, isRowSelectable, {
|
|
31
33
|
groupId,
|
|
32
34
|
autoSelectParents
|
|
33
35
|
}) => {
|
|
34
36
|
const groupNode = rowTree[groupId];
|
|
37
|
+
const rowParams = {
|
|
38
|
+
id: groupId,
|
|
39
|
+
row: rowsLookup[groupId],
|
|
40
|
+
columns
|
|
41
|
+
};
|
|
42
|
+
let isSelectable = true;
|
|
43
|
+
if (typeof isRowSelectable === 'function') {
|
|
44
|
+
isSelectable = isRowSelectable(rowParams);
|
|
45
|
+
}
|
|
35
46
|
if (!groupNode || groupNode.type !== 'group' || rowSelectionManager.has(groupId)) {
|
|
36
47
|
return {
|
|
37
48
|
isIndeterminate: false,
|
|
38
|
-
isChecked: rowSelectionManager.has(groupId)
|
|
49
|
+
isChecked: rowSelectionManager.has(groupId),
|
|
50
|
+
isSelectable
|
|
39
51
|
};
|
|
40
52
|
}
|
|
41
53
|
let hasSelectedDescendant = false;
|
|
@@ -60,7 +72,8 @@ export const checkboxPropsSelector = createSelector(gridRowTreeSelector, gridFil
|
|
|
60
72
|
traverseDescendants(groupId);
|
|
61
73
|
return {
|
|
62
74
|
isIndeterminate: hasSelectedDescendant && hasUnSelectedDescendant,
|
|
63
|
-
isChecked: autoSelectParents ? hasSelectedDescendant && !hasUnSelectedDescendant : false
|
|
75
|
+
isChecked: autoSelectParents ? hasSelectedDescendant && !hasUnSelectedDescendant : false,
|
|
76
|
+
isSelectable
|
|
64
77
|
};
|
|
65
78
|
});
|
|
66
79
|
export function isMultipleRowSelectionEnabled(props) {
|