@mui/x-data-grid 6.0.0-beta.2 → 6.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +93 -0
- package/components/GridRow.js +2 -6
- package/components/cell/GridActionsCell.js +24 -13
- package/components/cell/GridActionsCellItem.js +6 -3
- package/components/columnHeaders/ColumnHeaderMenuIcon.js +5 -4
- package/components/columnHeaders/GridColumnHeaderFilterIconButton.js +6 -6
- package/components/columnHeaders/GridColumnHeaderSortIcon.js +5 -4
- package/components/panel/filterPanel/GridFilterForm.js +8 -8
- package/components/toolbar/GridToolbarFilterButton.js +10 -7
- package/components/toolbar/GridToolbarQuickFilter.js +6 -6
- package/constants/defaultGridSlotsComponents.js +2 -0
- package/hooks/features/columnHeaders/useGridColumnHeaders.js +5 -3
- package/hooks/features/editing/useGridCellEditing.js +4 -1
- package/hooks/features/editing/useGridEditing.js +1 -1
- package/hooks/features/editing/useGridRowEditing.js +3 -0
- package/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +71 -10
- package/hooks/features/scroll/useGridScroll.js +7 -3
- package/hooks/features/virtualization/useGridVirtualScroller.js +20 -7
- package/index.js +1 -1
- package/legacy/components/GridRow.js +2 -6
- package/legacy/components/cell/GridActionsCell.js +28 -17
- package/legacy/components/cell/GridActionsCellItem.js +6 -3
- package/legacy/components/columnHeaders/ColumnHeaderMenuIcon.js +5 -4
- package/legacy/components/columnHeaders/GridColumnHeaderFilterIconButton.js +6 -6
- package/legacy/components/columnHeaders/GridColumnHeaderSortIcon.js +5 -4
- package/legacy/components/panel/filterPanel/GridFilterForm.js +8 -8
- package/legacy/components/toolbar/GridToolbarFilterButton.js +8 -2
- package/legacy/components/toolbar/GridToolbarQuickFilter.js +6 -6
- package/legacy/constants/defaultGridSlotsComponents.js +2 -0
- package/legacy/hooks/features/columnHeaders/useGridColumnHeaders.js +5 -3
- package/legacy/hooks/features/editing/useGridCellEditing.js +4 -1
- package/legacy/hooks/features/editing/useGridEditing.js +1 -1
- package/legacy/hooks/features/editing/useGridRowEditing.js +3 -0
- package/legacy/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +69 -10
- package/legacy/hooks/features/scroll/useGridScroll.js +7 -3
- package/legacy/hooks/features/virtualization/useGridVirtualScroller.js +20 -7
- package/legacy/index.js +1 -1
- package/legacy/utils/domUtils.js +8 -6
- package/models/api/gridEditingApi.d.ts +2 -2
- package/models/gridFilterOperator.d.ts +6 -0
- package/models/gridSlotsComponent.d.ts +5 -0
- package/models/gridSlotsComponentsProps.d.ts +1 -0
- package/modern/components/GridRow.js +2 -6
- package/modern/components/cell/GridActionsCell.js +23 -13
- package/modern/components/cell/GridActionsCellItem.js +5 -3
- package/modern/components/columnHeaders/ColumnHeaderMenuIcon.js +4 -4
- package/modern/components/columnHeaders/GridColumnHeaderFilterIconButton.js +4 -4
- package/modern/components/columnHeaders/GridColumnHeaderSortIcon.js +4 -4
- package/modern/components/panel/filterPanel/GridFilterForm.js +4 -4
- package/modern/components/toolbar/GridToolbarFilterButton.js +7 -1
- package/modern/components/toolbar/GridToolbarQuickFilter.js +4 -4
- package/modern/constants/defaultGridSlotsComponents.js +2 -0
- package/modern/hooks/features/columnHeaders/useGridColumnHeaders.js +5 -3
- package/modern/hooks/features/editing/useGridCellEditing.js +4 -1
- package/modern/hooks/features/editing/useGridEditing.js +1 -1
- package/modern/hooks/features/editing/useGridRowEditing.js +3 -0
- package/modern/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +71 -10
- package/modern/hooks/features/scroll/useGridScroll.js +7 -3
- package/modern/hooks/features/virtualization/useGridVirtualScroller.js +20 -7
- package/modern/index.js +1 -1
- package/modern/utils/domUtils.js +8 -6
- package/node/components/GridRow.js +2 -6
- package/node/components/cell/GridActionsCell.js +23 -13
- package/node/components/cell/GridActionsCellItem.js +5 -3
- package/node/components/columnHeaders/ColumnHeaderMenuIcon.js +4 -4
- package/node/components/columnHeaders/GridColumnHeaderFilterIconButton.js +4 -4
- package/node/components/columnHeaders/GridColumnHeaderSortIcon.js +4 -4
- package/node/components/panel/filterPanel/GridFilterForm.js +4 -4
- package/node/components/toolbar/GridToolbarFilterButton.js +7 -1
- package/node/components/toolbar/GridToolbarQuickFilter.js +4 -4
- package/node/constants/defaultGridSlotsComponents.js +2 -0
- package/node/hooks/features/columnHeaders/useGridColumnHeaders.js +4 -2
- package/node/hooks/features/editing/useGridCellEditing.js +4 -1
- package/node/hooks/features/editing/useGridEditing.js +1 -1
- package/node/hooks/features/editing/useGridRowEditing.js +3 -0
- package/node/hooks/features/keyboardNavigation/useGridKeyboardNavigation.js +71 -10
- package/node/hooks/features/scroll/useGridScroll.js +7 -3
- package/node/hooks/features/virtualization/useGridVirtualScroller.js +20 -7
- package/node/index.js +1 -1
- package/node/utils/domUtils.js +8 -6
- package/package.json +3 -3
- package/utils/domUtils.js +8 -6
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { unstable_composeClasses as composeClasses } from '@mui/utils';
|
|
4
|
-
import IconButton from '@mui/material/IconButton';
|
|
5
4
|
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
|
|
6
5
|
import { getDataGridUtilityClass } from '../../constants/gridClasses';
|
|
7
6
|
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
|
|
@@ -38,7 +37,7 @@ export const ColumnHeaderMenuIcon = /*#__PURE__*/React.memo(props => {
|
|
|
38
37
|
}, [apiRef, colDef.field]);
|
|
39
38
|
return /*#__PURE__*/_jsx("div", {
|
|
40
39
|
className: classes.root,
|
|
41
|
-
children: /*#__PURE__*/_jsx(
|
|
40
|
+
children: /*#__PURE__*/_jsx(rootProps.components.BaseIconButton, _extends({
|
|
42
41
|
ref: iconButtonRef,
|
|
43
42
|
tabIndex: -1,
|
|
44
43
|
className: classes.button,
|
|
@@ -49,10 +48,11 @@ export const ColumnHeaderMenuIcon = /*#__PURE__*/React.memo(props => {
|
|
|
49
48
|
"aria-expanded": open ? 'true' : undefined,
|
|
50
49
|
"aria-haspopup": "true",
|
|
51
50
|
"aria-controls": columnMenuId,
|
|
52
|
-
id: columnMenuButtonId
|
|
51
|
+
id: columnMenuButtonId
|
|
52
|
+
}, rootProps.componentsProps?.baseIconButton, {
|
|
53
53
|
children: /*#__PURE__*/_jsx(rootProps.components.ColumnMenuIcon, {
|
|
54
54
|
fontSize: "small"
|
|
55
55
|
})
|
|
56
|
-
})
|
|
56
|
+
}))
|
|
57
57
|
});
|
|
58
58
|
});
|
|
@@ -2,7 +2,6 @@ import _extends from "@babel/runtime/helpers/esm/extends";
|
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import { unstable_composeClasses as composeClasses } from '@mui/utils';
|
|
5
|
-
import IconButton from '@mui/material/IconButton';
|
|
6
5
|
import Badge from '@mui/material/Badge';
|
|
7
6
|
import { gridPreferencePanelStateSelector } from '../../hooks/features/preferencesPanel/gridPreferencePanelSelector';
|
|
8
7
|
import { GridPreferencePanelsValue } from '../../hooks/features/preferencesPanel/gridPreferencePanelsValue';
|
|
@@ -52,17 +51,18 @@ function GridColumnHeaderFilterIconButton(props) {
|
|
|
52
51
|
if (!counter) {
|
|
53
52
|
return null;
|
|
54
53
|
}
|
|
55
|
-
const iconButton = /*#__PURE__*/_jsx(
|
|
54
|
+
const iconButton = /*#__PURE__*/_jsx(rootProps.components.BaseIconButton, _extends({
|
|
56
55
|
onClick: toggleFilter,
|
|
57
56
|
color: "default",
|
|
58
57
|
"aria-label": apiRef.current.getLocaleText('columnHeaderFiltersLabel'),
|
|
59
58
|
size: "small",
|
|
60
|
-
tabIndex: -1
|
|
59
|
+
tabIndex: -1
|
|
60
|
+
}, rootProps.componentsProps?.baseIconButton, {
|
|
61
61
|
children: /*#__PURE__*/_jsx(rootProps.components.ColumnFilteredIcon, {
|
|
62
62
|
className: classes.icon,
|
|
63
63
|
fontSize: "small"
|
|
64
64
|
})
|
|
65
|
-
});
|
|
65
|
+
}));
|
|
66
66
|
return /*#__PURE__*/_jsx(rootProps.components.BaseTooltip, _extends({
|
|
67
67
|
title: apiRef.current.getLocaleText('columnHeaderFiltersTooltipActive')(counter),
|
|
68
68
|
enterDelay: 1000
|
|
@@ -3,7 +3,6 @@ import * as React from 'react';
|
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import { unstable_composeClasses as composeClasses } from '@mui/utils';
|
|
5
5
|
import Badge from '@mui/material/Badge';
|
|
6
|
-
import IconButton from '@mui/material/IconButton';
|
|
7
6
|
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
|
|
8
7
|
import { getDataGridUtilityClass } from '../../constants/gridClasses';
|
|
9
8
|
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
|
|
@@ -51,13 +50,14 @@ function GridColumnHeaderSortIconRaw(props) {
|
|
|
51
50
|
if (!iconElement) {
|
|
52
51
|
return null;
|
|
53
52
|
}
|
|
54
|
-
const iconButton = /*#__PURE__*/_jsx(
|
|
53
|
+
const iconButton = /*#__PURE__*/_jsx(rootProps.components.BaseIconButton, _extends({
|
|
55
54
|
tabIndex: -1,
|
|
56
55
|
"aria-label": apiRef.current.getLocaleText('columnHeaderSortIconLabel'),
|
|
57
56
|
title: apiRef.current.getLocaleText('columnHeaderSortIconLabel'),
|
|
58
|
-
size: "small"
|
|
57
|
+
size: "small"
|
|
58
|
+
}, rootProps.componentsProps?.baseIconButton, {
|
|
59
59
|
children: iconElement
|
|
60
|
-
});
|
|
60
|
+
}));
|
|
61
61
|
return /*#__PURE__*/_jsxs(GridIconButtonContainer, {
|
|
62
62
|
children: [index != null && /*#__PURE__*/_jsx(Badge, {
|
|
63
63
|
badgeContent: index,
|
|
@@ -5,7 +5,6 @@ const _excluded = ["item", "hasMultipleFilters", "deleteFilter", "applyFilterCha
|
|
|
5
5
|
import * as React from 'react';
|
|
6
6
|
import PropTypes from 'prop-types';
|
|
7
7
|
import { unstable_composeClasses as composeClasses, unstable_useId as useId, unstable_capitalize as capitalize } from '@mui/utils';
|
|
8
|
-
import IconButton from '@mui/material/IconButton';
|
|
9
8
|
import MenuItem from '@mui/material/MenuItem';
|
|
10
9
|
import InputLabel from '@mui/material/InputLabel';
|
|
11
10
|
import FormControl from '@mui/material/FormControl';
|
|
@@ -235,15 +234,16 @@ const GridFilterForm = /*#__PURE__*/React.forwardRef(function GridFilterForm(pro
|
|
|
235
234
|
as: rootProps.components.BaseFormControl
|
|
236
235
|
}, baseFormControlProps, deleteIconProps, {
|
|
237
236
|
className: clsx(classes.deleteIcon, baseFormControlProps.className, deleteIconProps.className),
|
|
238
|
-
children: /*#__PURE__*/_jsx(
|
|
237
|
+
children: /*#__PURE__*/_jsx(rootProps.components.BaseIconButton, _extends({
|
|
239
238
|
"aria-label": apiRef.current.getLocaleText('filterPanelDeleteIconLabel'),
|
|
240
239
|
title: apiRef.current.getLocaleText('filterPanelDeleteIconLabel'),
|
|
241
240
|
onClick: handleDeleteFilter,
|
|
242
|
-
size: "small"
|
|
241
|
+
size: "small"
|
|
242
|
+
}, rootProps.componentsProps?.baseIconButton, {
|
|
243
243
|
children: /*#__PURE__*/_jsx(rootProps.components.FilterPanelDeleteIcon, {
|
|
244
244
|
fontSize: "small"
|
|
245
245
|
})
|
|
246
|
-
})
|
|
246
|
+
}))
|
|
247
247
|
})), /*#__PURE__*/_jsx(FilterFormLogicOperatorInput, _extends({
|
|
248
248
|
variant: "standard",
|
|
249
249
|
as: rootProps.components.BaseFormControl
|
|
@@ -58,13 +58,19 @@ const GridToolbarFilterButton = /*#__PURE__*/React.forwardRef(function GridToolb
|
|
|
58
58
|
return apiRef.current.getLocaleText('toolbarFiltersTooltipShow');
|
|
59
59
|
}
|
|
60
60
|
const getOperatorLabel = item => lookup[item.field].filterOperators.find(operator => operator.value === item.operator).label || apiRef.current.getLocaleText(`filterOperator${capitalize(item.operator)}`).toString();
|
|
61
|
+
const getFilterItemValue = item => {
|
|
62
|
+
const {
|
|
63
|
+
getValueAsString
|
|
64
|
+
} = lookup[item.field].filterOperators.find(operator => operator.value === item.operator);
|
|
65
|
+
return getValueAsString ? getValueAsString(item.value) : item.value;
|
|
66
|
+
};
|
|
61
67
|
return /*#__PURE__*/_jsxs("div", {
|
|
62
68
|
children: [apiRef.current.getLocaleText('toolbarFiltersTooltipActive')(activeFilters.length), /*#__PURE__*/_jsx(GridToolbarFilterListRoot, {
|
|
63
69
|
className: classes.root,
|
|
64
70
|
children: activeFilters.map((item, index) => _extends({}, lookup[item.field] && /*#__PURE__*/_jsx("li", {
|
|
65
71
|
children: `${lookup[item.field].headerName || item.field}
|
|
66
72
|
${getOperatorLabel(item)}
|
|
67
|
-
${item.value
|
|
73
|
+
${item.value ? getFilterItemValue(item) : ''}`
|
|
68
74
|
}, index)))
|
|
69
75
|
})]
|
|
70
76
|
});
|
|
@@ -4,7 +4,6 @@ const _excluded = ["quickFilterParser", "quickFilterFormatter", "debounceMs"];
|
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import PropTypes from 'prop-types';
|
|
6
6
|
import TextField from '@mui/material/TextField';
|
|
7
|
-
import IconButton from '@mui/material/IconButton';
|
|
8
7
|
import { styled } from '@mui/material/styles';
|
|
9
8
|
import { unstable_debounce as debounce } from '@mui/utils';
|
|
10
9
|
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
|
|
@@ -91,17 +90,18 @@ function GridToolbarQuickFilter(props) {
|
|
|
91
90
|
startAdornment: /*#__PURE__*/_jsx(rootProps.components.QuickFilterIcon, {
|
|
92
91
|
fontSize: "small"
|
|
93
92
|
}),
|
|
94
|
-
endAdornment: /*#__PURE__*/_jsx(
|
|
93
|
+
endAdornment: /*#__PURE__*/_jsx(rootProps.components.BaseIconButton, _extends({
|
|
95
94
|
"aria-label": apiRef.current.getLocaleText('toolbarQuickFilterDeleteIconLabel'),
|
|
96
95
|
size: "small",
|
|
97
96
|
sx: {
|
|
98
97
|
visibility: searchValue ? 'visible' : 'hidden'
|
|
99
98
|
},
|
|
100
|
-
onClick: handleSearchReset
|
|
99
|
+
onClick: handleSearchReset
|
|
100
|
+
}, rootProps.componentsProps?.baseIconButton, {
|
|
101
101
|
children: /*#__PURE__*/_jsx(rootProps.components.QuickFilterClearIcon, {
|
|
102
102
|
fontSize: "small"
|
|
103
103
|
})
|
|
104
|
-
})
|
|
104
|
+
}))
|
|
105
105
|
}
|
|
106
106
|
}, other, rootProps.componentsProps?.baseTextField));
|
|
107
107
|
}
|
|
@@ -5,6 +5,7 @@ import MUIFormControl from '@mui/material/FormControl';
|
|
|
5
5
|
import MUISelect from '@mui/material/Select';
|
|
6
6
|
import MUISwitch from '@mui/material/Switch';
|
|
7
7
|
import MUIButton from '@mui/material/Button';
|
|
8
|
+
import MUIIconButton from '@mui/material/IconButton';
|
|
8
9
|
import MUITooltip from '@mui/material/Tooltip';
|
|
9
10
|
import MUIPopper from '@mui/material/Popper';
|
|
10
11
|
import { GridArrowDownwardIcon, GridArrowUpwardIcon, GridCell, GridSkeletonCell, GridCheckIcon, GridCloseIcon, GridColumnIcon, GridColumnsPanel, GridFilterAltIcon, GridFilterListIcon, GridFilterPanel, GridFooter, GridLoadingOverlay, GridNoRowsOverlay, GridPagination, GridPanel, GridPreferencesPanel, GridRow, GridSaveAltIcon, GridSeparatorIcon, GridTableRowsIcon, GridTripleDotsVerticalIcon, GridViewHeadlineIcon, GridViewStreamIcon, GridMoreVertIcon, GridExpandMoreIcon, GridKeyboardArrowRight, GridAddIcon, GridRemoveIcon, GridDragIcon, GridColumnHeaderFilterIconButton, GridSearchIcon, GridVisibilityOffIcon, GridViewColumnIcon, GridClearIcon } from '../components';
|
|
@@ -51,6 +52,7 @@ export const DATA_GRID_DEFAULT_SLOTS_COMPONENTS = _extends({}, DEFAULT_GRID_ICON
|
|
|
51
52
|
BaseSelect: MUISelect,
|
|
52
53
|
BaseSwitch: MUISwitch,
|
|
53
54
|
BaseButton: MUIButton,
|
|
55
|
+
BaseIconButton: MUIIconButton,
|
|
54
56
|
BaseTooltip: MUITooltip,
|
|
55
57
|
BasePopper: MUIPopper,
|
|
56
58
|
Cell: GridCell,
|
|
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
|
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import * as ReactDOM from 'react-dom';
|
|
4
4
|
import { unstable_useForkRef as useForkRef } from '@mui/utils';
|
|
5
|
-
import { styled } from '@mui/material/styles';
|
|
5
|
+
import { styled, useTheme } from '@mui/material/styles';
|
|
6
6
|
import { defaultMemoize } from 'reselect';
|
|
7
7
|
import { useGridPrivateApiContext } from '../../utils/useGridPrivateApiContext';
|
|
8
8
|
import { useGridSelector } from '../../utils/useGridSelector';
|
|
@@ -36,6 +36,7 @@ export const useGridColumnHeaders = props => {
|
|
|
36
36
|
innerRef: innerRefProp,
|
|
37
37
|
minColumnIndex = 0
|
|
38
38
|
} = props;
|
|
39
|
+
const theme = useTheme();
|
|
39
40
|
const [dragCol, setDragCol] = React.useState('');
|
|
40
41
|
const [resizeCol, setResizeCol] = React.useState('');
|
|
41
42
|
const apiRef = useGridPrivateApiContext();
|
|
@@ -87,9 +88,10 @@ export const useGridColumnHeaders = props => {
|
|
|
87
88
|
apiRef,
|
|
88
89
|
visibleRows: currentPage.rows
|
|
89
90
|
});
|
|
90
|
-
const
|
|
91
|
+
const direction = theme.direction === 'ltr' ? 1 : -1;
|
|
92
|
+
const offset = firstColumnToRender > 0 ? prevScrollLeft.current - direction * columnPositions[firstColumnToRender] : prevScrollLeft.current;
|
|
91
93
|
innerRef.current.style.transform = `translate3d(${-offset}px, 0px, 0px)`;
|
|
92
|
-
}, [columnPositions, minColumnIndex, rootProps.columnBuffer, apiRef, currentPage.rows, rootProps.rowBuffer]);
|
|
94
|
+
}, [columnPositions, minColumnIndex, rootProps.columnBuffer, apiRef, currentPage.rows, rootProps.rowBuffer, theme.direction]);
|
|
93
95
|
React.useLayoutEffect(() => {
|
|
94
96
|
if (renderContext) {
|
|
95
97
|
updateInnerPosition(renderContext);
|
|
@@ -382,10 +382,13 @@ export const useGridCellEditing = (apiRef, props) => {
|
|
|
382
382
|
const getRowWithUpdatedValuesFromCellEditing = React.useCallback((id, field) => {
|
|
383
383
|
const column = apiRef.current.getColumn(field);
|
|
384
384
|
const editingState = gridEditRowsStateSelector(apiRef.current.state);
|
|
385
|
+
const row = apiRef.current.getRow(id);
|
|
386
|
+
if (!editingState[id] || !editingState[id][field]) {
|
|
387
|
+
return apiRef.current.getRow(id);
|
|
388
|
+
}
|
|
385
389
|
const {
|
|
386
390
|
value
|
|
387
391
|
} = editingState[id][field];
|
|
388
|
-
const row = apiRef.current.getRow(id);
|
|
389
392
|
return column.valueSetter ? column.valueSetter({
|
|
390
393
|
value,
|
|
391
394
|
row
|
|
@@ -117,7 +117,7 @@ export const useGridEditing = (apiRef, props) => {
|
|
|
117
117
|
const editingSharedApi = {
|
|
118
118
|
isCellEditable,
|
|
119
119
|
setEditCellValue,
|
|
120
|
-
|
|
120
|
+
getRowWithUpdatedValues,
|
|
121
121
|
unstable_getEditCellMeta: getEditCellMeta
|
|
122
122
|
};
|
|
123
123
|
const editingSharedPrivateApi = {
|
|
@@ -503,6 +503,9 @@ export const useGridRowEditing = (apiRef, props) => {
|
|
|
503
503
|
const getRowWithUpdatedValuesFromRowEditing = React.useCallback(id => {
|
|
504
504
|
const editingState = gridEditRowsStateSelector(apiRef.current.state);
|
|
505
505
|
const row = apiRef.current.getRow(id);
|
|
506
|
+
if (!editingState[id]) {
|
|
507
|
+
return apiRef.current.getRow(id);
|
|
508
|
+
}
|
|
506
509
|
let rowUpdate = _extends({}, row);
|
|
507
510
|
Object.entries(editingState[id]).forEach(([field, fieldProps]) => {
|
|
508
511
|
const column = apiRef.current.getColumn(field);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import { useTheme } from '@mui/material/styles';
|
|
2
3
|
import { gridVisibleColumnDefinitionsSelector } from '../columns/gridColumnsSelector';
|
|
3
4
|
import { useGridLogger } from '../../utils/useGridLogger';
|
|
4
5
|
import { useGridApiEventHandler } from '../../utils/useGridApiEventHandler';
|
|
@@ -17,6 +18,40 @@ function enrichPageRowsWithPinnedRows(apiRef, rows) {
|
|
|
17
18
|
const pinnedRows = gridPinnedRowsSelector(apiRef) || {};
|
|
18
19
|
return [...(pinnedRows.top || []), ...rows, ...(pinnedRows.bottom || [])];
|
|
19
20
|
}
|
|
21
|
+
const getLeftColumnIndex = ({
|
|
22
|
+
currentColIndex,
|
|
23
|
+
firstColIndex,
|
|
24
|
+
lastColIndex,
|
|
25
|
+
direction
|
|
26
|
+
}) => {
|
|
27
|
+
if (direction === 'rtl') {
|
|
28
|
+
if (currentColIndex < lastColIndex) {
|
|
29
|
+
return currentColIndex + 1;
|
|
30
|
+
}
|
|
31
|
+
} else if (direction === 'ltr') {
|
|
32
|
+
if (currentColIndex > firstColIndex) {
|
|
33
|
+
return currentColIndex - 1;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
};
|
|
38
|
+
const getRightColumnIndex = ({
|
|
39
|
+
currentColIndex,
|
|
40
|
+
firstColIndex,
|
|
41
|
+
lastColIndex,
|
|
42
|
+
direction
|
|
43
|
+
}) => {
|
|
44
|
+
if (direction === 'rtl') {
|
|
45
|
+
if (currentColIndex > firstColIndex) {
|
|
46
|
+
return currentColIndex - 1;
|
|
47
|
+
}
|
|
48
|
+
} else if (direction === 'ltr') {
|
|
49
|
+
if (currentColIndex < lastColIndex) {
|
|
50
|
+
return currentColIndex + 1;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
};
|
|
20
55
|
|
|
21
56
|
/**
|
|
22
57
|
* @requires useGridSorting (method) - can be after
|
|
@@ -30,6 +65,7 @@ function enrichPageRowsWithPinnedRows(apiRef, rows) {
|
|
|
30
65
|
export const useGridKeyboardNavigation = (apiRef, props) => {
|
|
31
66
|
const logger = useGridLogger(apiRef, 'useGridKeyboardNavigation');
|
|
32
67
|
const initialCurrentPageRows = useGridVisibleRows(apiRef, props).rows;
|
|
68
|
+
const theme = useTheme();
|
|
33
69
|
const currentPageRows = React.useMemo(() => enrichPageRowsWithPinnedRows(apiRef, initialCurrentPageRows), [apiRef, initialCurrentPageRows]);
|
|
34
70
|
|
|
35
71
|
/**
|
|
@@ -110,15 +146,27 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
|
|
|
110
146
|
}
|
|
111
147
|
case 'ArrowRight':
|
|
112
148
|
{
|
|
113
|
-
|
|
114
|
-
|
|
149
|
+
const rightColIndex = getRightColumnIndex({
|
|
150
|
+
currentColIndex: colIndexBefore,
|
|
151
|
+
firstColIndex,
|
|
152
|
+
lastColIndex,
|
|
153
|
+
direction: theme.direction
|
|
154
|
+
});
|
|
155
|
+
if (rightColIndex !== null) {
|
|
156
|
+
goToHeader(rightColIndex, event);
|
|
115
157
|
}
|
|
116
158
|
break;
|
|
117
159
|
}
|
|
118
160
|
case 'ArrowLeft':
|
|
119
161
|
{
|
|
120
|
-
|
|
121
|
-
|
|
162
|
+
const leftColIndex = getLeftColumnIndex({
|
|
163
|
+
currentColIndex: colIndexBefore,
|
|
164
|
+
firstColIndex,
|
|
165
|
+
lastColIndex,
|
|
166
|
+
direction: theme.direction
|
|
167
|
+
});
|
|
168
|
+
if (leftColIndex !== null) {
|
|
169
|
+
goToHeader(leftColIndex, event);
|
|
122
170
|
}
|
|
123
171
|
break;
|
|
124
172
|
}
|
|
@@ -166,7 +214,7 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
|
|
|
166
214
|
if (shouldPreventDefault) {
|
|
167
215
|
event.preventDefault();
|
|
168
216
|
}
|
|
169
|
-
}, [apiRef, currentPageRows.length, goToCell, getRowIdFromIndex, goToHeader, goToGroupHeader]);
|
|
217
|
+
}, [apiRef, currentPageRows.length, theme.direction, goToCell, getRowIdFromIndex, goToHeader, goToGroupHeader]);
|
|
170
218
|
const focusedColumnGroup = useGridSelector(apiRef, unstable_gridFocusColumnGroupHeaderSelector);
|
|
171
219
|
const handleColumnGroupHeaderKeyDown = React.useCallback((params, event) => {
|
|
172
220
|
const dimensions = apiRef.current.getRootDimensions();
|
|
@@ -279,6 +327,7 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
|
|
|
279
327
|
if (currentPageRows.length === 0 || !dimensions) {
|
|
280
328
|
return;
|
|
281
329
|
}
|
|
330
|
+
const direction = theme.direction;
|
|
282
331
|
const viewportPageSize = apiRef.current.getViewportPageSize();
|
|
283
332
|
const colIndexBefore = params.field ? apiRef.current.getColumnIndex(params.field) : 0;
|
|
284
333
|
const rowIndexBefore = currentPageRows.findIndex(row => row.id === params.id);
|
|
@@ -307,15 +356,27 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
|
|
|
307
356
|
}
|
|
308
357
|
case 'ArrowRight':
|
|
309
358
|
{
|
|
310
|
-
|
|
311
|
-
|
|
359
|
+
const rightColIndex = getRightColumnIndex({
|
|
360
|
+
currentColIndex: colIndexBefore,
|
|
361
|
+
firstColIndex,
|
|
362
|
+
lastColIndex,
|
|
363
|
+
direction
|
|
364
|
+
});
|
|
365
|
+
if (rightColIndex !== null) {
|
|
366
|
+
goToCell(rightColIndex, getRowIdFromIndex(rowIndexBefore), direction === 'rtl' ? 'left' : 'right');
|
|
312
367
|
}
|
|
313
368
|
break;
|
|
314
369
|
}
|
|
315
370
|
case 'ArrowLeft':
|
|
316
371
|
{
|
|
317
|
-
|
|
318
|
-
|
|
372
|
+
const leftColIndex = getLeftColumnIndex({
|
|
373
|
+
currentColIndex: colIndexBefore,
|
|
374
|
+
firstColIndex,
|
|
375
|
+
lastColIndex,
|
|
376
|
+
direction
|
|
377
|
+
});
|
|
378
|
+
if (leftColIndex !== null) {
|
|
379
|
+
goToCell(leftColIndex, getRowIdFromIndex(rowIndexBefore), direction === 'rtl' ? 'right' : 'left');
|
|
319
380
|
}
|
|
320
381
|
break;
|
|
321
382
|
}
|
|
@@ -388,7 +449,7 @@ export const useGridKeyboardNavigation = (apiRef, props) => {
|
|
|
388
449
|
if (shouldPreventDefault) {
|
|
389
450
|
event.preventDefault();
|
|
390
451
|
}
|
|
391
|
-
}, [apiRef, currentPageRows, getRowIdFromIndex, goToCell, goToHeader]);
|
|
452
|
+
}, [apiRef, currentPageRows, theme.direction, getRowIdFromIndex, goToCell, goToHeader]);
|
|
392
453
|
useGridApiEventHandler(apiRef, 'columnHeaderKeyDown', handleColumnHeaderKeyDown);
|
|
393
454
|
useGridApiEventHandler(apiRef, 'columnGroupHeaderKeyDown', handleColumnGroupHeaderKeyDown);
|
|
394
455
|
useGridApiEventHandler(apiRef, 'cellKeyDown', handleCellKeyDown);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import { useTheme } from '@mui/material/styles';
|
|
2
3
|
import { useGridLogger } from '../../utils/useGridLogger';
|
|
3
4
|
import { gridColumnPositionsSelector, gridVisibleColumnDefinitionsSelector } from '../columns/gridColumnsSelector';
|
|
4
5
|
import { useGridSelector } from '../../utils/useGridSelector';
|
|
@@ -42,6 +43,7 @@ function scrollIntoView(dimensions) {
|
|
|
42
43
|
* @requires useGridColumnSpanning (method)
|
|
43
44
|
*/
|
|
44
45
|
export const useGridScroll = (apiRef, props) => {
|
|
46
|
+
const theme = useTheme();
|
|
45
47
|
const logger = useGridLogger(apiRef, 'useGridScroll');
|
|
46
48
|
const colRef = apiRef.current.columnHeadersElementRef;
|
|
47
49
|
const virtualScrollerRef = apiRef.current.virtualScrollerRef;
|
|
@@ -68,9 +70,10 @@ export const useGridScroll = (apiRef, props) => {
|
|
|
68
70
|
if (typeof cellWidth === 'undefined') {
|
|
69
71
|
cellWidth = visibleColumns[params.colIndex].computedWidth;
|
|
70
72
|
}
|
|
73
|
+
// When using RTL, `scrollLeft` becomes negative, so we must ensure that we only compare values.
|
|
71
74
|
scrollCoordinates.left = scrollIntoView({
|
|
72
75
|
clientHeight: virtualScrollerRef.current.clientWidth,
|
|
73
|
-
scrollTop: virtualScrollerRef.current.scrollLeft,
|
|
76
|
+
scrollTop: Math.abs(virtualScrollerRef.current.scrollLeft),
|
|
74
77
|
offsetHeight: cellWidth,
|
|
75
78
|
offsetTop: columnPositions[params.colIndex]
|
|
76
79
|
});
|
|
@@ -99,8 +102,9 @@ export const useGridScroll = (apiRef, props) => {
|
|
|
99
102
|
}, [logger, apiRef, virtualScrollerRef, props.pagination, visibleSortedRows]);
|
|
100
103
|
const scroll = React.useCallback(params => {
|
|
101
104
|
if (virtualScrollerRef.current && params.left != null && colRef.current) {
|
|
105
|
+
const direction = theme.direction === 'rtl' ? -1 : 1;
|
|
102
106
|
colRef.current.scrollLeft = params.left;
|
|
103
|
-
virtualScrollerRef.current.scrollLeft = params.left;
|
|
107
|
+
virtualScrollerRef.current.scrollLeft = direction * params.left;
|
|
104
108
|
logger.debug(`Scrolling left: ${params.left}`);
|
|
105
109
|
}
|
|
106
110
|
if (virtualScrollerRef.current && params.top != null) {
|
|
@@ -108,7 +112,7 @@ export const useGridScroll = (apiRef, props) => {
|
|
|
108
112
|
logger.debug(`Scrolling top: ${params.top}`);
|
|
109
113
|
}
|
|
110
114
|
logger.debug(`Scrolling, updating container, and viewport`);
|
|
111
|
-
}, [virtualScrollerRef, colRef, logger]);
|
|
115
|
+
}, [virtualScrollerRef, theme.direction, colRef, logger]);
|
|
112
116
|
const getScrollPosition = React.useCallback(() => {
|
|
113
117
|
if (!virtualScrollerRef?.current) {
|
|
114
118
|
return {
|
|
@@ -6,6 +6,7 @@ const _excluded = ["style"],
|
|
|
6
6
|
import * as React from 'react';
|
|
7
7
|
import * as ReactDOM from 'react-dom';
|
|
8
8
|
import { unstable_useForkRef as useForkRef, unstable_useEnhancedEffect as useEnhancedEffect } from '@mui/utils';
|
|
9
|
+
import { useTheme } from '@mui/material/styles';
|
|
9
10
|
import { useGridPrivateApiContext } from '../../utils/useGridPrivateApiContext';
|
|
10
11
|
import { useGridRootProps } from '../../utils/useGridRootProps';
|
|
11
12
|
import { useGridSelector } from '../../utils/useGridSelector';
|
|
@@ -35,7 +36,7 @@ export function binarySearch(offset, positions, sliceStart = 0, sliceEnd = posit
|
|
|
35
36
|
}
|
|
36
37
|
function exponentialSearch(offset, positions, index) {
|
|
37
38
|
let interval = 1;
|
|
38
|
-
while (index < positions.length && positions[index] < offset) {
|
|
39
|
+
while (index < positions.length && Math.abs(positions[index]) < offset) {
|
|
39
40
|
index += interval;
|
|
40
41
|
interval *= 2;
|
|
41
42
|
}
|
|
@@ -62,6 +63,7 @@ export const useGridVirtualScroller = props => {
|
|
|
62
63
|
renderZoneMaxColumnIndex = visibleColumns.length,
|
|
63
64
|
getRowProps
|
|
64
65
|
} = props;
|
|
66
|
+
const theme = useTheme();
|
|
65
67
|
const columnPositions = useGridSelector(apiRef, gridColumnPositionsSelector);
|
|
66
68
|
const columnsTotalWidth = useGridSelector(apiRef, gridColumnsTotalWidthSelector);
|
|
67
69
|
const cellFocus = useGridSelector(apiRef, gridFocusCellSelector);
|
|
@@ -137,8 +139,8 @@ export const useGridVirtualScroller = props => {
|
|
|
137
139
|
hasRowWithAutoHeight = apiRef.current.rowHasAutoHeight(row.id);
|
|
138
140
|
}
|
|
139
141
|
if (!hasRowWithAutoHeight) {
|
|
140
|
-
firstColumnIndex = binarySearch(left, columnPositions);
|
|
141
|
-
lastColumnIndex = binarySearch(left + containerDimensions.width, columnPositions);
|
|
142
|
+
firstColumnIndex = binarySearch(Math.abs(left), columnPositions);
|
|
143
|
+
lastColumnIndex = binarySearch(Math.abs(left) + containerDimensions.width, columnPositions);
|
|
142
144
|
}
|
|
143
145
|
return {
|
|
144
146
|
firstRowIndex,
|
|
@@ -168,7 +170,7 @@ export const useGridVirtualScroller = props => {
|
|
|
168
170
|
height: params.height
|
|
169
171
|
});
|
|
170
172
|
}, []);
|
|
171
|
-
useGridApiEventHandler(apiRef, '
|
|
173
|
+
useGridApiEventHandler(apiRef, 'debouncedResize', handleResize);
|
|
172
174
|
const updateRenderZonePosition = React.useCallback(nextRenderContext => {
|
|
173
175
|
const [firstRowToRender, lastRowToRender] = getRenderableIndexes({
|
|
174
176
|
firstIndex: nextRenderContext.firstRowIndex,
|
|
@@ -191,8 +193,9 @@ export const useGridVirtualScroller = props => {
|
|
|
191
193
|
lastRowToRender,
|
|
192
194
|
visibleRows: currentPage.rows
|
|
193
195
|
});
|
|
196
|
+
const direction = theme.direction === 'ltr' ? 1 : -1;
|
|
194
197
|
const top = gridRowsMetaSelector(apiRef.current.state).positions[firstRowToRender];
|
|
195
|
-
const left = gridColumnPositionsSelector(apiRef)[firstColumnToRender]; // Call directly the selector because it might be outdated when this method is called
|
|
198
|
+
const left = direction * gridColumnPositionsSelector(apiRef)[firstColumnToRender]; // Call directly the selector because it might be outdated when this method is called
|
|
196
199
|
renderZoneRef.current.style.transform = `translate3d(${left}px, ${top}px, 0px)`;
|
|
197
200
|
if (typeof onRenderZonePositioning === 'function') {
|
|
198
201
|
onRenderZonePositioning({
|
|
@@ -200,7 +203,7 @@ export const useGridVirtualScroller = props => {
|
|
|
200
203
|
left
|
|
201
204
|
});
|
|
202
205
|
}
|
|
203
|
-
}, [apiRef, currentPage.rows, onRenderZonePositioning, renderZoneMinColumnIndex, renderZoneMaxColumnIndex, rootProps.columnBuffer, rootProps.rowBuffer]);
|
|
206
|
+
}, [apiRef, currentPage.rows, onRenderZonePositioning, renderZoneMinColumnIndex, renderZoneMaxColumnIndex, rootProps.columnBuffer, rootProps.rowBuffer, theme.direction]);
|
|
204
207
|
const updateRenderContext = React.useCallback(nextRenderContext => {
|
|
205
208
|
setRenderContext(nextRenderContext);
|
|
206
209
|
updateRenderZonePosition(nextRenderContext);
|
|
@@ -243,9 +246,19 @@ export const useGridVirtualScroller = props => {
|
|
|
243
246
|
scrollPosition.current.left = scrollLeft;
|
|
244
247
|
|
|
245
248
|
// On iOS and macOS, negative offsets are possible when swiping past the start
|
|
246
|
-
if (
|
|
249
|
+
if (!prevRenderContext.current || scrollTop < 0) {
|
|
247
250
|
return;
|
|
248
251
|
}
|
|
252
|
+
if (theme.direction === 'ltr') {
|
|
253
|
+
if (scrollLeft < 0) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
if (theme.direction === 'rtl') {
|
|
258
|
+
if (scrollLeft > 0) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
249
262
|
|
|
250
263
|
// When virtualization is disabled, the context never changes during scroll
|
|
251
264
|
const nextRenderContext = disableVirtualization ? prevRenderContext.current : computeRenderContext();
|
package/modern/index.js
CHANGED
package/modern/utils/domUtils.js
CHANGED
|
@@ -25,16 +25,18 @@ function escapeOperandAttributeSelector(operand) {
|
|
|
25
25
|
export function getGridColumnHeaderElement(root, field) {
|
|
26
26
|
return root.querySelector(`[role="columnheader"][data-field="${escapeOperandAttributeSelector(field)}"]`);
|
|
27
27
|
}
|
|
28
|
+
function getGridRowElementSelector(id) {
|
|
29
|
+
return `.${gridClasses.row}[data-id="${escapeOperandAttributeSelector(String(id))}"]`;
|
|
30
|
+
}
|
|
28
31
|
export function getGridRowElement(root, id) {
|
|
29
|
-
return root.querySelector(
|
|
32
|
+
return root.querySelector(getGridRowElementSelector(id));
|
|
30
33
|
}
|
|
31
34
|
export function getGridCellElement(root, {
|
|
32
35
|
id,
|
|
33
36
|
field
|
|
34
37
|
}) {
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
return row.querySelector(`.${gridClasses.cell}[data-field="${escapeOperandAttributeSelector(field)}"]`);
|
|
38
|
+
const rowSelector = getGridRowElementSelector(id);
|
|
39
|
+
const cellSelector = `.${gridClasses.cell}[data-field="${escapeOperandAttributeSelector(field)}"]`;
|
|
40
|
+
const selector = `${rowSelector} ${cellSelector}`;
|
|
41
|
+
return root.querySelector(selector);
|
|
40
42
|
}
|
|
@@ -207,11 +207,7 @@ const GridRow = /*#__PURE__*/React.forwardRef(function GridRow(props, refProp) {
|
|
|
207
207
|
classNames.push((0, _clsx.default)(_gridClasses.gridClasses['cell--withRenderer'], rootProps.classes?.['cell--withRenderer']));
|
|
208
208
|
}
|
|
209
209
|
if (editCellState != null && column.renderEditCell) {
|
|
210
|
-
|
|
211
|
-
if (apiRef.current.unstable_getRowWithUpdatedValues) {
|
|
212
|
-
// Only the new editing API has this method
|
|
213
|
-
updatedRow = apiRef.current.unstable_getRowWithUpdatedValues(rowId, column.field);
|
|
214
|
-
}
|
|
210
|
+
const updatedRow = apiRef.current.getRowWithUpdatedValues(rowId, column.field);
|
|
215
211
|
const editCellStateRest = (0, _objectWithoutPropertiesLoose2.default)(editCellState, _excluded2);
|
|
216
212
|
const params = (0, _extends2.default)({}, cellParams, {
|
|
217
213
|
row: updatedRow
|
|
@@ -253,7 +249,7 @@ const GridRow = /*#__PURE__*/React.forwardRef(function GridRow(props, refProp) {
|
|
|
253
249
|
}, rootProps.componentsProps?.cell, {
|
|
254
250
|
children: content
|
|
255
251
|
}), column.field);
|
|
256
|
-
}, [apiRef, cellTabIndex, editRowsState, cellFocus, rootProps,
|
|
252
|
+
}, [apiRef, cellTabIndex, editRowsState, cellFocus, rootProps, rowHeight, rowId, treeDepth, sortModel.length]);
|
|
257
253
|
const sizes = apiRef.current.unstable_getRowInternalSizes(rowId);
|
|
258
254
|
let minHeight = rowHeight;
|
|
259
255
|
if (minHeight === 'auto' && sizes) {
|