@mui/x-data-grid 7.16.0 → 7.18.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 +184 -4
- package/DataGrid/DataGrid.js +11 -1
- package/DataGrid/useDataGridComponent.js +3 -0
- package/DataGrid/useDataGridProps.js +2 -1
- package/colDef/gridStringOperators.js +49 -33
- package/components/GridRow.js +1 -0
- package/components/cell/GridCell.js +30 -5
- package/components/columnHeaders/GridColumnHeaderItem.d.ts +2 -0
- package/components/columnHeaders/GridColumnHeaderItem.js +9 -2
- package/components/columnHeaders/GridColumnHeaderTitle.js +3 -1
- package/components/columnHeaders/GridGenericColumnHeaderItem.js +1 -2
- package/components/containers/GridRootStyles.js +3 -7
- package/components/panel/filterPanel/GridFilterForm.js +1 -1
- package/constants/gridClasses.d.ts +10 -0
- package/constants/gridClasses.js +1 -1
- package/constants/localeTextConstants.js +4 -0
- package/hooks/features/columnHeaders/useGridColumnHeaders.d.ts +0 -1
- package/hooks/features/columnHeaders/useGridColumnHeaders.js +17 -12
- package/hooks/features/columnResize/useGridColumnResize.js +6 -6
- package/hooks/features/dimensions/gridDimensionsApi.d.ts +4 -0
- package/hooks/features/dimensions/useGridDimensions.d.ts +1 -1
- package/hooks/features/dimensions/useGridDimensions.js +4 -1
- package/hooks/features/editing/useGridCellEditing.js +3 -19
- package/hooks/features/editing/useGridRowEditing.js +7 -2
- package/hooks/features/editing/utils.d.ts +2 -0
- package/hooks/features/editing/utils.js +15 -0
- package/hooks/features/export/serializers/csvSerializer.js +1 -1
- package/hooks/features/export/useGridPrintExport.js +2 -1
- package/hooks/features/filter/gridFilterUtils.js +1 -1
- package/hooks/features/focus/useGridFocus.js +2 -1
- package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +10 -46
- package/hooks/features/keyboardNavigation/utils.d.ts +17 -0
- package/hooks/features/keyboardNavigation/utils.js +58 -0
- package/hooks/features/rows/gridRowSpanningSelectors.d.ts +4 -0
- package/hooks/features/rows/gridRowSpanningSelectors.js +5 -0
- package/hooks/features/rows/gridRowSpanningUtils.d.ts +10 -0
- package/hooks/features/rows/gridRowSpanningUtils.js +42 -0
- package/hooks/features/rows/useGridRowSpanning.d.ts +27 -0
- package/hooks/features/rows/useGridRowSpanning.js +257 -0
- package/hooks/features/sorting/gridSortingUtils.js +1 -1
- package/hooks/features/virtualization/useGridVirtualScroller.d.ts +1 -1
- package/hooks/features/virtualization/useGridVirtualScroller.js +17 -7
- package/hooks/utils/useGridApiEventHandler.js +0 -1
- package/hooks/utils/useGridSelector.js +1 -1
- package/index.js +1 -1
- package/internals/index.d.ts +1 -0
- package/internals/index.js +1 -0
- package/internals/utils/index.d.ts +0 -1
- package/internals/utils/index.js +1 -2
- package/internals/utils/propValidation.js +1 -1
- package/locales/arSD.js +4 -0
- package/locales/beBY.js +4 -0
- package/locales/bgBG.js +4 -0
- package/locales/csCZ.js +4 -0
- package/locales/daDK.js +4 -0
- package/locales/deDE.js +4 -0
- package/locales/elGR.js +4 -0
- package/locales/esES.js +4 -0
- package/locales/faIR.js +4 -0
- package/locales/fiFI.js +4 -0
- package/locales/frFR.js +4 -0
- package/locales/heIL.js +4 -0
- package/locales/hrHR.js +4 -0
- package/locales/huHU.js +11 -8
- package/locales/isIS.js +4 -0
- package/locales/itIT.js +4 -0
- package/locales/jaJP.js +4 -0
- package/locales/koKR.js +4 -0
- package/locales/nbNO.js +4 -0
- package/locales/nlNL.js +4 -0
- package/locales/nnNO.js +4 -0
- package/locales/plPL.js +4 -0
- package/locales/ptBR.js +4 -0
- package/locales/ptPT.js +4 -0
- package/locales/roRO.js +4 -0
- package/locales/ruRU.js +4 -0
- package/locales/skSK.js +4 -0
- package/locales/svSE.js +4 -0
- package/locales/trTR.js +4 -0
- package/locales/ukUA.js +4 -0
- package/locales/urPK.js +4 -0
- package/locales/viVN.js +4 -0
- package/locales/zhCN.js +4 -0
- package/locales/zhHK.js +4 -0
- package/locales/zhTW.js +4 -0
- package/models/api/gridLocaleTextApi.d.ts +4 -0
- package/models/colDef/gridColDef.d.ts +4 -0
- package/models/gridStateCommunity.d.ts +2 -0
- package/models/props/DataGridProps.d.ts +10 -0
- package/modern/DataGrid/DataGrid.js +11 -1
- package/modern/DataGrid/useDataGridComponent.js +3 -0
- package/modern/DataGrid/useDataGridProps.js +2 -1
- package/modern/colDef/gridStringOperators.js +49 -33
- package/modern/components/GridRow.js +1 -0
- package/modern/components/cell/GridCell.js +30 -5
- package/modern/components/columnHeaders/GridColumnHeaderItem.js +9 -2
- package/modern/components/columnHeaders/GridColumnHeaderTitle.js +3 -1
- package/modern/components/columnHeaders/GridGenericColumnHeaderItem.js +1 -2
- package/modern/components/containers/GridRootStyles.js +3 -7
- package/modern/components/panel/filterPanel/GridFilterForm.js +1 -1
- package/modern/constants/gridClasses.js +1 -1
- package/modern/constants/localeTextConstants.js +4 -0
- package/modern/hooks/features/columnHeaders/useGridColumnHeaders.js +17 -12
- package/modern/hooks/features/columnResize/useGridColumnResize.js +6 -6
- package/modern/hooks/features/dimensions/useGridDimensions.js +4 -1
- package/modern/hooks/features/editing/useGridCellEditing.js +3 -19
- package/modern/hooks/features/editing/useGridRowEditing.js +7 -2
- package/modern/hooks/features/editing/utils.js +15 -0
- package/modern/hooks/features/export/serializers/csvSerializer.js +1 -1
- package/modern/hooks/features/export/useGridPrintExport.js +2 -1
- package/modern/hooks/features/filter/gridFilterUtils.js +1 -1
- package/modern/hooks/features/focus/useGridFocus.js +2 -1
- package/modern/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +10 -46
- package/modern/hooks/features/keyboardNavigation/utils.js +58 -0
- package/modern/hooks/features/rows/gridRowSpanningSelectors.js +5 -0
- package/modern/hooks/features/rows/gridRowSpanningUtils.js +42 -0
- package/modern/hooks/features/rows/useGridRowSpanning.js +257 -0
- package/modern/hooks/features/sorting/gridSortingUtils.js +1 -1
- package/modern/hooks/features/virtualization/useGridVirtualScroller.js +17 -7
- package/modern/hooks/utils/useGridApiEventHandler.js +0 -1
- package/modern/hooks/utils/useGridSelector.js +1 -1
- package/modern/index.js +1 -1
- package/modern/internals/index.js +1 -0
- package/modern/internals/utils/index.js +1 -2
- package/modern/internals/utils/propValidation.js +1 -1
- package/modern/locales/arSD.js +4 -0
- package/modern/locales/beBY.js +4 -0
- package/modern/locales/bgBG.js +4 -0
- package/modern/locales/csCZ.js +4 -0
- package/modern/locales/daDK.js +4 -0
- package/modern/locales/deDE.js +4 -0
- package/modern/locales/elGR.js +4 -0
- package/modern/locales/esES.js +4 -0
- package/modern/locales/faIR.js +4 -0
- package/modern/locales/fiFI.js +4 -0
- package/modern/locales/frFR.js +4 -0
- package/modern/locales/heIL.js +4 -0
- package/modern/locales/hrHR.js +4 -0
- package/modern/locales/huHU.js +11 -8
- package/modern/locales/isIS.js +4 -0
- package/modern/locales/itIT.js +4 -0
- package/modern/locales/jaJP.js +4 -0
- package/modern/locales/koKR.js +4 -0
- package/modern/locales/nbNO.js +4 -0
- package/modern/locales/nlNL.js +4 -0
- package/modern/locales/nnNO.js +4 -0
- package/modern/locales/plPL.js +4 -0
- package/modern/locales/ptBR.js +4 -0
- package/modern/locales/ptPT.js +4 -0
- package/modern/locales/roRO.js +4 -0
- package/modern/locales/ruRU.js +4 -0
- package/modern/locales/skSK.js +4 -0
- package/modern/locales/svSE.js +4 -0
- package/modern/locales/trTR.js +4 -0
- package/modern/locales/ukUA.js +4 -0
- package/modern/locales/urPK.js +4 -0
- package/modern/locales/viVN.js +4 -0
- package/modern/locales/zhCN.js +4 -0
- package/modern/locales/zhHK.js +4 -0
- package/modern/locales/zhTW.js +4 -0
- package/modern/utils/createSelector.js +1 -1
- package/modern/utils/domUtils.js +12 -12
- package/node/DataGrid/DataGrid.js +11 -1
- package/node/DataGrid/useDataGridComponent.js +3 -0
- package/node/DataGrid/useDataGridProps.js +2 -1
- package/node/colDef/gridStringOperators.js +49 -33
- package/node/components/GridRow.js +1 -0
- package/node/components/cell/GridCell.js +30 -5
- package/node/components/columnHeaders/GridColumnHeaderItem.js +9 -2
- package/node/components/columnHeaders/GridColumnHeaderTitle.js +3 -1
- package/node/components/columnHeaders/GridGenericColumnHeaderItem.js +1 -2
- package/node/components/containers/GridRootStyles.js +3 -7
- package/node/components/panel/filterPanel/GridFilterForm.js +1 -1
- package/node/constants/gridClasses.js +1 -1
- package/node/constants/localeTextConstants.js +4 -0
- package/node/hooks/features/columnHeaders/useGridColumnHeaders.js +17 -12
- package/node/hooks/features/columnResize/useGridColumnResize.js +6 -6
- package/node/hooks/features/dimensions/useGridDimensions.js +4 -1
- package/node/hooks/features/editing/useGridCellEditing.js +3 -19
- package/node/hooks/features/editing/useGridRowEditing.js +7 -2
- package/node/hooks/features/editing/utils.js +22 -0
- package/node/hooks/features/export/serializers/csvSerializer.js +1 -1
- package/node/hooks/features/export/useGridPrintExport.js +2 -1
- package/node/hooks/features/filter/gridFilterUtils.js +1 -1
- package/node/hooks/features/focus/useGridFocus.js +2 -1
- package/node/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +16 -53
- package/node/hooks/features/keyboardNavigation/utils.js +68 -0
- package/node/hooks/features/rows/gridRowSpanningSelectors.js +11 -0
- package/node/hooks/features/rows/gridRowSpanningUtils.js +52 -0
- package/node/hooks/features/rows/useGridRowSpanning.js +267 -0
- package/node/hooks/features/sorting/gridSortingUtils.js +1 -1
- package/node/hooks/features/virtualization/useGridVirtualScroller.js +17 -7
- package/node/hooks/utils/useGridApiEventHandler.js +0 -1
- package/node/hooks/utils/useGridSelector.js +1 -1
- package/node/index.js +1 -1
- package/node/internals/index.js +15 -0
- package/node/internals/utils/index.js +0 -11
- package/node/internals/utils/propValidation.js +1 -1
- package/node/locales/arSD.js +4 -0
- package/node/locales/beBY.js +4 -0
- package/node/locales/bgBG.js +4 -0
- package/node/locales/csCZ.js +4 -0
- package/node/locales/daDK.js +4 -0
- package/node/locales/deDE.js +4 -0
- package/node/locales/elGR.js +4 -0
- package/node/locales/esES.js +4 -0
- package/node/locales/faIR.js +4 -0
- package/node/locales/fiFI.js +4 -0
- package/node/locales/frFR.js +4 -0
- package/node/locales/heIL.js +4 -0
- package/node/locales/hrHR.js +4 -0
- package/node/locales/huHU.js +11 -8
- package/node/locales/isIS.js +4 -0
- package/node/locales/itIT.js +4 -0
- package/node/locales/jaJP.js +4 -0
- package/node/locales/koKR.js +4 -0
- package/node/locales/nbNO.js +4 -0
- package/node/locales/nlNL.js +4 -0
- package/node/locales/nnNO.js +4 -0
- package/node/locales/plPL.js +4 -0
- package/node/locales/ptBR.js +4 -0
- package/node/locales/ptPT.js +4 -0
- package/node/locales/roRO.js +4 -0
- package/node/locales/ruRU.js +4 -0
- package/node/locales/skSK.js +4 -0
- package/node/locales/svSE.js +4 -0
- package/node/locales/trTR.js +4 -0
- package/node/locales/ukUA.js +4 -0
- package/node/locales/urPK.js +4 -0
- package/node/locales/viVN.js +4 -0
- package/node/locales/zhCN.js +4 -0
- package/node/locales/zhHK.js +4 -0
- package/node/locales/zhTW.js +4 -0
- package/node/utils/createSelector.js +1 -1
- package/node/utils/domUtils.js +12 -12
- package/package.json +3 -3
- package/utils/createSelector.js +1 -1
- package/utils/domUtils.d.ts +4 -4
- package/utils/domUtils.js +12 -12
- package/internals/utils/warning.d.ts +0 -2
- package/internals/utils/warning.js +0 -21
- package/modern/internals/utils/warning.js +0 -21
- package/node/internals/utils/warning.js +0 -28
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { warnOnce } from '@mui/x-internals/warning';
|
|
1
2
|
import { GRID_CHECKBOX_SELECTION_COL_DEF } from "../../../../colDef/index.js";
|
|
2
|
-
import { warnOnce } from "../../../../internals/utils/warning.js";
|
|
3
3
|
function sanitizeCellValue(value, csvOptions) {
|
|
4
4
|
if (value === null || value === undefined) {
|
|
5
5
|
return '';
|
|
@@ -38,6 +38,7 @@ function buildPrintWindow(title) {
|
|
|
38
38
|
* @requires useGridParamsApi (method)
|
|
39
39
|
*/
|
|
40
40
|
export const useGridPrintExport = (apiRef, props) => {
|
|
41
|
+
const hasRootReference = apiRef.current.rootElementRef.current !== null;
|
|
41
42
|
const logger = useGridLogger(apiRef, 'useGridPrintExport');
|
|
42
43
|
const doc = React.useRef(null);
|
|
43
44
|
const previousGridState = React.useRef(null);
|
|
@@ -46,7 +47,7 @@ export const useGridPrintExport = (apiRef, props) => {
|
|
|
46
47
|
const previousVirtualizationState = React.useRef();
|
|
47
48
|
React.useEffect(() => {
|
|
48
49
|
doc.current = ownerDocument(apiRef.current.rootElementRef.current);
|
|
49
|
-
}, [apiRef]);
|
|
50
|
+
}, [apiRef, hasRootReference]);
|
|
50
51
|
|
|
51
52
|
// Returns a promise because updateColumns triggers state update and
|
|
52
53
|
// the new state needs to be in place before the grid can be sized correctly
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
+
import { warnOnce } from '@mui/x-internals/warning';
|
|
2
3
|
import { GridLogicOperator } from "../../../models/index.js";
|
|
3
4
|
import { getDefaultGridFilterModel } from "./gridFilterState.js";
|
|
4
|
-
import { warnOnce } from "../../../internals/utils/warning.js";
|
|
5
5
|
import { getPublicApiRef } from "../../../utils/getPublicApiRef.js";
|
|
6
6
|
import { gridColumnFieldsSelector, gridColumnLookupSelector, gridVisibleColumnFieldsSelector } from "../columns/index.js";
|
|
7
7
|
let hasEval;
|
|
@@ -34,6 +34,7 @@ export const focusStateInitializer = state => _extends({}, state, {
|
|
|
34
34
|
export const useGridFocus = (apiRef, props) => {
|
|
35
35
|
const logger = useGridLogger(apiRef, 'useGridFocus');
|
|
36
36
|
const lastClickedCell = React.useRef(null);
|
|
37
|
+
const hasRootReference = apiRef.current.rootElementRef.current !== null;
|
|
37
38
|
const publishCellFocusOut = React.useCallback((cell, event) => {
|
|
38
39
|
if (cell) {
|
|
39
40
|
// The row might have been deleted
|
|
@@ -380,7 +381,7 @@ export const useGridFocus = (apiRef, props) => {
|
|
|
380
381
|
return () => {
|
|
381
382
|
doc.removeEventListener('mouseup', handleDocumentClick);
|
|
382
383
|
};
|
|
383
|
-
}, [apiRef, handleDocumentClick]);
|
|
384
|
+
}, [apiRef, hasRootReference, handleDocumentClick]);
|
|
384
385
|
useGridApiEventHandler(apiRef, 'columnHeaderBlur', handleBlur);
|
|
385
386
|
useGridApiEventHandler(apiRef, 'cellDoubleClick', handleCellDoubleClick);
|
|
386
387
|
useGridApiEventHandler(apiRef, 'cellMouseDown', handleCellMouseDown);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { useRtl } from '@mui/system/RtlProvider';
|
|
3
|
-
import { gridVisibleColumnDefinitionsSelector } from "../columns/gridColumnsSelector.js";
|
|
3
|
+
import { gridVisibleColumnDefinitionsSelector, gridVisibleColumnFieldsSelector } from "../columns/gridColumnsSelector.js";
|
|
4
4
|
import { useGridLogger } from "../../utils/useGridLogger.js";
|
|
5
5
|
import { useGridApiEventHandler } from "../../utils/useGridApiEventHandler.js";
|
|
6
6
|
import { gridExpandedSortedRowEntriesSelector } from "../filter/gridFilterSelector.js";
|
|
@@ -10,50 +10,12 @@ import { gridClasses } from "../../../constants/gridClasses.js";
|
|
|
10
10
|
import { GridCellModes } from "../../../models/gridEditRowModel.js";
|
|
11
11
|
import { isNavigationKey } from "../../../utils/keyboardUtils.js";
|
|
12
12
|
import { GRID_DETAIL_PANEL_TOGGLE_FIELD } from "../../../constants/gridDetailPanelToggleField.js";
|
|
13
|
-
import { gridPinnedRowsSelector } from "../rows/gridRowsSelector.js";
|
|
14
13
|
import { gridFocusColumnGroupHeaderSelector } from "../focus/index.js";
|
|
15
14
|
import { gridColumnGroupsHeaderMaxDepthSelector } from "../columnGrouping/gridColumnGroupsSelector.js";
|
|
16
15
|
import { gridHeaderFilteringEditFieldSelector, gridHeaderFilteringMenuSelector } from "../headerFiltering/gridHeaderFilteringSelectors.js";
|
|
17
16
|
import { useGridRegisterPipeProcessor } from "../../core/pipeProcessing/index.js";
|
|
18
17
|
import { isEventTargetInPortal } from "../../../utils/domUtils.js";
|
|
19
|
-
|
|
20
|
-
const pinnedRows = gridPinnedRowsSelector(apiRef) || {};
|
|
21
|
-
return [...(pinnedRows.top || []), ...rows, ...(pinnedRows.bottom || [])];
|
|
22
|
-
}
|
|
23
|
-
const getLeftColumnIndex = ({
|
|
24
|
-
currentColIndex,
|
|
25
|
-
firstColIndex,
|
|
26
|
-
lastColIndex,
|
|
27
|
-
isRtl
|
|
28
|
-
}) => {
|
|
29
|
-
if (isRtl) {
|
|
30
|
-
if (currentColIndex < lastColIndex) {
|
|
31
|
-
return currentColIndex + 1;
|
|
32
|
-
}
|
|
33
|
-
} else if (!isRtl) {
|
|
34
|
-
if (currentColIndex > firstColIndex) {
|
|
35
|
-
return currentColIndex - 1;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return null;
|
|
39
|
-
};
|
|
40
|
-
const getRightColumnIndex = ({
|
|
41
|
-
currentColIndex,
|
|
42
|
-
firstColIndex,
|
|
43
|
-
lastColIndex,
|
|
44
|
-
isRtl
|
|
45
|
-
}) => {
|
|
46
|
-
if (isRtl) {
|
|
47
|
-
if (currentColIndex > firstColIndex) {
|
|
48
|
-
return currentColIndex - 1;
|
|
49
|
-
}
|
|
50
|
-
} else if (!isRtl) {
|
|
51
|
-
if (currentColIndex < lastColIndex) {
|
|
52
|
-
return currentColIndex + 1;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return null;
|
|
56
|
-
};
|
|
18
|
+
import { enrichPageRowsWithPinnedRows, getLeftColumnIndex, getRightColumnIndex, findNonRowSpannedCell } from "./utils.js";
|
|
57
19
|
|
|
58
20
|
/**
|
|
59
21
|
* @requires useGridSorting (method) - can be after
|
|
@@ -73,11 +35,12 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
|
|
|
73
35
|
|
|
74
36
|
/**
|
|
75
37
|
* @param {number} colIndex Index of the column to focus
|
|
76
|
-
* @param {
|
|
38
|
+
* @param {GridRowId} rowId index of the row to focus
|
|
77
39
|
* @param {string} closestColumnToUse Which closest column cell to use when the cell is spanned by `colSpan`.
|
|
40
|
+
* @param {string} rowSpanScanDirection Which direction to search to find the next cell not hidden by `rowSpan`.
|
|
78
41
|
* TODO replace with apiRef.current.moveFocusToRelativeCell()
|
|
79
42
|
*/
|
|
80
|
-
const goToCell = React.useCallback((colIndex, rowId, closestColumnToUse = 'left') => {
|
|
43
|
+
const goToCell = React.useCallback((colIndex, rowId, closestColumnToUse = 'left', rowSpanScanDirection = 'up') => {
|
|
81
44
|
const visibleSortedRows = gridExpandedSortedRowEntriesSelector(apiRef);
|
|
82
45
|
const nextCellColSpanInfo = apiRef.current.unstable_getCellColSpanInfo(rowId, colIndex);
|
|
83
46
|
if (nextCellColSpanInfo && nextCellColSpanInfo.spannedByColSpan) {
|
|
@@ -87,16 +50,17 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
|
|
|
87
50
|
colIndex = nextCellColSpanInfo.rightVisibleCellIndex;
|
|
88
51
|
}
|
|
89
52
|
}
|
|
53
|
+
const field = gridVisibleColumnFieldsSelector(apiRef)[colIndex];
|
|
54
|
+
const nonRowSpannedRowId = findNonRowSpannedCell(apiRef, rowId, field, rowSpanScanDirection);
|
|
90
55
|
// `scrollToIndexes` requires a rowIndex relative to all visible rows.
|
|
91
56
|
// Those rows do not include pinned rows, but pinned rows do not need scroll anyway.
|
|
92
|
-
const rowIndexRelativeToAllRows = visibleSortedRows.findIndex(row => row.id ===
|
|
57
|
+
const rowIndexRelativeToAllRows = visibleSortedRows.findIndex(row => row.id === nonRowSpannedRowId);
|
|
93
58
|
logger.debug(`Navigating to cell row ${rowIndexRelativeToAllRows}, col ${colIndex}`);
|
|
94
59
|
apiRef.current.scrollToIndexes({
|
|
95
60
|
colIndex,
|
|
96
61
|
rowIndex: rowIndexRelativeToAllRows
|
|
97
62
|
});
|
|
98
|
-
|
|
99
|
-
apiRef.current.setCellFocus(rowId, field);
|
|
63
|
+
apiRef.current.setCellFocus(nonRowSpannedRowId, field);
|
|
100
64
|
}, [apiRef, logger]);
|
|
101
65
|
const goToHeader = React.useCallback((colIndex, event) => {
|
|
102
66
|
logger.debug(`Navigating to header col ${colIndex}`);
|
|
@@ -432,7 +396,7 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
|
|
|
432
396
|
{
|
|
433
397
|
// "Enter" is only triggered by the row / cell editing feature
|
|
434
398
|
if (rowIndexBefore < lastRowIndexInPage) {
|
|
435
|
-
goToCell(colIndexBefore, getRowIdFromIndex(rowIndexBefore + 1));
|
|
399
|
+
goToCell(colIndexBefore, getRowIdFromIndex(rowIndexBefore + 1), isRtl ? 'right' : 'left', 'down');
|
|
436
400
|
}
|
|
437
401
|
break;
|
|
438
402
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { gridFilteredSortedRowIdsSelector } from "../filter/gridFilterSelector.js";
|
|
2
|
+
import { gridRowSpanningHiddenCellsSelector } from "../rows/gridRowSpanningSelectors.js";
|
|
3
|
+
import { gridPinnedRowsSelector } from "../rows/gridRowsSelector.js";
|
|
4
|
+
export function enrichPageRowsWithPinnedRows(apiRef, rows) {
|
|
5
|
+
const pinnedRows = gridPinnedRowsSelector(apiRef) || {};
|
|
6
|
+
return [...(pinnedRows.top || []), ...rows, ...(pinnedRows.bottom || [])];
|
|
7
|
+
}
|
|
8
|
+
export const getLeftColumnIndex = ({
|
|
9
|
+
currentColIndex,
|
|
10
|
+
firstColIndex,
|
|
11
|
+
lastColIndex,
|
|
12
|
+
isRtl
|
|
13
|
+
}) => {
|
|
14
|
+
if (isRtl) {
|
|
15
|
+
if (currentColIndex < lastColIndex) {
|
|
16
|
+
return currentColIndex + 1;
|
|
17
|
+
}
|
|
18
|
+
} else if (!isRtl) {
|
|
19
|
+
if (currentColIndex > firstColIndex) {
|
|
20
|
+
return currentColIndex - 1;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
};
|
|
25
|
+
export const getRightColumnIndex = ({
|
|
26
|
+
currentColIndex,
|
|
27
|
+
firstColIndex,
|
|
28
|
+
lastColIndex,
|
|
29
|
+
isRtl
|
|
30
|
+
}) => {
|
|
31
|
+
if (isRtl) {
|
|
32
|
+
if (currentColIndex > firstColIndex) {
|
|
33
|
+
return currentColIndex - 1;
|
|
34
|
+
}
|
|
35
|
+
} else if (!isRtl) {
|
|
36
|
+
if (currentColIndex < lastColIndex) {
|
|
37
|
+
return currentColIndex + 1;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
};
|
|
42
|
+
export function findNonRowSpannedCell(apiRef, rowId, field, rowSpanScanDirection) {
|
|
43
|
+
const rowSpanHiddenCells = gridRowSpanningHiddenCellsSelector(apiRef);
|
|
44
|
+
if (!rowSpanHiddenCells[rowId]?.[field]) {
|
|
45
|
+
return rowId;
|
|
46
|
+
}
|
|
47
|
+
const filteredSortedRowIds = gridFilteredSortedRowIdsSelector(apiRef);
|
|
48
|
+
// find closest non row spanned cell in the given `rowSpanScanDirection`
|
|
49
|
+
let nextRowIndex = filteredSortedRowIds.indexOf(rowId) + (rowSpanScanDirection === 'down' ? 1 : -1);
|
|
50
|
+
while (nextRowIndex >= 0 && nextRowIndex < filteredSortedRowIds.length) {
|
|
51
|
+
const nextRowId = filteredSortedRowIds[nextRowIndex];
|
|
52
|
+
if (!rowSpanHiddenCells[nextRowId]?.[field]) {
|
|
53
|
+
return nextRowId;
|
|
54
|
+
}
|
|
55
|
+
nextRowIndex += rowSpanScanDirection === 'down' ? 1 : -1;
|
|
56
|
+
}
|
|
57
|
+
return rowId;
|
|
58
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { createSelector } from "../../../utils/createSelector.js";
|
|
2
|
+
const gridRowSpanningStateSelector = state => state.rowSpanning;
|
|
3
|
+
export const gridRowSpanningHiddenCellsSelector = createSelector(gridRowSpanningStateSelector, rowSpanning => rowSpanning.hiddenCells);
|
|
4
|
+
export const gridRowSpanningSpannedCellsSelector = createSelector(gridRowSpanningStateSelector, rowSpanning => rowSpanning.spannedCells);
|
|
5
|
+
export const gridRowSpanningHiddenCellsOriginMapSelector = createSelector(gridRowSpanningStateSelector, rowSpanning => rowSpanning.hiddenCellOriginMap);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export function getUnprocessedRange(testRange, processedRange) {
|
|
2
|
+
if (testRange.firstRowIndex >= processedRange.firstRowIndex && testRange.lastRowIndex <= processedRange.lastRowIndex) {
|
|
3
|
+
return null;
|
|
4
|
+
}
|
|
5
|
+
// Overflowing at the end
|
|
6
|
+
// Example: testRange={ firstRowIndex: 10, lastRowIndex: 20 }, processedRange={ firstRowIndex: 0, lastRowIndex: 15 }
|
|
7
|
+
// Unprocessed Range={ firstRowIndex: 16, lastRowIndex: 20 }
|
|
8
|
+
if (testRange.firstRowIndex >= processedRange.firstRowIndex && testRange.lastRowIndex > processedRange.lastRowIndex) {
|
|
9
|
+
return {
|
|
10
|
+
firstRowIndex: processedRange.lastRowIndex,
|
|
11
|
+
lastRowIndex: testRange.lastRowIndex
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
// Overflowing at the beginning
|
|
15
|
+
// Example: testRange={ firstRowIndex: 0, lastRowIndex: 20 }, processedRange={ firstRowIndex: 16, lastRowIndex: 30 }
|
|
16
|
+
// Unprocessed Range={ firstRowIndex: 0, lastRowIndex: 15 }
|
|
17
|
+
if (testRange.firstRowIndex < processedRange.firstRowIndex && testRange.lastRowIndex <= processedRange.lastRowIndex) {
|
|
18
|
+
return {
|
|
19
|
+
firstRowIndex: testRange.firstRowIndex,
|
|
20
|
+
lastRowIndex: processedRange.firstRowIndex - 1
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
// TODO: Should return two ranges handle overflowing at both ends ?
|
|
24
|
+
return testRange;
|
|
25
|
+
}
|
|
26
|
+
export function isRowContextInitialized(renderContext) {
|
|
27
|
+
return renderContext.firstRowIndex !== 0 || renderContext.lastRowIndex !== 0;
|
|
28
|
+
}
|
|
29
|
+
export function isRowRangeUpdated(range1, range2) {
|
|
30
|
+
return range1.firstRowIndex !== range2.firstRowIndex || range1.lastRowIndex !== range2.lastRowIndex;
|
|
31
|
+
}
|
|
32
|
+
export const getCellValue = (row, colDef, apiRef) => {
|
|
33
|
+
if (!row) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
let cellValue = row[colDef.field];
|
|
37
|
+
const valueGetter = colDef.rowSpanValueGetter ?? colDef.valueGetter;
|
|
38
|
+
if (valueGetter) {
|
|
39
|
+
cellValue = valueGetter(cellValue, row, colDef, apiRef);
|
|
40
|
+
}
|
|
41
|
+
return cellValue;
|
|
42
|
+
};
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import useLazyRef from '@mui/utils/useLazyRef';
|
|
4
|
+
import { gridVisibleColumnDefinitionsSelector } from "../columns/gridColumnsSelector.js";
|
|
5
|
+
import { useGridVisibleRows } from "../../utils/useGridVisibleRows.js";
|
|
6
|
+
import { gridRenderContextSelector } from "../virtualization/gridVirtualizationSelectors.js";
|
|
7
|
+
import { useGridSelector } from "../../utils/useGridSelector.js";
|
|
8
|
+
import { getUnprocessedRange, isRowRangeUpdated, isRowContextInitialized, getCellValue } from "./gridRowSpanningUtils.js";
|
|
9
|
+
const EMPTY_STATE = {
|
|
10
|
+
spannedCells: {},
|
|
11
|
+
hiddenCells: {},
|
|
12
|
+
hiddenCellOriginMap: {}
|
|
13
|
+
};
|
|
14
|
+
const EMPTY_RANGE = {
|
|
15
|
+
firstRowIndex: 0,
|
|
16
|
+
lastRowIndex: 0
|
|
17
|
+
};
|
|
18
|
+
const skippedFields = new Set(['__check__', '__reorder__', '__detail_panel_toggle__']);
|
|
19
|
+
/**
|
|
20
|
+
* Default number of rows to process during state initialization to avoid flickering.
|
|
21
|
+
* Number `20` is arbitrarily chosen to be large enough to cover most of the cases without
|
|
22
|
+
* compromising performance.
|
|
23
|
+
*/
|
|
24
|
+
const DEFAULT_ROWS_TO_PROCESS = 20;
|
|
25
|
+
const computeRowSpanningState = (apiRef, colDefs, visibleRows, range, rangeToProcess, resetState, processedRange) => {
|
|
26
|
+
const spannedCells = resetState ? {} : _extends({}, apiRef.current.state.rowSpanning.spannedCells);
|
|
27
|
+
const hiddenCells = resetState ? {} : _extends({}, apiRef.current.state.rowSpanning.hiddenCells);
|
|
28
|
+
const hiddenCellOriginMap = resetState ? {} : _extends({}, apiRef.current.state.rowSpanning.hiddenCellOriginMap);
|
|
29
|
+
if (resetState) {
|
|
30
|
+
processedRange = EMPTY_RANGE;
|
|
31
|
+
}
|
|
32
|
+
colDefs.forEach(colDef => {
|
|
33
|
+
if (skippedFields.has(colDef.field)) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
for (let index = rangeToProcess.firstRowIndex; index <= rangeToProcess.lastRowIndex; index += 1) {
|
|
37
|
+
const row = visibleRows[index];
|
|
38
|
+
if (hiddenCells[row.id]?.[colDef.field]) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const cellValue = getCellValue(row.model, colDef, apiRef);
|
|
42
|
+
if (cellValue == null) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
let spannedRowId = row.id;
|
|
46
|
+
let spannedRowIndex = index;
|
|
47
|
+
let rowSpan = 0;
|
|
48
|
+
|
|
49
|
+
// For first index, also scan in the previous rows to handle the reset state case e.g by sorting
|
|
50
|
+
const backwardsHiddenCells = [];
|
|
51
|
+
if (index === rangeToProcess.firstRowIndex) {
|
|
52
|
+
let prevIndex = index - 1;
|
|
53
|
+
const prevRowEntry = visibleRows[prevIndex];
|
|
54
|
+
while (prevIndex >= range.firstRowIndex && getCellValue(prevRowEntry.model, colDef, apiRef) === cellValue) {
|
|
55
|
+
const currentRow = visibleRows[prevIndex + 1];
|
|
56
|
+
if (hiddenCells[currentRow.id]) {
|
|
57
|
+
hiddenCells[currentRow.id][colDef.field] = true;
|
|
58
|
+
} else {
|
|
59
|
+
hiddenCells[currentRow.id] = {
|
|
60
|
+
[colDef.field]: true
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
backwardsHiddenCells.push(index);
|
|
64
|
+
rowSpan += 1;
|
|
65
|
+
spannedRowId = prevRowEntry.id;
|
|
66
|
+
spannedRowIndex = prevIndex;
|
|
67
|
+
prevIndex -= 1;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
backwardsHiddenCells.forEach(hiddenCellIndex => {
|
|
71
|
+
if (hiddenCellOriginMap[hiddenCellIndex]) {
|
|
72
|
+
hiddenCellOriginMap[hiddenCellIndex][colDef.field] = spannedRowIndex;
|
|
73
|
+
} else {
|
|
74
|
+
hiddenCellOriginMap[hiddenCellIndex] = {
|
|
75
|
+
[colDef.field]: spannedRowIndex
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Scan the next rows
|
|
81
|
+
let relativeIndex = index + 1;
|
|
82
|
+
while (relativeIndex <= range.lastRowIndex && visibleRows[relativeIndex] && getCellValue(visibleRows[relativeIndex].model, colDef, apiRef) === cellValue) {
|
|
83
|
+
const currentRow = visibleRows[relativeIndex];
|
|
84
|
+
if (hiddenCells[currentRow.id]) {
|
|
85
|
+
hiddenCells[currentRow.id][colDef.field] = true;
|
|
86
|
+
} else {
|
|
87
|
+
hiddenCells[currentRow.id] = {
|
|
88
|
+
[colDef.field]: true
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
if (hiddenCellOriginMap[relativeIndex]) {
|
|
92
|
+
hiddenCellOriginMap[relativeIndex][colDef.field] = spannedRowIndex;
|
|
93
|
+
} else {
|
|
94
|
+
hiddenCellOriginMap[relativeIndex] = {
|
|
95
|
+
[colDef.field]: spannedRowIndex
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
relativeIndex += 1;
|
|
99
|
+
rowSpan += 1;
|
|
100
|
+
}
|
|
101
|
+
if (rowSpan > 0) {
|
|
102
|
+
if (spannedCells[spannedRowId]) {
|
|
103
|
+
spannedCells[spannedRowId][colDef.field] = rowSpan + 1;
|
|
104
|
+
} else {
|
|
105
|
+
spannedCells[spannedRowId] = {
|
|
106
|
+
[colDef.field]: rowSpan + 1
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
processedRange = {
|
|
112
|
+
firstRowIndex: Math.min(processedRange.firstRowIndex, rangeToProcess.firstRowIndex),
|
|
113
|
+
lastRowIndex: Math.max(processedRange.lastRowIndex, rangeToProcess.lastRowIndex)
|
|
114
|
+
};
|
|
115
|
+
});
|
|
116
|
+
return {
|
|
117
|
+
spannedCells,
|
|
118
|
+
hiddenCells,
|
|
119
|
+
hiddenCellOriginMap,
|
|
120
|
+
processedRange
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* @requires columnsStateInitializer (method) - should be initialized before
|
|
126
|
+
* @requires rowsStateInitializer (method) - should be initialized before
|
|
127
|
+
* @requires filterStateInitializer (method) - should be initialized before
|
|
128
|
+
*/
|
|
129
|
+
export const rowSpanningStateInitializer = (state, props, apiRef) => {
|
|
130
|
+
if (props.unstable_rowSpanning) {
|
|
131
|
+
const rowIds = state.rows.dataRowIds || [];
|
|
132
|
+
const orderedFields = state.columns.orderedFields || [];
|
|
133
|
+
const dataRowIdToModelLookup = state.rows.dataRowIdToModelLookup;
|
|
134
|
+
const columnsLookup = state.columns.lookup;
|
|
135
|
+
const isFilteringPending = Boolean(state.filter.filterModel.items.length) || Boolean(state.filter.filterModel.quickFilterValues?.length);
|
|
136
|
+
if (!rowIds.length || !orderedFields.length || !dataRowIdToModelLookup || !columnsLookup || isFilteringPending) {
|
|
137
|
+
return _extends({}, state, {
|
|
138
|
+
rowSpanning: EMPTY_STATE
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
const rangeToProcess = {
|
|
142
|
+
firstRowIndex: 0,
|
|
143
|
+
lastRowIndex: Math.min(DEFAULT_ROWS_TO_PROCESS - 1, Math.max(rowIds.length - 1, 0))
|
|
144
|
+
};
|
|
145
|
+
const rows = rowIds.map(id => ({
|
|
146
|
+
id,
|
|
147
|
+
model: dataRowIdToModelLookup[id]
|
|
148
|
+
}));
|
|
149
|
+
const colDefs = orderedFields.map(field => columnsLookup[field]);
|
|
150
|
+
const {
|
|
151
|
+
spannedCells,
|
|
152
|
+
hiddenCells,
|
|
153
|
+
hiddenCellOriginMap
|
|
154
|
+
} = computeRowSpanningState(apiRef, colDefs, rows, rangeToProcess, rangeToProcess, true, EMPTY_RANGE);
|
|
155
|
+
return _extends({}, state, {
|
|
156
|
+
rowSpanning: {
|
|
157
|
+
spannedCells,
|
|
158
|
+
hiddenCells,
|
|
159
|
+
hiddenCellOriginMap
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
return _extends({}, state, {
|
|
164
|
+
rowSpanning: EMPTY_STATE
|
|
165
|
+
});
|
|
166
|
+
};
|
|
167
|
+
export const useGridRowSpanning = (apiRef, props) => {
|
|
168
|
+
const {
|
|
169
|
+
range,
|
|
170
|
+
rows: visibleRows
|
|
171
|
+
} = useGridVisibleRows(apiRef, props);
|
|
172
|
+
const renderContext = useGridSelector(apiRef, gridRenderContextSelector);
|
|
173
|
+
const colDefs = useGridSelector(apiRef, gridVisibleColumnDefinitionsSelector);
|
|
174
|
+
const processedRange = useLazyRef(() => {
|
|
175
|
+
return Object.keys(apiRef.current.state.rowSpanning.spannedCells).length > 0 ? {
|
|
176
|
+
firstRowIndex: 0,
|
|
177
|
+
lastRowIndex: Math.min(DEFAULT_ROWS_TO_PROCESS - 1, Math.max(apiRef.current.state.rows.dataRowIds.length - 1, 0))
|
|
178
|
+
} : EMPTY_RANGE;
|
|
179
|
+
});
|
|
180
|
+
const lastRange = React.useRef(EMPTY_RANGE);
|
|
181
|
+
const updateRowSpanningState = React.useCallback(
|
|
182
|
+
// A reset needs to occur when:
|
|
183
|
+
// - The `unstable_rowSpanning` prop is updated (feature flag)
|
|
184
|
+
// - The filtering is applied
|
|
185
|
+
// - The sorting is applied
|
|
186
|
+
// - The `paginationModel` is updated
|
|
187
|
+
// - The rows are updated
|
|
188
|
+
(resetState = true) => {
|
|
189
|
+
if (!props.unstable_rowSpanning) {
|
|
190
|
+
if (apiRef.current.state.rowSpanning !== EMPTY_STATE) {
|
|
191
|
+
apiRef.current.setState(state => _extends({}, state, {
|
|
192
|
+
rowSpanning: EMPTY_STATE
|
|
193
|
+
}));
|
|
194
|
+
}
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
if (range === null || !isRowContextInitialized(renderContext)) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
if (resetState) {
|
|
201
|
+
processedRange.current = EMPTY_RANGE;
|
|
202
|
+
}
|
|
203
|
+
const rangeToProcess = getUnprocessedRange({
|
|
204
|
+
firstRowIndex: renderContext.firstRowIndex,
|
|
205
|
+
lastRowIndex: renderContext.lastRowIndex - 1
|
|
206
|
+
}, processedRange.current);
|
|
207
|
+
if (rangeToProcess === null) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const {
|
|
211
|
+
spannedCells,
|
|
212
|
+
hiddenCells,
|
|
213
|
+
hiddenCellOriginMap,
|
|
214
|
+
processedRange: newProcessedRange
|
|
215
|
+
} = computeRowSpanningState(apiRef, colDefs, visibleRows, range, rangeToProcess, resetState, processedRange.current);
|
|
216
|
+
processedRange.current = newProcessedRange;
|
|
217
|
+
const newSpannedCellsCount = Object.keys(spannedCells).length;
|
|
218
|
+
const newHiddenCellsCount = Object.keys(hiddenCells).length;
|
|
219
|
+
const currentSpannedCellsCount = Object.keys(apiRef.current.state.rowSpanning.spannedCells).length;
|
|
220
|
+
const currentHiddenCellsCount = Object.keys(apiRef.current.state.rowSpanning.hiddenCells).length;
|
|
221
|
+
const shouldUpdateState = resetState || newSpannedCellsCount !== currentSpannedCellsCount || newHiddenCellsCount !== currentHiddenCellsCount;
|
|
222
|
+
if (!shouldUpdateState) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
apiRef.current.setState(state => {
|
|
226
|
+
return _extends({}, state, {
|
|
227
|
+
rowSpanning: {
|
|
228
|
+
spannedCells,
|
|
229
|
+
hiddenCells,
|
|
230
|
+
hiddenCellOriginMap
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
}, [apiRef, props.unstable_rowSpanning, range, renderContext, visibleRows, colDefs, processedRange]);
|
|
235
|
+
const prevRenderContext = React.useRef(renderContext);
|
|
236
|
+
const isFirstRender = React.useRef(true);
|
|
237
|
+
const shouldResetState = React.useRef(false);
|
|
238
|
+
React.useEffect(() => {
|
|
239
|
+
const firstRender = isFirstRender.current;
|
|
240
|
+
if (isFirstRender.current) {
|
|
241
|
+
isFirstRender.current = false;
|
|
242
|
+
}
|
|
243
|
+
if (range && lastRange.current && isRowRangeUpdated(range, lastRange.current)) {
|
|
244
|
+
lastRange.current = range;
|
|
245
|
+
shouldResetState.current = true;
|
|
246
|
+
}
|
|
247
|
+
if (!firstRender && prevRenderContext.current !== renderContext) {
|
|
248
|
+
if (isRowRangeUpdated(prevRenderContext.current, renderContext)) {
|
|
249
|
+
updateRowSpanningState(shouldResetState.current);
|
|
250
|
+
shouldResetState.current = false;
|
|
251
|
+
}
|
|
252
|
+
prevRenderContext.current = renderContext;
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
updateRowSpanningState();
|
|
256
|
+
}, [updateRowSpanningState, renderContext, range, lastRange]);
|
|
257
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
|
-
import { warnOnce } from
|
|
2
|
+
import { warnOnce } from '@mui/x-internals/warning';
|
|
3
3
|
export const sanitizeSortModel = (model, disableMultipleColumnsSorting) => {
|
|
4
4
|
if (disableMultipleColumnsSorting && model.length > 1) {
|
|
5
5
|
if (process.env.NODE_ENV !== 'production') {
|
|
@@ -24,6 +24,7 @@ import { getFirstNonSpannedColumnToRender } from "../columns/gridColumnsUtils.js
|
|
|
24
24
|
import { getMinimalContentHeight } from "../rows/gridRowsUtils.js";
|
|
25
25
|
import { gridRenderContextSelector, gridVirtualizationRowEnabledSelector, gridVirtualizationColumnEnabledSelector } from "./gridVirtualizationSelectors.js";
|
|
26
26
|
import { EMPTY_RENDER_CONTEXT } from "./useGridVirtualization.js";
|
|
27
|
+
import { gridRowSpanningHiddenCellsOriginMapSelector } from "../rows/gridRowSpanningSelectors.js";
|
|
27
28
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
28
29
|
const MINIMUM_COLUMN_WIDTH = 50;
|
|
29
30
|
var ScrollDirection = /*#__PURE__*/function (ScrollDirection) {
|
|
@@ -325,7 +326,7 @@ export const useGridVirtualScroller = () => {
|
|
|
325
326
|
if (!isPinnedSection && frozenContext.current && rowIndexInPage >= frozenContext.current.firstRowIndex && rowIndexInPage < frozenContext.current.lastRowIndex) {
|
|
326
327
|
currentRenderContext = frozenContext.current;
|
|
327
328
|
}
|
|
328
|
-
const offsetLeft = computeOffsetLeft(columnPositions, currentRenderContext,
|
|
329
|
+
const offsetLeft = computeOffsetLeft(columnPositions, currentRenderContext, pinnedColumns.left.length);
|
|
329
330
|
const showBottomBorder = isLastVisibleInSection && params.position === 'top';
|
|
330
331
|
rows.push(/*#__PURE__*/_jsx(rootProps.slots.row, _extends({
|
|
331
332
|
row: model,
|
|
@@ -353,7 +354,7 @@ export const useGridVirtualScroller = () => {
|
|
|
353
354
|
if (panel) {
|
|
354
355
|
rows.push(panel);
|
|
355
356
|
}
|
|
356
|
-
if (
|
|
357
|
+
if (params.position === undefined && isLastVisibleInSection) {
|
|
357
358
|
rows.push(apiRef.current.getInfiniteLoadingTriggerElement?.({
|
|
358
359
|
lastRowId: id
|
|
359
360
|
}));
|
|
@@ -447,6 +448,7 @@ function inputsSelector(apiRef, rootProps, enabledForRows, enabledForColumns) {
|
|
|
447
448
|
const dimensions = gridDimensionsSelector(apiRef.current.state);
|
|
448
449
|
const currentPage = getVisibleRows(apiRef, rootProps);
|
|
449
450
|
const visibleColumns = gridVisibleColumnDefinitionsSelector(apiRef);
|
|
451
|
+
const hiddenCellsOriginMap = gridRowSpanningHiddenCellsOriginMapSelector(apiRef);
|
|
450
452
|
const lastRowId = apiRef.current.state.rows.dataRowIds.at(-1);
|
|
451
453
|
const lastColumn = visibleColumns.at(-1);
|
|
452
454
|
return {
|
|
@@ -467,7 +469,8 @@ function inputsSelector(apiRef, rootProps, enabledForRows, enabledForColumns) {
|
|
|
467
469
|
rows: currentPage.rows,
|
|
468
470
|
range: currentPage.range,
|
|
469
471
|
pinnedColumns: gridVisiblePinnedColumnDefinitionsSelector(apiRef),
|
|
470
|
-
visibleColumns
|
|
472
|
+
visibleColumns,
|
|
473
|
+
hiddenCellsOriginMap
|
|
471
474
|
};
|
|
472
475
|
}
|
|
473
476
|
function computeRenderContext(inputs, scrollPosition, scrollCache) {
|
|
@@ -485,10 +488,18 @@ function computeRenderContext(inputs, scrollPosition, scrollCache) {
|
|
|
485
488
|
if (inputs.enabledForRows) {
|
|
486
489
|
// Clamp the value because the search may return an index out of bounds.
|
|
487
490
|
// In the last index, this is not needed because Array.slice doesn't include it.
|
|
488
|
-
|
|
491
|
+
let firstRowIndex = Math.min(getNearestIndexToRender(inputs, top, {
|
|
489
492
|
atStart: true,
|
|
490
493
|
lastPosition: inputs.rowsMeta.positions[inputs.rowsMeta.positions.length - 1] + inputs.lastRowHeight
|
|
491
494
|
}), inputs.rowsMeta.positions.length - 1);
|
|
495
|
+
|
|
496
|
+
// If any of the cells in the `firstRowIndex` is hidden due to an extended row span,
|
|
497
|
+
// Make sure the row from where the rowSpan is originated is visible.
|
|
498
|
+
const rowSpanHiddenCellOrigin = inputs.hiddenCellsOriginMap[firstRowIndex];
|
|
499
|
+
if (rowSpanHiddenCellOrigin) {
|
|
500
|
+
const minSpannedRowIndex = Math.min(...Object.values(rowSpanHiddenCellOrigin));
|
|
501
|
+
firstRowIndex = Math.min(firstRowIndex, minSpannedRowIndex);
|
|
502
|
+
}
|
|
492
503
|
const lastRowIndex = inputs.autoHeight ? firstRowIndex + inputs.rows.length : getNearestIndexToRender(inputs, top + inputs.viewportInnerHeight);
|
|
493
504
|
renderContext.firstRowIndex = firstRowIndex;
|
|
494
505
|
renderContext.lastRowIndex = lastRowIndex;
|
|
@@ -642,9 +653,8 @@ export function areRenderContextsEqual(context1, context2) {
|
|
|
642
653
|
}
|
|
643
654
|
return context1.firstRowIndex === context2.firstRowIndex && context1.lastRowIndex === context2.lastRowIndex && context1.firstColumnIndex === context2.firstColumnIndex && context1.lastColumnIndex === context2.lastColumnIndex;
|
|
644
655
|
}
|
|
645
|
-
export function computeOffsetLeft(columnPositions, renderContext,
|
|
646
|
-
const
|
|
647
|
-
const left = factor * (columnPositions[renderContext.firstColumnIndex] ?? 0) - (columnPositions[pinnedLeftLength] ?? 0);
|
|
656
|
+
export function computeOffsetLeft(columnPositions, renderContext, pinnedLeftLength) {
|
|
657
|
+
const left = (columnPositions[renderContext.firstColumnIndex] ?? 0) - (columnPositions[pinnedLeftLength] ?? 0);
|
|
648
658
|
return Math.abs(left);
|
|
649
659
|
}
|
|
650
660
|
function directionForDelta(dx, dy) {
|
|
@@ -90,7 +90,6 @@ const optionsSubscriberOptions = {
|
|
|
90
90
|
isFirst: true
|
|
91
91
|
};
|
|
92
92
|
export function useGridApiOptionHandler(apiRef, eventName, handler) {
|
|
93
|
-
// Validate that only one per event name?
|
|
94
93
|
useGridApiEventHandler(apiRef, eventName, handler, optionsSubscriberOptions);
|
|
95
94
|
}
|
|
96
95
|
export { GridSignature };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { fastObjectShallowCompare } from '@mui/x-internals/fastObjectShallowCompare';
|
|
3
|
+
import { warnOnce } from '@mui/x-internals/warning';
|
|
3
4
|
import { useLazyRef } from "./useLazyRef.js";
|
|
4
5
|
import { useOnMount } from "./useOnMount.js";
|
|
5
|
-
import { warnOnce } from "../../internals/utils/warning.js";
|
|
6
6
|
function isOutputSelector(selector) {
|
|
7
7
|
return selector.acceptsApiRef;
|
|
8
8
|
}
|
package/modern/index.js
CHANGED
|
@@ -32,6 +32,7 @@ export { useGridPreferencesPanel, preferencePanelStateInitializer } from "../hoo
|
|
|
32
32
|
export { useGridEditing, editingStateInitializer } from "../hooks/features/editing/useGridEditing.js";
|
|
33
33
|
export { gridEditRowsStateSelector } from "../hooks/features/editing/gridEditingSelectors.js";
|
|
34
34
|
export { useGridRows, rowsStateInitializer } from "../hooks/features/rows/useGridRows.js";
|
|
35
|
+
export { useGridRowSpanning, rowSpanningStateInitializer } from "../hooks/features/rows/useGridRowSpanning.js";
|
|
35
36
|
export { useGridAriaAttributes } from "../hooks/utils/useGridAriaAttributes.js";
|
|
36
37
|
export { useGridRowAriaAttributes } from "../hooks/features/rows/useGridRowAriaAttributes.js";
|
|
37
38
|
export { useGridRowsPreProcessors } from "../hooks/features/rows/useGridRowsPreProcessors.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { warnOnce } from
|
|
1
|
+
import { warnOnce } from '@mui/x-internals/warning';
|
|
2
2
|
import { isNumber } from "../../utils/utils.js";
|
|
3
3
|
import { GridSignature } from "../../hooks/utils/useGridApiEventHandler.js";
|
|
4
4
|
export const propValidatorsDataGrid = [props => props.autoPageSize && props.autoHeight && ['MUI X: `<DataGrid autoPageSize={true} autoHeight={true} />` are not valid props.', 'You cannot use both the `autoPageSize` and `autoHeight` props at the same time because `autoHeight` scales the height of the Data Grid according to the `pageSize`.', '', 'Please remove one of these two props.'].join('\n') || undefined, props => props.paginationMode === 'client' && props.paginationMeta != null && ['MUI X: Usage of the `paginationMeta` prop with client-side pagination (`paginationMode="client"`) has no effect.', '`paginationMeta` is only meant to be used with `paginationMode="server"`.'].join('\n') || undefined, props => props.signature === GridSignature.DataGrid && props.paginationMode === 'client' && isNumber(props.rowCount) && ['MUI X: Usage of the `rowCount` prop with client side pagination (`paginationMode="client"`) has no effect.', '`rowCount` is only meant to be used with `paginationMode="server"`.'].join('\n') || undefined, props => props.paginationMode === 'server' && props.rowCount == null && !props.unstable_dataSource && ["MUI X: The `rowCount` prop must be passed using `paginationMode='server'`", 'For more detail, see http://mui.com/components/data-grid/pagination/#index-based-pagination'].join('\n') || undefined];
|