@mui/x-data-grid 8.18.0 → 8.20.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 +175 -0
- package/DataGrid/useDataGridComponent.js +4 -3
- package/components/GridRow.js +5 -2
- package/components/GridRowDragAndDropOverlay.d.ts +7 -0
- package/components/GridRowDragAndDropOverlay.js +73 -0
- 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 +17 -40
- 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/constants/gridClasses.d.ts +0 -8
- package/constants/gridClasses.js +1 -1
- package/esm/DataGrid/useDataGridComponent.js +5 -4
- package/esm/components/GridRow.js +5 -2
- package/esm/components/GridRowDragAndDropOverlay.d.ts +7 -0
- package/esm/components/GridRowDragAndDropOverlay.js +66 -0
- 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 +17 -40
- 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/constants/gridClasses.d.ts +0 -8
- package/esm/constants/gridClasses.js +1 -1
- package/esm/hooks/core/gridPropsSelectors.d.ts +2 -1
- package/esm/hooks/core/gridPropsSelectors.js +3 -0
- package/esm/hooks/core/pipeProcessing/gridPipeProcessingApi.d.ts +4 -3
- 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/dataSource/useGridDataSourceBase.js +2 -2
- package/esm/hooks/features/dimensions/useGridDimensions.js +12 -6
- package/esm/hooks/features/editing/useGridCellEditing.js +1 -1
- package/esm/hooks/features/editing/useGridRowEditing.js +1 -1
- package/esm/hooks/features/export/serializers/csvSerializer.js +2 -4
- package/esm/hooks/features/export/useGridPrintExport.js +18 -18
- package/esm/hooks/features/filter/gridFilterUtils.js +5 -11
- package/esm/hooks/features/filter/index.d.ts +1 -1
- package/esm/hooks/features/filter/index.js +1 -1
- 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/rowReorder/gridRowReorderInterfaces.d.ts +19 -0
- package/esm/hooks/features/rowReorder/gridRowReorderSelector.d.ts +20 -1
- package/esm/hooks/features/rowReorder/gridRowReorderSelector.js +19 -1
- package/esm/hooks/features/rowSelection/useGridRowSelection.js +17 -8
- 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/rows/useGridRows.js +3 -1
- package/esm/hooks/features/rows/useGridRowsOverridableMethods.d.ts +1 -0
- package/esm/hooks/features/rows/useGridRowsOverridableMethods.js +57 -7
- package/esm/hooks/features/scroll/useGridScroll.js +2 -3
- package/esm/hooks/features/sorting/gridSortingUtils.js +1 -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/useGridSelector.js +2 -4
- 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/internals/index.d.ts +5 -4
- package/esm/internals/index.js +3 -3
- package/esm/material/index.js +1 -4
- package/esm/models/api/gridRowApi.d.ts +14 -1
- package/esm/models/api/index.d.ts +1 -1
- package/esm/models/api/index.js +0 -1
- package/esm/models/colDef/gridColDef.d.ts +14 -0
- package/esm/models/configuration/gridConfiguration.d.ts +2 -2
- package/esm/models/configuration/gridRowConfiguration.d.ts +6 -5
- 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/pipeProcessing/gridPipeProcessingApi.d.ts +4 -3
- 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/dataSource/useGridDataSourceBase.js +2 -2
- package/hooks/features/dimensions/useGridDimensions.js +12 -6
- package/hooks/features/editing/useGridCellEditing.js +1 -1
- package/hooks/features/editing/useGridRowEditing.js +1 -1
- package/hooks/features/export/serializers/csvSerializer.js +2 -4
- package/hooks/features/export/useGridPrintExport.js +18 -18
- package/hooks/features/filter/gridFilterUtils.js +5 -11
- package/hooks/features/filter/index.d.ts +1 -1
- package/hooks/features/filter/index.js +6 -0
- 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/rowReorder/gridRowReorderInterfaces.d.ts +19 -0
- package/hooks/features/rowReorder/gridRowReorderSelector.d.ts +20 -1
- package/hooks/features/rowReorder/gridRowReorderSelector.js +20 -2
- package/hooks/features/rowSelection/useGridRowSelection.js +17 -8
- 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/rows/useGridRows.js +3 -1
- package/hooks/features/rows/useGridRowsOverridableMethods.d.ts +1 -0
- package/hooks/features/rows/useGridRowsOverridableMethods.js +57 -7
- package/hooks/features/scroll/useGridScroll.js +2 -3
- package/hooks/features/sorting/gridSortingUtils.js +1 -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/useGridSelector.js +2 -4
- package/hooks/utils/useRunOncePerLoop.d.ts +4 -1
- package/hooks/utils/useRunOncePerLoop.js +27 -18
- package/index.js +1 -1
- package/internals/index.d.ts +5 -4
- package/internals/index.js +16 -9
- package/material/index.js +1 -4
- package/models/api/gridRowApi.d.ts +14 -1
- package/models/api/index.d.ts +1 -1
- package/models/api/index.js +0 -11
- package/models/colDef/gridColDef.d.ts +14 -0
- package/models/configuration/gridConfiguration.d.ts +2 -2
- package/models/configuration/gridRowConfiguration.d.ts +6 -5
- 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
|
@@ -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;
|
|
@@ -101,6 +100,14 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
101
100
|
const currentModel = gridRowSelectionStateSelector(apiRef);
|
|
102
101
|
if (currentModel !== model) {
|
|
103
102
|
logger.debug(`Setting selection model`);
|
|
103
|
+
|
|
104
|
+
// clear the reference to the last selected row if that row is not in the model anymore
|
|
105
|
+
if (lastRowToggled.current !== null) {
|
|
106
|
+
const isInModel = model.ids.has(lastRowToggled.current);
|
|
107
|
+
if (model.type === 'include' && !isInModel || model.type === 'exclude' && isInModel) {
|
|
108
|
+
lastRowToggled.current = null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
104
111
|
apiRef.current.setState(state => _extends({}, state, {
|
|
105
112
|
rowSelection: props.rowSelection ? model : emptyModel
|
|
106
113
|
}), reason);
|
|
@@ -128,7 +135,8 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
128
135
|
if (!apiRef.current.isRowSelectable(id)) {
|
|
129
136
|
return;
|
|
130
137
|
}
|
|
131
|
-
|
|
138
|
+
const tree = gridRowTreeSelector(apiRef);
|
|
139
|
+
lastRowToggled.current = isSelected ? id : null;
|
|
132
140
|
if (resetSelection) {
|
|
133
141
|
logger.debug(`Setting selection for row ${id}`);
|
|
134
142
|
const newSelectionModel = {
|
|
@@ -173,12 +181,13 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
173
181
|
apiRef.current.setRowSelectionModel(newSelectionModel, 'singleRowSelection');
|
|
174
182
|
}
|
|
175
183
|
}
|
|
176
|
-
}, [apiRef, logger, applyAutoSelection,
|
|
184
|
+
}, [apiRef, logger, applyAutoSelection, props.rowSelectionPropagation?.descendants, props.rowSelectionPropagation?.parents, canHaveMultipleSelection]);
|
|
177
185
|
const selectRows = React.useCallback((ids, isSelected = true, resetSelection = false) => {
|
|
178
186
|
logger.debug(`Setting selection for several rows`);
|
|
179
187
|
if (props.rowSelection === false) {
|
|
180
188
|
return;
|
|
181
189
|
}
|
|
190
|
+
const tree = gridRowTreeSelector(apiRef);
|
|
182
191
|
const selectableIds = new Set();
|
|
183
192
|
for (let i = 0; i < ids.length; i += 1) {
|
|
184
193
|
const id = ids[i];
|
|
@@ -239,7 +248,7 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
239
248
|
if (isSelectionValid) {
|
|
240
249
|
apiRef.current.setRowSelectionModel(newSelectionModel, 'multipleRowsSelection');
|
|
241
250
|
}
|
|
242
|
-
}, [logger, applyAutoSelection, canHaveMultipleSelection, apiRef,
|
|
251
|
+
}, [logger, applyAutoSelection, canHaveMultipleSelection, apiRef, props.rowSelectionPropagation?.descendants, props.rowSelectionPropagation?.parents, props.rowSelection]);
|
|
243
252
|
const getPropagatedRowSelectionModel = React.useCallback(inputSelectionModel => {
|
|
244
253
|
if (!isNestedData || !applyAutoSelection || inputSelectionModel.type === 'exclude' || inputSelectionModel.ids.size === 0 && inputSelectionModel.type === 'include') {
|
|
245
254
|
return inputSelectionModel;
|
|
@@ -248,6 +257,7 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
248
257
|
type: inputSelectionModel.type,
|
|
249
258
|
ids: new Set(inputSelectionModel.ids)
|
|
250
259
|
};
|
|
260
|
+
const tree = gridRowTreeSelector(apiRef);
|
|
251
261
|
const selectionManager = createRowSelectionManager(propagatedSelectionModel);
|
|
252
262
|
const addRow = rowId => {
|
|
253
263
|
selectionManager.select(rowId);
|
|
@@ -256,7 +266,7 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
256
266
|
findRowsToSelect(apiRef, tree, id, props.rowSelectionPropagation?.descendants ?? false, props.rowSelectionPropagation?.parents ?? false, addRow, selectionManager);
|
|
257
267
|
}
|
|
258
268
|
return propagatedSelectionModel;
|
|
259
|
-
}, [apiRef,
|
|
269
|
+
}, [apiRef, props.rowSelectionPropagation?.descendants, props.rowSelectionPropagation?.parents, isNestedData, applyAutoSelection]);
|
|
260
270
|
const selectRowRange = React.useCallback(({
|
|
261
271
|
startId,
|
|
262
272
|
endId
|
|
@@ -325,7 +335,7 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
325
335
|
if (!props.rowSelectionPropagation?.parents) {
|
|
326
336
|
continue;
|
|
327
337
|
}
|
|
328
|
-
const node =
|
|
338
|
+
const node = rowTree[id];
|
|
329
339
|
if (node?.type === 'group') {
|
|
330
340
|
const isAutoGenerated = node.isAutoGenerated;
|
|
331
341
|
if (isAutoGenerated) {
|
|
@@ -366,7 +376,7 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
366
376
|
apiRef.current.setRowSelectionModel(newSelectionModel, 'multipleRowsSelection');
|
|
367
377
|
}
|
|
368
378
|
}
|
|
369
|
-
}, [apiRef, isNestedData, props.rowSelectionPropagation?.parents, props.keepNonExistentRowsSelected, props.filterMode,
|
|
379
|
+
}, [apiRef, isNestedData, props.rowSelectionPropagation?.parents, props.keepNonExistentRowsSelected, props.filterMode, getRowsToBeSelected]);
|
|
370
380
|
const handleSingleRowSelection = React.useCallback((id, event) => {
|
|
371
381
|
const hasCtrlKey = event.metaKey || event.ctrlKey;
|
|
372
382
|
|
|
@@ -530,7 +540,6 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
530
540
|
}
|
|
531
541
|
apiRef.current.setRowSelectionModel(propRowSelectionModel);
|
|
532
542
|
});
|
|
533
|
-
useGridEvent(apiRef, 'sortedRowsSet', runIfRowSelectionIsEnabled(() => removeOutdatedSelection(true)));
|
|
534
543
|
useGridEvent(apiRef, 'filteredRowsSet', runIfRowSelectionIsEnabled(() => removeOutdatedSelection()));
|
|
535
544
|
useGridEvent(apiRef, 'rowClick', runIfRowSelectionIsEnabled(handleRowClick));
|
|
536
545
|
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) {
|
|
@@ -9,8 +9,7 @@ import { gridRenderContextSelector } from "../virtualization/gridVirtualizationS
|
|
|
9
9
|
import { getUnprocessedRange, isRowContextInitialized, getCellValue } from "./gridRowSpanningUtils.js";
|
|
10
10
|
import { useGridEvent } from "../../utils/useGridEvent.js";
|
|
11
11
|
import { runIf } from "../../../utils/utils.js";
|
|
12
|
-
import {
|
|
13
|
-
import { gridDataRowIdsSelector } from "./gridRowsSelector.js";
|
|
12
|
+
import { useRunOncePerLoop } from "../../utils/useRunOncePerLoop.js";
|
|
14
13
|
const EMPTY_CACHES = {
|
|
15
14
|
spannedCells: {},
|
|
16
15
|
hiddenCells: {},
|
|
@@ -24,13 +23,6 @@ const EMPTY_STATE = {
|
|
|
24
23
|
caches: EMPTY_CACHES,
|
|
25
24
|
processedRange: EMPTY_RANGE
|
|
26
25
|
};
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Default number of rows to process during state initialization to avoid flickering.
|
|
30
|
-
* Number `20` is arbitrarily chosen to be large enough to cover most of the cases without
|
|
31
|
-
* compromising performance.
|
|
32
|
-
*/
|
|
33
|
-
const DEFAULT_ROWS_TO_PROCESS = 20;
|
|
34
26
|
const computeRowSpanningState = (apiRef, colDefs, visibleRows, range, rangeToProcess, resetState) => {
|
|
35
27
|
const virtualizer = apiRef.current.virtualizer;
|
|
36
28
|
const previousState = resetState ? EMPTY_STATE : Rowspan.selectors.state(virtualizer.store.state);
|
|
@@ -128,65 +120,25 @@ const computeRowSpanningState = (apiRef, colDefs, visibleRows, range, rangeToPro
|
|
|
128
120
|
processedRange
|
|
129
121
|
};
|
|
130
122
|
};
|
|
131
|
-
const getInitialRangeToProcess = (props, apiRef) => {
|
|
132
|
-
const rowCount = gridDataRowIdsSelector(apiRef).length;
|
|
133
|
-
if (props.pagination) {
|
|
134
|
-
const pageSize = gridPageSizeSelector(apiRef);
|
|
135
|
-
let paginationLastRowIndex = DEFAULT_ROWS_TO_PROCESS;
|
|
136
|
-
if (pageSize > 0) {
|
|
137
|
-
paginationLastRowIndex = pageSize - 1;
|
|
138
|
-
}
|
|
139
|
-
return {
|
|
140
|
-
firstRowIndex: 0,
|
|
141
|
-
lastRowIndex: Math.min(paginationLastRowIndex, rowCount)
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
return {
|
|
145
|
-
firstRowIndex: 0,
|
|
146
|
-
lastRowIndex: Math.min(DEFAULT_ROWS_TO_PROCESS, rowCount)
|
|
147
|
-
};
|
|
148
|
-
};
|
|
149
123
|
|
|
150
124
|
/**
|
|
151
125
|
* @requires columnsStateInitializer (method) - should be initialized before
|
|
152
126
|
* @requires rowsStateInitializer (method) - should be initialized before
|
|
153
127
|
* @requires filterStateInitializer (method) - should be initialized before
|
|
154
128
|
*/
|
|
155
|
-
export const rowSpanningStateInitializer =
|
|
156
|
-
if (!props.rowSpanning) {
|
|
157
|
-
return _extends({}, state, {
|
|
158
|
-
rowSpanning: EMPTY_STATE
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
const rowIds = state.rows.dataRowIds || [];
|
|
162
|
-
const orderedFields = state.columns.orderedFields || [];
|
|
163
|
-
const dataRowIdToModelLookup = state.rows.dataRowIdToModelLookup;
|
|
164
|
-
const columnsLookup = state.columns.lookup;
|
|
165
|
-
const isFilteringPending = Boolean(state.filter.filterModel.items.length) || Boolean(state.filter.filterModel.quickFilterValues?.length);
|
|
166
|
-
if (!rowIds.length || !orderedFields.length || !dataRowIdToModelLookup || !columnsLookup || isFilteringPending) {
|
|
167
|
-
return _extends({}, state, {
|
|
168
|
-
rowSpanning: EMPTY_STATE
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
const rangeToProcess = getInitialRangeToProcess(props, apiRef);
|
|
172
|
-
const rows = rowIds.map(id => ({
|
|
173
|
-
id,
|
|
174
|
-
model: dataRowIdToModelLookup[id]
|
|
175
|
-
}));
|
|
176
|
-
const colDefs = orderedFields.map(field => columnsLookup[field]);
|
|
177
|
-
const rowSpanning = computeRowSpanningState(apiRef, colDefs, rows, rangeToProcess, rangeToProcess, true);
|
|
129
|
+
export const rowSpanningStateInitializer = state => {
|
|
178
130
|
return _extends({}, state, {
|
|
179
|
-
rowSpanning
|
|
131
|
+
rowSpanning: EMPTY_STATE
|
|
180
132
|
});
|
|
181
133
|
};
|
|
182
134
|
export const useGridRowSpanning = (apiRef, props) => {
|
|
183
|
-
const store = apiRef.current.virtualizer.store;
|
|
184
135
|
const updateRowSpanningState = React.useCallback((renderContext, resetState = false) => {
|
|
136
|
+
const store = apiRef.current.virtualizer.store;
|
|
185
137
|
const {
|
|
186
138
|
range,
|
|
187
139
|
rows: visibleRows
|
|
188
140
|
} = getVisibleRows(apiRef);
|
|
189
|
-
if (resetState
|
|
141
|
+
if (resetState) {
|
|
190
142
|
store.set('rowSpanning', EMPTY_STATE);
|
|
191
143
|
}
|
|
192
144
|
if (range === null || !isRowContextInitialized(renderContext)) {
|
|
@@ -212,7 +164,7 @@ export const useGridRowSpanning = (apiRef, props) => {
|
|
|
212
164
|
return;
|
|
213
165
|
}
|
|
214
166
|
store.set('rowSpanning', newState);
|
|
215
|
-
}, [apiRef
|
|
167
|
+
}, [apiRef]);
|
|
216
168
|
|
|
217
169
|
// Reset events trigger a full re-computation of the row spanning state:
|
|
218
170
|
// - The `rowSpanning` prop is updated (feature flag)
|
|
@@ -220,25 +172,36 @@ export const useGridRowSpanning = (apiRef, props) => {
|
|
|
220
172
|
// - The sorting is applied
|
|
221
173
|
// - The `paginationModel` is updated
|
|
222
174
|
// - The rows are updated
|
|
175
|
+
const {
|
|
176
|
+
schedule: deferredUpdateRowSpanningState,
|
|
177
|
+
cancel
|
|
178
|
+
} = useRunOncePerLoop(updateRowSpanningState);
|
|
223
179
|
const resetRowSpanningState = React.useCallback(() => {
|
|
224
180
|
const renderContext = gridRenderContextSelector(apiRef);
|
|
225
181
|
if (!isRowContextInitialized(renderContext)) {
|
|
226
182
|
return;
|
|
227
183
|
}
|
|
228
|
-
|
|
229
|
-
}, [apiRef,
|
|
230
|
-
useGridEvent(apiRef, 'renderedRowsIntervalChange', runIf(props.rowSpanning,
|
|
184
|
+
deferredUpdateRowSpanningState(renderContext, true);
|
|
185
|
+
}, [apiRef, deferredUpdateRowSpanningState]);
|
|
186
|
+
useGridEvent(apiRef, 'renderedRowsIntervalChange', runIf(props.rowSpanning, renderContext => {
|
|
187
|
+
const didHavePendingReset = cancel();
|
|
188
|
+
updateRowSpanningState(renderContext, didHavePendingReset);
|
|
189
|
+
}));
|
|
231
190
|
useGridEvent(apiRef, 'sortedRowsSet', runIf(props.rowSpanning, resetRowSpanningState));
|
|
232
191
|
useGridEvent(apiRef, 'paginationModelChange', runIf(props.rowSpanning, resetRowSpanningState));
|
|
233
192
|
useGridEvent(apiRef, 'filteredRowsSet', runIf(props.rowSpanning, resetRowSpanningState));
|
|
234
193
|
useGridEvent(apiRef, 'columnsChange', runIf(props.rowSpanning, resetRowSpanningState));
|
|
235
194
|
React.useEffect(() => {
|
|
195
|
+
const store = apiRef.current.virtualizer?.store;
|
|
196
|
+
if (!store) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
236
199
|
if (!props.rowSpanning) {
|
|
237
200
|
if (store.state.rowSpanning !== EMPTY_STATE) {
|
|
238
201
|
store.set('rowSpanning', EMPTY_STATE);
|
|
239
202
|
}
|
|
240
|
-
} else if (store.state.rowSpanning
|
|
241
|
-
|
|
203
|
+
} else if (store.state.rowSpanning === EMPTY_STATE) {
|
|
204
|
+
updateRowSpanningState(gridRenderContextSelector(apiRef));
|
|
242
205
|
}
|
|
243
|
-
}, [apiRef,
|
|
206
|
+
}, [apiRef, props.rowSpanning, updateRowSpanningState]);
|
|
244
207
|
};
|
|
@@ -52,7 +52,8 @@ export const useGridRows = (apiRef, props, configuration) => {
|
|
|
52
52
|
|
|
53
53
|
// Get overridable methods from configuration
|
|
54
54
|
const {
|
|
55
|
-
setRowIndex
|
|
55
|
+
setRowIndex,
|
|
56
|
+
setRowPosition
|
|
56
57
|
} = configuration.hooks.useGridRowsOverridableMethods(apiRef, props);
|
|
57
58
|
const getRow = React.useCallback(id => {
|
|
58
59
|
const model = gridRowsLookupSelector(apiRef)[id];
|
|
@@ -337,6 +338,7 @@ export const useGridRows = (apiRef, props, configuration) => {
|
|
|
337
338
|
};
|
|
338
339
|
const rowProApi = {
|
|
339
340
|
setRowIndex,
|
|
341
|
+
setRowPosition,
|
|
340
342
|
setRowChildrenExpansion,
|
|
341
343
|
getRowGroupChildren,
|
|
342
344
|
expandAllRows,
|
|
@@ -3,4 +3,5 @@ import { GridRowId } from "../../../models/gridRows.js";
|
|
|
3
3
|
import { GridPrivateApiCommunity } from "../../../models/api/gridApiCommunity.js";
|
|
4
4
|
export declare const useGridRowsOverridableMethods: (apiRef: RefObject<GridPrivateApiCommunity>) => {
|
|
5
5
|
setRowIndex: (rowId: GridRowId, targetIndex: number) => void;
|
|
6
|
+
setRowPosition: (sourceRowId: GridRowId, targetRowId: GridRowId, position: import("../../../internals/index.js").RowReorderDropPosition) => void | Promise<void>;
|
|
6
7
|
};
|
|
@@ -1,20 +1,69 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { gridRowTreeSelector, gridRowNodeSelector } from "./gridRowsSelector.js";
|
|
4
|
+
import { gridExpandedSortedRowIndexLookupSelector } from "../filter/gridFilterSelector.js";
|
|
4
5
|
import { GRID_ROOT_GROUP_ID } from "./gridRowsUtils.js";
|
|
5
6
|
export const useGridRowsOverridableMethods = apiRef => {
|
|
7
|
+
const setRowPosition = React.useCallback((sourceRowId, targetRowId, position) => {
|
|
8
|
+
const sourceNode = gridRowNodeSelector(apiRef, sourceRowId);
|
|
9
|
+
const targetNode = gridRowNodeSelector(apiRef, targetRowId);
|
|
10
|
+
if (!sourceNode) {
|
|
11
|
+
throw new Error(`MUI X: No row with id #${sourceRowId} found.`);
|
|
12
|
+
}
|
|
13
|
+
if (!targetNode) {
|
|
14
|
+
throw new Error(`MUI X: No row with id #${targetRowId} found.`);
|
|
15
|
+
}
|
|
16
|
+
if (sourceNode.type !== 'leaf') {
|
|
17
|
+
throw new Error(`MUI X: The row reordering does not support reordering of footer or grouping rows.`);
|
|
18
|
+
}
|
|
19
|
+
if (position === 'inside') {
|
|
20
|
+
throw new Error(`MUI X: The 'inside' position is only supported for tree data. Use 'above' or 'below' for flat data.`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Get the target index from the targetRowId using the lookup selector
|
|
24
|
+
const sortedFilteredRowIndexLookup = gridExpandedSortedRowIndexLookupSelector(apiRef);
|
|
25
|
+
const targetRowIndexUnadjusted = sortedFilteredRowIndexLookup[targetRowId];
|
|
26
|
+
if (targetRowIndexUnadjusted === undefined) {
|
|
27
|
+
throw new Error(`MUI X: Target row with id #${targetRowId} not found in current view.`);
|
|
28
|
+
}
|
|
29
|
+
const sourceRowIndex = sortedFilteredRowIndexLookup[sourceRowId];
|
|
30
|
+
if (sourceRowIndex === undefined) {
|
|
31
|
+
throw new Error(`MUI X: Source row with id #${sourceRowId} not found in current view.`);
|
|
32
|
+
}
|
|
33
|
+
const dragDirection = targetRowIndexUnadjusted < sourceRowIndex ? 'up' : 'down';
|
|
34
|
+
let targetRowIndex;
|
|
35
|
+
if (dragDirection === 'up') {
|
|
36
|
+
targetRowIndex = position === 'above' ? targetRowIndexUnadjusted : targetRowIndexUnadjusted + 1;
|
|
37
|
+
} else {
|
|
38
|
+
targetRowIndex = position === 'above' ? targetRowIndexUnadjusted - 1 : targetRowIndexUnadjusted;
|
|
39
|
+
}
|
|
40
|
+
if (targetRowIndex === sourceRowIndex) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
apiRef.current.setState(state => {
|
|
44
|
+
const group = gridRowTreeSelector(apiRef)[GRID_ROOT_GROUP_ID];
|
|
45
|
+
const allRows = group.children;
|
|
46
|
+
const updatedRows = [...allRows];
|
|
47
|
+
updatedRows.splice(targetRowIndex, 0, updatedRows.splice(sourceRowIndex, 1)[0]);
|
|
48
|
+
return _extends({}, state, {
|
|
49
|
+
rows: _extends({}, state.rows, {
|
|
50
|
+
tree: _extends({}, state.rows.tree, {
|
|
51
|
+
[GRID_ROOT_GROUP_ID]: _extends({}, group, {
|
|
52
|
+
children: updatedRows
|
|
53
|
+
})
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
apiRef.current.publishEvent('rowsSet');
|
|
59
|
+
}, [apiRef]);
|
|
6
60
|
const setRowIndex = React.useCallback((rowId, targetIndex) => {
|
|
7
61
|
const node = gridRowNodeSelector(apiRef, rowId);
|
|
8
62
|
if (!node) {
|
|
9
63
|
throw new Error(`MUI X: No row with id #${rowId} found.`);
|
|
10
64
|
}
|
|
11
|
-
|
|
12
|
-
// TODO: Remove irrelevant checks
|
|
13
|
-
if (node.parent !== GRID_ROOT_GROUP_ID) {
|
|
14
|
-
throw new Error(`MUI X: The row reordering do not support reordering of grouped rows yet.`);
|
|
15
|
-
}
|
|
16
65
|
if (node.type !== 'leaf') {
|
|
17
|
-
throw new Error(`MUI X: The row reordering
|
|
66
|
+
throw new Error(`MUI X: The row reordering does not support reordering of footer or grouping rows.`);
|
|
18
67
|
}
|
|
19
68
|
apiRef.current.setState(state => {
|
|
20
69
|
const group = gridRowTreeSelector(apiRef)[GRID_ROOT_GROUP_ID];
|
|
@@ -38,6 +87,7 @@ export const useGridRowsOverridableMethods = apiRef => {
|
|
|
38
87
|
apiRef.current.publishEvent('rowsSet');
|
|
39
88
|
}, [apiRef]);
|
|
40
89
|
return {
|
|
41
|
-
setRowIndex
|
|
90
|
+
setRowIndex,
|
|
91
|
+
setRowPosition
|
|
42
92
|
};
|
|
43
93
|
};
|
|
@@ -2,7 +2,6 @@ import * as React from 'react';
|
|
|
2
2
|
import { useRtl } from '@mui/system/RtlProvider';
|
|
3
3
|
import { useGridLogger } from "../../utils/useGridLogger.js";
|
|
4
4
|
import { gridColumnPositionsSelector, gridVisibleColumnDefinitionsSelector } from "../columns/gridColumnsSelector.js";
|
|
5
|
-
import { useGridSelector } from "../../utils/useGridSelector.js";
|
|
6
5
|
import { gridPageSelector, gridPageSizeSelector } from "../pagination/gridPaginationSelector.js";
|
|
7
6
|
import { gridRowCountSelector } from "../rows/gridRowsSelector.js";
|
|
8
7
|
import { gridRowsMetaSelector } from "../rows/gridRowsMetaSelector.js";
|
|
@@ -47,7 +46,6 @@ export const useGridScroll = (apiRef, props) => {
|
|
|
47
46
|
const logger = useGridLogger(apiRef, 'useGridScroll');
|
|
48
47
|
const colRef = apiRef.current.columnHeadersContainerRef;
|
|
49
48
|
const virtualScrollerRef = apiRef.current.virtualScrollerRef;
|
|
50
|
-
const visibleSortedRows = useGridSelector(apiRef, gridExpandedSortedRowEntriesSelector);
|
|
51
49
|
const scrollToIndexes = React.useCallback(params => {
|
|
52
50
|
const dimensions = gridDimensionsSelector(apiRef);
|
|
53
51
|
const totalRowCount = gridRowCountSelector(apiRef);
|
|
@@ -62,6 +60,7 @@ export const useGridScroll = (apiRef, props) => {
|
|
|
62
60
|
const columnPositions = gridColumnPositionsSelector(apiRef);
|
|
63
61
|
let cellWidth;
|
|
64
62
|
if (typeof params.rowIndex !== 'undefined') {
|
|
63
|
+
const visibleSortedRows = gridExpandedSortedRowEntriesSelector(apiRef);
|
|
65
64
|
const rowId = visibleSortedRows[params.rowIndex]?.id;
|
|
66
65
|
const cellColSpanInfo = apiRef.current.unstable_getCellColSpanInfo(rowId, params.colIndex);
|
|
67
66
|
if (cellColSpanInfo && !cellColSpanInfo.spannedByColSpan) {
|
|
@@ -98,7 +97,7 @@ export const useGridScroll = (apiRef, props) => {
|
|
|
98
97
|
return true;
|
|
99
98
|
}
|
|
100
99
|
return false;
|
|
101
|
-
}, [logger, apiRef, virtualScrollerRef, props.pagination
|
|
100
|
+
}, [logger, apiRef, virtualScrollerRef, props.pagination]);
|
|
102
101
|
const scroll = React.useCallback(params => {
|
|
103
102
|
if (virtualScrollerRef.current && params.left !== undefined && colRef.current) {
|
|
104
103
|
const direction = isRtl ? -1 : 1;
|
|
@@ -3,9 +3,7 @@ import { warnOnce } from '@mui/x-internals/warning';
|
|
|
3
3
|
import { gridRowNodeSelector } from "../rows/gridRowsSelector.js";
|
|
4
4
|
export const sanitizeSortModel = (model, disableMultipleColumnsSorting) => {
|
|
5
5
|
if (disableMultipleColumnsSorting && model.length > 1) {
|
|
6
|
-
|
|
7
|
-
warnOnce(['MUI X: The `sortModel` can only contain a single item when the `disableMultipleColumnsSorting` prop is set to `true`.', 'If you are using the community version of the Data Grid, this prop is always `true`.'], 'error');
|
|
8
|
-
}
|
|
6
|
+
warnOnce(['MUI X: The `sortModel` can only contain a single item when the `disableMultipleColumnsSorting` prop is set to `true`.', 'If you are using the community version of the Data Grid, this prop is always `true`.'], 'error');
|
|
9
7
|
return [model[0]];
|
|
10
8
|
}
|
|
11
9
|
return model;
|
|
@@ -7,4 +7,4 @@ export declare const sortingStateInitializer: GridStateInitializer<Pick<DataGrid
|
|
|
7
7
|
* @requires useGridRows (event)
|
|
8
8
|
* @requires useGridColumns (event)
|
|
9
9
|
*/
|
|
10
|
-
export declare const useGridSorting: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, "initialState" | "sortModel" | "onSortModelChange" | "sortingOrder" | "sortingMode" | "disableColumnSorting" | "disableMultipleColumnsSorting" | "multipleColumnsSortingMode">) => void;
|
|
10
|
+
export declare const useGridSorting: (apiRef: RefObject<GridPrivateApiCommunity>, props: Pick<DataGridProcessedProps, "initialState" | "sortModel" | "onSortModelChange" | "sortingOrder" | "sortingMode" | "disableColumnSorting" | "disableMultipleColumnsSorting" | "multipleColumnsSortingMode" | "signature">) => void;
|
|
@@ -30,9 +30,6 @@ export const virtualizationStateInitializer = (state, props) => {
|
|
|
30
30
|
});
|
|
31
31
|
};
|
|
32
32
|
export function useGridVirtualization(apiRef, rootProps) {
|
|
33
|
-
const {
|
|
34
|
-
virtualizer
|
|
35
|
-
} = apiRef.current;
|
|
36
33
|
const {
|
|
37
34
|
autoHeight,
|
|
38
35
|
disableVirtualization
|
|
@@ -43,7 +40,14 @@ export function useGridVirtualization(apiRef, rootProps) {
|
|
|
43
40
|
*/
|
|
44
41
|
|
|
45
42
|
const setVirtualization = enabled => {
|
|
43
|
+
const {
|
|
44
|
+
virtualizer
|
|
45
|
+
} = apiRef.current;
|
|
46
46
|
enabled &&= HAS_LAYOUT;
|
|
47
|
+
const snapshot = virtualizer.store.getSnapshot();
|
|
48
|
+
if (snapshot.virtualization.enabled === enabled && snapshot.virtualization.enabledForRows === enabled && snapshot.virtualization.enabledForColumns === enabled) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
47
51
|
virtualizer.store.set('virtualization', _extends({}, virtualizer.store.state.virtualization, {
|
|
48
52
|
enabled,
|
|
49
53
|
enabledForColumns: enabled,
|
|
@@ -51,7 +55,14 @@ export function useGridVirtualization(apiRef, rootProps) {
|
|
|
51
55
|
}));
|
|
52
56
|
};
|
|
53
57
|
const setColumnVirtualization = enabled => {
|
|
58
|
+
const {
|
|
59
|
+
virtualizer
|
|
60
|
+
} = apiRef.current;
|
|
54
61
|
enabled &&= HAS_LAYOUT;
|
|
62
|
+
const snapshot = virtualizer.store.getSnapshot();
|
|
63
|
+
if (snapshot.virtualization.enabledForColumns === enabled) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
55
66
|
virtualizer.store.set('virtualization', _extends({}, virtualizer.store.state.virtualization, {
|
|
56
67
|
enabledForColumns: enabled
|
|
57
68
|
}));
|
|
@@ -61,7 +72,12 @@ export function useGridVirtualization(apiRef, rootProps) {
|
|
|
61
72
|
unstable_setColumnVirtualization: setColumnVirtualization
|
|
62
73
|
};
|
|
63
74
|
useGridApiMethod(apiRef, api, 'public');
|
|
64
|
-
const forceUpdateRenderContext =
|
|
75
|
+
const forceUpdateRenderContext = () => {
|
|
76
|
+
const {
|
|
77
|
+
virtualizer
|
|
78
|
+
} = apiRef.current;
|
|
79
|
+
virtualizer?.api.scheduleUpdateRenderContext();
|
|
80
|
+
};
|
|
65
81
|
apiRef.current.register('private', {
|
|
66
82
|
updateRenderContext: forceUpdateRenderContext
|
|
67
83
|
});
|
|
@@ -76,7 +92,10 @@ export function useGridVirtualization(apiRef, rootProps) {
|
|
|
76
92
|
|
|
77
93
|
/* eslint-disable react-hooks/exhaustive-deps */
|
|
78
94
|
React.useEffect(() => {
|
|
95
|
+
if (!apiRef.current.virtualizer) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
79
98
|
setVirtualization(!rootProps.disableVirtualization);
|
|
80
|
-
}, [disableVirtualization, autoHeight]);
|
|
99
|
+
}, [apiRef, disableVirtualization, autoHeight]);
|
|
81
100
|
/* eslint-enable react-hooks/exhaustive-deps */
|
|
82
101
|
}
|
|
@@ -24,7 +24,9 @@ export function useGridEvent(apiRef, eventName, handler, options) {
|
|
|
24
24
|
const cleanupTokenRef = React.useRef(null);
|
|
25
25
|
if (!subscription.current && handlerRef.current) {
|
|
26
26
|
const enhancedHandler = (params, event, details) => {
|
|
27
|
-
|
|
27
|
+
// Check for the existence of the event once more to avoid Safari 26 issue
|
|
28
|
+
// https://github.com/mui/mui-x/issues/20159
|
|
29
|
+
if (event && !event.defaultMuiPrevented) {
|
|
28
30
|
handlerRef.current?.(params, event, details);
|
|
29
31
|
}
|
|
30
32
|
};
|
|
@@ -51,7 +53,9 @@ export function useGridEvent(apiRef, eventName, handler, options) {
|
|
|
51
53
|
React.useEffect(() => {
|
|
52
54
|
if (!subscription.current && handlerRef.current) {
|
|
53
55
|
const enhancedHandler = (params, event, details) => {
|
|
54
|
-
|
|
56
|
+
// Check for the existence of the event once more to avoid Safari 26 issue
|
|
57
|
+
// https://github.com/mui/mui-x/issues/20159
|
|
58
|
+
if (event && !event.defaultMuiPrevented) {
|
|
55
59
|
handlerRef.current?.(params, event, details);
|
|
56
60
|
}
|
|
57
61
|
};
|
|
@@ -31,10 +31,8 @@ const createRefs = () => ({
|
|
|
31
31
|
const EMPTY = [];
|
|
32
32
|
const emptyGetSnapshot = () => null;
|
|
33
33
|
export function useGridSelector(apiRef, selector, args = undefined, equals = defaultCompare) {
|
|
34
|
-
if (
|
|
35
|
-
|
|
36
|
-
warnOnce(['MUI X: `useGridSelector` has been called before the initialization of the state.', 'This hook can only be used inside the context of the grid.']);
|
|
37
|
-
}
|
|
34
|
+
if (!apiRef.current.state) {
|
|
35
|
+
warnOnce(['MUI X: `useGridSelector` has been called before the initialization of the state.', 'This hook can only be used inside the context of the grid.']);
|
|
38
36
|
}
|
|
39
37
|
const refs = useLazyRef(createRefs);
|
|
40
38
|
const didInit = refs.current.selector !== null;
|
|
@@ -1 +1,4 @@
|
|
|
1
|
-
export declare function useRunOncePerLoop<T extends (...args: any[]) => void>(callback: T
|
|
1
|
+
export declare function useRunOncePerLoop<T extends (...args: any[]) => void>(callback: T): {
|
|
2
|
+
schedule: (...args: Parameters<T>) => void;
|
|
3
|
+
cancel: () => boolean;
|
|
4
|
+
};
|
|
@@ -1,26 +1,36 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
1
3
|
import * as React from 'react';
|
|
2
|
-
export function useRunOncePerLoop(callback
|
|
3
|
-
const
|
|
4
|
+
export function useRunOncePerLoop(callback) {
|
|
5
|
+
const scheduledCallbackRef = React.useRef(null);
|
|
4
6
|
const schedule = React.useCallback((...args) => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
+
// for robustness, a fallback in case we don't react to state updates and layoutEffect is not run
|
|
8
|
+
// if we react to state updates, layoutEffect will run before microtasks
|
|
9
|
+
if (!scheduledCallbackRef.current) {
|
|
10
|
+
queueMicrotask(() => {
|
|
11
|
+
if (scheduledCallbackRef.current) {
|
|
12
|
+
scheduledCallbackRef.current();
|
|
13
|
+
}
|
|
14
|
+
});
|
|
7
15
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
scheduledRef.current = false;
|
|
16
|
+
scheduledCallbackRef.current = () => {
|
|
17
|
+
scheduledCallbackRef.current = null;
|
|
11
18
|
callback(...args);
|
|
12
19
|
};
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
return;
|
|
20
|
+
}, [callback]);
|
|
21
|
+
React.useLayoutEffect(() => {
|
|
22
|
+
if (scheduledCallbackRef.current) {
|
|
23
|
+
scheduledCallbackRef.current();
|
|
18
24
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
25
|
+
});
|
|
26
|
+
return {
|
|
27
|
+
schedule,
|
|
28
|
+
cancel: () => {
|
|
29
|
+
if (scheduledCallbackRef.current) {
|
|
30
|
+
scheduledCallbackRef.current = null;
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
return false;
|
|
23
34
|
}
|
|
24
|
-
}
|
|
25
|
-
return schedule;
|
|
35
|
+
};
|
|
26
36
|
}
|
package/esm/index.js
CHANGED