@mui/x-data-grid 8.27.0 → 8.27.3
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 +158 -0
- package/DataGrid/DataGrid.js +7 -0
- package/DataGrid/index.js +0 -1
- package/components/GridColumnSortButton.js +2 -2
- package/components/GridScrollArea.js +2 -2
- package/components/GridScrollShadows.js +2 -2
- package/components/GridSkeletonLoadingOverlay.js +2 -2
- package/components/base/GridOverlays.js +3 -3
- package/components/columnHeaders/GridColumnHeaderItem.js +31 -1
- package/components/columnHeaders/GridColumnHeaderTitle.js +2 -2
- package/components/columnHeaders/GridIconButtonContainer.js +2 -2
- package/components/containers/GridRootStyles.js +23 -217
- package/components/menu/columnMenu/GridColumnMenu.d.ts +2 -2
- package/components/menu/columnMenu/GridColumnMenu.js +2 -0
- package/components/menu/columnMenu/GridColumnMenuProps.d.ts +9 -1
- package/components/menu/columnMenu/index.d.ts +1 -1
- package/components/menu/columnMenu/index.js +0 -12
- package/components/toolbar/GridToolbarQuickFilter.js +4 -4
- package/components/toolbarV8/GridToolbar.js +3 -3
- package/components/toolbarV8/Toolbar.d.ts +1 -1
- package/components/toolbarV8/Toolbar.js +2 -2
- package/components/virtualization/GridBottomContainer.js +2 -2
- package/components/virtualization/GridMainContainer.js +3 -3
- package/components/virtualization/GridTopContainer.js +2 -2
- package/components/virtualization/GridVirtualScrollbar.d.ts +1 -1
- package/components/virtualization/GridVirtualScrollbar.js +5 -5
- package/components/virtualization/GridVirtualScroller.js +2 -2
- package/components/virtualization/GridVirtualScrollerFiller.js +6 -6
- package/constants/dataGridPropsDefaultValues.js +1 -0
- package/esm/DataGrid/DataGrid.js +7 -0
- package/esm/DataGrid/index.js +0 -1
- package/esm/components/GridColumnSortButton.js +1 -1
- package/esm/components/GridScrollArea.js +1 -1
- package/esm/components/GridScrollShadows.js +1 -1
- package/esm/components/GridSkeletonLoadingOverlay.js +1 -1
- package/esm/components/base/GridOverlays.js +1 -1
- package/esm/components/columnHeaders/GridColumnHeaderItem.js +31 -1
- package/esm/components/columnHeaders/GridColumnHeaderTitle.js +1 -1
- package/esm/components/columnHeaders/GridIconButtonContainer.js +1 -1
- package/esm/components/containers/GridRootStyles.js +23 -217
- package/esm/components/menu/columnMenu/GridColumnMenu.d.ts +2 -2
- package/esm/components/menu/columnMenu/GridColumnMenu.js +2 -0
- package/esm/components/menu/columnMenu/GridColumnMenuProps.d.ts +9 -1
- package/esm/components/menu/columnMenu/index.d.ts +1 -1
- package/esm/components/menu/columnMenu/index.js +0 -1
- package/esm/components/toolbar/GridToolbarQuickFilter.js +1 -1
- package/esm/components/toolbarV8/GridToolbar.js +1 -1
- package/esm/components/toolbarV8/Toolbar.d.ts +1 -1
- package/esm/components/toolbarV8/Toolbar.js +1 -1
- package/esm/components/virtualization/GridBottomContainer.js +1 -1
- package/esm/components/virtualization/GridMainContainer.js +1 -1
- package/esm/components/virtualization/GridTopContainer.js +1 -1
- package/esm/components/virtualization/GridVirtualScrollbar.d.ts +1 -1
- package/esm/components/virtualization/GridVirtualScrollbar.js +1 -1
- package/esm/components/virtualization/GridVirtualScroller.js +1 -1
- package/esm/components/virtualization/GridVirtualScrollerFiller.js +1 -1
- package/esm/constants/dataGridPropsDefaultValues.js +1 -0
- package/esm/hooks/features/columnMenu/getColumnMenuItemKeys.d.ts +17 -0
- package/esm/hooks/features/columnMenu/getColumnMenuItemKeys.js +36 -0
- package/esm/hooks/features/columnMenu/useGridColumnMenuSlots.js +11 -16
- package/esm/hooks/features/dataSource/models.d.ts +4 -1
- package/esm/hooks/features/dataSource/useGridDataSourceBase.d.ts +5 -2
- package/esm/hooks/features/dataSource/useGridDataSourceBase.js +93 -6
- package/esm/hooks/features/editing/useGridRowEditing.js +14 -4
- package/esm/index.js +1 -1
- package/esm/internals/index.d.ts +1 -0
- package/esm/models/api/gridEditingApi.d.ts +0 -1
- package/esm/models/params/gridRowParams.d.ts +0 -1
- package/esm/models/props/DataGridProps.d.ts +7 -0
- package/hooks/features/columnMenu/getColumnMenuItemKeys.d.ts +17 -0
- package/hooks/features/columnMenu/getColumnMenuItemKeys.js +43 -0
- package/hooks/features/columnMenu/useGridColumnMenuSlots.js +11 -16
- package/hooks/features/dataSource/models.d.ts +4 -1
- package/hooks/features/dataSource/useGridDataSourceBase.d.ts +5 -2
- package/hooks/features/dataSource/useGridDataSourceBase.js +92 -5
- package/hooks/features/editing/useGridRowEditing.js +14 -4
- package/index.js +1 -1
- package/internals/index.d.ts +1 -0
- package/models/api/gridEditingApi.d.ts +0 -1
- package/models/params/gridRowParams.d.ts +0 -1
- package/models/props/DataGridProps.d.ts +7 -0
- package/package.json +1 -1
- package/esm/index.css +0 -5
- package/index.css +0 -5
|
@@ -5,6 +5,7 @@ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWith
|
|
|
5
5
|
const _excluded = ["skipCache", "keepChildrenExpanded"];
|
|
6
6
|
import * as React from 'react';
|
|
7
7
|
import useLazyRef from '@mui/utils/useLazyRef';
|
|
8
|
+
import useEventCallback from '@mui/utils/useEventCallback';
|
|
8
9
|
import debounce from '@mui/utils/debounce';
|
|
9
10
|
import { warnOnce } from '@mui/x-internals/warning';
|
|
10
11
|
import { isDeepEqual } from '@mui/x-internals/isDeepEqual';
|
|
@@ -12,7 +13,8 @@ import { GRID_ROOT_GROUP_ID } from "../rows/gridRowsUtils.js";
|
|
|
12
13
|
import { runIf } from "../../../utils/utils.js";
|
|
13
14
|
import { GridStrategyGroup } from "../../core/strategyProcessing/index.js";
|
|
14
15
|
import { useGridSelector } from "../../utils/useGridSelector.js";
|
|
15
|
-
import { gridPaginationModelSelector } from "../pagination/gridPaginationSelector.js";
|
|
16
|
+
import { gridPaginationModelSelector, gridVisibleRowsSelector } from "../pagination/gridPaginationSelector.js";
|
|
17
|
+
import { gridRowTreeSelector } from "../rows/gridRowsSelector.js";
|
|
16
18
|
import { gridGetRowsParamsSelector } from "./gridDataSourceSelector.js";
|
|
17
19
|
import { CacheChunkManager, DataSourceRowsUpdateStrategy } from "./utils.js";
|
|
18
20
|
import { GridDataSourceCacheDefault } from "./cache.js";
|
|
@@ -38,7 +40,9 @@ export const useGridDataSourceBase = (apiRef, props, options = {}) => {
|
|
|
38
40
|
}, [currentStrategy]);
|
|
39
41
|
const paginationModel = useGridSelector(apiRef, gridPaginationModelSelector);
|
|
40
42
|
const lastRequestId = React.useRef(0);
|
|
43
|
+
const pollingIntervalRef = React.useRef(null);
|
|
41
44
|
const onDataSourceErrorProp = props.onDataSourceError;
|
|
45
|
+
const revalidateMs = props.dataSourceRevalidateMs;
|
|
42
46
|
const cacheChunkManager = useLazyRef(() => {
|
|
43
47
|
if (!props.pagination) {
|
|
44
48
|
return new CacheChunkManager(paginationModel.pageSize);
|
|
@@ -128,6 +132,69 @@ export const useGridDataSourceBase = (apiRef, props, options = {}) => {
|
|
|
128
132
|
const handleStrategyActivityChange = React.useCallback(() => {
|
|
129
133
|
setCurrentStrategy(apiRef.current.getActiveStrategy(GridStrategyGroup.DataSource));
|
|
130
134
|
}, [apiRef]);
|
|
135
|
+
const fetchRowChildrenOption = options.fetchRowChildren;
|
|
136
|
+
const revalidate = useEventCallback(async () => {
|
|
137
|
+
const getRows = props.dataSource?.getRows;
|
|
138
|
+
if (!getRows || !standardRowsUpdateStrategyActive) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const revalidateExpandedGroups = () => {
|
|
142
|
+
if (currentStrategy !== DataSourceRowsUpdateStrategy.GroupedData || !fetchRowChildrenOption) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const rowTree = gridRowTreeSelector(apiRef);
|
|
146
|
+
const visibleRows = gridVisibleRowsSelector(apiRef).rows;
|
|
147
|
+
const expandedGroupIds = visibleRows.reduce((acc, row) => {
|
|
148
|
+
const node = rowTree[row.id];
|
|
149
|
+
if (node.type === 'group' && node.id !== GRID_ROOT_GROUP_ID && node.childrenExpanded === true) {
|
|
150
|
+
acc.push(row.id);
|
|
151
|
+
}
|
|
152
|
+
return acc;
|
|
153
|
+
}, []);
|
|
154
|
+
if (expandedGroupIds.length > 0) {
|
|
155
|
+
fetchRowChildrenOption(expandedGroupIds, {
|
|
156
|
+
showChildrenLoading: false
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
const fetchParams = _extends({}, gridGetRowsParamsSelector(apiRef), apiRef.current.unstable_applyPipeProcessors('getRowsParams', {}));
|
|
161
|
+
const cacheKeys = cacheChunkManager.getCacheKeys(fetchParams);
|
|
162
|
+
const responses = cacheKeys.map(cacheKey => cache.get(cacheKey));
|
|
163
|
+
if (responses.every(response => response !== undefined)) {
|
|
164
|
+
revalidateExpandedGroups();
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
try {
|
|
168
|
+
const response = await getRows(fetchParams);
|
|
169
|
+
const currentParams = _extends({}, gridGetRowsParamsSelector(apiRef), apiRef.current.unstable_applyPipeProcessors('getRowsParams', {}));
|
|
170
|
+
if (!isDeepEqual(fetchParams, currentParams)) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const cacheResponses = cacheChunkManager.splitResponse(fetchParams, response);
|
|
174
|
+
cacheResponses.forEach((cacheResponse, key) => cache.set(key, cacheResponse));
|
|
175
|
+
apiRef.current.applyStrategyProcessor('dataSourceRowsUpdate', {
|
|
176
|
+
response,
|
|
177
|
+
fetchParams,
|
|
178
|
+
options: {}
|
|
179
|
+
});
|
|
180
|
+
revalidateExpandedGroups();
|
|
181
|
+
} catch {
|
|
182
|
+
// Ignore background revalidation errors.
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
const stopPolling = React.useCallback(() => {
|
|
186
|
+
if (pollingIntervalRef.current !== null) {
|
|
187
|
+
clearInterval(pollingIntervalRef.current);
|
|
188
|
+
pollingIntervalRef.current = null;
|
|
189
|
+
}
|
|
190
|
+
}, []);
|
|
191
|
+
const startPolling = useEventCallback(() => {
|
|
192
|
+
stopPolling();
|
|
193
|
+
if (revalidateMs <= 0 || !standardRowsUpdateStrategyActive) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
pollingIntervalRef.current = setInterval(revalidate, revalidateMs);
|
|
197
|
+
});
|
|
131
198
|
const handleDataUpdate = React.useCallback(params => {
|
|
132
199
|
if ('error' in params) {
|
|
133
200
|
apiRef.current.setRows([]);
|
|
@@ -144,7 +211,8 @@ export const useGridDataSourceBase = (apiRef, props, options = {}) => {
|
|
|
144
211
|
params: params.fetchParams,
|
|
145
212
|
response
|
|
146
213
|
}, true);
|
|
147
|
-
|
|
214
|
+
startPolling();
|
|
215
|
+
}, [apiRef, startPolling]);
|
|
148
216
|
const dataSourceUpdateRow = props.dataSource?.updateRow;
|
|
149
217
|
const handleEditRowOption = options.handleEditRow;
|
|
150
218
|
const editRow = React.useCallback(async params => {
|
|
@@ -184,6 +252,10 @@ export const useGridDataSourceBase = (apiRef, props, options = {}) => {
|
|
|
184
252
|
}
|
|
185
253
|
};
|
|
186
254
|
const debouncedFetchRows = React.useMemo(() => debounce(fetchRows, 0), [fetchRows]);
|
|
255
|
+
const handleFetchRowsOnParamsChange = React.useCallback(() => {
|
|
256
|
+
stopPolling();
|
|
257
|
+
debouncedFetchRows();
|
|
258
|
+
}, [stopPolling, debouncedFetchRows]);
|
|
187
259
|
const isFirstRender = React.useRef(true);
|
|
188
260
|
React.useEffect(() => {
|
|
189
261
|
if (isFirstRender.current) {
|
|
@@ -196,6 +268,17 @@ export const useGridDataSourceBase = (apiRef, props, options = {}) => {
|
|
|
196
268
|
const newCache = getCache(props.dataSourceCache, options.cacheOptions);
|
|
197
269
|
setCache(prevCache => prevCache !== newCache ? newCache : prevCache);
|
|
198
270
|
}, [props.dataSourceCache, options.cacheOptions]);
|
|
271
|
+
React.useEffect(() => {
|
|
272
|
+
if (!standardRowsUpdateStrategyActive) {
|
|
273
|
+
stopPolling();
|
|
274
|
+
}
|
|
275
|
+
}, [standardRowsUpdateStrategyActive, stopPolling]);
|
|
276
|
+
React.useEffect(() => {
|
|
277
|
+
if (revalidateMs <= 0) {
|
|
278
|
+
stopPolling();
|
|
279
|
+
}
|
|
280
|
+
}, [revalidateMs, stopPolling]);
|
|
281
|
+
React.useEffect(() => stopPolling, [stopPolling]);
|
|
199
282
|
React.useEffect(() => {
|
|
200
283
|
// Return early if the proper strategy isn't set yet
|
|
201
284
|
// Context: https://github.com/mui/mui-x/issues/19650
|
|
@@ -203,6 +286,8 @@ export const useGridDataSourceBase = (apiRef, props, options = {}) => {
|
|
|
203
286
|
return undefined;
|
|
204
287
|
}
|
|
205
288
|
if (props.dataSource) {
|
|
289
|
+
stopPolling();
|
|
290
|
+
apiRef.current.setRows([]);
|
|
206
291
|
apiRef.current.dataSource.cache.clear();
|
|
207
292
|
apiRef.current.dataSource.fetchRows();
|
|
208
293
|
}
|
|
@@ -210,7 +295,7 @@ export const useGridDataSourceBase = (apiRef, props, options = {}) => {
|
|
|
210
295
|
// ignore the current request on unmount
|
|
211
296
|
lastRequestId.current += 1;
|
|
212
297
|
};
|
|
213
|
-
}, [apiRef, props.dataSource, currentStrategy]);
|
|
298
|
+
}, [apiRef, props.dataSource, currentStrategy, stopPolling]);
|
|
214
299
|
return {
|
|
215
300
|
api: {
|
|
216
301
|
public: dataSourceApi
|
|
@@ -222,13 +307,15 @@ export const useGridDataSourceBase = (apiRef, props, options = {}) => {
|
|
|
222
307
|
processor: handleDataUpdate
|
|
223
308
|
},
|
|
224
309
|
setStrategyAvailability,
|
|
310
|
+
startPolling,
|
|
311
|
+
stopPolling,
|
|
225
312
|
cacheChunkManager,
|
|
226
313
|
cache,
|
|
227
314
|
events: {
|
|
228
315
|
strategyAvailabilityChange: handleStrategyActivityChange,
|
|
229
|
-
sortModelChange: runIf(standardRowsUpdateStrategyActive,
|
|
230
|
-
filterModelChange: runIf(standardRowsUpdateStrategyActive,
|
|
231
|
-
paginationModelChange: runIf(standardRowsUpdateStrategyActive,
|
|
316
|
+
sortModelChange: runIf(standardRowsUpdateStrategyActive, handleFetchRowsOnParamsChange),
|
|
317
|
+
filterModelChange: runIf(standardRowsUpdateStrategyActive, handleFetchRowsOnParamsChange),
|
|
318
|
+
paginationModelChange: runIf(standardRowsUpdateStrategyActive, handleFetchRowsOnParamsChange)
|
|
232
319
|
}
|
|
233
320
|
};
|
|
234
321
|
};
|
|
@@ -184,12 +184,15 @@ export const useGridRowEditing = (apiRef, props) => {
|
|
|
184
184
|
const rowParams = apiRef.current.getRowParams(params.id);
|
|
185
185
|
const newParams = _extends({}, rowParams, {
|
|
186
186
|
field: params.field,
|
|
187
|
-
reason
|
|
187
|
+
reason,
|
|
188
|
+
// Only pass the pressed key when the row editing is controlled via `rowModesModel`.
|
|
189
|
+
// In uncontrolled mode, the default editor already inserts the character and passing it here would duplicate it.
|
|
190
|
+
key: rowModesModelProp && isPrintableKey(event) ? event.key : undefined
|
|
188
191
|
});
|
|
189
192
|
apiRef.current.publishEvent('rowEditStart', newParams, event);
|
|
190
193
|
}
|
|
191
194
|
}
|
|
192
|
-
}, [apiRef, hasFieldsWithErrors]);
|
|
195
|
+
}, [apiRef, hasFieldsWithErrors, rowModesModelProp]);
|
|
193
196
|
const handleRowEditStart = React.useCallback(params => {
|
|
194
197
|
const {
|
|
195
198
|
id,
|
|
@@ -201,10 +204,17 @@ export const useGridRowEditing = (apiRef, props) => {
|
|
|
201
204
|
fieldToFocus: field
|
|
202
205
|
};
|
|
203
206
|
if (reason === GridRowEditStartReasons.printableKeyDown || reason === GridRowEditStartReasons.deleteKeyDown) {
|
|
204
|
-
|
|
207
|
+
// If the user typed a printable key, initialize the value with that key
|
|
208
|
+
// to avoid losing the first character when the component is controlled.
|
|
209
|
+
if (rowModesModelProp && reason === GridRowEditStartReasons.printableKeyDown && params.key && field) {
|
|
210
|
+
startRowEditModeParams.initialValue = params.key;
|
|
211
|
+
} else {
|
|
212
|
+
// For Delete / Backspace or for uncontrolled row editing we clear the value
|
|
213
|
+
startRowEditModeParams.deleteValue = !!field;
|
|
214
|
+
}
|
|
205
215
|
}
|
|
206
216
|
apiRef.current.startRowEditMode(startRowEditModeParams);
|
|
207
|
-
}, [apiRef]);
|
|
217
|
+
}, [apiRef, rowModesModelProp]);
|
|
208
218
|
const handleRowEditStop = React.useCallback(params => {
|
|
209
219
|
const {
|
|
210
220
|
id,
|
package/esm/index.js
CHANGED
package/esm/internals/index.d.ts
CHANGED
|
@@ -29,6 +29,7 @@ export { gridHeaderFilteringEditFieldSelector, gridHeaderFilteringMenuSelector }
|
|
|
29
29
|
export type { GridSlotsComponentsProps } from "../models/gridSlotsComponentsProps.js";
|
|
30
30
|
export type { GridFilterInputValueProps } from "../models/gridFilterInputComponent.js";
|
|
31
31
|
export { useGridColumnMenu, columnMenuStateInitializer } from "../hooks/features/columnMenu/useGridColumnMenu.js";
|
|
32
|
+
export type { GridColumnMenuComponent } from "../components/menu/columnMenu/GridColumnMenuProps.js";
|
|
32
33
|
export { useGridColumns, columnsStateInitializer } from "../hooks/features/columns/useGridColumns.js";
|
|
33
34
|
export * from "../hooks/features/columns/gridColumnsUtils.js";
|
|
34
35
|
export { useGridColumnSpanning } from "../hooks/features/columns/useGridColumnSpanning.js";
|
|
@@ -73,7 +73,6 @@ export interface GridRowEditStartParams<R extends GridValidRowModel = any> exten
|
|
|
73
73
|
reason?: GridRowEditStartReasons;
|
|
74
74
|
/**
|
|
75
75
|
* If the reason is related to a keyboard event, it contains which key was pressed.
|
|
76
|
-
* @deprecated No longer needed.
|
|
77
76
|
*/
|
|
78
77
|
key?: string;
|
|
79
78
|
}
|
|
@@ -325,6 +325,13 @@ export interface DataGridPropsWithDefaultValues<R extends GridValidRowModel = an
|
|
|
325
325
|
* @default 0
|
|
326
326
|
*/
|
|
327
327
|
throttleRowsMs: number;
|
|
328
|
+
/**
|
|
329
|
+
* If positive, the Data Grid will periodically revalidate data source rows by re-fetching them from the server when the cache entry has expired.
|
|
330
|
+
* If the refetched rows are different from the current rows, the grid will update the rows.
|
|
331
|
+
* Set to `0` to disable polling.
|
|
332
|
+
* @default 0
|
|
333
|
+
*/
|
|
334
|
+
dataSourceRevalidateMs: number;
|
|
328
335
|
/**
|
|
329
336
|
* If `true`, reordering columns is disabled.
|
|
330
337
|
* @default false
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { RefObject } from '@mui/x-internals/types';
|
|
2
|
+
import type { GridPrivateApiCommunity } from "../../../models/api/gridApiCommunity.js";
|
|
3
|
+
import type { GridColDef } from "../../../models/colDef/gridColDef.js";
|
|
4
|
+
import type { GridColumnMenuSlotProps } from "./columnMenuInterfaces.js";
|
|
5
|
+
export interface GetColumnMenuItemKeysParams {
|
|
6
|
+
apiRef: RefObject<GridPrivateApiCommunity>;
|
|
7
|
+
colDef: GridColDef;
|
|
8
|
+
defaultSlots: Record<string, any>;
|
|
9
|
+
defaultSlotProps: Record<string, GridColumnMenuSlotProps>;
|
|
10
|
+
slots?: Record<string, any>;
|
|
11
|
+
slotProps?: Record<string, GridColumnMenuSlotProps>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Returns the list of column menu item keys (sorted by `displayOrder`) that should be rendered for a given column.
|
|
15
|
+
* This is shared between the column header (to know if menu is empty) and the menu itself (to render items).
|
|
16
|
+
*/
|
|
17
|
+
export declare function getColumnMenuItemKeys(params: GetColumnMenuItemKeysParams): string[];
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.getColumnMenuItemKeys = getColumnMenuItemKeys;
|
|
8
|
+
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
9
|
+
/**
|
|
10
|
+
* Returns the list of column menu item keys (sorted by `displayOrder`) that should be rendered for a given column.
|
|
11
|
+
* This is shared between the column header (to know if menu is empty) and the menu itself (to render items).
|
|
12
|
+
*/
|
|
13
|
+
function getColumnMenuItemKeys(params) {
|
|
14
|
+
const {
|
|
15
|
+
apiRef,
|
|
16
|
+
colDef,
|
|
17
|
+
defaultSlots,
|
|
18
|
+
defaultSlotProps,
|
|
19
|
+
slots = {},
|
|
20
|
+
slotProps = {}
|
|
21
|
+
} = params;
|
|
22
|
+
const processedComponents = (0, _extends2.default)({}, defaultSlots, slots);
|
|
23
|
+
let processedSlotProps = defaultSlotProps;
|
|
24
|
+
if (slotProps && Object.keys(slotProps).length > 0) {
|
|
25
|
+
const mergedProps = (0, _extends2.default)({}, slotProps);
|
|
26
|
+
Object.entries(defaultSlotProps).forEach(([key, currentSlotProps]) => {
|
|
27
|
+
mergedProps[key] = (0, _extends2.default)({}, currentSlotProps, slotProps[key] || {});
|
|
28
|
+
});
|
|
29
|
+
processedSlotProps = mergedProps;
|
|
30
|
+
}
|
|
31
|
+
const defaultItems = apiRef.current.unstable_applyPipeProcessors('columnMenu', [], colDef);
|
|
32
|
+
const defaultComponentKeys = Object.keys(defaultSlots);
|
|
33
|
+
const userItems = Object.keys(slots).filter(key => !defaultComponentKeys.includes(key));
|
|
34
|
+
const uniqueItems = Array.from(new Set([...defaultItems, ...userItems]));
|
|
35
|
+
const cleansedItems = uniqueItems.filter(key => processedComponents[key] != null);
|
|
36
|
+
return cleansedItems.sort((a, b) => {
|
|
37
|
+
const leftItemProps = processedSlotProps[a];
|
|
38
|
+
const rightItemProps = processedSlotProps[b];
|
|
39
|
+
const leftDisplayOrder = Number.isFinite(leftItemProps?.displayOrder) ? leftItemProps.displayOrder : 100;
|
|
40
|
+
const rightDisplayOrder = Number.isFinite(rightItemProps?.displayOrder) ? rightItemProps.displayOrder : 100;
|
|
41
|
+
return leftDisplayOrder - rightDisplayOrder;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
@@ -11,6 +11,7 @@ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")
|
|
|
11
11
|
var React = _interopRequireWildcard(require("react"));
|
|
12
12
|
var _useGridRootProps = require("../../utils/useGridRootProps");
|
|
13
13
|
var _useGridPrivateApiContext = require("../../utils/useGridPrivateApiContext");
|
|
14
|
+
var _getColumnMenuItemKeys = require("./getColumnMenuItemKeys");
|
|
14
15
|
const _excluded = ["displayOrder"];
|
|
15
16
|
const useGridColumnMenuSlots = props => {
|
|
16
17
|
const apiRef = (0, _useGridPrivateApiContext.useGridPrivateApiContext)();
|
|
@@ -35,22 +36,16 @@ const useGridColumnMenuSlots = props => {
|
|
|
35
36
|
});
|
|
36
37
|
return mergedProps;
|
|
37
38
|
}, [defaultSlotProps, slotProps]);
|
|
38
|
-
const defaultItems = apiRef.current.unstable_applyPipeProcessors('columnMenu', [], props.colDef);
|
|
39
|
-
const userItems = React.useMemo(() => {
|
|
40
|
-
const defaultComponentKeys = Object.keys(defaultSlots);
|
|
41
|
-
return Object.keys(slots).filter(key => !defaultComponentKeys.includes(key));
|
|
42
|
-
}, [slots, defaultSlots]);
|
|
43
39
|
return React.useMemo(() => {
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return leftDisplayOrder - rightDisplayOrder;
|
|
40
|
+
const sortedKeys = (0, _getColumnMenuItemKeys.getColumnMenuItemKeys)({
|
|
41
|
+
apiRef,
|
|
42
|
+
colDef,
|
|
43
|
+
defaultSlots,
|
|
44
|
+
defaultSlotProps,
|
|
45
|
+
slots,
|
|
46
|
+
slotProps
|
|
52
47
|
});
|
|
53
|
-
return
|
|
48
|
+
return sortedKeys.reduce((acc, key, index) => {
|
|
54
49
|
let itemProps = {
|
|
55
50
|
colDef,
|
|
56
51
|
onClick: hideMenu
|
|
@@ -60,8 +55,8 @@ const useGridColumnMenuSlots = props => {
|
|
|
60
55
|
const customProps = (0, _objectWithoutPropertiesLoose2.default)(processedComponentProps, _excluded);
|
|
61
56
|
itemProps = (0, _extends2.default)({}, itemProps, customProps);
|
|
62
57
|
}
|
|
63
|
-
return addDividers && index !==
|
|
58
|
+
return addDividers && index !== sortedKeys.length - 1 ? [...acc, [processedComponents[key], itemProps], [rootProps.slots.baseDivider, {}]] : [...acc, [processedComponents[key], itemProps]];
|
|
64
59
|
}, []);
|
|
65
|
-
}, [addDividers, colDef,
|
|
60
|
+
}, [addDividers, apiRef, colDef, defaultSlotProps, defaultSlots, hideMenu, processedComponents, processedSlotProps, slotProps, slots, rootProps.slots.baseDivider]);
|
|
66
61
|
};
|
|
67
62
|
exports.useGridColumnMenuSlots = useGridColumnMenuSlots;
|
|
@@ -5,6 +5,9 @@ import type { GridDataSourceCacheDefaultConfig } from "./cache.js";
|
|
|
5
5
|
* The parameters for the `fetchRows` method.
|
|
6
6
|
*/
|
|
7
7
|
export type GridDataSourceFetchRowsParams<T> = Partial<T> & GridGetRowsOptions;
|
|
8
|
+
export interface GridDataSourceFetchRowChildrenOptions {
|
|
9
|
+
showChildrenLoading?: boolean;
|
|
10
|
+
}
|
|
8
11
|
export interface GridDataSourceApi {
|
|
9
12
|
/**
|
|
10
13
|
* The data source API.
|
|
@@ -38,7 +41,7 @@ export interface GridDataSourceApiBase {
|
|
|
38
41
|
}
|
|
39
42
|
export interface GridDataSourceBaseOptions {
|
|
40
43
|
cacheOptions?: GridDataSourceCacheDefaultConfig;
|
|
41
|
-
fetchRowChildren?: (parents: GridRowId[]) => void;
|
|
44
|
+
fetchRowChildren?: (parents: GridRowId[], options?: GridDataSourceFetchRowChildrenOptions) => void;
|
|
42
45
|
clearDataSourceState?: () => void;
|
|
43
46
|
handleEditRow?: (params: GridUpdateRowParams, updatedRow: GridRowModel) => void;
|
|
44
47
|
}
|
|
@@ -6,17 +6,20 @@ import type { GridPrivateApiCommunity } from "../../../models/api/gridApiCommuni
|
|
|
6
6
|
import type { DataGridProcessedProps } from "../../../models/props/DataGridProps.js";
|
|
7
7
|
import type { GridStrategyProcessor } from "../../core/strategyProcessing/index.js";
|
|
8
8
|
import type { GridEventListener } from "../../../models/events/index.js";
|
|
9
|
-
|
|
9
|
+
import type { GridRowId } from "../../../models/gridRows.js";
|
|
10
|
+
export declare const useGridDataSourceBase: <Api extends GridPrivateApiCommunity>(apiRef: RefObject<Api>, props: Pick<DataGridProcessedProps, "dataSource" | "dataSourceCache" | "onDataSourceError" | "pageSizeOptions" | "pagination" | "signature" | "dataSourceRevalidateMs">, options?: GridDataSourceBaseOptions) => {
|
|
10
11
|
api: {
|
|
11
12
|
public: GridDataSourceApi;
|
|
12
13
|
};
|
|
13
|
-
debouncedFetchRows: ((parentId?:
|
|
14
|
+
debouncedFetchRows: ((parentId?: GridRowId, params?: import("./models.js").GridDataSourceFetchRowsParams<import("@mui/x-data-grid").GridGetRowsParams>) => Promise<void>) & import("@mui/utils/debounce").Cancelable;
|
|
14
15
|
strategyProcessor: {
|
|
15
16
|
strategyName: DataSourceRowsUpdateStrategy;
|
|
16
17
|
group: "dataSourceRowsUpdate";
|
|
17
18
|
processor: GridStrategyProcessor<"dataSourceRowsUpdate">;
|
|
18
19
|
};
|
|
19
20
|
setStrategyAvailability: () => void;
|
|
21
|
+
startPolling: () => void;
|
|
22
|
+
stopPolling: () => void;
|
|
20
23
|
cacheChunkManager: CacheChunkManager;
|
|
21
24
|
cache: GridDataSourceCache;
|
|
22
25
|
events: {
|
|
@@ -11,6 +11,7 @@ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")
|
|
|
11
11
|
var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
|
|
12
12
|
var React = _interopRequireWildcard(require("react"));
|
|
13
13
|
var _useLazyRef = _interopRequireDefault(require("@mui/utils/useLazyRef"));
|
|
14
|
+
var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
|
|
14
15
|
var _debounce = _interopRequireDefault(require("@mui/utils/debounce"));
|
|
15
16
|
var _warning = require("@mui/x-internals/warning");
|
|
16
17
|
var _isDeepEqual = require("@mui/x-internals/isDeepEqual");
|
|
@@ -19,6 +20,7 @@ var _utils = require("../../../utils/utils");
|
|
|
19
20
|
var _strategyProcessing = require("../../core/strategyProcessing");
|
|
20
21
|
var _useGridSelector = require("../../utils/useGridSelector");
|
|
21
22
|
var _gridPaginationSelector = require("../pagination/gridPaginationSelector");
|
|
23
|
+
var _gridRowsSelector = require("../rows/gridRowsSelector");
|
|
22
24
|
var _gridDataSourceSelector = require("./gridDataSourceSelector");
|
|
23
25
|
var _utils2 = require("./utils");
|
|
24
26
|
var _cache = require("./cache");
|
|
@@ -45,7 +47,9 @@ const useGridDataSourceBase = (apiRef, props, options = {}) => {
|
|
|
45
47
|
}, [currentStrategy]);
|
|
46
48
|
const paginationModel = (0, _useGridSelector.useGridSelector)(apiRef, _gridPaginationSelector.gridPaginationModelSelector);
|
|
47
49
|
const lastRequestId = React.useRef(0);
|
|
50
|
+
const pollingIntervalRef = React.useRef(null);
|
|
48
51
|
const onDataSourceErrorProp = props.onDataSourceError;
|
|
52
|
+
const revalidateMs = props.dataSourceRevalidateMs;
|
|
49
53
|
const cacheChunkManager = (0, _useLazyRef.default)(() => {
|
|
50
54
|
if (!props.pagination) {
|
|
51
55
|
return new _utils2.CacheChunkManager(paginationModel.pageSize);
|
|
@@ -135,6 +139,69 @@ const useGridDataSourceBase = (apiRef, props, options = {}) => {
|
|
|
135
139
|
const handleStrategyActivityChange = React.useCallback(() => {
|
|
136
140
|
setCurrentStrategy(apiRef.current.getActiveStrategy(_strategyProcessing.GridStrategyGroup.DataSource));
|
|
137
141
|
}, [apiRef]);
|
|
142
|
+
const fetchRowChildrenOption = options.fetchRowChildren;
|
|
143
|
+
const revalidate = (0, _useEventCallback.default)(async () => {
|
|
144
|
+
const getRows = props.dataSource?.getRows;
|
|
145
|
+
if (!getRows || !standardRowsUpdateStrategyActive) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
const revalidateExpandedGroups = () => {
|
|
149
|
+
if (currentStrategy !== _utils2.DataSourceRowsUpdateStrategy.GroupedData || !fetchRowChildrenOption) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const rowTree = (0, _gridRowsSelector.gridRowTreeSelector)(apiRef);
|
|
153
|
+
const visibleRows = (0, _gridPaginationSelector.gridVisibleRowsSelector)(apiRef).rows;
|
|
154
|
+
const expandedGroupIds = visibleRows.reduce((acc, row) => {
|
|
155
|
+
const node = rowTree[row.id];
|
|
156
|
+
if (node.type === 'group' && node.id !== _gridRowsUtils.GRID_ROOT_GROUP_ID && node.childrenExpanded === true) {
|
|
157
|
+
acc.push(row.id);
|
|
158
|
+
}
|
|
159
|
+
return acc;
|
|
160
|
+
}, []);
|
|
161
|
+
if (expandedGroupIds.length > 0) {
|
|
162
|
+
fetchRowChildrenOption(expandedGroupIds, {
|
|
163
|
+
showChildrenLoading: false
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
const fetchParams = (0, _extends2.default)({}, (0, _gridDataSourceSelector.gridGetRowsParamsSelector)(apiRef), apiRef.current.unstable_applyPipeProcessors('getRowsParams', {}));
|
|
168
|
+
const cacheKeys = cacheChunkManager.getCacheKeys(fetchParams);
|
|
169
|
+
const responses = cacheKeys.map(cacheKey => cache.get(cacheKey));
|
|
170
|
+
if (responses.every(response => response !== undefined)) {
|
|
171
|
+
revalidateExpandedGroups();
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
try {
|
|
175
|
+
const response = await getRows(fetchParams);
|
|
176
|
+
const currentParams = (0, _extends2.default)({}, (0, _gridDataSourceSelector.gridGetRowsParamsSelector)(apiRef), apiRef.current.unstable_applyPipeProcessors('getRowsParams', {}));
|
|
177
|
+
if (!(0, _isDeepEqual.isDeepEqual)(fetchParams, currentParams)) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const cacheResponses = cacheChunkManager.splitResponse(fetchParams, response);
|
|
181
|
+
cacheResponses.forEach((cacheResponse, key) => cache.set(key, cacheResponse));
|
|
182
|
+
apiRef.current.applyStrategyProcessor('dataSourceRowsUpdate', {
|
|
183
|
+
response,
|
|
184
|
+
fetchParams,
|
|
185
|
+
options: {}
|
|
186
|
+
});
|
|
187
|
+
revalidateExpandedGroups();
|
|
188
|
+
} catch {
|
|
189
|
+
// Ignore background revalidation errors.
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
const stopPolling = React.useCallback(() => {
|
|
193
|
+
if (pollingIntervalRef.current !== null) {
|
|
194
|
+
clearInterval(pollingIntervalRef.current);
|
|
195
|
+
pollingIntervalRef.current = null;
|
|
196
|
+
}
|
|
197
|
+
}, []);
|
|
198
|
+
const startPolling = (0, _useEventCallback.default)(() => {
|
|
199
|
+
stopPolling();
|
|
200
|
+
if (revalidateMs <= 0 || !standardRowsUpdateStrategyActive) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
pollingIntervalRef.current = setInterval(revalidate, revalidateMs);
|
|
204
|
+
});
|
|
138
205
|
const handleDataUpdate = React.useCallback(params => {
|
|
139
206
|
if ('error' in params) {
|
|
140
207
|
apiRef.current.setRows([]);
|
|
@@ -151,7 +218,8 @@ const useGridDataSourceBase = (apiRef, props, options = {}) => {
|
|
|
151
218
|
params: params.fetchParams,
|
|
152
219
|
response
|
|
153
220
|
}, true);
|
|
154
|
-
|
|
221
|
+
startPolling();
|
|
222
|
+
}, [apiRef, startPolling]);
|
|
155
223
|
const dataSourceUpdateRow = props.dataSource?.updateRow;
|
|
156
224
|
const handleEditRowOption = options.handleEditRow;
|
|
157
225
|
const editRow = React.useCallback(async params => {
|
|
@@ -191,6 +259,10 @@ const useGridDataSourceBase = (apiRef, props, options = {}) => {
|
|
|
191
259
|
}
|
|
192
260
|
};
|
|
193
261
|
const debouncedFetchRows = React.useMemo(() => (0, _debounce.default)(fetchRows, 0), [fetchRows]);
|
|
262
|
+
const handleFetchRowsOnParamsChange = React.useCallback(() => {
|
|
263
|
+
stopPolling();
|
|
264
|
+
debouncedFetchRows();
|
|
265
|
+
}, [stopPolling, debouncedFetchRows]);
|
|
194
266
|
const isFirstRender = React.useRef(true);
|
|
195
267
|
React.useEffect(() => {
|
|
196
268
|
if (isFirstRender.current) {
|
|
@@ -203,6 +275,17 @@ const useGridDataSourceBase = (apiRef, props, options = {}) => {
|
|
|
203
275
|
const newCache = getCache(props.dataSourceCache, options.cacheOptions);
|
|
204
276
|
setCache(prevCache => prevCache !== newCache ? newCache : prevCache);
|
|
205
277
|
}, [props.dataSourceCache, options.cacheOptions]);
|
|
278
|
+
React.useEffect(() => {
|
|
279
|
+
if (!standardRowsUpdateStrategyActive) {
|
|
280
|
+
stopPolling();
|
|
281
|
+
}
|
|
282
|
+
}, [standardRowsUpdateStrategyActive, stopPolling]);
|
|
283
|
+
React.useEffect(() => {
|
|
284
|
+
if (revalidateMs <= 0) {
|
|
285
|
+
stopPolling();
|
|
286
|
+
}
|
|
287
|
+
}, [revalidateMs, stopPolling]);
|
|
288
|
+
React.useEffect(() => stopPolling, [stopPolling]);
|
|
206
289
|
React.useEffect(() => {
|
|
207
290
|
// Return early if the proper strategy isn't set yet
|
|
208
291
|
// Context: https://github.com/mui/mui-x/issues/19650
|
|
@@ -210,6 +293,8 @@ const useGridDataSourceBase = (apiRef, props, options = {}) => {
|
|
|
210
293
|
return undefined;
|
|
211
294
|
}
|
|
212
295
|
if (props.dataSource) {
|
|
296
|
+
stopPolling();
|
|
297
|
+
apiRef.current.setRows([]);
|
|
213
298
|
apiRef.current.dataSource.cache.clear();
|
|
214
299
|
apiRef.current.dataSource.fetchRows();
|
|
215
300
|
}
|
|
@@ -217,7 +302,7 @@ const useGridDataSourceBase = (apiRef, props, options = {}) => {
|
|
|
217
302
|
// ignore the current request on unmount
|
|
218
303
|
lastRequestId.current += 1;
|
|
219
304
|
};
|
|
220
|
-
}, [apiRef, props.dataSource, currentStrategy]);
|
|
305
|
+
}, [apiRef, props.dataSource, currentStrategy, stopPolling]);
|
|
221
306
|
return {
|
|
222
307
|
api: {
|
|
223
308
|
public: dataSourceApi
|
|
@@ -229,13 +314,15 @@ const useGridDataSourceBase = (apiRef, props, options = {}) => {
|
|
|
229
314
|
processor: handleDataUpdate
|
|
230
315
|
},
|
|
231
316
|
setStrategyAvailability,
|
|
317
|
+
startPolling,
|
|
318
|
+
stopPolling,
|
|
232
319
|
cacheChunkManager,
|
|
233
320
|
cache,
|
|
234
321
|
events: {
|
|
235
322
|
strategyAvailabilityChange: handleStrategyActivityChange,
|
|
236
|
-
sortModelChange: (0, _utils.runIf)(standardRowsUpdateStrategyActive,
|
|
237
|
-
filterModelChange: (0, _utils.runIf)(standardRowsUpdateStrategyActive,
|
|
238
|
-
paginationModelChange: (0, _utils.runIf)(standardRowsUpdateStrategyActive,
|
|
323
|
+
sortModelChange: (0, _utils.runIf)(standardRowsUpdateStrategyActive, handleFetchRowsOnParamsChange),
|
|
324
|
+
filterModelChange: (0, _utils.runIf)(standardRowsUpdateStrategyActive, handleFetchRowsOnParamsChange),
|
|
325
|
+
paginationModelChange: (0, _utils.runIf)(standardRowsUpdateStrategyActive, handleFetchRowsOnParamsChange)
|
|
239
326
|
}
|
|
240
327
|
};
|
|
241
328
|
};
|
|
@@ -191,12 +191,15 @@ const useGridRowEditing = (apiRef, props) => {
|
|
|
191
191
|
const rowParams = apiRef.current.getRowParams(params.id);
|
|
192
192
|
const newParams = (0, _extends2.default)({}, rowParams, {
|
|
193
193
|
field: params.field,
|
|
194
|
-
reason
|
|
194
|
+
reason,
|
|
195
|
+
// Only pass the pressed key when the row editing is controlled via `rowModesModel`.
|
|
196
|
+
// In uncontrolled mode, the default editor already inserts the character and passing it here would duplicate it.
|
|
197
|
+
key: rowModesModelProp && (0, _keyboardUtils.isPrintableKey)(event) ? event.key : undefined
|
|
195
198
|
});
|
|
196
199
|
apiRef.current.publishEvent('rowEditStart', newParams, event);
|
|
197
200
|
}
|
|
198
201
|
}
|
|
199
|
-
}, [apiRef, hasFieldsWithErrors]);
|
|
202
|
+
}, [apiRef, hasFieldsWithErrors, rowModesModelProp]);
|
|
200
203
|
const handleRowEditStart = React.useCallback(params => {
|
|
201
204
|
const {
|
|
202
205
|
id,
|
|
@@ -208,10 +211,17 @@ const useGridRowEditing = (apiRef, props) => {
|
|
|
208
211
|
fieldToFocus: field
|
|
209
212
|
};
|
|
210
213
|
if (reason === _gridRowParams.GridRowEditStartReasons.printableKeyDown || reason === _gridRowParams.GridRowEditStartReasons.deleteKeyDown) {
|
|
211
|
-
|
|
214
|
+
// If the user typed a printable key, initialize the value with that key
|
|
215
|
+
// to avoid losing the first character when the component is controlled.
|
|
216
|
+
if (rowModesModelProp && reason === _gridRowParams.GridRowEditStartReasons.printableKeyDown && params.key && field) {
|
|
217
|
+
startRowEditModeParams.initialValue = params.key;
|
|
218
|
+
} else {
|
|
219
|
+
// For Delete / Backspace or for uncontrolled row editing we clear the value
|
|
220
|
+
startRowEditModeParams.deleteValue = !!field;
|
|
221
|
+
}
|
|
212
222
|
}
|
|
213
223
|
apiRef.current.startRowEditMode(startRowEditModeParams);
|
|
214
|
-
}, [apiRef]);
|
|
224
|
+
}, [apiRef, rowModesModelProp]);
|
|
215
225
|
const handleRowEditStop = React.useCallback(params => {
|
|
216
226
|
const {
|
|
217
227
|
id,
|
package/index.js
CHANGED
package/internals/index.d.ts
CHANGED
|
@@ -29,6 +29,7 @@ export { gridHeaderFilteringEditFieldSelector, gridHeaderFilteringMenuSelector }
|
|
|
29
29
|
export type { GridSlotsComponentsProps } from "../models/gridSlotsComponentsProps.js";
|
|
30
30
|
export type { GridFilterInputValueProps } from "../models/gridFilterInputComponent.js";
|
|
31
31
|
export { useGridColumnMenu, columnMenuStateInitializer } from "../hooks/features/columnMenu/useGridColumnMenu.js";
|
|
32
|
+
export type { GridColumnMenuComponent } from "../components/menu/columnMenu/GridColumnMenuProps.js";
|
|
32
33
|
export { useGridColumns, columnsStateInitializer } from "../hooks/features/columns/useGridColumns.js";
|
|
33
34
|
export * from "../hooks/features/columns/gridColumnsUtils.js";
|
|
34
35
|
export { useGridColumnSpanning } from "../hooks/features/columns/useGridColumnSpanning.js";
|