@mui/x-data-grid 7.19.0 → 7.20.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.
Files changed (77) hide show
  1. package/CHANGELOG.md +105 -13
  2. package/DataGrid/DataGrid.js +7 -0
  3. package/components/columnHeaders/GridColumnHeaderItem.js +1 -0
  4. package/hooks/core/useGridRefs.js +4 -0
  5. package/hooks/features/dimensions/useGridDimensions.js +2 -2
  6. package/hooks/features/editing/useGridCellEditing.js +3 -1
  7. package/hooks/features/editing/useGridRowEditing.js +3 -1
  8. package/hooks/features/events/useGridEvents.d.ts +1 -1
  9. package/hooks/features/events/useGridEvents.js +1 -0
  10. package/hooks/features/filter/gridFilterUtils.js +1 -1
  11. package/hooks/features/rowSelection/utils.js +6 -6
  12. package/hooks/features/rows/gridRowsUtils.js +1 -1
  13. package/hooks/features/rows/useGridRowSpanning.js +1 -1
  14. package/hooks/features/scroll/useGridScroll.js +7 -3
  15. package/hooks/features/sorting/gridSortingUtils.js +1 -1
  16. package/hooks/features/virtualization/useGridVirtualScroller.js +2 -2
  17. package/hooks/utils/useGridApiContext.js +1 -1
  18. package/hooks/utils/useGridApiEventHandler.d.ts +1 -1
  19. package/hooks/utils/useGridApiEventHandler.js +1 -1
  20. package/hooks/utils/useGridConfiguration.js +1 -1
  21. package/hooks/utils/useGridPrivateApiContext.js +1 -1
  22. package/index.d.ts +2 -2
  23. package/index.js +3 -3
  24. package/joy/icons.js +0 -1
  25. package/locales/jaJP.js +4 -4
  26. package/models/api/gridApiCommunity.d.ts +1 -1
  27. package/models/api/gridCoreApi.d.ts +9 -1
  28. package/models/api/gridFilterApi.d.ts +1 -1
  29. package/models/events/gridEventLookup.d.ts +7 -0
  30. package/models/gridStateCommunity.d.ts +2 -2
  31. package/models/props/DataGridProps.d.ts +23 -14
  32. package/modern/DataGrid/DataGrid.js +7 -0
  33. package/modern/components/columnHeaders/GridColumnHeaderItem.js +1 -0
  34. package/modern/hooks/core/useGridRefs.js +4 -0
  35. package/modern/hooks/features/dimensions/useGridDimensions.js +2 -2
  36. package/modern/hooks/features/editing/useGridCellEditing.js +3 -1
  37. package/modern/hooks/features/editing/useGridRowEditing.js +3 -1
  38. package/modern/hooks/features/events/useGridEvents.js +1 -0
  39. package/modern/hooks/features/filter/gridFilterUtils.js +1 -1
  40. package/modern/hooks/features/rowSelection/utils.js +6 -6
  41. package/modern/hooks/features/rows/gridRowsUtils.js +1 -1
  42. package/modern/hooks/features/rows/useGridRowSpanning.js +1 -1
  43. package/modern/hooks/features/scroll/useGridScroll.js +7 -3
  44. package/modern/hooks/features/sorting/gridSortingUtils.js +1 -1
  45. package/modern/hooks/features/virtualization/useGridVirtualScroller.js +2 -2
  46. package/modern/hooks/utils/useGridApiContext.js +1 -1
  47. package/modern/hooks/utils/useGridApiEventHandler.js +1 -1
  48. package/modern/hooks/utils/useGridConfiguration.js +1 -1
  49. package/modern/hooks/utils/useGridPrivateApiContext.js +1 -1
  50. package/modern/index.js +3 -3
  51. package/modern/joy/icons.js +0 -1
  52. package/modern/locales/jaJP.js +4 -4
  53. package/modern/utils/domUtils.js +1 -1
  54. package/node/DataGrid/DataGrid.js +7 -0
  55. package/node/components/columnHeaders/GridColumnHeaderItem.js +1 -0
  56. package/node/hooks/core/useGridRefs.js +4 -0
  57. package/node/hooks/features/dimensions/useGridDimensions.js +2 -2
  58. package/node/hooks/features/editing/useGridCellEditing.js +3 -1
  59. package/node/hooks/features/editing/useGridRowEditing.js +3 -1
  60. package/node/hooks/features/events/useGridEvents.js +1 -0
  61. package/node/hooks/features/filter/gridFilterUtils.js +1 -1
  62. package/node/hooks/features/rowSelection/utils.js +6 -6
  63. package/node/hooks/features/rows/gridRowsUtils.js +1 -1
  64. package/node/hooks/features/rows/useGridRowSpanning.js +1 -1
  65. package/node/hooks/features/scroll/useGridScroll.js +7 -3
  66. package/node/hooks/features/sorting/gridSortingUtils.js +1 -1
  67. package/node/hooks/features/virtualization/useGridVirtualScroller.js +2 -2
  68. package/node/hooks/utils/useGridApiContext.js +1 -1
  69. package/node/hooks/utils/useGridApiEventHandler.js +1 -1
  70. package/node/hooks/utils/useGridConfiguration.js +1 -1
  71. package/node/hooks/utils/useGridPrivateApiContext.js +1 -1
  72. package/node/index.js +1 -1
  73. package/node/joy/icons.js +0 -1
  74. package/node/locales/jaJP.js +4 -4
  75. package/node/utils/domUtils.js +1 -1
  76. package/package.json +4 -4
  77. package/utils/domUtils.js +1 -1
@@ -8,7 +8,7 @@ import { GridFeatureMode } from '../gridFeatureMode';
8
8
  import { Logger } from '../logger';
9
9
  import { GridSortDirection, GridSortModel } from '../gridSortModel';
10
10
  import { GridSlotsComponent } from '../gridSlotsComponent';
11
- import { GridRowIdGetter, GridRowsProp, GridValidRowModel } from '../gridRows';
11
+ import { GridRowId, GridRowIdGetter, GridRowsProp, GridValidRowModel } from '../gridRows';
12
12
  import { GridEventListener } from '../events';
13
13
  import { GridCallbackDetails, GridLocaleText } from '../api';
14
14
  import { GridApiCommunity } from '../api/gridApiCommunity';
@@ -35,25 +35,25 @@ export interface GridExperimentalFeatures {
35
35
  warnIfFocusStateIsNotSynced: boolean;
36
36
  }
37
37
  /**
38
- * The props users can give to the `DataGrid` component.
38
+ * The props users can give to the Data Grid component.
39
39
  */
40
40
  export type DataGridProps<R extends GridValidRowModel = any> = Omit<Partial<DataGridPropsWithDefaultValues<R>> & DataGridPropsWithComplexDefaultValueBeforeProcessing & DataGridPropsWithoutDefaultValue<R>, DataGridForcedPropsKey> & {
41
41
  pagination?: true;
42
42
  };
43
43
  /**
44
- * The props of the `DataGrid` component after the pre-processing phase that the user should not be able to override.
44
+ * The props of the Data Grid component after the pre-processing phase that the user should not be able to override.
45
45
  * Those are usually used in feature-hook for which the pro-plan has more advanced features (eg: multi-sorting, multi-filtering, ...).
46
46
  */
47
47
  export type DataGridForcedPropsKey = 'checkboxSelectionVisibleOnly' | 'disableMultipleColumnsFiltering' | 'disableMultipleColumnsSorting' | 'disableColumnReorder' | 'keepColumnPositionIfDraggedOutside' | 'throttleRowsMs' | 'hideFooterRowCount' | 'pagination' | 'signature';
48
48
  /**
49
- * The `DataGrid` options with a default value that must be merged with the value given through props.
49
+ * The Data Grid options with a default value that must be merged with the value given through props.
50
50
  */
51
51
  export interface DataGridPropsWithComplexDefaultValueAfterProcessing {
52
52
  slots: GridSlotsComponent;
53
53
  localeText: GridLocaleText;
54
54
  }
55
55
  /**
56
- * The `DataGrid` options with a default value that must be merged with the value given through props.
56
+ * The Data Grid options with a default value that must be merged with the value given through props.
57
57
  */
58
58
  export interface DataGridPropsWithComplexDefaultValueBeforeProcessing {
59
59
  /**
@@ -67,7 +67,7 @@ export interface DataGridPropsWithComplexDefaultValueBeforeProcessing {
67
67
  localeText?: Partial<GridLocaleText>;
68
68
  }
69
69
  /**
70
- * The `DataGrid` options with a default value overridable through props
70
+ * The Data Grid options with a default value overridable through props
71
71
  * None of the entry of this interface should be optional, they all have default values and `DataGridProps` already applies a `Partial<DataGridSimpleOptions>` for the public interface
72
72
  * The controlled model do not have a default value at the prop processing level, so they must be defined in `DataGridOtherProps`
73
73
  * TODO: add multiSortKey
@@ -370,7 +370,7 @@ export interface DataGridPropsWithDefaultValues<R extends GridValidRowModel = an
370
370
  unstable_rowSpanning: boolean;
371
371
  }
372
372
  /**
373
- * The `DataGrid` props with no default value.
373
+ * The Data Grid props with no default value.
374
374
  */
375
375
  export interface DataGridPropsWithoutDefaultValue<R extends GridValidRowModel = any> extends CommonProps {
376
376
  /**
@@ -515,6 +515,12 @@ export interface DataGridPropsWithoutDefaultValue<R extends GridValidRowModel =
515
515
  * @param {GridCallbackDetails} details Additional details for this callback.
516
516
  */
517
517
  onColumnHeaderClick?: GridEventListener<'columnHeaderClick'>;
518
+ /**
519
+ * Callback fired when a contextmenu event comes from a column header element.
520
+ * @param {GridColumnHeaderParams} params With all properties from [[GridColumnHeaderParams]].
521
+ * @param {MuiEvent<React.MouseEvent>} event The event object.
522
+ */
523
+ onColumnHeaderContextMenu?: GridEventListener<'columnHeaderContextMenu'>;
518
524
  /**
519
525
  * Callback fired when a double click event comes from a column header element.
520
526
  * @param {GridColumnHeaderParams} params With all properties from [[GridColumnHeaderParams]].
@@ -750,9 +756,12 @@ export interface DataGridPropsWithoutDefaultValue<R extends GridValidRowModel =
750
756
  * @template R
751
757
  * @param {R} newRow Row object with the new values.
752
758
  * @param {R} oldRow Row object with the old values.
759
+ * @param {{ rowId: GridRowId }} params Additional parameters.
753
760
  * @returns {Promise<R> | R} The final values to update the row.
754
761
  */
755
- processRowUpdate?: (newRow: R, oldRow: R) => Promise<R> | R;
762
+ processRowUpdate?: (newRow: R, oldRow: R, params: {
763
+ rowId: GridRowId;
764
+ }) => Promise<R> | R;
756
765
  /**
757
766
  * Callback called when `processRowUpdate` throws an error or rejects.
758
767
  * @param {any} error The error thrown.
@@ -796,12 +805,12 @@ export interface DataGridProSharedPropsWithDefaultValue {
796
805
  headerFilters: boolean;
797
806
  /**
798
807
  * When `rowSelectionPropagation.descendants` is set to `true`.
799
- * - Selecting a parent will auto-select all its filtered descendants.
800
- * - Deselecting a parent will auto-deselect all its filtered descendants.
808
+ * - Selecting a parent selects all its filtered descendants automatically.
809
+ * - Deselecting a parent row deselects all its filtered descendants automatically.
801
810
  *
802
- * When `rowSelectionPropagation.parents=true`
803
- * - Selecting all descendants of a parent would auto-select it.
804
- * - Deselecting a descendant of a selected parent would deselect the parent.
811
+ * When `rowSelectionPropagation.parents` is set to `true`
812
+ * - Selecting all the filtered descendants of a parent selects the parent automatically.
813
+ * - Deselecting a descendant of a selected parent deselects the parent automatically.
805
814
  *
806
815
  * Works with tree data and row grouping on the client-side only.
807
816
  * @default { parents: false, descendants: false }
@@ -823,7 +832,7 @@ export interface DataGridPremiumSharedPropsWithDefaultValue {
823
832
  cellSelection: boolean;
824
833
  }
825
834
  /**
826
- * The props of the `DataGrid` component after the pre-processing phase.
835
+ * The props of the Data Grid component after the pre-processing phase.
827
836
  */
828
837
  export interface DataGridProcessedProps<R extends GridValidRowModel = any> extends DataGridPropsWithDefaultValues, DataGridPropsWithComplexDefaultValueAfterProcessing, DataGridPropsWithoutDefaultValue<R>, DataGridProSharedPropsWithoutDefaultValue, Partial<DataGridProSharedPropsWithDefaultValue>, Partial<DataGridPremiumSharedPropsWithDefaultValue> {
829
838
  }
@@ -438,6 +438,12 @@ DataGridRaw.propTypes = {
438
438
  * @param {GridCallbackDetails} details Additional details for this callback.
439
439
  */
440
440
  onColumnHeaderClick: PropTypes.func,
441
+ /**
442
+ * Callback fired when a contextmenu event comes from a column header element.
443
+ * @param {GridColumnHeaderParams} params With all properties from [[GridColumnHeaderParams]].
444
+ * @param {MuiEvent<React.MouseEvent>} event The event object.
445
+ */
446
+ onColumnHeaderContextMenu: PropTypes.func,
441
447
  /**
442
448
  * Callback fired when a double click event comes from a column header element.
443
449
  * @param {GridColumnHeaderParams} params With all properties from [[GridColumnHeaderParams]].
@@ -655,6 +661,7 @@ DataGridRaw.propTypes = {
655
661
  * @template R
656
662
  * @param {R} newRow Row object with the new values.
657
663
  * @param {R} oldRow Row object with the old values.
664
+ * @param {{ rowId: GridRowId }} params Additional parameters.
658
665
  * @returns {Promise<R> | R} The final values to update the row.
659
666
  */
660
667
  processRowUpdate: PropTypes.func,
@@ -92,6 +92,7 @@ function GridColumnHeaderItem(props) {
92
92
  }, [apiRef, colDef.field]);
93
93
  const mouseEventsHandlers = React.useMemo(() => ({
94
94
  onClick: publish('columnHeaderClick'),
95
+ onContextMenu: publish('columnHeaderContextMenu'),
95
96
  onDoubleClick: publish('columnHeaderDoubleClick'),
96
97
  onMouseOver: publish('columnHeaderOver'),
97
98
  // TODO remove as it's not used
@@ -3,6 +3,8 @@ export const useGridRefs = apiRef => {
3
3
  const rootElementRef = React.useRef(null);
4
4
  const mainElementRef = React.useRef(null);
5
5
  const virtualScrollerRef = React.useRef(null);
6
+ const virtualScrollbarVerticalRef = React.useRef(null);
7
+ const virtualScrollbarHorizontalRef = React.useRef(null);
6
8
  const columnHeadersContainerRef = React.useRef(null);
7
9
  apiRef.current.register('public', {
8
10
  rootElementRef
@@ -10,6 +12,8 @@ export const useGridRefs = apiRef => {
10
12
  apiRef.current.register('private', {
11
13
  mainElementRef,
12
14
  virtualScrollerRef,
15
+ virtualScrollbarVerticalRef,
16
+ virtualScrollbarHorizontalRef,
13
17
  columnHeadersContainerRef
14
18
  });
15
19
  };
@@ -238,11 +238,11 @@ export function useGridDimensions(apiRef, props) {
238
238
  // jsdom has no layout capabilities
239
239
  const isJSDOM = /jsdom/.test(window.navigator.userAgent);
240
240
  if (size.height === 0 && !errorShown.current && !props.autoHeight && !isJSDOM) {
241
- logger.error(['The parent DOM element of the data grid has an empty height.', 'Please make sure that this element has an intrinsic height.', 'The grid displays with a height of 0px.', '', 'More details: https://mui.com/r/x-data-grid-no-dimensions.'].join('\n'));
241
+ logger.error(['The parent DOM element of the Data Grid has an empty height.', 'Please make sure that this element has an intrinsic height.', 'The grid displays with a height of 0px.', '', 'More details: https://mui.com/r/x-data-grid-no-dimensions.'].join('\n'));
242
242
  errorShown.current = true;
243
243
  }
244
244
  if (size.width === 0 && !errorShown.current && !isJSDOM) {
245
- logger.error(['The parent DOM element of the data grid has an empty width.', 'Please make sure that this element has an intrinsic width.', 'The grid displays with a width of 0px.', '', 'More details: https://mui.com/r/x-data-grid-no-dimensions.'].join('\n'));
245
+ logger.error(['The parent DOM element of the Data Grid has an empty width.', 'Please make sure that this element has an intrinsic width.', 'The grid displays with a width of 0px.', '', 'More details: https://mui.com/r/x-data-grid-no-dimensions.'].join('\n'));
246
246
  errorShown.current = true;
247
247
  }
248
248
  if (isFirstSizing.current) {
@@ -324,7 +324,9 @@ export const useGridCellEditing = (apiRef, props) => {
324
324
  };
325
325
  try {
326
326
  const row = apiRef.current.getRow(id);
327
- Promise.resolve(processRowUpdate(rowUpdate, row)).then(finalRowUpdate => {
327
+ Promise.resolve(processRowUpdate(rowUpdate, row, {
328
+ rowId: id
329
+ })).then(finalRowUpdate => {
328
330
  apiRef.current.updateRows([finalRowUpdate]);
329
331
  finishCellEditMode();
330
332
  }).catch(handleError);
@@ -397,7 +397,9 @@ export const useGridRowEditing = (apiRef, props) => {
397
397
  }
398
398
  };
399
399
  try {
400
- Promise.resolve(processRowUpdate(rowUpdate, row)).then(finalRowUpdate => {
400
+ Promise.resolve(processRowUpdate(rowUpdate, row, {
401
+ rowId: id
402
+ })).then(finalRowUpdate => {
401
403
  apiRef.current.updateRows([finalRowUpdate]);
402
404
  finishRowEditMode();
403
405
  }).catch(handleError);
@@ -5,6 +5,7 @@ import { useGridApiOptionHandler } from "../../utils/useGridApiEventHandler.js";
5
5
  */
6
6
  export function useGridEvents(apiRef, props) {
7
7
  useGridApiOptionHandler(apiRef, 'columnHeaderClick', props.onColumnHeaderClick);
8
+ useGridApiOptionHandler(apiRef, 'columnHeaderContextMenu', props.onColumnHeaderContextMenu);
8
9
  useGridApiOptionHandler(apiRef, 'columnHeaderDoubleClick', props.onColumnHeaderDoubleClick);
9
10
  useGridApiOptionHandler(apiRef, 'columnHeaderOver', props.onColumnHeaderOver);
10
11
  useGridApiOptionHandler(apiRef, 'columnHeaderOut', props.onColumnHeaderOut);
@@ -41,7 +41,7 @@ export const sanitizeFilterModel = (model, disableMultipleColumnsFiltering, apiR
41
41
  let items;
42
42
  if (hasSeveralItems && disableMultipleColumnsFiltering) {
43
43
  if (process.env.NODE_ENV !== 'production') {
44
- warnOnce(['MUI X: The `filterModel` can only contain a single item when the `disableMultipleColumnsFiltering` prop is set to `true`.', 'If you are using the community version of the `DataGrid`, this prop is always `true`.'], 'error');
44
+ warnOnce(['MUI X: The `filterModel` can only contain a single item when the `disableMultipleColumnsFiltering` prop is set to `true`.', 'If you are using the community version of the Data Grid, this prop is always `true`.'], 'error');
45
45
  }
46
46
  items = [model.items[0]];
47
47
  } else {
@@ -44,21 +44,21 @@ export function getCheckboxPropsSelector(groupId, autoSelectParents) {
44
44
  isChecked: true
45
45
  };
46
46
  }
47
- let selectableDescendentsCount = 0;
48
- let selectedDescendentsCount = 0;
47
+ let selectableDescendantsCount = 0;
48
+ let selectedDescendantsCount = 0;
49
49
  const startIndex = sortedRowIds.findIndex(id => id === groupId) + 1;
50
50
  for (let index = startIndex; index < sortedRowIds.length && rowTree[sortedRowIds[index]]?.depth > groupNode.depth; index += 1) {
51
51
  const id = sortedRowIds[index];
52
52
  if (filteredRowsLookup[id] !== false) {
53
- selectableDescendentsCount += 1;
53
+ selectableDescendantsCount += 1;
54
54
  if (rowSelectionLookup[id] !== undefined) {
55
- selectedDescendentsCount += 1;
55
+ selectedDescendantsCount += 1;
56
56
  }
57
57
  }
58
58
  }
59
59
  return {
60
- isIndeterminate: selectedDescendentsCount > 0 && selectedDescendentsCount < selectableDescendentsCount || selectedDescendentsCount === selectableDescendentsCount && rowSelectionLookup[groupId] === undefined,
61
- isChecked: autoSelectParents ? selectedDescendentsCount > 0 : rowSelectionLookup[groupId] === groupId
60
+ isIndeterminate: selectedDescendantsCount > 0 && selectedDescendantsCount < selectableDescendantsCount || selectedDescendantsCount === selectableDescendantsCount && rowSelectionLookup[groupId] === undefined,
61
+ isChecked: autoSelectParents ? selectedDescendantsCount > 0 : rowSelectionLookup[groupId] === groupId
62
62
  };
63
63
  });
64
64
  }
@@ -24,7 +24,7 @@ export const buildRootGroup = () => ({
24
24
  */
25
25
  export function checkGridRowIdIsValid(id, row, detailErrorMessage = 'A row was provided without id in the rows prop:') {
26
26
  if (id == null) {
27
- throw new Error(['MUI X: The data grid component requires all rows to have a unique `id` property.', 'Alternatively, you can use the `getRowId` prop to specify a custom id for each row.', detailErrorMessage, JSON.stringify(row)].join('\n'));
27
+ throw new Error(['MUI X: The Data Grid component requires all rows to have a unique `id` property.', 'Alternatively, you can use the `getRowId` prop to specify a custom id for each row.', detailErrorMessage, JSON.stringify(row)].join('\n'));
28
28
  }
29
29
  }
30
30
  export const getRowIdFromRowModel = (rowModel, getRowId, detailErrorMessage) => {
@@ -202,7 +202,7 @@ export const useGridRowSpanning = (apiRef, props) => {
202
202
  }
203
203
  const rangeToProcess = getUnprocessedRange({
204
204
  firstRowIndex: renderContext.firstRowIndex,
205
- lastRowIndex: renderContext.lastRowIndex - 1
205
+ lastRowIndex: Math.min(renderContext.lastRowIndex - 1, range.lastRowIndex)
206
206
  }, processedRange.current);
207
207
  if (rangeToProcess === null) {
208
208
  return;
@@ -47,6 +47,8 @@ export const useGridScroll = (apiRef, props) => {
47
47
  const logger = useGridLogger(apiRef, 'useGridScroll');
48
48
  const colRef = apiRef.current.columnHeadersContainerRef;
49
49
  const virtualScrollerRef = apiRef.current.virtualScrollerRef;
50
+ const virtualScrollbarHorizontalRef = apiRef.current.virtualScrollbarHorizontalRef;
51
+ const virtualScrollbarVerticalRef = apiRef.current.virtualScrollbarVerticalRef;
50
52
  const visibleSortedRows = useGridSelector(apiRef, gridExpandedSortedRowEntriesSelector);
51
53
  const scrollToIndexes = React.useCallback(params => {
52
54
  const dimensions = gridDimensionsSelector(apiRef.current.state);
@@ -100,18 +102,20 @@ export const useGridScroll = (apiRef, props) => {
100
102
  return false;
101
103
  }, [logger, apiRef, virtualScrollerRef, props.pagination, visibleSortedRows]);
102
104
  const scroll = React.useCallback(params => {
103
- if (virtualScrollerRef.current && params.left !== undefined && colRef.current) {
105
+ if (virtualScrollerRef.current && virtualScrollbarHorizontalRef.current && params.left !== undefined && colRef.current) {
104
106
  const direction = isRtl ? -1 : 1;
105
107
  colRef.current.scrollLeft = params.left;
106
108
  virtualScrollerRef.current.scrollLeft = direction * params.left;
109
+ virtualScrollbarHorizontalRef.current.scrollLeft = direction * params.left;
107
110
  logger.debug(`Scrolling left: ${params.left}`);
108
111
  }
109
- if (virtualScrollerRef.current && params.top !== undefined) {
112
+ if (virtualScrollerRef.current && virtualScrollbarVerticalRef.current && params.top !== undefined) {
110
113
  virtualScrollerRef.current.scrollTop = params.top;
114
+ virtualScrollbarVerticalRef.current.scrollTop = params.top;
111
115
  logger.debug(`Scrolling top: ${params.top}`);
112
116
  }
113
117
  logger.debug(`Scrolling, updating container, and viewport`);
114
- }, [virtualScrollerRef, isRtl, colRef, logger]);
118
+ }, [virtualScrollerRef, virtualScrollbarHorizontalRef, virtualScrollbarVerticalRef, isRtl, colRef, logger]);
115
119
  const getScrollPosition = React.useCallback(() => {
116
120
  if (!virtualScrollerRef?.current) {
117
121
  return {
@@ -3,7 +3,7 @@ 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') {
6
- warnOnce(['MUI X: The `sortModel` can only contain a single item when the `disableMultipleColumnsSorting` prop is set to `true`.', 'If you are using the community version of the `DataGrid`, this prop is always `true`.'], 'error');
6
+ warnOnce(['MUI X: The `sortModel` can only contain a single item when the `disableMultipleColumnsSorting` prop is set to `true`.', 'If you are using the community version of the Data Grid, this prop is always `true`.'], 'error');
7
7
  }
8
8
  return [model[0]];
9
9
  }
@@ -73,8 +73,8 @@ export const useGridVirtualScroller = () => {
73
73
  const gridRootRef = apiRef.current.rootElementRef;
74
74
  const mainRef = apiRef.current.mainElementRef;
75
75
  const scrollerRef = apiRef.current.virtualScrollerRef;
76
- const scrollbarVerticalRef = React.useRef(null);
77
- const scrollbarHorizontalRef = React.useRef(null);
76
+ const scrollbarVerticalRef = apiRef.current.virtualScrollbarVerticalRef;
77
+ const scrollbarHorizontalRef = apiRef.current.virtualScrollbarHorizontalRef;
78
78
  const contentHeight = dimensions.contentSize.height;
79
79
  const columnsTotalWidth = dimensions.columnsTotalWidth;
80
80
  const hasColSpan = useGridSelector(apiRef, gridHasColSpanSelector);
@@ -3,7 +3,7 @@ import { GridApiContext } from "../../components/GridApiContext.js";
3
3
  export function useGridApiContext() {
4
4
  const apiRef = React.useContext(GridApiContext);
5
5
  if (apiRef === undefined) {
6
- throw new Error(['MUI X: Could not find the data grid context.', 'It looks like you rendered your component outside of a DataGrid, DataGridPro or DataGridPremium parent component.', 'This can also happen if you are bundling multiple versions of the data grid.'].join('\n'));
6
+ throw new Error(['MUI X: Could not find the Data Grid context.', 'It looks like you rendered your component outside of a DataGrid, DataGridPro or DataGridPremium parent component.', 'This can also happen if you are bundling multiple versions of the Data Grid.'].join('\n'));
7
7
  }
8
8
  return apiRef;
9
9
  }
@@ -3,7 +3,7 @@ import { TimerBasedCleanupTracking } from "../../utils/cleanupTracking/TimerBase
3
3
  import { FinalizationRegistryBasedCleanupTracking } from "../../utils/cleanupTracking/FinalizationRegistryBasedCleanupTracking.js";
4
4
  /**
5
5
  * Signal to the underlying logic what version of the public component API
6
- * of the data grid is exposed.
6
+ * of the Data Grid is exposed.
7
7
  */
8
8
  var GridSignature = /*#__PURE__*/function (GridSignature) {
9
9
  GridSignature["DataGrid"] = "DataGrid";
@@ -3,7 +3,7 @@ import { GridConfigurationContext } from "../../components/GridConfigurationCont
3
3
  export const useGridConfiguration = () => {
4
4
  const configuration = React.useContext(GridConfigurationContext);
5
5
  if (configuration === undefined) {
6
- throw new Error(['MUI X: Could not find the data grid configuration context.', 'It looks like you rendered your component outside of a DataGrid, DataGridPro or DataGridPremium parent component.', 'This can also happen if you are bundling multiple versions of the data grid.'].join('\n'));
6
+ throw new Error(['MUI X: Could not find the Data Grid configuration context.', 'It looks like you rendered your component outside of a DataGrid, DataGridPro or DataGridPremium parent component.', 'This can also happen if you are bundling multiple versions of the Data Grid.'].join('\n'));
7
7
  }
8
8
  return configuration;
9
9
  };
@@ -6,7 +6,7 @@ if (process.env.NODE_ENV !== 'production') {
6
6
  export function useGridPrivateApiContext() {
7
7
  const privateApiRef = React.useContext(GridPrivateApiContext);
8
8
  if (privateApiRef === undefined) {
9
- throw new Error(['MUI X: Could not find the data grid private context.', 'It looks like you rendered your component outside of a DataGrid, DataGridPro or DataGridPremium parent component.', 'This can also happen if you are bundling multiple versions of the data grid.'].join('\n'));
9
+ throw new Error(['MUI X: Could not find the Data Grid private context.', 'It looks like you rendered your component outside of a DataGrid, DataGridPro or DataGridPremium parent component.', 'This can also happen if you are bundling multiple versions of the Data Grid.'].join('\n'));
10
10
  }
11
11
  return privateApiRef;
12
12
  }
package/modern/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v7.19.0
2
+ * @mui/x-data-grid v7.20.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -29,9 +29,9 @@ export { GridColumnMenu, GRID_COLUMN_MENU_SLOTS, GRID_COLUMN_MENU_SLOT_PROPS } f
29
29
  */
30
30
 
31
31
  /**
32
- * The state of `DataGrid`.
32
+ * The state of Data Grid.
33
33
  */
34
34
 
35
35
  /**
36
- * The initial state of `DataGrid`.
36
+ * The initial state of Data Grid.
37
37
  */
@@ -34,7 +34,6 @@ function createSvgIcon(path, displayName) {
34
34
  } = _ref,
35
35
  props = _objectWithoutPropertiesLoose(_ref, _excluded);
36
36
  return /*#__PURE__*/_jsx(SvgIcon, _extends({
37
- "data-testid": `${displayName}Icon`,
38
37
  ref: ref,
39
38
  fill: "none",
40
39
  stroke: "currentColor",
@@ -47,9 +47,9 @@ const jaJPGrid = {
47
47
  filterPanelInputPlaceholder: '値を入力…',
48
48
  // Filter operators text
49
49
  filterOperatorContains: '...を含む',
50
- // filterOperatorDoesNotContain: 'does not contain',
50
+ filterOperatorDoesNotContain: '...を含まない',
51
51
  filterOperatorEquals: '...に等しい',
52
- // filterOperatorDoesNotEqual: 'does not equal',
52
+ filterOperatorDoesNotEqual: '...に等しくない',
53
53
  filterOperatorStartsWith: '...で始まる',
54
54
  filterOperatorEndsWith: '...で終わる',
55
55
  filterOperatorIs: '...である',
@@ -69,9 +69,9 @@ const jaJPGrid = {
69
69
  'filterOperator<=': '<=',
70
70
  // Header filter operators text
71
71
  headerFilterOperatorContains: '含む',
72
- // headerFilterOperatorDoesNotContain: 'Does not contain',
72
+ headerFilterOperatorDoesNotContain: '含まない',
73
73
  headerFilterOperatorEquals: '等しい',
74
- // headerFilterOperatorDoesNotEqual: 'Does not equal',
74
+ headerFilterOperatorDoesNotEqual: '等しくない',
75
75
  headerFilterOperatorStartsWith: 'で始まる',
76
76
  headerFilterOperatorEndsWith: 'で終わる',
77
77
  headerFilterOperatorIs: 'である',
@@ -187,7 +187,7 @@ export function findGridCells(api, field) {
187
187
  }
188
188
  function queryRows(api) {
189
189
  return api.virtualScrollerRef.current.querySelectorAll(
190
- // Use > to ignore rows from nested data grids (for example in detail panel)
190
+ // Use > to ignore rows from nested Data Grids (for example in detail panel)
191
191
  `:scope > div > div > .${gridClasses.row}`);
192
192
  }
193
193
  function parseCellColIndex(col) {
@@ -445,6 +445,12 @@ DataGridRaw.propTypes = {
445
445
  * @param {GridCallbackDetails} details Additional details for this callback.
446
446
  */
447
447
  onColumnHeaderClick: _propTypes.default.func,
448
+ /**
449
+ * Callback fired when a contextmenu event comes from a column header element.
450
+ * @param {GridColumnHeaderParams} params With all properties from [[GridColumnHeaderParams]].
451
+ * @param {MuiEvent<React.MouseEvent>} event The event object.
452
+ */
453
+ onColumnHeaderContextMenu: _propTypes.default.func,
448
454
  /**
449
455
  * Callback fired when a double click event comes from a column header element.
450
456
  * @param {GridColumnHeaderParams} params With all properties from [[GridColumnHeaderParams]].
@@ -662,6 +668,7 @@ DataGridRaw.propTypes = {
662
668
  * @template R
663
669
  * @param {R} newRow Row object with the new values.
664
670
  * @param {R} oldRow Row object with the old values.
671
+ * @param {{ rowId: GridRowId }} params Additional parameters.
665
672
  * @returns {Promise<R> | R} The final values to update the row.
666
673
  */
667
674
  processRowUpdate: _propTypes.default.func,
@@ -100,6 +100,7 @@ function GridColumnHeaderItem(props) {
100
100
  }, [apiRef, colDef.field]);
101
101
  const mouseEventsHandlers = React.useMemo(() => ({
102
102
  onClick: publish('columnHeaderClick'),
103
+ onContextMenu: publish('columnHeaderContextMenu'),
103
104
  onDoubleClick: publish('columnHeaderDoubleClick'),
104
105
  onMouseOver: publish('columnHeaderOver'),
105
106
  // TODO remove as it's not used
@@ -10,6 +10,8 @@ const useGridRefs = apiRef => {
10
10
  const rootElementRef = React.useRef(null);
11
11
  const mainElementRef = React.useRef(null);
12
12
  const virtualScrollerRef = React.useRef(null);
13
+ const virtualScrollbarVerticalRef = React.useRef(null);
14
+ const virtualScrollbarHorizontalRef = React.useRef(null);
13
15
  const columnHeadersContainerRef = React.useRef(null);
14
16
  apiRef.current.register('public', {
15
17
  rootElementRef
@@ -17,6 +19,8 @@ const useGridRefs = apiRef => {
17
19
  apiRef.current.register('private', {
18
20
  mainElementRef,
19
21
  virtualScrollerRef,
22
+ virtualScrollbarVerticalRef,
23
+ virtualScrollbarHorizontalRef,
20
24
  columnHeadersContainerRef
21
25
  });
22
26
  };
@@ -248,11 +248,11 @@ function useGridDimensions(apiRef, props) {
248
248
  // jsdom has no layout capabilities
249
249
  const isJSDOM = /jsdom/.test(window.navigator.userAgent);
250
250
  if (size.height === 0 && !errorShown.current && !props.autoHeight && !isJSDOM) {
251
- logger.error(['The parent DOM element of the data grid has an empty height.', 'Please make sure that this element has an intrinsic height.', 'The grid displays with a height of 0px.', '', 'More details: https://mui.com/r/x-data-grid-no-dimensions.'].join('\n'));
251
+ logger.error(['The parent DOM element of the Data Grid has an empty height.', 'Please make sure that this element has an intrinsic height.', 'The grid displays with a height of 0px.', '', 'More details: https://mui.com/r/x-data-grid-no-dimensions.'].join('\n'));
252
252
  errorShown.current = true;
253
253
  }
254
254
  if (size.width === 0 && !errorShown.current && !isJSDOM) {
255
- logger.error(['The parent DOM element of the data grid has an empty width.', 'Please make sure that this element has an intrinsic width.', 'The grid displays with a width of 0px.', '', 'More details: https://mui.com/r/x-data-grid-no-dimensions.'].join('\n'));
255
+ logger.error(['The parent DOM element of the Data Grid has an empty width.', 'Please make sure that this element has an intrinsic width.', 'The grid displays with a width of 0px.', '', 'More details: https://mui.com/r/x-data-grid-no-dimensions.'].join('\n'));
256
256
  errorShown.current = true;
257
257
  }
258
258
  if (isFirstSizing.current) {
@@ -332,7 +332,9 @@ const useGridCellEditing = (apiRef, props) => {
332
332
  };
333
333
  try {
334
334
  const row = apiRef.current.getRow(id);
335
- Promise.resolve(processRowUpdate(rowUpdate, row)).then(finalRowUpdate => {
335
+ Promise.resolve(processRowUpdate(rowUpdate, row, {
336
+ rowId: id
337
+ })).then(finalRowUpdate => {
336
338
  apiRef.current.updateRows([finalRowUpdate]);
337
339
  finishCellEditMode();
338
340
  }).catch(handleError);
@@ -405,7 +405,9 @@ const useGridRowEditing = (apiRef, props) => {
405
405
  }
406
406
  };
407
407
  try {
408
- Promise.resolve(processRowUpdate(rowUpdate, row)).then(finalRowUpdate => {
408
+ Promise.resolve(processRowUpdate(rowUpdate, row, {
409
+ rowId: id
410
+ })).then(finalRowUpdate => {
409
411
  apiRef.current.updateRows([finalRowUpdate]);
410
412
  finishRowEditMode();
411
413
  }).catch(handleError);
@@ -11,6 +11,7 @@ var _useGridApiEventHandler = require("../../utils/useGridApiEventHandler");
11
11
  */
12
12
  function useGridEvents(apiRef, props) {
13
13
  (0, _useGridApiEventHandler.useGridApiOptionHandler)(apiRef, 'columnHeaderClick', props.onColumnHeaderClick);
14
+ (0, _useGridApiEventHandler.useGridApiOptionHandler)(apiRef, 'columnHeaderContextMenu', props.onColumnHeaderContextMenu);
14
15
  (0, _useGridApiEventHandler.useGridApiOptionHandler)(apiRef, 'columnHeaderDoubleClick', props.onColumnHeaderDoubleClick);
15
16
  (0, _useGridApiEventHandler.useGridApiOptionHandler)(apiRef, 'columnHeaderOver', props.onColumnHeaderOver);
16
17
  (0, _useGridApiEventHandler.useGridApiOptionHandler)(apiRef, 'columnHeaderOut', props.onColumnHeaderOut);
@@ -49,7 +49,7 @@ const sanitizeFilterModel = (model, disableMultipleColumnsFiltering, apiRef) =>
49
49
  let items;
50
50
  if (hasSeveralItems && disableMultipleColumnsFiltering) {
51
51
  if (process.env.NODE_ENV !== 'production') {
52
- (0, _warning.warnOnce)(['MUI X: The `filterModel` can only contain a single item when the `disableMultipleColumnsFiltering` prop is set to `true`.', 'If you are using the community version of the `DataGrid`, this prop is always `true`.'], 'error');
52
+ (0, _warning.warnOnce)(['MUI X: The `filterModel` can only contain a single item when the `disableMultipleColumnsFiltering` prop is set to `true`.', 'If you are using the community version of the Data Grid, this prop is always `true`.'], 'error');
53
53
  }
54
54
  items = [model.items[0]];
55
55
  } else {
@@ -52,21 +52,21 @@ function getCheckboxPropsSelector(groupId, autoSelectParents) {
52
52
  isChecked: true
53
53
  };
54
54
  }
55
- let selectableDescendentsCount = 0;
56
- let selectedDescendentsCount = 0;
55
+ let selectableDescendantsCount = 0;
56
+ let selectedDescendantsCount = 0;
57
57
  const startIndex = sortedRowIds.findIndex(id => id === groupId) + 1;
58
58
  for (let index = startIndex; index < sortedRowIds.length && rowTree[sortedRowIds[index]]?.depth > groupNode.depth; index += 1) {
59
59
  const id = sortedRowIds[index];
60
60
  if (filteredRowsLookup[id] !== false) {
61
- selectableDescendentsCount += 1;
61
+ selectableDescendantsCount += 1;
62
62
  if (rowSelectionLookup[id] !== undefined) {
63
- selectedDescendentsCount += 1;
63
+ selectedDescendantsCount += 1;
64
64
  }
65
65
  }
66
66
  }
67
67
  return {
68
- isIndeterminate: selectedDescendentsCount > 0 && selectedDescendentsCount < selectableDescendentsCount || selectedDescendentsCount === selectableDescendentsCount && rowSelectionLookup[groupId] === undefined,
69
- isChecked: autoSelectParents ? selectedDescendentsCount > 0 : rowSelectionLookup[groupId] === groupId
68
+ isIndeterminate: selectedDescendantsCount > 0 && selectedDescendantsCount < selectableDescendantsCount || selectedDescendantsCount === selectableDescendantsCount && rowSelectionLookup[groupId] === undefined,
69
+ isChecked: autoSelectParents ? selectedDescendantsCount > 0 : rowSelectionLookup[groupId] === groupId
70
70
  };
71
71
  });
72
72
  }
@@ -38,7 +38,7 @@ const buildRootGroup = () => ({
38
38
  exports.buildRootGroup = buildRootGroup;
39
39
  function checkGridRowIdIsValid(id, row, detailErrorMessage = 'A row was provided without id in the rows prop:') {
40
40
  if (id == null) {
41
- throw new Error(['MUI X: The data grid component requires all rows to have a unique `id` property.', 'Alternatively, you can use the `getRowId` prop to specify a custom id for each row.', detailErrorMessage, JSON.stringify(row)].join('\n'));
41
+ throw new Error(['MUI X: The Data Grid component requires all rows to have a unique `id` property.', 'Alternatively, you can use the `getRowId` prop to specify a custom id for each row.', detailErrorMessage, JSON.stringify(row)].join('\n'));
42
42
  }
43
43
  }
44
44
  const getRowIdFromRowModel = (rowModel, getRowId, detailErrorMessage) => {
@@ -211,7 +211,7 @@ const useGridRowSpanning = (apiRef, props) => {
211
211
  }
212
212
  const rangeToProcess = (0, _gridRowSpanningUtils.getUnprocessedRange)({
213
213
  firstRowIndex: renderContext.firstRowIndex,
214
- lastRowIndex: renderContext.lastRowIndex - 1
214
+ lastRowIndex: Math.min(renderContext.lastRowIndex - 1, range.lastRowIndex)
215
215
  }, processedRange.current);
216
216
  if (rangeToProcess === null) {
217
217
  return;