@mui/x-data-grid 7.25.0 → 7.27.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 +133 -0
- package/DataGrid/DataGrid.js +6 -0
- package/DataGrid/useDataGridComponent.js +3 -3
- package/components/GridRow.js +8 -2
- package/components/GridScrollArea.d.ts +5 -2
- package/components/GridScrollArea.js +32 -25
- package/components/GridSkeletonLoadingOverlay.js +2 -1
- package/components/containers/GridRoot.js +11 -9
- package/components/containers/GridRootStyles.js +3 -3
- package/components/virtualization/GridMainContainer.d.ts +2 -2
- package/components/virtualization/GridMainContainer.js +1 -1
- package/components/virtualization/GridVirtualScroller.js +21 -14
- package/constants/dataGridPropsDefaultValues.js +1 -0
- package/hooks/core/pipeProcessing/useGridRegisterPipeProcessor.d.ts +1 -1
- package/hooks/core/pipeProcessing/useGridRegisterPipeProcessor.js +6 -4
- package/hooks/core/useGridStateInitialization.js +3 -2
- package/hooks/features/clipboard/useGridClipboard.js +1 -1
- package/hooks/features/columnHeaders/useGridColumnHeaders.js +10 -14
- package/hooks/features/columns/gridColumnsSelector.d.ts +0 -5
- package/hooks/features/columns/gridColumnsSelector.js +0 -12
- package/hooks/features/dimensions/gridDimensionsSelectors.d.ts +16 -0
- package/hooks/features/dimensions/gridDimensionsSelectors.js +26 -1
- package/hooks/features/dimensions/index.d.ts +1 -1
- package/hooks/features/dimensions/index.js +1 -2
- package/hooks/features/dimensions/useGridDimensions.js +97 -70
- package/hooks/features/editing/gridEditingSelectors.d.ts +5 -1
- package/hooks/features/editing/gridEditingSelectors.js +6 -1
- package/hooks/features/editing/useGridRowEditing.js +4 -4
- package/hooks/features/filter/gridFilterState.d.ts +5 -0
- package/hooks/features/filter/gridFilterState.js +5 -0
- package/hooks/features/filter/useGridFilter.js +6 -13
- package/hooks/features/pagination/useGridPagination.js +1 -1
- package/hooks/features/pagination/useGridPaginationModel.d.ts +1 -1
- package/hooks/features/pagination/useGridPaginationModel.js +44 -0
- package/hooks/features/rowSelection/useGridRowSelection.js +1 -1
- package/hooks/features/rowSelection/utils.js +1 -1
- package/hooks/features/rows/gridRowsMetaState.d.ts +8 -0
- package/hooks/features/rows/gridRowsUtils.d.ts +0 -4
- package/hooks/features/rows/gridRowsUtils.js +0 -16
- package/hooks/features/rows/useGridRowsMeta.js +33 -17
- package/hooks/features/sorting/gridSortingSelector.js +10 -9
- package/hooks/features/virtualization/useGridVirtualScroller.d.ts +6 -0
- package/hooks/features/virtualization/useGridVirtualScroller.js +43 -27
- package/hooks/utils/useGridNativeEventListener.d.ts +0 -1
- package/hooks/utils/useGridNativeEventListener.js +12 -22
- package/hooks/utils/useGridSelector.d.ts +8 -1
- package/hooks/utils/useGridSelector.js +42 -8
- package/hooks/utils/useIsSSR.d.ts +1 -0
- package/hooks/utils/useIsSSR.js +5 -0
- package/index.js +1 -1
- package/internals/index.d.ts +2 -1
- package/internals/index.js +2 -1
- package/locales/plPL.js +31 -35
- package/locales/ukUA.js +9 -10
- package/models/api/gridStateApi.d.ts +1 -0
- package/models/events/gridEventLookup.d.ts +6 -0
- package/models/props/DataGridProps.d.ts +6 -0
- package/modern/DataGrid/DataGrid.js +6 -0
- package/modern/DataGrid/useDataGridComponent.js +3 -3
- package/modern/components/GridRow.js +8 -2
- package/modern/components/GridScrollArea.js +32 -25
- package/modern/components/GridSkeletonLoadingOverlay.js +2 -1
- package/modern/components/containers/GridRoot.js +11 -9
- package/modern/components/containers/GridRootStyles.js +3 -3
- package/modern/components/virtualization/GridMainContainer.js +1 -1
- package/modern/components/virtualization/GridVirtualScroller.js +21 -14
- package/modern/constants/dataGridPropsDefaultValues.js +1 -0
- package/modern/hooks/core/pipeProcessing/useGridRegisterPipeProcessor.js +6 -4
- package/modern/hooks/core/useGridStateInitialization.js +3 -2
- package/modern/hooks/features/clipboard/useGridClipboard.js +1 -1
- package/modern/hooks/features/columnHeaders/useGridColumnHeaders.js +10 -14
- package/modern/hooks/features/columns/gridColumnsSelector.js +0 -12
- package/modern/hooks/features/dimensions/gridDimensionsSelectors.js +26 -1
- package/modern/hooks/features/dimensions/index.js +1 -2
- package/modern/hooks/features/dimensions/useGridDimensions.js +97 -70
- package/modern/hooks/features/editing/gridEditingSelectors.js +6 -1
- package/modern/hooks/features/editing/useGridRowEditing.js +4 -4
- package/modern/hooks/features/filter/gridFilterState.js +5 -0
- package/modern/hooks/features/filter/useGridFilter.js +6 -13
- package/modern/hooks/features/pagination/useGridPagination.js +1 -1
- package/modern/hooks/features/pagination/useGridPaginationModel.js +44 -0
- package/modern/hooks/features/rowSelection/useGridRowSelection.js +1 -1
- package/modern/hooks/features/rowSelection/utils.js +1 -1
- package/modern/hooks/features/rows/gridRowsUtils.js +0 -16
- package/modern/hooks/features/rows/useGridRowsMeta.js +33 -17
- package/modern/hooks/features/sorting/gridSortingSelector.js +10 -9
- package/modern/hooks/features/virtualization/useGridVirtualScroller.js +43 -27
- package/modern/hooks/utils/useGridNativeEventListener.js +12 -22
- package/modern/hooks/utils/useGridSelector.js +42 -8
- package/modern/hooks/utils/useIsSSR.js +5 -0
- package/modern/index.js +1 -1
- package/modern/internals/index.js +2 -1
- package/modern/locales/plPL.js +31 -35
- package/modern/locales/ukUA.js +9 -10
- package/node/DataGrid/DataGrid.js +6 -0
- package/node/DataGrid/useDataGridComponent.js +3 -3
- package/node/components/GridRow.js +7 -2
- package/node/components/GridScrollArea.js +31 -24
- package/node/components/GridSkeletonLoadingOverlay.js +2 -1
- package/node/components/containers/GridRoot.js +10 -8
- package/node/components/containers/GridRootStyles.js +3 -3
- package/node/components/virtualization/GridMainContainer.js +1 -1
- package/node/components/virtualization/GridVirtualScroller.js +21 -14
- package/node/constants/dataGridPropsDefaultValues.js +1 -0
- package/node/hooks/core/pipeProcessing/useGridRegisterPipeProcessor.js +6 -4
- package/node/hooks/core/useGridStateInitialization.js +3 -2
- package/node/hooks/features/clipboard/useGridClipboard.js +1 -1
- package/node/hooks/features/columnHeaders/useGridColumnHeaders.js +10 -14
- package/node/hooks/features/columns/gridColumnsSelector.js +1 -13
- package/node/hooks/features/dimensions/gridDimensionsSelectors.js +38 -2
- package/node/hooks/features/dimensions/index.js +13 -11
- package/node/hooks/features/dimensions/useGridDimensions.js +94 -67
- package/node/hooks/features/editing/gridEditingSelectors.js +5 -1
- package/node/hooks/features/editing/useGridRowEditing.js +4 -4
- package/node/hooks/features/filter/gridFilterState.js +6 -1
- package/node/hooks/features/filter/useGridFilter.js +5 -12
- package/node/hooks/features/pagination/useGridPagination.js +1 -1
- package/node/hooks/features/pagination/useGridPaginationModel.js +44 -0
- package/node/hooks/features/rowSelection/useGridRowSelection.js +1 -1
- package/node/hooks/features/rowSelection/utils.js +1 -1
- package/node/hooks/features/rows/gridRowsUtils.js +0 -17
- package/node/hooks/features/rows/useGridRowsMeta.js +31 -15
- package/node/hooks/features/sorting/gridSortingSelector.js +10 -9
- package/node/hooks/features/virtualization/useGridVirtualScroller.js +42 -26
- package/node/hooks/utils/useGridNativeEventListener.js +12 -23
- package/node/hooks/utils/useGridSelector.js +42 -8
- package/node/hooks/utils/useIsSSR.js +12 -0
- package/node/index.js +1 -1
- package/node/internals/index.js +20 -7
- package/node/locales/plPL.js +31 -35
- package/node/locales/ukUA.js +9 -10
- package/package.json +3 -2
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
2
|
import * as React from 'react';
|
|
3
|
+
import { gridFilterModelSelector, gridFilterActiveItemsSelector } from "../filter/gridFilterSelector.js";
|
|
3
4
|
import { gridDensityFactorSelector } from "../density/index.js";
|
|
4
5
|
import { useGridLogger, useGridSelector, useGridApiMethod, useGridApiEventHandler } from "../../utils/index.js";
|
|
6
|
+
import { isDeepEqual, runIf } from "../../../utils/utils.js";
|
|
5
7
|
import { useGridRegisterPipeProcessor } from "../../core/pipeProcessing/index.js";
|
|
6
8
|
import { gridPageCountSelector, gridPaginationModelSelector } from "./gridPaginationSelector.js";
|
|
7
9
|
import { getPageCount, defaultPageSize, throwIfPageSizeExceedsTheLimit, getDefaultGridPaginationModel, getValidPage } from "./gridPaginationUtils.js";
|
|
@@ -31,6 +33,7 @@ export const getDerivedPaginationModel = (paginationState, signature, pagination
|
|
|
31
33
|
export const useGridPaginationModel = (apiRef, props) => {
|
|
32
34
|
const logger = useGridLogger(apiRef, 'useGridPaginationModel');
|
|
33
35
|
const densityFactor = useGridSelector(apiRef, gridDensityFactorSelector);
|
|
36
|
+
const previousFilterModel = React.useRef(gridFilterModelSelector(apiRef));
|
|
34
37
|
const rowHeight = Math.floor(props.rowHeight * densityFactor);
|
|
35
38
|
apiRef.current.registerControlState({
|
|
36
39
|
stateId: 'paginationModel',
|
|
@@ -143,14 +146,55 @@ export const useGridPaginationModel = (apiRef, props) => {
|
|
|
143
146
|
return;
|
|
144
147
|
}
|
|
145
148
|
const paginationModel = gridPaginationModelSelector(apiRef);
|
|
149
|
+
if (paginationModel.page === 0) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
146
152
|
const pageCount = gridPageCountSelector(apiRef);
|
|
147
153
|
if (paginationModel.page > pageCount - 1) {
|
|
148
154
|
apiRef.current.setPage(Math.max(0, pageCount - 1));
|
|
149
155
|
}
|
|
150
156
|
}, [apiRef]);
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Goes to the first row of the grid
|
|
160
|
+
*/
|
|
161
|
+
const navigateToStart = React.useCallback(() => {
|
|
162
|
+
const paginationModel = gridPaginationModelSelector(apiRef);
|
|
163
|
+
if (paginationModel.page !== 0) {
|
|
164
|
+
apiRef.current.setPage(0);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// If the page was not changed it might be needed to scroll to the top
|
|
168
|
+
const scrollPosition = apiRef.current.getScrollPosition();
|
|
169
|
+
if (scrollPosition.top !== 0) {
|
|
170
|
+
apiRef.current.scroll({
|
|
171
|
+
top: 0
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}, [apiRef]);
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Resets the page only if the active items or quick filter has changed from the last time.
|
|
178
|
+
* This is to avoid resetting the page when the filter model is changed
|
|
179
|
+
* because of and update of the operator from an item that does not have the value
|
|
180
|
+
* or reseting when the filter panel is just opened
|
|
181
|
+
*/
|
|
182
|
+
const handleFilterModelChange = React.useCallback(filterModel => {
|
|
183
|
+
const currentActiveFilters = _extends({}, filterModel, {
|
|
184
|
+
// replace items with the active items
|
|
185
|
+
items: gridFilterActiveItemsSelector(apiRef)
|
|
186
|
+
});
|
|
187
|
+
if (isDeepEqual(currentActiveFilters, previousFilterModel.current)) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
previousFilterModel.current = currentActiveFilters;
|
|
191
|
+
navigateToStart();
|
|
192
|
+
}, [apiRef, navigateToStart]);
|
|
151
193
|
useGridApiEventHandler(apiRef, 'viewportInnerSizeChange', handleUpdateAutoPageSize);
|
|
152
194
|
useGridApiEventHandler(apiRef, 'paginationModelChange', handlePaginationModelChange);
|
|
153
195
|
useGridApiEventHandler(apiRef, 'rowCountChange', handleRowCountChange);
|
|
196
|
+
useGridApiEventHandler(apiRef, 'sortModelChange', runIf(props.resetPageOnSortFilter, navigateToStart));
|
|
197
|
+
useGridApiEventHandler(apiRef, 'filterModelChange', runIf(props.resetPageOnSortFilter, handleFilterModelChange));
|
|
154
198
|
|
|
155
199
|
/**
|
|
156
200
|
* EFFECTS
|
|
@@ -258,7 +258,7 @@ export const useGridRowSelection = (apiRef, props) => {
|
|
|
258
258
|
if (props.filterMode === 'server') {
|
|
259
259
|
return !rowsLookup[id];
|
|
260
260
|
}
|
|
261
|
-
return filteredRowsLookup[id]
|
|
261
|
+
return !rowsLookup[id] || filteredRowsLookup[id] === false;
|
|
262
262
|
};
|
|
263
263
|
let hasChanged = false;
|
|
264
264
|
currentSelection.forEach(id => {
|
|
@@ -92,7 +92,7 @@ const getFilteredRowNodeSiblings = (tree, filteredRows, id) => {
|
|
|
92
92
|
return [];
|
|
93
93
|
}
|
|
94
94
|
const parentNode = tree[parent];
|
|
95
|
-
return parentNode.children.filter(childId => childId !== id && filteredRows[childId]);
|
|
95
|
+
return parentNode.children.filter(childId => childId !== id && filteredRows[childId] !== false);
|
|
96
96
|
};
|
|
97
97
|
export const findRowsToSelect = (apiRef, tree, selectedRow, autoSelectDescendants, autoSelectParents, addRow) => {
|
|
98
98
|
const filteredRows = gridFilteredRowsLookupSelector(apiRef);
|
|
@@ -10,4 +10,12 @@ export interface GridRowsMetaState {
|
|
|
10
10
|
* The grid rows positions.
|
|
11
11
|
*/
|
|
12
12
|
positions: number[];
|
|
13
|
+
/**
|
|
14
|
+
* The total height of the pinned top rows.
|
|
15
|
+
*/
|
|
16
|
+
pinnedTopRowsTotalHeight: number;
|
|
17
|
+
/**
|
|
18
|
+
* The total height of the pinned bottom rows.
|
|
19
|
+
*/
|
|
20
|
+
pinnedBottomRowsTotalHeight: number;
|
|
13
21
|
}
|
|
@@ -33,10 +33,6 @@ export declare const updateCacheWithNewRows: ({ previousCache, getRowId, updates
|
|
|
33
33
|
updates: GridRowModelUpdate[];
|
|
34
34
|
groupKeys?: string[];
|
|
35
35
|
}) => GridRowsInternalCache;
|
|
36
|
-
export declare function calculatePinnedRowsHeight(apiRef: RefObject<GridApiCommunity>): {
|
|
37
|
-
top: number;
|
|
38
|
-
bottom: number;
|
|
39
|
-
};
|
|
40
36
|
export declare const minimalContentHeight = "var(--DataGrid-overlayHeight, calc(var(--height) * 2))";
|
|
41
37
|
export declare function computeRowsUpdates(apiRef: RefObject<GridApiCommunity>, updates: GridRowModelUpdate[], getRowId: DataGridProcessedProps['getRowId']): GridRowModelUpdate[];
|
|
42
38
|
export declare const getValidRowHeight: (rowHeightProp: any, defaultRowHeight: number, warningMessage: string) => number;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
-
import { gridPinnedRowsSelector } from "./gridRowsSelector.js";
|
|
3
2
|
export const GRID_ROOT_GROUP_ID = `auto-generated-group-node-root`;
|
|
4
3
|
export const GRID_ID_AUTOGENERATED = Symbol('mui.id_autogenerated');
|
|
5
4
|
export const buildRootGroup = () => ({
|
|
@@ -269,21 +268,6 @@ export const updateCacheWithNewRows = ({
|
|
|
269
268
|
rowCountPropBeforePartialUpdates: previousCache.rowCountPropBeforePartialUpdates
|
|
270
269
|
};
|
|
271
270
|
};
|
|
272
|
-
export function calculatePinnedRowsHeight(apiRef) {
|
|
273
|
-
const pinnedRows = gridPinnedRowsSelector(apiRef);
|
|
274
|
-
const topPinnedRowsHeight = pinnedRows?.top?.reduce((acc, value) => {
|
|
275
|
-
acc += apiRef.current.unstable_getRowHeight(value.id);
|
|
276
|
-
return acc;
|
|
277
|
-
}, 0) || 0;
|
|
278
|
-
const bottomPinnedRowsHeight = pinnedRows?.bottom?.reduce((acc, value) => {
|
|
279
|
-
acc += apiRef.current.unstable_getRowHeight(value.id);
|
|
280
|
-
return acc;
|
|
281
|
-
}, 0) || 0;
|
|
282
|
-
return {
|
|
283
|
-
top: topPinnedRowsHeight,
|
|
284
|
-
bottom: bottomPinnedRowsHeight
|
|
285
|
-
};
|
|
286
|
-
}
|
|
287
271
|
export const minimalContentHeight = 'var(--DataGrid-overlayHeight, calc(var(--height) * 2))';
|
|
288
272
|
export function computeRowsUpdates(apiRef, updates, getRowId) {
|
|
289
273
|
const nonPinnedRowsUpdates = [];
|
|
@@ -8,12 +8,10 @@ import { eslintUseValue } from "../../../utils/utils.js";
|
|
|
8
8
|
import { useGridApiMethod } from "../../utils/useGridApiMethod.js";
|
|
9
9
|
import { useGridSelector } from "../../utils/useGridSelector.js";
|
|
10
10
|
import { gridDensityFactorSelector } from "../density/densitySelector.js";
|
|
11
|
-
import { gridFilterModelSelector } from "../filter/gridFilterSelector.js";
|
|
12
11
|
import { gridPaginationSelector } from "../pagination/gridPaginationSelector.js";
|
|
13
|
-
import { gridSortModelSelector } from "../sorting/gridSortingSelector.js";
|
|
14
12
|
import { useGridRegisterPipeApplier } from "../../core/pipeProcessing/index.js";
|
|
15
|
-
import { gridPinnedRowsSelector } from "./gridRowsSelector.js";
|
|
16
|
-
import { gridDimensionsSelector } from "../dimensions/gridDimensionsSelectors.js";
|
|
13
|
+
import { gridPinnedRowsSelector, gridRowCountSelector } from "./gridRowsSelector.js";
|
|
14
|
+
import { gridDimensionsSelector, gridRowHeightSelector } from "../dimensions/gridDimensionsSelectors.js";
|
|
17
15
|
import { getValidRowHeight, getRowHeightWarning } from "./gridRowsUtils.js";
|
|
18
16
|
/* eslint-disable no-underscore-dangle */
|
|
19
17
|
|
|
@@ -21,10 +19,18 @@ export const rowsMetaStateInitializer = (state, props, apiRef) => {
|
|
|
21
19
|
apiRef.current.caches.rowsMeta = {
|
|
22
20
|
heights: new Map()
|
|
23
21
|
};
|
|
22
|
+
const baseRowHeight = gridRowHeightSelector(apiRef.current.state);
|
|
23
|
+
const dataRowCount = gridRowCountSelector(apiRef);
|
|
24
|
+
const pagination = gridPaginationSelector(apiRef.current.state);
|
|
25
|
+
const rowCount = Math.min(pagination.enabled ? pagination.paginationModel.pageSize : dataRowCount, dataRowCount);
|
|
24
26
|
return _extends({}, state, {
|
|
25
27
|
rowsMeta: {
|
|
26
|
-
currentPageTotalHeight:
|
|
27
|
-
positions:
|
|
28
|
+
currentPageTotalHeight: rowCount * baseRowHeight,
|
|
29
|
+
positions: Array.from({
|
|
30
|
+
length: rowCount
|
|
31
|
+
}, (_, i) => i * baseRowHeight),
|
|
32
|
+
pinnedTopRowsTotalHeight: 0,
|
|
33
|
+
pinnedBottomRowsTotalHeight: 0
|
|
28
34
|
}
|
|
29
35
|
});
|
|
30
36
|
};
|
|
@@ -44,12 +50,9 @@ export const useGridRowsMeta = (apiRef, props) => {
|
|
|
44
50
|
const hasRowWithAutoHeight = React.useRef(false);
|
|
45
51
|
const isHeightMetaValid = React.useRef(false);
|
|
46
52
|
const densityFactor = useGridSelector(apiRef, gridDensityFactorSelector);
|
|
47
|
-
const filterModel = useGridSelector(apiRef, gridFilterModelSelector);
|
|
48
|
-
const paginationState = useGridSelector(apiRef, gridPaginationSelector);
|
|
49
|
-
const sortModel = useGridSelector(apiRef, gridSortModelSelector);
|
|
50
53
|
const currentPage = useGridVisibleRows(apiRef, props);
|
|
51
54
|
const pinnedRows = useGridSelector(apiRef, gridPinnedRowsSelector);
|
|
52
|
-
const rowHeight = useGridSelector(apiRef,
|
|
55
|
+
const rowHeight = useGridSelector(apiRef, gridRowHeightSelector);
|
|
53
56
|
const getRowHeightEntry = rowId => {
|
|
54
57
|
let entry = heightCache.get(rowId);
|
|
55
58
|
if (entry === undefined) {
|
|
@@ -114,8 +117,14 @@ export const useGridRowsMeta = (apiRef, props) => {
|
|
|
114
117
|
}, [apiRef, currentPage.rows, getRowHeightProp, getEstimatedRowHeight, rowHeight, getRowSpacing, densityFactor]);
|
|
115
118
|
const hydrateRowsMeta = React.useCallback(() => {
|
|
116
119
|
hasRowWithAutoHeight.current = false;
|
|
117
|
-
pinnedRows.top.
|
|
118
|
-
|
|
120
|
+
const pinnedTopRowsTotalHeight = pinnedRows.top.reduce((acc, row) => {
|
|
121
|
+
const entry = processHeightEntry(row);
|
|
122
|
+
return acc + entry.content + entry.spacingTop + entry.spacingBottom + entry.detail;
|
|
123
|
+
}, 0);
|
|
124
|
+
const pinnedBottomRowsTotalHeight = pinnedRows.bottom.reduce((acc, row) => {
|
|
125
|
+
const entry = processHeightEntry(row);
|
|
126
|
+
return acc + entry.content + entry.spacingTop + entry.spacingBottom + entry.detail;
|
|
127
|
+
}, 0);
|
|
119
128
|
const positions = [];
|
|
120
129
|
const currentPageTotalHeight = currentPage.rows.reduce((acc, row) => {
|
|
121
130
|
positions.push(acc);
|
|
@@ -127,14 +136,21 @@ export const useGridRowsMeta = (apiRef, props) => {
|
|
|
127
136
|
// No row has height=auto, so all rows are already measured
|
|
128
137
|
lastMeasuredRowIndex.current = Infinity;
|
|
129
138
|
}
|
|
139
|
+
const didHeightsChange = pinnedTopRowsTotalHeight !== apiRef.current.state.rowsMeta.pinnedTopRowsTotalHeight || pinnedBottomRowsTotalHeight !== apiRef.current.state.rowsMeta.pinnedBottomRowsTotalHeight || currentPageTotalHeight !== apiRef.current.state.rowsMeta.currentPageTotalHeight;
|
|
140
|
+
const rowsMeta = {
|
|
141
|
+
currentPageTotalHeight,
|
|
142
|
+
positions,
|
|
143
|
+
pinnedTopRowsTotalHeight,
|
|
144
|
+
pinnedBottomRowsTotalHeight
|
|
145
|
+
};
|
|
130
146
|
apiRef.current.setState(state => {
|
|
131
147
|
return _extends({}, state, {
|
|
132
|
-
rowsMeta
|
|
133
|
-
currentPageTotalHeight,
|
|
134
|
-
positions
|
|
135
|
-
}
|
|
148
|
+
rowsMeta
|
|
136
149
|
});
|
|
137
150
|
});
|
|
151
|
+
if (didHeightsChange) {
|
|
152
|
+
apiRef.current.updateDimensions();
|
|
153
|
+
}
|
|
138
154
|
isHeightMetaValid.current = true;
|
|
139
155
|
}, [apiRef, pinnedRows, currentPage.rows, processHeightEntry]);
|
|
140
156
|
const getRowHeight = rowId => {
|
|
@@ -184,7 +200,7 @@ export const useGridRowsMeta = (apiRef, props) => {
|
|
|
184
200
|
// Because of variable row height this is needed for the virtualization
|
|
185
201
|
useEnhancedEffect(() => {
|
|
186
202
|
hydrateRowsMeta();
|
|
187
|
-
}, [
|
|
203
|
+
}, [hydrateRowsMeta]);
|
|
188
204
|
const rowsMetaApi = {
|
|
189
205
|
unstable_getRowHeight: getRowHeight,
|
|
190
206
|
unstable_setLastMeasuredRowIndex: setLastMeasuredRowIndex,
|
|
@@ -24,15 +24,16 @@ export const gridSortedRowEntriesSelector = createSelectorMemoized(gridSortedRow
|
|
|
24
24
|
id,
|
|
25
25
|
model
|
|
26
26
|
});
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
27
|
+
} else {
|
|
28
|
+
const rowNode = rowTree[id];
|
|
29
|
+
if (rowNode && isAutogeneratedRowNode(rowNode)) {
|
|
30
|
+
acc.push({
|
|
31
|
+
id,
|
|
32
|
+
model: {
|
|
33
|
+
[GRID_ID_AUTOGENERATED]: id
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
36
37
|
}
|
|
37
38
|
return acc;
|
|
38
39
|
}, []));
|
|
@@ -47,6 +47,12 @@ export declare const useGridVirtualScroller: () => {
|
|
|
47
47
|
left: number;
|
|
48
48
|
}>;
|
|
49
49
|
};
|
|
50
|
+
getScrollAreaProps: () => {
|
|
51
|
+
scrollPosition: React.RefObject<{
|
|
52
|
+
top: number;
|
|
53
|
+
left: number;
|
|
54
|
+
}>;
|
|
55
|
+
};
|
|
50
56
|
};
|
|
51
57
|
export declare function areRenderContextsEqual(context1: GridRenderContext, context2: GridRenderContext): boolean;
|
|
52
58
|
export declare function computeOffsetLeft(columnPositions: number[], renderContext: GridColumnsRenderContext, pinnedLeftLength: number): number;
|
|
@@ -6,15 +6,15 @@ import useLazyRef from '@mui/utils/useLazyRef';
|
|
|
6
6
|
import useTimeout from '@mui/utils/useTimeout';
|
|
7
7
|
import { useRtl } from '@mui/system/RtlProvider';
|
|
8
8
|
import reactMajor from '@mui/x-internals/reactMajor';
|
|
9
|
+
import { gridDimensionsSelector, gridColumnsTotalWidthSelector, gridContentHeightSelector, gridHasFillerSelector, gridRowHeightSelector, gridVerticalScrollbarWidthSelector } from "../dimensions/gridDimensionsSelectors.js";
|
|
9
10
|
import { useGridPrivateApiContext } from "../../utils/useGridPrivateApiContext.js";
|
|
10
11
|
import { useGridRootProps } from "../../utils/useGridRootProps.js";
|
|
11
12
|
import { useGridSelector } from "../../utils/useGridSelector.js";
|
|
12
13
|
import { useRunOnce } from "../../utils/useRunOnce.js";
|
|
13
14
|
import { gridVisibleColumnDefinitionsSelector, gridVisiblePinnedColumnDefinitionsSelector, gridColumnPositionsSelector, gridHasColSpanSelector } from "../columns/gridColumnsSelector.js";
|
|
14
|
-
import { gridDimensionsSelector } from "../dimensions/gridDimensionsSelectors.js";
|
|
15
15
|
import { gridPinnedRowsSelector } from "../rows/gridRowsSelector.js";
|
|
16
16
|
import { useGridVisibleRows, getVisibleRows } from "../../utils/useGridVisibleRows.js";
|
|
17
|
-
import {
|
|
17
|
+
import { useGridApiOptionHandler } from "../../utils/index.js";
|
|
18
18
|
import * as platform from "../../../utils/platform.js";
|
|
19
19
|
import { clamp, range } from "../../../utils/utils.js";
|
|
20
20
|
import { selectedIdsLookupSelector } from "../rowSelection/gridRowSelectionSelector.js";
|
|
@@ -57,8 +57,6 @@ export const useGridVirtualScroller = () => {
|
|
|
57
57
|
const visibleColumns = useGridSelector(apiRef, () => listView ? [gridListColumnSelector(apiRef.current.state)] : gridVisibleColumnDefinitionsSelector(apiRef));
|
|
58
58
|
const enabledForRows = useGridSelector(apiRef, gridVirtualizationRowEnabledSelector) && !isJSDOM;
|
|
59
59
|
const enabledForColumns = useGridSelector(apiRef, gridVirtualizationColumnEnabledSelector) && !isJSDOM;
|
|
60
|
-
const dimensions = useGridSelector(apiRef, gridDimensionsSelector);
|
|
61
|
-
const outerSize = dimensions.viewportOuterSize;
|
|
62
60
|
const pinnedRows = useGridSelector(apiRef, gridPinnedRowsSelector);
|
|
63
61
|
const pinnedColumnDefinitions = gridVisiblePinnedColumnDefinitionsSelector(apiRef);
|
|
64
62
|
const pinnedColumns = listView ? EMPTY_PINNED_COLUMN_FIELDS : pinnedColumnDefinitions;
|
|
@@ -71,10 +69,14 @@ export const useGridVirtualScroller = () => {
|
|
|
71
69
|
const scrollerRef = apiRef.current.virtualScrollerRef;
|
|
72
70
|
const scrollbarVerticalRef = apiRef.current.virtualScrollbarVerticalRef;
|
|
73
71
|
const scrollbarHorizontalRef = apiRef.current.virtualScrollbarHorizontalRef;
|
|
74
|
-
const contentHeight = dimensions.contentSize.height;
|
|
75
|
-
const columnsTotalWidth = dimensions.columnsTotalWidth;
|
|
76
72
|
const hasColSpan = useGridSelector(apiRef, gridHasColSpanSelector);
|
|
77
73
|
const isRenderContextReady = React.useRef(false);
|
|
74
|
+
const rowHeight = useGridSelector(apiRef, gridRowHeightSelector);
|
|
75
|
+
const contentHeight = useGridSelector(apiRef, gridContentHeightSelector);
|
|
76
|
+
const columnsTotalWidth = useGridSelector(apiRef, gridColumnsTotalWidthSelector);
|
|
77
|
+
const needsHorizontalScrollbar = useGridSelector(apiRef, needsHorizontalScrollbarSelector);
|
|
78
|
+
const verticalScrollbarWidth = useGridSelector(apiRef, gridVerticalScrollbarWidthSelector);
|
|
79
|
+
const gridHasFiller = useGridSelector(apiRef, gridHasFillerSelector);
|
|
78
80
|
const previousSize = React.useRef(null);
|
|
79
81
|
const mainRefCallback = React.useCallback(node => {
|
|
80
82
|
mainRef.current = node;
|
|
@@ -141,7 +143,7 @@ export const useGridVirtualScroller = () => {
|
|
|
141
143
|
const focusedVirtualCell = useGridSelector(apiRef, gridFocusedVirtualCellSelector);
|
|
142
144
|
const scrollTimeout = useTimeout();
|
|
143
145
|
const frozenContext = React.useRef(undefined);
|
|
144
|
-
const scrollCache = useLazyRef(() => createScrollCache(isRtl, rootProps.rowBufferPx, rootProps.columnBufferPx,
|
|
146
|
+
const scrollCache = useLazyRef(() => createScrollCache(isRtl, rootProps.rowBufferPx, rootProps.columnBufferPx, rowHeight * 15, MINIMUM_COLUMN_WIDTH * 6)).current;
|
|
145
147
|
const updateRenderContext = React.useCallback(nextRenderContext => {
|
|
146
148
|
if (areRenderContextsEqual(nextRenderContext, apiRef.current.state.virtualization.renderContext)) {
|
|
147
149
|
return;
|
|
@@ -156,19 +158,21 @@ export const useGridVirtualScroller = () => {
|
|
|
156
158
|
});
|
|
157
159
|
|
|
158
160
|
// The lazy-loading hook is listening to `renderedRowsIntervalChange`,
|
|
159
|
-
// but only does something if
|
|
160
|
-
//
|
|
161
|
-
|
|
161
|
+
// but only does something if we already have a render context, because
|
|
162
|
+
// otherwise we would call an update directly on mount
|
|
163
|
+
const isReady = gridDimensionsSelector(apiRef.current.state).isReady;
|
|
164
|
+
if (isReady && didRowsIntervalChange) {
|
|
162
165
|
previousRowContext.current = nextRenderContext;
|
|
163
166
|
apiRef.current.publishEvent('renderedRowsIntervalChange', nextRenderContext);
|
|
164
167
|
}
|
|
165
168
|
previousContextScrollPosition.current = scrollPosition.current;
|
|
166
|
-
}, [apiRef
|
|
169
|
+
}, [apiRef]);
|
|
167
170
|
const triggerUpdateRenderContext = useEventCallback(() => {
|
|
168
171
|
const scroller = scrollerRef.current;
|
|
169
172
|
if (!scroller) {
|
|
170
173
|
return undefined;
|
|
171
174
|
}
|
|
175
|
+
const dimensions = gridDimensionsSelector(apiRef.current.state);
|
|
172
176
|
const maxScrollTop = Math.ceil(dimensions.minimumSize.height - dimensions.viewportOuterSize.height);
|
|
173
177
|
const maxScrollLeft = Math.ceil(dimensions.minimumSize.width - dimensions.viewportInnerSize.width);
|
|
174
178
|
|
|
@@ -188,7 +192,7 @@ export const useGridVirtualScroller = () => {
|
|
|
188
192
|
const columnScroll = Math.abs(scrollPosition.current.left - previousContextScrollPosition.current.left);
|
|
189
193
|
|
|
190
194
|
// PERF: use the computed minimum column width instead of a static one
|
|
191
|
-
const didCrossThreshold = rowScroll >=
|
|
195
|
+
const didCrossThreshold = rowScroll >= rowHeight || columnScroll >= MINIMUM_COLUMN_WIDTH;
|
|
192
196
|
const didChangeDirection = scrollCache.direction !== direction;
|
|
193
197
|
const shouldUpdate = didCrossThreshold || didChangeDirection;
|
|
194
198
|
if (!shouldUpdate) {
|
|
@@ -210,7 +214,7 @@ export const useGridVirtualScroller = () => {
|
|
|
210
214
|
}
|
|
211
215
|
}
|
|
212
216
|
scrollCache.direction = direction;
|
|
213
|
-
scrollCache.buffer = bufferForDirection(isRtl, direction, rootProps.rowBufferPx, rootProps.columnBufferPx,
|
|
217
|
+
scrollCache.buffer = bufferForDirection(isRtl, direction, rootProps.rowBufferPx, rootProps.columnBufferPx, rowHeight * 15, MINIMUM_COLUMN_WIDTH * 6);
|
|
214
218
|
const inputs = inputsSelector(apiRef, rootProps, enabledForRows, enabledForColumns);
|
|
215
219
|
const nextRenderContext = computeRenderContext(inputs, scrollPosition.current, scrollCache);
|
|
216
220
|
|
|
@@ -222,6 +226,10 @@ export const useGridVirtualScroller = () => {
|
|
|
222
226
|
return nextRenderContext;
|
|
223
227
|
});
|
|
224
228
|
const forceUpdateRenderContext = () => {
|
|
229
|
+
// skip update if dimensions are not ready and virtualization is enabled
|
|
230
|
+
if (!gridDimensionsSelector(apiRef.current.state).isReady && (enabledForRows || enabledForColumns)) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
225
233
|
const inputs = inputsSelector(apiRef, rootProps, enabledForRows, enabledForColumns);
|
|
226
234
|
const nextRenderContext = computeRenderContext(inputs, scrollPosition.current, scrollCache);
|
|
227
235
|
// Reset the frozen context when the render context changes, see the illustration in https://github.com/mui/mui-x/pull/12353
|
|
@@ -250,7 +258,12 @@ export const useGridVirtualScroller = () => {
|
|
|
250
258
|
if (!params.rows && !currentPage.range) {
|
|
251
259
|
return [];
|
|
252
260
|
}
|
|
253
|
-
|
|
261
|
+
let baseRenderContext = renderContext;
|
|
262
|
+
if (params.renderContext) {
|
|
263
|
+
baseRenderContext = params.renderContext;
|
|
264
|
+
baseRenderContext.firstColumnIndex = renderContext.firstColumnIndex;
|
|
265
|
+
baseRenderContext.lastColumnIndex = renderContext.lastColumnIndex;
|
|
266
|
+
}
|
|
254
267
|
const isLastSection = !hasBottomPinnedRows && params.position === undefined || hasBottomPinnedRows && params.position === 'bottom';
|
|
255
268
|
const isPinnedSection = params.position !== undefined;
|
|
256
269
|
let rowIndexOffset;
|
|
@@ -344,7 +357,7 @@ export const useGridVirtualScroller = () => {
|
|
|
344
357
|
}
|
|
345
358
|
}
|
|
346
359
|
let currentRenderContext = baseRenderContext;
|
|
347
|
-
if (
|
|
360
|
+
if (frozenContext.current && rowIndexInPage >= frozenContext.current.firstRowIndex && rowIndexInPage < frozenContext.current.lastRowIndex) {
|
|
348
361
|
currentRenderContext = frozenContext.current;
|
|
349
362
|
}
|
|
350
363
|
const isVirtualFocusRow = rowIndexInPage === virtualRowIndex;
|
|
@@ -359,7 +372,7 @@ export const useGridVirtualScroller = () => {
|
|
|
359
372
|
index: rowIndex,
|
|
360
373
|
selected: isSelected,
|
|
361
374
|
offsetLeft: offsetLeft,
|
|
362
|
-
columnsTotalWidth:
|
|
375
|
+
columnsTotalWidth: columnsTotalWidth,
|
|
363
376
|
rowHeight: baseRowHeight,
|
|
364
377
|
pinnedColumns: pinnedColumns,
|
|
365
378
|
visibleColumns: visibleColumns,
|
|
@@ -370,8 +383,8 @@ export const useGridVirtualScroller = () => {
|
|
|
370
383
|
isLastVisible: isLastVisible,
|
|
371
384
|
isNotVisible: isVirtualFocusRow,
|
|
372
385
|
showBottomBorder: showBottomBorder,
|
|
373
|
-
scrollbarWidth:
|
|
374
|
-
gridHasFiller:
|
|
386
|
+
scrollbarWidth: verticalScrollbarWidth,
|
|
387
|
+
gridHasFiller: gridHasFiller
|
|
375
388
|
}, rowProps), id));
|
|
376
389
|
if (isVirtualFocusRow) {
|
|
377
390
|
return;
|
|
@@ -388,7 +401,6 @@ export const useGridVirtualScroller = () => {
|
|
|
388
401
|
});
|
|
389
402
|
return rows;
|
|
390
403
|
};
|
|
391
|
-
const needsHorizontalScrollbar = outerSize.width && columnsTotalWidth > outerSize.width;
|
|
392
404
|
const scrollerStyle = React.useMemo(() => ({
|
|
393
405
|
overflowX: !needsHorizontalScrollbar || listView ? 'hidden' : undefined,
|
|
394
406
|
overflowY: rootProps.autoHeight ? 'hidden' : undefined
|
|
@@ -424,14 +436,11 @@ export const useGridVirtualScroller = () => {
|
|
|
424
436
|
scrollerRef.current.scrollLeft = 0;
|
|
425
437
|
}
|
|
426
438
|
}, [listView, scrollerRef]);
|
|
427
|
-
useRunOnce(
|
|
428
|
-
const inputs = inputsSelector(apiRef, rootProps, enabledForRows, enabledForColumns);
|
|
429
|
-
const initialRenderContext = computeRenderContext(inputs, scrollPosition.current, scrollCache);
|
|
430
|
-
updateRenderContext(initialRenderContext);
|
|
439
|
+
useRunOnce(renderContext !== EMPTY_RENDER_CONTEXT, () => {
|
|
431
440
|
apiRef.current.publishEvent('scrollPositionChange', {
|
|
432
441
|
top: scrollPosition.current.top,
|
|
433
442
|
left: scrollPosition.current.left,
|
|
434
|
-
renderContext
|
|
443
|
+
renderContext
|
|
435
444
|
});
|
|
436
445
|
isRenderContextReady.current = true;
|
|
437
446
|
if (rootProps.initialState?.scroll && scrollerRef.current) {
|
|
@@ -484,9 +493,9 @@ export const useGridVirtualScroller = () => {
|
|
|
484
493
|
apiRef.current.register('private', {
|
|
485
494
|
updateRenderContext: forceUpdateRenderContext
|
|
486
495
|
});
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
496
|
+
useGridApiOptionHandler(apiRef, 'sortedRowsSet', forceUpdateRenderContext);
|
|
497
|
+
useGridApiOptionHandler(apiRef, 'paginationModelChange', forceUpdateRenderContext);
|
|
498
|
+
useGridApiOptionHandler(apiRef, 'columnsChange', forceUpdateRenderContext);
|
|
490
499
|
return {
|
|
491
500
|
renderContext,
|
|
492
501
|
setPanels,
|
|
@@ -522,9 +531,16 @@ export const useGridVirtualScroller = () => {
|
|
|
522
531
|
ref: scrollbarHorizontalRef,
|
|
523
532
|
role: 'presentation',
|
|
524
533
|
scrollPosition
|
|
534
|
+
}),
|
|
535
|
+
getScrollAreaProps: () => ({
|
|
536
|
+
scrollPosition
|
|
525
537
|
})
|
|
526
538
|
};
|
|
527
539
|
};
|
|
540
|
+
// dimension selectors
|
|
541
|
+
function needsHorizontalScrollbarSelector(state) {
|
|
542
|
+
return state.dimensions.viewportOuterSize.width > 0 && state.dimensions.columnsTotalWidth > state.dimensions.viewportOuterSize.width;
|
|
543
|
+
}
|
|
528
544
|
function inputsSelector(apiRef, rootProps, enabledForRows, enabledForColumns) {
|
|
529
545
|
const dimensions = gridDimensionsSelector(apiRef.current.state);
|
|
530
546
|
const currentPage = getVisibleRows(apiRef, rootProps);
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
1
|
import { RefObject } from '@mui/x-internals/types';
|
|
3
2
|
import { GridPrivateApiCommon } from '../../models/api/gridApiCommon';
|
|
4
3
|
export declare const useGridNativeEventListener: <PrivateApi extends GridPrivateApiCommon, K extends keyof HTMLElementEventMap>(apiRef: RefObject<PrivateApi>, ref: React.RefObject<HTMLDivElement | null> | (() => HTMLElement | undefined | null), eventName: K, handler?: (event: HTMLElementEventMap[K]) => any, options?: AddEventListenerOptions) => void;
|
|
@@ -1,27 +1,17 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { isFunction } from "../../utils/utils.js";
|
|
3
1
|
import { useGridLogger } from "./useGridLogger.js";
|
|
2
|
+
import { useGridApiOptionHandler } from "./useGridApiEventHandler.js";
|
|
4
3
|
export const useGridNativeEventListener = (apiRef, ref, eventName, handler, options) => {
|
|
5
4
|
const logger = useGridLogger(apiRef, 'useNativeEventListener');
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
return handlerRef.current && handlerRef.current(event);
|
|
11
|
-
}, []);
|
|
12
|
-
React.useEffect(() => {
|
|
13
|
-
handlerRef.current = handler;
|
|
14
|
-
}, [handler]);
|
|
15
|
-
React.useEffect(() => {
|
|
16
|
-
if (targetElement && eventName && !added) {
|
|
17
|
-
logger.debug(`Binding native ${eventName} event`);
|
|
18
|
-
targetElement.addEventListener(eventName, wrapHandler, options);
|
|
19
|
-
setAdded(true);
|
|
20
|
-
const unsubscribe = () => {
|
|
21
|
-
logger.debug(`Clearing native ${eventName} event`);
|
|
22
|
-
targetElement.removeEventListener(eventName, wrapHandler, options);
|
|
23
|
-
};
|
|
24
|
-
apiRef.current.subscribeEvent('unmount', unsubscribe);
|
|
5
|
+
useGridApiOptionHandler(apiRef, 'rootMount', () => {
|
|
6
|
+
const targetElement = typeof ref === 'function' ? ref() : ref.current;
|
|
7
|
+
if (!targetElement || !eventName || !handler) {
|
|
8
|
+
return undefined;
|
|
25
9
|
}
|
|
26
|
-
|
|
10
|
+
logger.debug(`Binding native ${eventName} event`);
|
|
11
|
+
targetElement.addEventListener(eventName, handler, options);
|
|
12
|
+
return () => {
|
|
13
|
+
logger.debug(`Clearing native ${eventName} event`);
|
|
14
|
+
targetElement.removeEventListener(eventName, handler, options);
|
|
15
|
+
};
|
|
16
|
+
});
|
|
27
17
|
};
|
|
@@ -5,6 +5,13 @@ import type { OutputSelector, OutputSelectorV8 } from '../../utils/createSelecto
|
|
|
5
5
|
type Selector<Api extends GridApiCommon, Args, T> = ((state: Api['state']) => T) | OutputSelectorV8<Api['state'], Args, T>;
|
|
6
6
|
export declare const objectShallowCompare: typeof fastObjectShallowCompare;
|
|
7
7
|
export declare const argsEqual: (prev: any, curr: any) => boolean;
|
|
8
|
+
type Refs<T> = {
|
|
9
|
+
state: T;
|
|
10
|
+
equals: <U = T>(a: U, b: U) => boolean;
|
|
11
|
+
selector: Selector<any, any, T>;
|
|
12
|
+
args: any;
|
|
13
|
+
subscription: undefined | (() => void);
|
|
14
|
+
};
|
|
8
15
|
export declare const useGridSelector: <Api extends GridApiCommon, T>(apiRef: RefObject<Api>, selector: ((state: Api["state"]) => T) | OutputSelector<Api["state"], T>, equals?: (a: T, b: T) => boolean) => T;
|
|
9
|
-
export declare const useGridSelectorV8: <Api extends GridApiCommon, Args, T>(apiRef: RefObject<Api>, selector: Selector<Api, Args, T>, args?: Args, equals?: <
|
|
16
|
+
export declare const useGridSelectorV8: <Api extends GridApiCommon, Args, T>(apiRef: RefObject<Api>, selector: Selector<Api, Args, T>, args?: Args, equals?: Refs<T>["equals"]) => T;
|
|
10
17
|
export {};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { fastObjectShallowCompare } from '@mui/x-internals/fastObjectShallowCompare';
|
|
3
3
|
import { warnOnce } from '@mui/x-internals/warning';
|
|
4
|
+
import { useSyncExternalStore } from 'use-sync-external-store/shim';
|
|
4
5
|
import { useLazyRef } from "./useLazyRef.js";
|
|
5
|
-
import { useOnMount } from "./useOnMount.js";
|
|
6
6
|
function isOutputSelector(selector) {
|
|
7
7
|
return selector.acceptsApiRef;
|
|
8
8
|
}
|
|
@@ -42,8 +42,10 @@ const createRefs = () => ({
|
|
|
42
42
|
state: null,
|
|
43
43
|
equals: null,
|
|
44
44
|
selector: null,
|
|
45
|
-
args:
|
|
45
|
+
args: undefined
|
|
46
46
|
});
|
|
47
|
+
const EMPTY = [];
|
|
48
|
+
const emptyGetSnapshot = () => null;
|
|
47
49
|
|
|
48
50
|
// TODO v8: Remove this function
|
|
49
51
|
export const useGridSelector = (apiRef, selector, equals = defaultCompare) => {
|
|
@@ -60,15 +62,31 @@ export const useGridSelector = (apiRef, selector, equals = defaultCompare) => {
|
|
|
60
62
|
refs.current.state = state;
|
|
61
63
|
refs.current.equals = equals;
|
|
62
64
|
refs.current.selector = selector;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
const subscribe = React.useCallback(() => {
|
|
66
|
+
if (refs.current.subscription) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
refs.current.subscription = apiRef.current.store.subscribe(() => {
|
|
65
70
|
const newState = applySelector(apiRef, refs.current.selector);
|
|
66
71
|
if (!refs.current.equals(refs.current.state, newState)) {
|
|
67
72
|
refs.current.state = newState;
|
|
68
73
|
setState(newState);
|
|
69
74
|
}
|
|
70
75
|
});
|
|
71
|
-
|
|
76
|
+
return null;
|
|
77
|
+
},
|
|
78
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
79
|
+
EMPTY);
|
|
80
|
+
const unsubscribe = React.useCallback(() => {
|
|
81
|
+
return () => {
|
|
82
|
+
if (refs.current.subscription) {
|
|
83
|
+
refs.current.subscription();
|
|
84
|
+
refs.current.subscription = undefined;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
88
|
+
}, EMPTY);
|
|
89
|
+
useSyncExternalStore(unsubscribe, subscribe, emptyGetSnapshot);
|
|
72
90
|
return state;
|
|
73
91
|
};
|
|
74
92
|
|
|
@@ -96,14 +114,30 @@ export const useGridSelectorV8 = (apiRef, selector, args = undefined, equals = d
|
|
|
96
114
|
setState(newState);
|
|
97
115
|
}
|
|
98
116
|
}
|
|
99
|
-
|
|
100
|
-
|
|
117
|
+
const subscribe = React.useCallback(() => {
|
|
118
|
+
if (refs.current.subscription) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
refs.current.subscription = apiRef.current.store.subscribe(() => {
|
|
101
122
|
const newState = applySelectorV8(apiRef, refs.current.selector, refs.current.args, apiRef.current.instanceId);
|
|
102
123
|
if (!refs.current.equals(refs.current.state, newState)) {
|
|
103
124
|
refs.current.state = newState;
|
|
104
125
|
setState(newState);
|
|
105
126
|
}
|
|
106
127
|
});
|
|
107
|
-
|
|
128
|
+
return null;
|
|
129
|
+
},
|
|
130
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
131
|
+
EMPTY);
|
|
132
|
+
const unsubscribe = React.useCallback(() => {
|
|
133
|
+
return () => {
|
|
134
|
+
if (refs.current.subscription) {
|
|
135
|
+
refs.current.subscription();
|
|
136
|
+
refs.current.subscription = undefined;
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
140
|
+
}, EMPTY);
|
|
141
|
+
useSyncExternalStore(unsubscribe, subscribe, emptyGetSnapshot);
|
|
108
142
|
return state;
|
|
109
143
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useIsSSR: () => boolean;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { useSyncExternalStore } from 'use-sync-external-store/shim';
|
|
2
|
+
const emptySubscribe = () => () => {};
|
|
3
|
+
const clientSnapshot = () => false;
|
|
4
|
+
const serverSnapshot = () => true;
|
|
5
|
+
export const useIsSSR = () => useSyncExternalStore(emptySubscribe, clientSnapshot, serverSnapshot);
|