@mui/x-data-grid 7.17.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 +98 -5
- package/DataGrid/DataGrid.js +11 -1
- package/DataGrid/useDataGridComponent.js +3 -0
- package/DataGrid/useDataGridProps.js +2 -1
- package/components/GridRow.js +1 -0
- package/components/cell/GridCell.js +30 -5
- package/hooks/features/columnHeaders/useGridColumnHeaders.d.ts +0 -1
- package/hooks/features/columnHeaders/useGridColumnHeaders.js +11 -11
- 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 +2 -18
- package/hooks/features/editing/useGridRowEditing.js +6 -1
- package/hooks/features/editing/utils.d.ts +2 -0
- package/hooks/features/editing/utils.js +15 -0
- package/hooks/features/export/useGridPrintExport.js +2 -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/virtualization/useGridVirtualScroller.d.ts +1 -1
- package/hooks/features/virtualization/useGridVirtualScroller.js +17 -7
- package/hooks/utils/useGridApiEventHandler.js +0 -1
- package/index.js +1 -1
- package/internals/index.d.ts +1 -0
- package/internals/index.js +1 -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/components/GridRow.js +1 -0
- package/modern/components/cell/GridCell.js +30 -5
- package/modern/hooks/features/columnHeaders/useGridColumnHeaders.js +11 -11
- 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 +2 -18
- package/modern/hooks/features/editing/useGridRowEditing.js +6 -1
- package/modern/hooks/features/editing/utils.js +15 -0
- package/modern/hooks/features/export/useGridPrintExport.js +2 -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/virtualization/useGridVirtualScroller.js +17 -7
- package/modern/hooks/utils/useGridApiEventHandler.js +0 -1
- package/modern/index.js +1 -1
- package/modern/internals/index.js +1 -0
- 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/components/GridRow.js +1 -0
- package/node/components/cell/GridCell.js +30 -5
- package/node/hooks/features/columnHeaders/useGridColumnHeaders.js +11 -11
- 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 +2 -18
- package/node/hooks/features/editing/useGridRowEditing.js +6 -1
- package/node/hooks/features/editing/utils.js +22 -0
- package/node/hooks/features/export/useGridPrintExport.js +2 -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/virtualization/useGridVirtualScroller.js +17 -7
- package/node/hooks/utils/useGridApiEventHandler.js +0 -1
- package/node/index.js +1 -1
- package/node/internals/index.js +15 -0
- package/node/utils/domUtils.js +12 -12
- package/package.json +3 -3
- package/utils/domUtils.d.ts +4 -4
- package/utils/domUtils.js +12 -12
|
@@ -5,6 +5,7 @@ import { GridHeaderFilteringState } from './gridHeaderFilteringModel';
|
|
|
5
5
|
import type { GridRowSelectionModel } from './gridRowSelectionModel';
|
|
6
6
|
import type { GridVisibleRowsLookupState } from '../hooks/features/filter/gridFilterState';
|
|
7
7
|
import type { GridColumnResizeState } from '../hooks/features/columnResize';
|
|
8
|
+
import type { GridRowSpanningState } from '../hooks/features/rows/useGridRowSpanning';
|
|
8
9
|
/**
|
|
9
10
|
* The state of `DataGrid`.
|
|
10
11
|
*/
|
|
@@ -30,6 +31,7 @@ export interface GridStateCommunity {
|
|
|
30
31
|
density: GridDensityState;
|
|
31
32
|
virtualization: GridVirtualizationState;
|
|
32
33
|
columnResize: GridColumnResizeState;
|
|
34
|
+
rowSpanning: GridRowSpanningState;
|
|
33
35
|
}
|
|
34
36
|
/**
|
|
35
37
|
* The initial state of `DataGrid`.
|
|
@@ -357,6 +357,11 @@ export interface DataGridPropsWithDefaultValues<R extends GridValidRowModel = an
|
|
|
357
357
|
* @default false
|
|
358
358
|
*/
|
|
359
359
|
disableAutosize: boolean;
|
|
360
|
+
/**
|
|
361
|
+
* If `true`, the Data Grid will auto span the cells over the rows having the same value.
|
|
362
|
+
* @default false
|
|
363
|
+
*/
|
|
364
|
+
unstable_rowSpanning: boolean;
|
|
360
365
|
}
|
|
361
366
|
/**
|
|
362
367
|
* The `DataGrid` props with no default value.
|
|
@@ -748,6 +753,11 @@ export interface DataGridPropsWithoutDefaultValue<R extends GridValidRowModel =
|
|
|
748
753
|
*/
|
|
749
754
|
onProcessRowUpdateError?: (error: any) => void;
|
|
750
755
|
columnGroupingModel?: GridColumnGroupingModel;
|
|
756
|
+
/**
|
|
757
|
+
* Sets the height in pixels of the column group headers in the Data Grid.
|
|
758
|
+
* Inherits the `columnHeaderHeight` value if not set.
|
|
759
|
+
*/
|
|
760
|
+
columnGroupHeaderHeight?: number;
|
|
751
761
|
/**
|
|
752
762
|
* Callback called when the data is copied to the clipboard.
|
|
753
763
|
* @param {string} data The data copied to the clipboard.
|
|
@@ -118,6 +118,11 @@ DataGridRaw.propTypes = {
|
|
|
118
118
|
* @default 150
|
|
119
119
|
*/
|
|
120
120
|
columnBufferPx: PropTypes.number,
|
|
121
|
+
/**
|
|
122
|
+
* Sets the height in pixels of the column group headers in the Data Grid.
|
|
123
|
+
* Inherits the `columnHeaderHeight` value if not set.
|
|
124
|
+
*/
|
|
125
|
+
columnGroupHeaderHeight: PropTypes.number,
|
|
121
126
|
columnGroupingModel: PropTypes.arrayOf(PropTypes.object),
|
|
122
127
|
/**
|
|
123
128
|
* Sets the height in pixel of the column headers in the Data Grid.
|
|
@@ -743,5 +748,10 @@ DataGridRaw.propTypes = {
|
|
|
743
748
|
/**
|
|
744
749
|
* The system prop that allows defining system overrides as well as additional CSS styles.
|
|
745
750
|
*/
|
|
746
|
-
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object])
|
|
751
|
+
sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
|
|
752
|
+
/**
|
|
753
|
+
* If `true`, the Data Grid will auto span the cells over the rows having the same value.
|
|
754
|
+
* @default false
|
|
755
|
+
*/
|
|
756
|
+
unstable_rowSpanning: PropTypes.bool
|
|
747
757
|
};
|
|
@@ -27,6 +27,7 @@ import { useGridColumnSpanning } from "../hooks/features/columns/useGridColumnSp
|
|
|
27
27
|
import { useGridColumnGrouping, columnGroupsStateInitializer } from "../hooks/features/columnGrouping/useGridColumnGrouping.js";
|
|
28
28
|
import { useGridVirtualization, virtualizationStateInitializer } from "../hooks/features/virtualization/index.js";
|
|
29
29
|
import { columnResizeStateInitializer, useGridColumnResize } from "../hooks/features/columnResize/useGridColumnResize.js";
|
|
30
|
+
import { rowSpanningStateInitializer, useGridRowSpanning } from "../hooks/features/rows/useGridRowSpanning.js";
|
|
30
31
|
export const useDataGridComponent = (inputApiRef, props) => {
|
|
31
32
|
const apiRef = useGridInitialization(inputApiRef, props);
|
|
32
33
|
|
|
@@ -48,6 +49,7 @@ export const useDataGridComponent = (inputApiRef, props) => {
|
|
|
48
49
|
useGridInitializeState(sortingStateInitializer, apiRef, props);
|
|
49
50
|
useGridInitializeState(preferencePanelStateInitializer, apiRef, props);
|
|
50
51
|
useGridInitializeState(filterStateInitializer, apiRef, props);
|
|
52
|
+
useGridInitializeState(rowSpanningStateInitializer, apiRef, props);
|
|
51
53
|
useGridInitializeState(densityStateInitializer, apiRef, props);
|
|
52
54
|
useGridInitializeState(columnResizeStateInitializer, apiRef, props);
|
|
53
55
|
useGridInitializeState(paginationStateInitializer, apiRef, props);
|
|
@@ -59,6 +61,7 @@ export const useDataGridComponent = (inputApiRef, props) => {
|
|
|
59
61
|
useGridRowSelection(apiRef, props);
|
|
60
62
|
useGridColumns(apiRef, props);
|
|
61
63
|
useGridRows(apiRef, props);
|
|
64
|
+
useGridRowSpanning(apiRef, props);
|
|
62
65
|
useGridParamsApi(apiRef);
|
|
63
66
|
useGridColumnSpanning(apiRef);
|
|
64
67
|
useGridColumnGrouping(apiRef, props);
|
|
@@ -73,7 +73,8 @@ export const DATA_GRID_PROPS_DEFAULT_VALUES = {
|
|
|
73
73
|
showColumnVerticalBorder: false,
|
|
74
74
|
sortingMode: 'client',
|
|
75
75
|
sortingOrder: ['asc', 'desc', null],
|
|
76
|
-
throttleRowsMs: 0
|
|
76
|
+
throttleRowsMs: 0,
|
|
77
|
+
unstable_rowSpanning: false
|
|
77
78
|
};
|
|
78
79
|
const defaultSlots = DATA_GRID_DEFAULT_SLOTS_COMPONENTS;
|
|
79
80
|
export const useDataGridProps = inProps => {
|
|
@@ -338,6 +338,7 @@ process.env.NODE_ENV !== "production" ? GridRow.propTypes = {
|
|
|
338
338
|
height: PropTypes.number.isRequired,
|
|
339
339
|
width: PropTypes.number.isRequired
|
|
340
340
|
}).isRequired,
|
|
341
|
+
groupHeaderHeight: PropTypes.number.isRequired,
|
|
341
342
|
hasScrollX: PropTypes.bool.isRequired,
|
|
342
343
|
hasScrollY: PropTypes.bool.isRequired,
|
|
343
344
|
headerFilterHeight: PropTypes.number.isRequired,
|
|
@@ -7,6 +7,7 @@ import PropTypes from 'prop-types';
|
|
|
7
7
|
import clsx from 'clsx';
|
|
8
8
|
import { unstable_useForkRef as useForkRef, unstable_composeClasses as composeClasses, unstable_ownerDocument as ownerDocument, unstable_capitalize as capitalize } from '@mui/utils';
|
|
9
9
|
import { fastMemo } from '@mui/x-internals/fastMemo';
|
|
10
|
+
import { useRtl } from '@mui/system/RtlProvider';
|
|
10
11
|
import { doesSupportPreventScroll } from "../../utils/doesSupportPreventScroll.js";
|
|
11
12
|
import { getDataGridUtilityClass, gridClasses } from "../../constants/gridClasses.js";
|
|
12
13
|
import { GridCellModes } from "../../models/index.js";
|
|
@@ -17,6 +18,7 @@ import { gridFocusCellSelector } from "../../hooks/features/focus/gridFocusState
|
|
|
17
18
|
import { MissingRowIdError } from "../../hooks/features/rows/useGridParamsApi.js";
|
|
18
19
|
import { shouldCellShowLeftBorder, shouldCellShowRightBorder } from "../../utils/cellBorderUtils.js";
|
|
19
20
|
import { GridPinnedColumnPosition } from "../../hooks/features/columns/gridColumnsInterfaces.js";
|
|
21
|
+
import { gridRowSpanningHiddenCellsSelector, gridRowSpanningSpannedCellsSelector } from "../../hooks/features/rows/gridRowSpanningSelectors.js";
|
|
20
22
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
21
23
|
export let PinnedPosition = /*#__PURE__*/function (PinnedPosition) {
|
|
22
24
|
PinnedPosition[PinnedPosition["NONE"] = 0] = "NONE";
|
|
@@ -106,6 +108,7 @@ const GridCell = /*#__PURE__*/React.forwardRef(function GridCell(props, ref) {
|
|
|
106
108
|
other = _objectWithoutPropertiesLoose(props, _excluded);
|
|
107
109
|
const apiRef = useGridApiContext();
|
|
108
110
|
const rootProps = useGridRootProps();
|
|
111
|
+
const isRtl = useRtl();
|
|
109
112
|
const field = column.field;
|
|
110
113
|
const cellParams = useGridSelector(apiRef, () => {
|
|
111
114
|
// This is required because `.getCellParams` tries to get the `state.rows.tree` entry
|
|
@@ -126,6 +129,8 @@ const GridCell = /*#__PURE__*/React.forwardRef(function GridCell(props, ref) {
|
|
|
126
129
|
id: rowId,
|
|
127
130
|
field
|
|
128
131
|
}));
|
|
132
|
+
const hiddenCells = useGridSelector(apiRef, gridRowSpanningHiddenCellsSelector);
|
|
133
|
+
const spannedCells = useGridSelector(apiRef, gridRowSpanningSpannedCellsSelector);
|
|
129
134
|
const {
|
|
130
135
|
cellMode,
|
|
131
136
|
hasFocus,
|
|
@@ -198,6 +203,8 @@ const GridCell = /*#__PURE__*/React.forwardRef(function GridCell(props, ref) {
|
|
|
198
203
|
propHandler(event);
|
|
199
204
|
}
|
|
200
205
|
}, [apiRef, field, rowId]);
|
|
206
|
+
const isCellRowSpanned = hiddenCells[rowId]?.[field] ?? false;
|
|
207
|
+
const rowSpan = spannedCells[rowId]?.[field] ?? 1;
|
|
201
208
|
const style = React.useMemo(() => {
|
|
202
209
|
if (isNotVisible) {
|
|
203
210
|
return {
|
|
@@ -210,14 +217,21 @@ const GridCell = /*#__PURE__*/React.forwardRef(function GridCell(props, ref) {
|
|
|
210
217
|
const cellStyle = _extends({
|
|
211
218
|
'--width': `${width}px`
|
|
212
219
|
}, styleProp);
|
|
213
|
-
|
|
214
|
-
|
|
220
|
+
const isLeftPinned = pinnedPosition === PinnedPosition.LEFT;
|
|
221
|
+
const isRightPinned = pinnedPosition === PinnedPosition.RIGHT;
|
|
222
|
+
if (isLeftPinned || isRightPinned) {
|
|
223
|
+
let side = isLeftPinned ? 'left' : 'right';
|
|
224
|
+
if (isRtl) {
|
|
225
|
+
side = isLeftPinned ? 'right' : 'left';
|
|
226
|
+
}
|
|
227
|
+
cellStyle[side] = pinnedOffset;
|
|
215
228
|
}
|
|
216
|
-
if (
|
|
217
|
-
cellStyle.
|
|
229
|
+
if (rowSpan > 1) {
|
|
230
|
+
cellStyle.height = `calc(var(--height) * ${rowSpan})`;
|
|
231
|
+
cellStyle.zIndex = 5;
|
|
218
232
|
}
|
|
219
233
|
return cellStyle;
|
|
220
|
-
}, [width, isNotVisible, styleProp, pinnedOffset, pinnedPosition]);
|
|
234
|
+
}, [width, isNotVisible, styleProp, pinnedOffset, pinnedPosition, isRtl, rowSpan]);
|
|
221
235
|
React.useEffect(() => {
|
|
222
236
|
if (!hasFocus || cellMode === GridCellModes.Edit) {
|
|
223
237
|
return;
|
|
@@ -237,6 +251,16 @@ const GridCell = /*#__PURE__*/React.forwardRef(function GridCell(props, ref) {
|
|
|
237
251
|
}
|
|
238
252
|
}
|
|
239
253
|
}, [hasFocus, cellMode, apiRef]);
|
|
254
|
+
if (isCellRowSpanned) {
|
|
255
|
+
return /*#__PURE__*/_jsx("div", {
|
|
256
|
+
"data-colindex": colIndex,
|
|
257
|
+
role: "presentation",
|
|
258
|
+
style: _extends({}, style, {
|
|
259
|
+
minWidth: 'var(--width)',
|
|
260
|
+
maxWidth: 'var(--width)'
|
|
261
|
+
})
|
|
262
|
+
});
|
|
263
|
+
}
|
|
240
264
|
if (cellParams === EMPTY_CELL_PARAMS) {
|
|
241
265
|
return null;
|
|
242
266
|
}
|
|
@@ -297,6 +321,7 @@ const GridCell = /*#__PURE__*/React.forwardRef(function GridCell(props, ref) {
|
|
|
297
321
|
"data-colindex": colIndex,
|
|
298
322
|
"aria-colindex": colIndex + 1,
|
|
299
323
|
"aria-colspan": colSpan,
|
|
324
|
+
"aria-rowspan": rowSpan,
|
|
300
325
|
style: style,
|
|
301
326
|
title: title,
|
|
302
327
|
tabIndex: tabIndex,
|
|
@@ -53,7 +53,7 @@ export const useGridColumnHeaders = props => {
|
|
|
53
53
|
const renderContext = useGridSelector(apiRef, gridRenderContextColumnsSelector);
|
|
54
54
|
const pinnedColumns = useGridSelector(apiRef, gridVisiblePinnedColumnDefinitionsSelector);
|
|
55
55
|
const columnsLookup = useGridSelector(apiRef, gridColumnLookupSelector);
|
|
56
|
-
const offsetLeft = computeOffsetLeft(columnPositions, renderContext,
|
|
56
|
+
const offsetLeft = computeOffsetLeft(columnPositions, renderContext, pinnedColumns.left.length);
|
|
57
57
|
const gridHasFiller = dimensions.columnsTotalWidth < dimensions.viewportOuterSize.width;
|
|
58
58
|
React.useEffect(() => {
|
|
59
59
|
apiRef.current.columnHeadersContainerRef.current.scrollLeft = 0;
|
|
@@ -83,7 +83,6 @@ export const useGridColumnHeaders = props => {
|
|
|
83
83
|
const getColumnsToRender = params => {
|
|
84
84
|
const {
|
|
85
85
|
renderContext: currentContext = renderContext,
|
|
86
|
-
// TODO: `minFirstColumn` is not used anymore, could be refactored out.
|
|
87
86
|
maxLastColumn = visibleColumns.length
|
|
88
87
|
} = params || {};
|
|
89
88
|
const firstColumnToRender = currentContext.firstColumnIndex;
|
|
@@ -123,16 +122,22 @@ export const useGridColumnHeaders = props => {
|
|
|
123
122
|
computedWidth
|
|
124
123
|
}) => {
|
|
125
124
|
let style;
|
|
126
|
-
|
|
125
|
+
const isLeftPinned = pinnedPosition === GridPinnedColumnPosition.LEFT;
|
|
126
|
+
const isRightPinned = pinnedPosition === GridPinnedColumnPosition.RIGHT;
|
|
127
|
+
if (isLeftPinned || isRightPinned) {
|
|
127
128
|
const pinnedOffset = getPinnedCellOffset(pinnedPosition, computedWidth, columnIndex, columnPositions, dimensions);
|
|
129
|
+
let side = isLeftPinned ? 'left' : 'right';
|
|
130
|
+
if (isRtl) {
|
|
131
|
+
side = isLeftPinned ? 'right' : 'left';
|
|
132
|
+
}
|
|
128
133
|
if (pinnedPosition === 'left') {
|
|
129
134
|
style = {
|
|
130
|
-
|
|
135
|
+
[side]: pinnedOffset
|
|
131
136
|
};
|
|
132
137
|
}
|
|
133
138
|
if (pinnedPosition === 'right') {
|
|
134
139
|
style = {
|
|
135
|
-
|
|
140
|
+
[side]: pinnedOffset
|
|
136
141
|
};
|
|
137
142
|
}
|
|
138
143
|
}
|
|
@@ -191,18 +196,15 @@ export const useGridColumnHeaders = props => {
|
|
|
191
196
|
children: [leftRenderContext && getColumnHeaders({
|
|
192
197
|
position: GridPinnedColumnPosition.LEFT,
|
|
193
198
|
renderContext: leftRenderContext,
|
|
194
|
-
minFirstColumn: leftRenderContext.firstColumnIndex,
|
|
195
199
|
maxLastColumn: leftRenderContext.lastColumnIndex
|
|
196
200
|
}, {
|
|
197
201
|
disableReorder: true
|
|
198
202
|
}), getColumnHeaders({
|
|
199
203
|
renderContext,
|
|
200
|
-
minFirstColumn: pinnedColumns.left.length,
|
|
201
204
|
maxLastColumn: visibleColumns.length - pinnedColumns.right.length
|
|
202
205
|
}), rightRenderContext && getColumnHeaders({
|
|
203
206
|
position: GridPinnedColumnPosition.RIGHT,
|
|
204
207
|
renderContext: rightRenderContext,
|
|
205
|
-
minFirstColumn: rightRenderContext.firstColumnIndex,
|
|
206
208
|
maxLastColumn: rightRenderContext.lastColumnIndex
|
|
207
209
|
}, {
|
|
208
210
|
disableReorder: true,
|
|
@@ -282,7 +284,7 @@ export const useGridColumnHeaders = props => {
|
|
|
282
284
|
depth: depth,
|
|
283
285
|
isLastColumn: headerInfo.colIndex === visibleColumns.length - headerInfo.fields.length,
|
|
284
286
|
maxDepth: headerGroupingMaxDepth,
|
|
285
|
-
height: dimensions.
|
|
287
|
+
height: dimensions.groupHeaderHeight,
|
|
286
288
|
hasFocus: hasFocus,
|
|
287
289
|
tabIndex: tabIndex,
|
|
288
290
|
pinnedPosition: pinnedPosition,
|
|
@@ -309,7 +311,6 @@ export const useGridColumnHeaders = props => {
|
|
|
309
311
|
params: {
|
|
310
312
|
position: GridPinnedColumnPosition.LEFT,
|
|
311
313
|
renderContext: leftRenderContext,
|
|
312
|
-
minFirstColumn: leftRenderContext.firstColumnIndex,
|
|
313
314
|
maxLastColumn: leftRenderContext.lastColumnIndex
|
|
314
315
|
}
|
|
315
316
|
}), getColumnGroupHeaders({
|
|
@@ -322,7 +323,6 @@ export const useGridColumnHeaders = props => {
|
|
|
322
323
|
params: {
|
|
323
324
|
position: GridPinnedColumnPosition.RIGHT,
|
|
324
325
|
renderContext: rightRenderContext,
|
|
325
|
-
minFirstColumn: rightRenderContext.firstColumnIndex,
|
|
326
326
|
maxLastColumn: rightRenderContext.lastColumnIndex
|
|
327
327
|
}
|
|
328
328
|
})]
|
|
@@ -302,13 +302,13 @@ export const useGridColumnResize = (apiRef, props) => {
|
|
|
302
302
|
}
|
|
303
303
|
refs.groupHeaderElements = findGroupHeaderElementsFromField(apiRef.current.columnHeadersContainerRef?.current, colDef.field);
|
|
304
304
|
refs.cellElements = findGridCellElementsFromCol(refs.columnHeaderElement, apiRef.current);
|
|
305
|
-
refs.fillerLeft = findGridElement(apiRef.current, 'filler--pinnedLeft');
|
|
306
|
-
refs.fillerRight = findGridElement(apiRef.current, 'filler--pinnedRight');
|
|
305
|
+
refs.fillerLeft = findGridElement(apiRef.current, isRtl ? 'filler--pinnedRight' : 'filler--pinnedLeft');
|
|
306
|
+
refs.fillerRight = findGridElement(apiRef.current, isRtl ? 'filler--pinnedLeft' : 'filler--pinnedRight');
|
|
307
307
|
const pinnedPosition = apiRef.current.unstable_applyPipeProcessors('isColumnPinned', false, refs.colDef.field);
|
|
308
|
-
refs.leftPinnedCellsAfter = pinnedPosition !== GridPinnedColumnPosition.LEFT ? [] : findLeftPinnedCellsAfterCol(apiRef.current, refs.columnHeaderElement);
|
|
309
|
-
refs.rightPinnedCellsBefore = pinnedPosition !== GridPinnedColumnPosition.RIGHT ? [] : findRightPinnedCellsBeforeCol(apiRef.current, refs.columnHeaderElement);
|
|
310
|
-
refs.leftPinnedHeadersAfter = pinnedPosition !== GridPinnedColumnPosition.LEFT ? [] : findLeftPinnedHeadersAfterCol(apiRef.current, refs.columnHeaderElement);
|
|
311
|
-
refs.rightPinnedHeadersBefore = pinnedPosition !== GridPinnedColumnPosition.RIGHT ? [] : findRightPinnedHeadersBeforeCol(apiRef.current, refs.columnHeaderElement);
|
|
308
|
+
refs.leftPinnedCellsAfter = pinnedPosition !== GridPinnedColumnPosition.LEFT ? [] : findLeftPinnedCellsAfterCol(apiRef.current, refs.columnHeaderElement, isRtl);
|
|
309
|
+
refs.rightPinnedCellsBefore = pinnedPosition !== GridPinnedColumnPosition.RIGHT ? [] : findRightPinnedCellsBeforeCol(apiRef.current, refs.columnHeaderElement, isRtl);
|
|
310
|
+
refs.leftPinnedHeadersAfter = pinnedPosition !== GridPinnedColumnPosition.LEFT ? [] : findLeftPinnedHeadersAfterCol(apiRef.current, refs.columnHeaderElement, isRtl);
|
|
311
|
+
refs.rightPinnedHeadersBefore = pinnedPosition !== GridPinnedColumnPosition.RIGHT ? [] : findRightPinnedHeadersBeforeCol(apiRef.current, refs.columnHeaderElement, isRtl);
|
|
312
312
|
resizeDirection.current = getResizeDirection(separator, isRtl);
|
|
313
313
|
initialOffsetToSeparator.current = computeOffsetToSeparator(xStart, refs.columnHeaderElement.getBoundingClientRect(), resizeDirection.current);
|
|
314
314
|
};
|
|
@@ -29,6 +29,7 @@ const EMPTY_DIMENSIONS = {
|
|
|
29
29
|
hasScrollY: false,
|
|
30
30
|
scrollbarSize: 0,
|
|
31
31
|
headerHeight: 0,
|
|
32
|
+
groupHeaderHeight: 0,
|
|
32
33
|
headerFilterHeight: 0,
|
|
33
34
|
rowWidth: 0,
|
|
34
35
|
rowHeight: 0,
|
|
@@ -55,6 +56,7 @@ export function useGridDimensions(apiRef, props) {
|
|
|
55
56
|
const densityFactor = useGridSelector(apiRef, gridDensityFactorSelector);
|
|
56
57
|
const rowHeight = Math.floor(props.rowHeight * densityFactor);
|
|
57
58
|
const headerHeight = Math.floor(props.columnHeaderHeight * densityFactor);
|
|
59
|
+
const groupHeaderHeight = Math.floor((props.columnGroupHeaderHeight ?? props.columnHeaderHeight) * densityFactor);
|
|
58
60
|
const headerFilterHeight = Math.floor((props.headerFilterHeight ?? props.columnHeaderHeight) * densityFactor);
|
|
59
61
|
const columnsTotalWidth = roundToDecimalPlaces(gridColumnsTotalWidthSelector(apiRef), 6);
|
|
60
62
|
const headersTotalHeight = getTotalHeaderHeight(apiRef, props);
|
|
@@ -175,6 +177,7 @@ export function useGridDimensions(apiRef, props) {
|
|
|
175
177
|
hasScrollY,
|
|
176
178
|
scrollbarSize,
|
|
177
179
|
headerHeight,
|
|
180
|
+
groupHeaderHeight,
|
|
178
181
|
headerFilterHeight,
|
|
179
182
|
rowWidth,
|
|
180
183
|
rowHeight,
|
|
@@ -191,7 +194,7 @@ export function useGridDimensions(apiRef, props) {
|
|
|
191
194
|
apiRef.current.publishEvent('viewportInnerSizeChange', newDimensions.viewportInnerSize);
|
|
192
195
|
}
|
|
193
196
|
apiRef.current.updateRenderContext?.();
|
|
194
|
-
}, [apiRef, setDimensions, props.scrollbarSize, props.autoHeight, rowsMeta.currentPageTotalHeight, rowHeight, headerHeight, headerFilterHeight, columnsTotalWidth, headersTotalHeight, leftPinnedWidth, rightPinnedWidth]);
|
|
197
|
+
}, [apiRef, setDimensions, props.scrollbarSize, props.autoHeight, rowsMeta.currentPageTotalHeight, rowHeight, headerHeight, groupHeaderHeight, headerFilterHeight, columnsTotalWidth, headersTotalHeight, leftPinnedWidth, rightPinnedWidth]);
|
|
195
198
|
const apiPublic = {
|
|
196
199
|
resize,
|
|
197
200
|
getRootDimensions
|
|
@@ -14,6 +14,7 @@ import { isPrintableKey, isPasteShortcut } from "../../../utils/keyboardUtils.js
|
|
|
14
14
|
import { gridRowsDataRowIdToIdLookupSelector } from "../rows/gridRowsSelector.js";
|
|
15
15
|
import { deepClone } from "../../../utils/utils.js";
|
|
16
16
|
import { GridCellEditStartReasons, GridCellEditStopReasons } from "../../../models/params/gridEditCellParams.js";
|
|
17
|
+
import { getDefaultCellValue } from "./utils.js";
|
|
17
18
|
export const useGridCellEditing = (apiRef, props) => {
|
|
18
19
|
const [cellModesModel, setCellModesModel] = React.useState({});
|
|
19
20
|
const cellModesModelRef = React.useRef(cellModesModel);
|
|
@@ -249,24 +250,7 @@ export const useGridCellEditing = (apiRef, props) => {
|
|
|
249
250
|
} = params;
|
|
250
251
|
let newValue = apiRef.current.getCellValue(id, field);
|
|
251
252
|
if (deleteValue) {
|
|
252
|
-
|
|
253
|
-
switch (fieldType) {
|
|
254
|
-
case 'boolean':
|
|
255
|
-
newValue = false;
|
|
256
|
-
break;
|
|
257
|
-
case 'date':
|
|
258
|
-
case 'dateTime':
|
|
259
|
-
case 'number':
|
|
260
|
-
newValue = undefined;
|
|
261
|
-
break;
|
|
262
|
-
case 'singleSelect':
|
|
263
|
-
newValue = null;
|
|
264
|
-
break;
|
|
265
|
-
case 'string':
|
|
266
|
-
default:
|
|
267
|
-
newValue = '';
|
|
268
|
-
break;
|
|
269
|
-
}
|
|
253
|
+
newValue = getDefaultCellValue(apiRef.current.getColumn(field));
|
|
270
254
|
} else if (initialValue) {
|
|
271
255
|
newValue = initialValue;
|
|
272
256
|
}
|
|
@@ -16,6 +16,7 @@ import { gridRowsDataRowIdToIdLookupSelector } from "../rows/gridRowsSelector.js
|
|
|
16
16
|
import { deepClone } from "../../../utils/utils.js";
|
|
17
17
|
import { GridRowEditStopReasons, GridRowEditStartReasons } from "../../../models/params/gridRowParams.js";
|
|
18
18
|
import { GRID_ACTIONS_COLUMN_TYPE } from "../../../colDef/index.js";
|
|
19
|
+
import { getDefaultCellValue } from "./utils.js";
|
|
19
20
|
export const useGridRowEditing = (apiRef, props) => {
|
|
20
21
|
const [rowModesModel, setRowModesModel] = React.useState({});
|
|
21
22
|
const rowModesModelRef = React.useRef(rowModesModel);
|
|
@@ -319,7 +320,11 @@ export const useGridRowEditing = (apiRef, props) => {
|
|
|
319
320
|
}
|
|
320
321
|
let newValue = apiRef.current.getCellValue(id, field);
|
|
321
322
|
if (fieldToFocus === field && (deleteValue || initialValue)) {
|
|
322
|
-
|
|
323
|
+
if (deleteValue) {
|
|
324
|
+
newValue = getDefaultCellValue(apiRef.current.getColumn(field));
|
|
325
|
+
} else if (initialValue) {
|
|
326
|
+
newValue = initialValue;
|
|
327
|
+
}
|
|
323
328
|
}
|
|
324
329
|
acc[field] = {
|
|
325
330
|
value: newValue,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const getDefaultCellValue = colDef => {
|
|
2
|
+
switch (colDef.type) {
|
|
3
|
+
case 'boolean':
|
|
4
|
+
return false;
|
|
5
|
+
case 'date':
|
|
6
|
+
case 'dateTime':
|
|
7
|
+
case 'number':
|
|
8
|
+
return undefined;
|
|
9
|
+
case 'singleSelect':
|
|
10
|
+
return null;
|
|
11
|
+
case 'string':
|
|
12
|
+
default:
|
|
13
|
+
return '';
|
|
14
|
+
}
|
|
15
|
+
};
|
|
@@ -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
|
|
@@ -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);
|