@mui/x-data-grid 7.12.0 → 7.13.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 (122) hide show
  1. package/CHANGELOG.md +151 -2
  2. package/DataGrid/DataGrid.js +10 -1
  3. package/components/GridColumnHeaders.js +1 -1
  4. package/components/GridConfigurationContext.d.ts +2 -0
  5. package/components/GridConfigurationContext.js +5 -0
  6. package/components/GridHeaders.js +2 -5
  7. package/components/GridRow.js +6 -8
  8. package/components/GridScrollArea.js +1 -1
  9. package/components/GridSkeletonLoadingOverlay.js +1 -1
  10. package/components/cell/GridCell.js +1 -1
  11. package/components/cell/GridSkeletonCell.js +2 -2
  12. package/components/columnHeaders/GridColumnHeaderItem.js +1 -1
  13. package/components/containers/GridRootStyles.js +9 -2
  14. package/components/virtualization/GridMainContainer.js +3 -2
  15. package/components/virtualization/GridVirtualScrollerFiller.js +1 -1
  16. package/context/GridContextProvider.d.ts +3 -1
  17. package/context/GridContextProvider.js +12 -7
  18. package/hooks/core/useGridRefs.js +3 -1
  19. package/hooks/core/useGridStateInitialization.js +1 -3
  20. package/hooks/features/dimensions/useGridDimensions.js +1 -1
  21. package/hooks/features/export/serializers/csvSerializer.js +4 -3
  22. package/hooks/features/filter/gridFilterSelector.d.ts +20 -7
  23. package/hooks/features/filter/gridFilterSelector.js +34 -0
  24. package/hooks/features/filter/gridFilterState.d.ts +6 -0
  25. package/hooks/features/filter/index.d.ts +2 -1
  26. package/hooks/features/filter/index.js +1 -1
  27. package/hooks/features/filter/useGridFilter.js +3 -0
  28. package/hooks/features/rowSelection/useGridRowSelection.js +6 -4
  29. package/hooks/features/rows/useGridRowAriaAttributes.d.ts +2 -0
  30. package/hooks/features/rows/useGridRowAriaAttributes.js +19 -0
  31. package/hooks/utils/useGridAriaAttributes.d.ts +2 -6
  32. package/hooks/utils/useGridAriaAttributes.js +5 -8
  33. package/hooks/utils/useGridConfiguration.d.ts +2 -0
  34. package/hooks/utils/useGridConfiguration.js +9 -0
  35. package/hooks/utils/useGridSelector.d.ts +1 -1
  36. package/hooks/utils/useGridSelector.js +1 -1
  37. package/index.js +1 -1
  38. package/internals/index.d.ts +3 -1
  39. package/internals/index.js +3 -1
  40. package/locales/viVN.js +4 -5
  41. package/models/api/gridCoreApi.d.ts +1 -1
  42. package/models/configuration/gridConfiguration.d.ts +10 -0
  43. package/models/configuration/gridConfiguration.js +1 -0
  44. package/models/configuration/gridRowConfiguration.d.ts +12 -0
  45. package/models/configuration/gridRowConfiguration.js +1 -0
  46. package/models/gridDataSource.d.ts +2 -1
  47. package/models/gridRows.d.ts +2 -2
  48. package/models/props/DataGridProps.d.ts +1 -1
  49. package/modern/DataGrid/DataGrid.js +10 -1
  50. package/modern/components/GridColumnHeaders.js +1 -1
  51. package/modern/components/GridConfigurationContext.js +5 -0
  52. package/modern/components/GridHeaders.js +2 -5
  53. package/modern/components/GridRow.js +6 -8
  54. package/modern/components/GridScrollArea.js +1 -1
  55. package/modern/components/GridSkeletonLoadingOverlay.js +1 -1
  56. package/modern/components/cell/GridCell.js +1 -1
  57. package/modern/components/cell/GridSkeletonCell.js +2 -2
  58. package/modern/components/columnHeaders/GridColumnHeaderItem.js +1 -1
  59. package/modern/components/containers/GridRootStyles.js +9 -2
  60. package/modern/components/virtualization/GridMainContainer.js +3 -2
  61. package/modern/components/virtualization/GridVirtualScrollerFiller.js +1 -1
  62. package/modern/context/GridContextProvider.js +12 -7
  63. package/modern/hooks/core/useGridRefs.js +3 -1
  64. package/modern/hooks/core/useGridStateInitialization.js +1 -3
  65. package/modern/hooks/features/dimensions/useGridDimensions.js +1 -1
  66. package/modern/hooks/features/export/serializers/csvSerializer.js +4 -3
  67. package/modern/hooks/features/filter/gridFilterSelector.js +34 -0
  68. package/modern/hooks/features/filter/index.js +1 -1
  69. package/modern/hooks/features/filter/useGridFilter.js +3 -0
  70. package/modern/hooks/features/rowSelection/useGridRowSelection.js +6 -4
  71. package/modern/hooks/features/rows/useGridRowAriaAttributes.js +19 -0
  72. package/modern/hooks/utils/useGridAriaAttributes.js +5 -8
  73. package/modern/hooks/utils/useGridConfiguration.js +9 -0
  74. package/modern/hooks/utils/useGridSelector.js +1 -1
  75. package/modern/index.js +1 -1
  76. package/modern/internals/index.js +3 -1
  77. package/modern/locales/viVN.js +4 -5
  78. package/modern/models/configuration/gridConfiguration.js +1 -0
  79. package/modern/models/configuration/gridRowConfiguration.js +1 -0
  80. package/node/DataGrid/DataGrid.js +10 -1
  81. package/node/components/GridColumnHeaders.js +1 -1
  82. package/node/{utils/fastMemo.js → components/GridConfigurationContext.js} +4 -4
  83. package/node/components/GridHeaders.js +2 -5
  84. package/node/components/GridRow.js +6 -8
  85. package/node/components/GridScrollArea.js +1 -1
  86. package/node/components/GridSkeletonLoadingOverlay.js +1 -1
  87. package/node/components/cell/GridCell.js +1 -1
  88. package/node/components/cell/GridSkeletonCell.js +2 -2
  89. package/node/components/columnHeaders/GridColumnHeaderItem.js +1 -1
  90. package/node/components/containers/GridRootStyles.js +9 -2
  91. package/node/components/virtualization/GridMainContainer.js +3 -2
  92. package/node/components/virtualization/GridVirtualScrollerFiller.js +1 -1
  93. package/node/context/GridContextProvider.js +12 -7
  94. package/node/hooks/core/useGridRefs.js +3 -1
  95. package/node/hooks/core/useGridStateInitialization.js +1 -3
  96. package/node/hooks/features/dimensions/useGridDimensions.js +1 -1
  97. package/node/hooks/features/export/serializers/csvSerializer.js +4 -3
  98. package/node/hooks/features/filter/gridFilterSelector.js +35 -1
  99. package/node/hooks/features/filter/index.js +97 -15
  100. package/node/hooks/features/filter/useGridFilter.js +3 -0
  101. package/node/hooks/features/rowSelection/useGridRowSelection.js +6 -4
  102. package/node/hooks/features/rows/useGridRowAriaAttributes.js +28 -0
  103. package/node/hooks/utils/useGridAriaAttributes.js +4 -7
  104. package/node/hooks/utils/useGridConfiguration.js +18 -0
  105. package/node/hooks/utils/useGridSelector.js +1 -1
  106. package/node/index.js +1 -1
  107. package/node/internals/index.js +31 -12
  108. package/node/locales/viVN.js +4 -5
  109. package/node/models/configuration/gridConfiguration.js +5 -0
  110. package/node/models/configuration/gridRowConfiguration.js +5 -0
  111. package/package.json +12 -2
  112. package/modern/utils/fastMemo.js +0 -5
  113. package/modern/utils/fastObjectShallowCompare.js +0 -28
  114. package/modern/utils/throttle.js +0 -19
  115. package/node/utils/fastObjectShallowCompare.js +0 -34
  116. package/node/utils/throttle.js +0 -25
  117. package/utils/fastMemo.d.ts +0 -1
  118. package/utils/fastMemo.js +0 -5
  119. package/utils/fastObjectShallowCompare.d.ts +0 -1
  120. package/utils/fastObjectShallowCompare.js +0 -28
  121. package/utils/throttle.d.ts +0 -4
  122. package/utils/throttle.js +0 -19
@@ -32,6 +32,12 @@ export const gridVisibleRowsLookupSelector = state => state.visibleRowsLookup;
32
32
  */
33
33
  export const gridFilteredRowsLookupSelector = createSelector(gridFilterStateSelector, filterState => filterState.filteredRowsLookup);
34
34
 
35
+ /**
36
+ * @category Filtering
37
+ * @ignore - do not document.
38
+ */
39
+ export const gridFilteredChildrenCountLookupSelector = createSelector(gridFilterStateSelector, filterState => filterState.filteredChildrenCountLookup);
40
+
35
41
  /**
36
42
  * @category Filtering
37
43
  * @ignore - do not document.
@@ -66,6 +72,34 @@ export const gridFilteredSortedRowEntriesSelector = createSelectorMemoized(gridF
66
72
  */
67
73
  export const gridFilteredSortedRowIdsSelector = createSelectorMemoized(gridFilteredSortedRowEntriesSelector, filteredSortedRowEntries => filteredSortedRowEntries.map(row => row.id));
68
74
 
75
+ /**
76
+ * Get the ids to position in the current tree level lookup of the rows accessible after the filtering process.
77
+ * Does not contain the collapsed children.
78
+ * @category Filtering
79
+ * @ignore - do not document.
80
+ */
81
+ export const gridExpandedSortedRowTreeLevelPositionLookupSelector = createSelectorMemoized(gridExpandedSortedRowIdsSelector, gridRowTreeSelector, (visibleSortedRowIds, rowTree) => {
82
+ const depthPositionCounter = {};
83
+ let lastDepth = 0;
84
+ return visibleSortedRowIds.reduce((acc, rowId) => {
85
+ const rowNode = rowTree[rowId];
86
+ if (!depthPositionCounter[rowNode.depth]) {
87
+ depthPositionCounter[rowNode.depth] = 0;
88
+ }
89
+
90
+ // going deeper in the tree should reset the counter
91
+ // since it might have been used in some other branch at the same level, up in the tree
92
+ // going back up should keep the counter and continue where it left off
93
+ if (rowNode.depth > lastDepth) {
94
+ depthPositionCounter[rowNode.depth] = 0;
95
+ }
96
+ lastDepth = rowNode.depth;
97
+ depthPositionCounter[rowNode.depth] += 1;
98
+ acc[rowId] = depthPositionCounter[rowNode.depth];
99
+ return acc;
100
+ }, {});
101
+ });
102
+
69
103
  /**
70
104
  * Get the id and the model of the top level rows accessible after the filtering process.
71
105
  * @category Filtering
@@ -17,6 +17,12 @@ export interface GridFilterState {
17
17
  * This is the equivalent of the `visibleRowsLookup` if all the groups were expanded.
18
18
  */
19
19
  filteredRowsLookup: Record<GridRowId, boolean>;
20
+ /**
21
+ * Amount of children that are passing the filters or have children that are passing the filter (does not count grand children).
22
+ * If a row is not registered in this lookup, it is supposed to have no descendant passing the filters.
23
+ * If `GridDataSource` is being used to load the data, the value is `-1` if there are some children but the count is unknown.
24
+ */
25
+ filteredChildrenCountLookup: Record<GridRowId, number>;
20
26
  /**
21
27
  * Amount of descendants that are passing the filters.
22
28
  * For the Tree Data, it includes all the intermediate depth levels (= amount of children + amount of grand children + ...).
@@ -1,3 +1,4 @@
1
1
  export type { GridFilterState, GridFilterInitialState } from './gridFilterState';
2
2
  export { getDefaultGridFilterModel } from './gridFilterState';
3
- export * from './gridFilterSelector';
3
+ export { gridFilterModelSelector, gridQuickFilterValuesSelector, gridVisibleRowsLookupSelector, gridFilteredRowsLookupSelector, gridFilteredDescendantCountLookupSelector, gridExpandedSortedRowEntriesSelector, gridExpandedSortedRowIdsSelector, gridFilteredSortedRowEntriesSelector, gridFilteredSortedRowIdsSelector, gridFilteredSortedTopLevelRowEntriesSelector, gridExpandedRowCountSelector, gridFilteredTopLevelRowCountSelector, gridFilteredRowCountSelector, gridFilteredDescendantRowCountSelector, gridFilterActiveItemsSelector, gridFilterActiveItemsLookupSelector, } from './gridFilterSelector';
4
+ export type { GridFilterActiveItemsLookup } from './gridFilterSelector';
@@ -1,2 +1,2 @@
1
1
  export { getDefaultGridFilterModel } from './gridFilterState';
2
- export * from './gridFilterSelector';
2
+ export { gridFilterModelSelector, gridQuickFilterValuesSelector, gridVisibleRowsLookupSelector, gridFilteredRowsLookupSelector, gridFilteredDescendantCountLookupSelector, gridExpandedSortedRowEntriesSelector, gridExpandedSortedRowIdsSelector, gridFilteredSortedRowEntriesSelector, gridFilteredSortedRowIdsSelector, gridFilteredSortedTopLevelRowEntriesSelector, gridExpandedRowCountSelector, gridFilteredTopLevelRowCountSelector, gridFilteredRowCountSelector, gridFilteredDescendantRowCountSelector, gridFilterActiveItemsSelector, gridFilterActiveItemsLookupSelector } from './gridFilterSelector';
@@ -23,6 +23,7 @@ export const filterStateInitializer = (state, props, apiRef) => {
23
23
  filter: {
24
24
  filterModel: sanitizeFilterModel(filterModel, props.disableMultipleColumnsFiltering, apiRef),
25
25
  filteredRowsLookup: {},
26
+ filteredChildrenCountLookup: {},
26
27
  filteredDescendantCountLookup: {}
27
28
  },
28
29
  visibleRowsLookup: {}
@@ -273,6 +274,7 @@ export const useGridFilter = (apiRef, props) => {
273
274
  if (props.filterMode !== 'client' || !params.isRowMatchingFilters) {
274
275
  return {
275
276
  filteredRowsLookup: {},
277
+ filteredChildrenCountLookup: {},
276
278
  filteredDescendantCountLookup: {}
277
279
  };
278
280
  }
@@ -301,6 +303,7 @@ export const useGridFilter = (apiRef, props) => {
301
303
  }
302
304
  return {
303
305
  filteredRowsLookup,
306
+ filteredChildrenCountLookup: {},
304
307
  filteredDescendantCountLookup: {}
305
308
  };
306
309
  }, [apiRef, props.filterMode, getRowId, getRowsRef]);
@@ -105,6 +105,9 @@ export const useGridRowSelection = (apiRef, props) => {
105
105
  }, [apiRef, logger, props.rowSelection, props.signature, canHaveMultipleSelection]);
106
106
  const isRowSelected = React.useCallback(id => gridRowSelectionStateSelector(apiRef.current.state).includes(id), [apiRef]);
107
107
  const isRowSelectable = React.useCallback(id => {
108
+ if (props.rowSelection === false) {
109
+ return false;
110
+ }
108
111
  if (propIsRowSelectable && !propIsRowSelectable(apiRef.current.getRowParams(id))) {
109
112
  return false;
110
113
  }
@@ -113,7 +116,7 @@ export const useGridRowSelection = (apiRef, props) => {
113
116
  return false;
114
117
  }
115
118
  return true;
116
- }, [apiRef, propIsRowSelectable]);
119
+ }, [apiRef, props.rowSelection, propIsRowSelectable]);
117
120
  const getSelectedRows = React.useCallback(() => selectedGridRowsSelector(apiRef), [apiRef]);
118
121
  const selectRow = React.useCallback((id, isSelected = true, resetSelection = false) => {
119
122
  if (!apiRef.current.isRowSelectable(id)) {
@@ -272,11 +275,10 @@ export const useGridRowSelection = (apiRef, props) => {
272
275
  }
273
276
  }, [apiRef, expandMouseRowRangeSelection, canHaveMultipleSelection]);
274
277
  const handleHeaderSelectionCheckboxChange = React.useCallback(params => {
275
- const shouldLimitSelectionToCurrentPage = props.checkboxSelectionVisibleOnly && props.pagination;
276
- const rowsToBeSelected = shouldLimitSelectionToCurrentPage ? gridPaginatedVisibleSortedGridRowIdsSelector(apiRef) : gridExpandedSortedRowIdsSelector(apiRef);
278
+ const rowsToBeSelected = props.pagination && props.checkboxSelectionVisibleOnly && props.paginationMode === 'client' ? gridPaginatedVisibleSortedGridRowIdsSelector(apiRef) : gridExpandedSortedRowIdsSelector(apiRef);
277
279
  const filterModel = gridFilterModelSelector(apiRef);
278
280
  apiRef.current.selectRows(rowsToBeSelected, params.value, filterModel?.items.length > 0);
279
- }, [apiRef, props.checkboxSelectionVisibleOnly, props.pagination]);
281
+ }, [apiRef, props.checkboxSelectionVisibleOnly, props.pagination, props.paginationMode]);
280
282
  const handleCellKeyDown = React.useCallback((params, event) => {
281
283
  // Get the most recent cell mode because it may have been changed by another listener
282
284
  if (apiRef.current.getCellMode(params.id, params.field) === GridCellModes.Edit) {
@@ -0,0 +1,2 @@
1
+ import { GetRowAriaAttributesFn } from '../../../models/configuration/gridRowConfiguration';
2
+ export declare const useGridRowAriaAttributes: () => GetRowAriaAttributesFn;
@@ -0,0 +1,19 @@
1
+ import * as React from 'react';
2
+ import { selectedIdsLookupSelector } from '../rowSelection';
3
+ import { useGridSelector } from '../../utils/useGridSelector';
4
+ import { gridColumnGroupsHeaderMaxDepthSelector } from '../columnGrouping/gridColumnGroupsSelector';
5
+ import { useGridPrivateApiContext } from '../../utils/useGridPrivateApiContext';
6
+ export const useGridRowAriaAttributes = () => {
7
+ const apiRef = useGridPrivateApiContext();
8
+ const selectedIdsLookup = useGridSelector(apiRef, selectedIdsLookupSelector);
9
+ const headerGroupingMaxDepth = useGridSelector(apiRef, gridColumnGroupsHeaderMaxDepthSelector);
10
+ return React.useCallback((rowNode, index) => {
11
+ const ariaAttributes = {};
12
+ const ariaRowIndex = index + headerGroupingMaxDepth + 2; // 1 for the header row and 1 as it's 1-based
13
+ ariaAttributes['aria-rowindex'] = ariaRowIndex;
14
+ if (apiRef.current.isRowSelectable(rowNode.id)) {
15
+ ariaAttributes['aria-selected'] = selectedIdsLookup[rowNode.id] !== undefined;
16
+ }
17
+ return ariaAttributes;
18
+ }, [apiRef, selectedIdsLookup, headerGroupingMaxDepth]);
19
+ };
@@ -1,6 +1,2 @@
1
- export declare const useGridAriaAttributes: () => {
2
- role: string;
3
- 'aria-colcount': number;
4
- 'aria-rowcount': number;
5
- 'aria-multiselectable': boolean;
6
- };
1
+ import * as React from 'react';
2
+ export declare const useGridAriaAttributes: () => React.HTMLAttributes<HTMLElement>;
@@ -2,24 +2,21 @@ import { gridVisibleColumnDefinitionsSelector } from '../features/columns/gridCo
2
2
  import { useGridSelector } from './useGridSelector';
3
3
  import { useGridRootProps } from './useGridRootProps';
4
4
  import { gridColumnGroupsHeaderMaxDepthSelector } from '../features/columnGrouping/gridColumnGroupsSelector';
5
- import { gridPinnedRowsCountSelector, gridRowCountSelector } from '../features/rows/gridRowsSelector';
5
+ import { gridPinnedRowsCountSelector } from '../features/rows/gridRowsSelector';
6
6
  import { useGridPrivateApiContext } from './useGridPrivateApiContext';
7
7
  import { isMultipleRowSelectionEnabled } from '../features/rowSelection/utils';
8
+ import { gridExpandedRowCountSelector } from '../features/filter/gridFilterSelector';
8
9
  export const useGridAriaAttributes = () => {
9
10
  const apiRef = useGridPrivateApiContext();
10
11
  const rootProps = useGridRootProps();
11
12
  const visibleColumns = useGridSelector(apiRef, gridVisibleColumnDefinitionsSelector);
12
- const totalRowCount = useGridSelector(apiRef, gridRowCountSelector);
13
+ const accessibleRowCount = useGridSelector(apiRef, gridExpandedRowCountSelector);
13
14
  const headerGroupingMaxDepth = useGridSelector(apiRef, gridColumnGroupsHeaderMaxDepthSelector);
14
15
  const pinnedRowsCount = useGridSelector(apiRef, gridPinnedRowsCountSelector);
15
- let role = 'grid';
16
- if (rootProps.treeData) {
17
- role = 'treegrid';
18
- }
19
16
  return {
20
- role,
17
+ role: 'grid',
21
18
  'aria-colcount': visibleColumns.length,
22
- 'aria-rowcount': headerGroupingMaxDepth + 1 + pinnedRowsCount + totalRowCount,
19
+ 'aria-rowcount': headerGroupingMaxDepth + 1 + pinnedRowsCount + accessibleRowCount,
23
20
  'aria-multiselectable': isMultipleRowSelectionEnabled(rootProps)
24
21
  };
25
22
  };
@@ -0,0 +1,2 @@
1
+ import { GridConfiguration } from '../../models/configuration/gridConfiguration';
2
+ export declare const useGridConfiguration: () => GridConfiguration;
@@ -0,0 +1,9 @@
1
+ import * as React from 'react';
2
+ import { GridConfigurationContext } from '../../components/GridConfigurationContext';
3
+ export const useGridConfiguration = () => {
4
+ const configuration = React.useContext(GridConfigurationContext);
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'));
7
+ }
8
+ return configuration;
9
+ };
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
+ import { fastObjectShallowCompare } from '@mui/x-internals/fastObjectShallowCompare';
2
3
  import type { GridApiCommon } from '../../models/api/gridApiCommon';
3
4
  import { OutputSelector } from '../../utils/createSelector';
4
- import { fastObjectShallowCompare } from '../../utils/fastObjectShallowCompare';
5
5
  export declare const objectShallowCompare: typeof fastObjectShallowCompare;
6
6
  export declare const useGridSelector: <Api extends GridApiCommon, T>(apiRef: React.MutableRefObject<Api>, selector: ((state: Api["state"]) => T) | OutputSelector<Api["state"], T>, equals?: (a: T, b: T) => boolean) => T;
@@ -1,8 +1,8 @@
1
1
  import * as React from 'react';
2
+ import { fastObjectShallowCompare } from '@mui/x-internals/fastObjectShallowCompare';
2
3
  import { useLazyRef } from './useLazyRef';
3
4
  import { useOnMount } from './useOnMount';
4
5
  import { warnOnce } from '../../internals/utils/warning';
5
- import { fastObjectShallowCompare } from '../../utils/fastObjectShallowCompare';
6
6
  function isOutputSelector(selector) {
7
7
  return selector.acceptsApiRef;
8
8
  }
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid v7.12.0
2
+ * @mui/x-data-grid v7.13.0
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -31,6 +31,7 @@ export { useGridCsvExport } from '../hooks/features/export/useGridCsvExport';
31
31
  export { useGridPrintExport } from '../hooks/features/export/useGridPrintExport';
32
32
  export { useGridFilter, filterStateInitializer } from '../hooks/features/filter/useGridFilter';
33
33
  export { passFilterLogic } from '../hooks/features/filter/gridFilterUtils';
34
+ export { gridFilteredChildrenCountLookupSelector, gridExpandedSortedRowTreeLevelPositionLookupSelector, } from '../hooks/features/filter/gridFilterSelector';
34
35
  export { isSingleSelectColDef } from '../components/panel/filterPanel/filterPanelUtils';
35
36
  export type { GridAggregatedFilterItemApplier, GridAggregatedFilterItemApplierResult, } from '../hooks/features/filter/gridFilterState';
36
37
  export { useGridFocus, focusStateInitializer } from '../hooks/features/focus/useGridFocus';
@@ -40,6 +41,8 @@ export { useGridPreferencesPanel, preferencePanelStateInitializer, } from '../ho
40
41
  export { useGridEditing, editingStateInitializer } from '../hooks/features/editing/useGridEditing';
41
42
  export { gridEditRowsStateSelector } from '../hooks/features/editing/gridEditingSelectors';
42
43
  export { useGridRows, rowsStateInitializer } from '../hooks/features/rows/useGridRows';
44
+ export { useGridAriaAttributes } from '../hooks/utils/useGridAriaAttributes';
45
+ export { useGridRowAriaAttributes } from '../hooks/features/rows/useGridRowAriaAttributes';
43
46
  export { useGridRowsPreProcessors } from '../hooks/features/rows/useGridRowsPreProcessors';
44
47
  export type { GridRowTreeCreationParams, GridRowTreeCreationValue, GridHydrateRowsValue, GridRowsPartialUpdates, GridRowsPartialUpdateAction, GridTreeDepths, GridRowTreeUpdatedGroupsManager, GridRowTreeUpdateGroupAction, GridPinnedRowsState, } from '../hooks/features/rows/gridRowsInterfaces';
45
48
  export { getTreeNodeDescendants, buildRootGroup } from '../hooks/features/rows/gridRowsUtils';
@@ -74,7 +77,6 @@ export { gridRowGroupsToFetchSelector } from '../hooks/features/rows/gridRowsSel
74
77
  export { findParentElementFromClassName, getActiveElement, isEventTargetInPortal, } from '../utils/domUtils';
75
78
  export { isNavigationKey, isPasteShortcut } from '../utils/keyboardUtils';
76
79
  export * from '../utils/utils';
77
- export * from '../utils/fastMemo';
78
80
  export { exportAs } from '../utils/exportAs';
79
81
  export * from '../utils/getPublicApiRef';
80
82
  export * from '../utils/cellBorderUtils';
@@ -23,6 +23,7 @@ export { useGridCsvExport } from '../hooks/features/export/useGridCsvExport';
23
23
  export { useGridPrintExport } from '../hooks/features/export/useGridPrintExport';
24
24
  export { useGridFilter, filterStateInitializer } from '../hooks/features/filter/useGridFilter';
25
25
  export { passFilterLogic } from '../hooks/features/filter/gridFilterUtils';
26
+ export { gridFilteredChildrenCountLookupSelector, gridExpandedSortedRowTreeLevelPositionLookupSelector } from '../hooks/features/filter/gridFilterSelector';
26
27
  export { isSingleSelectColDef } from '../components/panel/filterPanel/filterPanelUtils';
27
28
  export { useGridFocus, focusStateInitializer } from '../hooks/features/focus/useGridFocus';
28
29
  export { useGridKeyboardNavigation } from '../hooks/features/keyboardNavigation/useGridKeyboardNavigation';
@@ -31,6 +32,8 @@ export { useGridPreferencesPanel, preferencePanelStateInitializer } from '../hoo
31
32
  export { useGridEditing, editingStateInitializer } from '../hooks/features/editing/useGridEditing';
32
33
  export { gridEditRowsStateSelector } from '../hooks/features/editing/gridEditingSelectors';
33
34
  export { useGridRows, rowsStateInitializer } from '../hooks/features/rows/useGridRows';
35
+ export { useGridAriaAttributes } from '../hooks/utils/useGridAriaAttributes';
36
+ export { useGridRowAriaAttributes } from '../hooks/features/rows/useGridRowAriaAttributes';
34
37
  export { useGridRowsPreProcessors } from '../hooks/features/rows/useGridRowsPreProcessors';
35
38
  export { getTreeNodeDescendants, buildRootGroup } from '../hooks/features/rows/gridRowsUtils';
36
39
  export { useGridRowsMeta, rowsMetaStateInitializer } from '../hooks/features/rows/useGridRowsMeta';
@@ -59,7 +62,6 @@ export { gridRowGroupsToFetchSelector } from '../hooks/features/rows/gridRowsSel
59
62
  export { findParentElementFromClassName, getActiveElement, isEventTargetInPortal } from '../utils/domUtils';
60
63
  export { isNavigationKey, isPasteShortcut } from '../utils/keyboardUtils';
61
64
  export * from '../utils/utils';
62
- export * from '../utils/fastMemo';
63
65
  export { exportAs } from '../utils/exportAs';
64
66
  export * from '../utils/getPublicApiRef';
65
67
  export * from '../utils/cellBorderUtils';
package/locales/viVN.js CHANGED
@@ -30,11 +30,10 @@ const viVNGrid = {
30
30
  toolbarExportPrint: 'In',
31
31
  toolbarExportExcel: 'Xuất Excel',
32
32
  // Columns management text
33
- // columnsManagementSearchTitle: 'Search',
34
- // columnsManagementNoColumns: 'No columns',
35
- // columnsManagementShowHideAllText: 'Show/Hide All',
36
- // columnsManagementReset: 'Reset',
37
-
33
+ columnsManagementSearchTitle: 'Tìm kiếm',
34
+ columnsManagementNoColumns: 'Không có cột',
35
+ columnsManagementShowHideAllText: 'Hiện/Ẩn Tất cả',
36
+ columnsManagementReset: 'Đặt lại',
38
37
  // Filter panel text
39
38
  filterPanelAddFilter: 'Thêm bộ lọc',
40
39
  filterPanelRemoveAll: 'Xóa tất cả',
@@ -67,7 +67,7 @@ export interface GridCorePrivateApi<GridPublicApi extends GridApiCommon, GridPri
67
67
  /**
68
68
  * The React ref of the grid column container virtualized div element.
69
69
  */
70
- columnHeadersContainerRef?: React.RefObject<HTMLDivElement>;
70
+ columnHeadersContainerRef: React.RefObject<HTMLDivElement>;
71
71
  /**
72
72
  * The React ref of the grid header filter row element.
73
73
  */
@@ -0,0 +1,10 @@
1
+ import * as React from 'react';
2
+ import { GridRowAriaAttributesInternalHook } from './gridRowConfiguration';
3
+ export interface GridAriaAttributesInternalHook {
4
+ useGridAriaAttributes: () => React.HTMLAttributes<HTMLElement>;
5
+ }
6
+ export interface GridInternalHook extends GridAriaAttributesInternalHook, GridRowAriaAttributesInternalHook {
7
+ }
8
+ export interface GridConfiguration {
9
+ hooks: GridInternalHook;
10
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ import * as React from 'react';
2
+ import { GridTreeNode } from '../gridRows';
3
+ /**
4
+ * Get the ARIA attributes for a row
5
+ * @param {GridTreeNode} rowNode The row node
6
+ * @param {number} index The position index of the row
7
+ * @returns {React.HTMLAttributes<HTMLElement>} The ARIA attributes
8
+ */
9
+ export type GetRowAriaAttributesFn = (rowNode: GridTreeNode, index: number) => React.HTMLAttributes<HTMLElement>;
10
+ export interface GridRowAriaAttributesInternalHook {
11
+ useGridRowAriaAttributes: () => GetRowAriaAttributesFn;
12
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -63,7 +63,8 @@ export interface GridDataSource {
63
63
  /**
64
64
  * Used to determine the number of children a row has on server.
65
65
  * @param {GridRowModel} row The row to check the number of children
66
- * @returns {number} The number of children the row has
66
+ * @returns {number} The number of children the row has.
67
+ * If the children count is not available for some reason, but there are some children, `getChildrenCount` should return `-1`.
67
68
  */
68
69
  getChildrenCount?: (row: GridRowModel) => number;
69
70
  }
@@ -104,9 +104,9 @@ export interface GridDataGroupNode extends GridBasicGroupNode {
104
104
  }
105
105
  export interface GridDataSourceGroupNode extends GridDataGroupNode {
106
106
  /**
107
- * If true, this node has children on server.
107
+ * Number of children this node has on the server. Equals to `-1` if there are some children but the count is unknown.
108
108
  */
109
- hasServerChildren: boolean;
109
+ serverChildrenCount: number;
110
110
  /**
111
111
  * The cached path to be passed on as `groupKey` to the server.
112
112
  */
@@ -441,7 +441,7 @@ export interface DataGridPropsWithoutDefaultValue<R extends GridValidRowModel =
441
441
  /**
442
442
  * Determines if a row can be selected.
443
443
  * @param {GridRowParams} params With all properties from [[GridRowParams]].
444
- * @returns {boolean} A boolean indicating if the cell is selectable.
444
+ * @returns {boolean} A boolean indicating if the row is selectable.
445
445
  */
446
446
  isRowSelectable?: (params: GridRowParams<R>) => boolean;
447
447
  /**
@@ -4,11 +4,19 @@ import _extends from "@babel/runtime/helpers/esm/extends";
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
6
  import { GridBody, GridFooterPlaceholder, GridHeader, GridRoot } from '../components';
7
+ import { useGridAriaAttributes } from '../hooks/utils/useGridAriaAttributes';
8
+ import { useGridRowAriaAttributes } from '../hooks/features/rows/useGridRowAriaAttributes';
7
9
  import { GridContextProvider } from '../context/GridContextProvider';
8
10
  import { useDataGridComponent } from './useDataGridComponent';
9
11
  import { useDataGridProps } from './useDataGridProps';
10
12
  import { propValidatorsDataGrid, validateProps } from '../internals/utils/propValidation';
11
13
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
+ const configuration = {
15
+ hooks: {
16
+ useGridAriaAttributes,
17
+ useGridRowAriaAttributes
18
+ }
19
+ };
12
20
  let propValidators;
13
21
  if (process.env.NODE_ENV !== 'production') {
14
22
  propValidators = [...propValidatorsDataGrid,
@@ -23,6 +31,7 @@ const DataGridRaw = /*#__PURE__*/React.forwardRef(function DataGrid(inProps, ref
23
31
  }
24
32
  return /*#__PURE__*/_jsx(GridContextProvider, {
25
33
  privateApiRef: privateApiRef,
34
+ configuration: configuration,
26
35
  props: props,
27
36
  children: /*#__PURE__*/_jsxs(GridRoot, _extends({
28
37
  className: props.className,
@@ -321,7 +330,7 @@ DataGridRaw.propTypes = {
321
330
  /**
322
331
  * Determines if a row can be selected.
323
332
  * @param {GridRowParams} params With all properties from [[GridRowParams]].
324
- * @returns {boolean} A boolean indicating if the cell is selectable.
333
+ * @returns {boolean} A boolean indicating if the row is selectable.
325
334
  */
326
335
  isRowSelectable: PropTypes.func,
327
336
  /**
@@ -3,7 +3,7 @@ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWith
3
3
  const _excluded = ["className", "visibleColumns", "sortColumnLookup", "filterColumnLookup", "columnHeaderTabIndexState", "columnGroupHeaderTabIndexState", "columnHeaderFocus", "columnGroupHeaderFocus", "headerGroupingMaxDepth", "columnMenuState", "columnVisibility", "columnGroupsHeaderStructure", "hasOtherElementInTabSequence"];
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
- import { fastMemo } from '../utils/fastMemo';
6
+ import { fastMemo } from '@mui/x-internals/fastMemo';
7
7
  import { useGridColumnHeaders } from '../hooks/features/columnHeaders/useGridColumnHeaders';
8
8
  import { GridBaseColumnHeaders } from './columnHeaders/GridBaseColumnHeaders';
9
9
  import { jsxs as _jsxs } from "react/jsx-runtime";
@@ -0,0 +1,5 @@
1
+ import * as React from 'react';
2
+ export const GridConfigurationContext = /*#__PURE__*/React.createContext(undefined);
3
+ if (process.env.NODE_ENV !== 'production') {
4
+ GridConfigurationContext.displayName = 'GridConfigurationContext';
5
+ }
@@ -1,6 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
- import { fastMemo } from '../utils/fastMemo';
3
+ import { fastMemo } from '@mui/x-internals/fastMemo';
4
4
  import { useGridPrivateApiContext } from '../hooks/utils/useGridPrivateApiContext';
5
5
  import { useGridSelector } from '../hooks/utils/useGridSelector';
6
6
  import { useGridRootProps } from '../hooks/utils/useGridRootProps';
@@ -27,10 +27,7 @@ function GridHeaders() {
27
27
  const columnVisibility = useGridSelector(apiRef, gridColumnVisibilityModelSelector);
28
28
  const columnGroupsHeaderStructure = useGridSelector(apiRef, gridColumnGroupsHeaderStructureSelector);
29
29
  const hasOtherElementInTabSequence = !(columnGroupHeaderTabIndexState === null && columnHeaderTabIndexState === null && cellTabIndexState === null);
30
- const columnsContainerRef = React.useRef(null);
31
- apiRef.current.register('private', {
32
- columnHeadersContainerRef: columnsContainerRef
33
- });
30
+ const columnsContainerRef = apiRef.current.columnHeadersContainerRef;
34
31
  return /*#__PURE__*/_jsx(rootProps.slots.columnHeaders, _extends({
35
32
  ref: columnsContainerRef,
36
33
  visibleColumns: visibleColumns,
@@ -5,7 +5,7 @@ import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
6
  import clsx from 'clsx';
7
7
  import { unstable_useForkRef as useForkRef } from '@mui/utils';
8
- import { fastMemo } from '../utils/fastMemo';
8
+ import { fastMemo } from '@mui/x-internals/fastMemo';
9
9
  import { GridEditModes, GridRowModes, GridCellModes } from '../models/gridEditRowModel';
10
10
  import { useGridApiContext } from '../hooks/utils/useGridApiContext';
11
11
  import { gridClasses } from '../constants/gridClasses';
@@ -20,11 +20,11 @@ import { GRID_ACTIONS_COLUMN_TYPE } from '../colDef/gridActionsColDef';
20
20
  import { GRID_DETAIL_PANEL_TOGGLE_FIELD } from '../constants/gridDetailPanelToggleField';
21
21
  import { gridSortModelSelector } from '../hooks/features/sorting/gridSortingSelector';
22
22
  import { gridRowMaximumTreeDepthSelector } from '../hooks/features/rows/gridRowsSelector';
23
- import { gridColumnGroupsHeaderMaxDepthSelector } from '../hooks/features/columnGrouping/gridColumnGroupsSelector';
24
23
  import { gridEditRowsStateSelector } from '../hooks/features/editing/gridEditingSelectors';
25
24
  import { PinnedPosition, gridPinnedColumnPositionLookup } from './cell/GridCell';
26
25
  import { GridScrollbarFillerCell as ScrollbarFiller } from './GridScrollbarFillerCell';
27
26
  import { getPinnedCellOffset } from '../internals/utils/getPinnedCellOffset';
27
+ import { useGridConfiguration } from '../hooks/utils/useGridConfiguration';
28
28
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
29
29
  function EmptyCell({
30
30
  width
@@ -68,12 +68,12 @@ const GridRow = /*#__PURE__*/React.forwardRef(function GridRow(props, refProp) {
68
68
  } = props,
69
69
  other = _objectWithoutPropertiesLoose(props, _excluded);
70
70
  const apiRef = useGridApiContext();
71
+ const configuration = useGridConfiguration();
71
72
  const ref = React.useRef(null);
72
73
  const rootProps = useGridRootProps();
73
74
  const currentPage = useGridVisibleRows(apiRef, rootProps);
74
75
  const sortModel = useGridSelector(apiRef, gridSortModelSelector);
75
76
  const treeDepth = useGridSelector(apiRef, gridRowMaximumTreeDepthSelector);
76
- const headerGroupingMaxDepth = useGridSelector(apiRef, gridColumnGroupsHeaderMaxDepthSelector);
77
77
  const columnPositions = useGridSelector(apiRef, gridColumnPositionsSelector);
78
78
  const editRowsState = useGridSelector(apiRef, gridEditRowsStateSelector);
79
79
  const handleRef = useForkRef(ref, refProp);
@@ -85,11 +85,10 @@ const GridRow = /*#__PURE__*/React.forwardRef(function GridRow(props, refProp) {
85
85
  const hasFocusCell = focusedColumnIndex !== undefined;
86
86
  const hasVirtualFocusCellLeft = hasFocusCell && focusedColumnIndex >= pinnedColumns.left.length && focusedColumnIndex < renderContext.firstColumnIndex;
87
87
  const hasVirtualFocusCellRight = hasFocusCell && focusedColumnIndex < visibleColumns.length - pinnedColumns.right.length && focusedColumnIndex >= renderContext.lastColumnIndex;
88
- const ariaRowIndex = index + headerGroupingMaxDepth + 2; // 1 for the header row and 1 as it's 1-based
89
-
90
88
  const classes = composeGridClasses(rootProps.classes, {
91
89
  root: ['row', selected && 'selected', editable && 'row--editable', editing && 'row--editing', isFirstVisible && 'row--firstVisible', isLastVisible && 'row--lastVisible', showBottomBorder && 'row--borderBottom', rowHeight === 'auto' && 'row--dynamicHeight']
92
90
  });
91
+ const getRowAriaAttributes = configuration.hooks.useGridRowAriaAttributes();
93
92
  React.useLayoutEffect(() => {
94
93
  if (currentPage.range) {
95
94
  // The index prop is relative to the rows from all pages. As example, the index prop of the
@@ -212,6 +211,7 @@ const GridRow = /*#__PURE__*/React.forwardRef(function GridRow(props, refProp) {
212
211
  return rowStyle;
213
212
  }, [isNotVisible, rowHeight, styleProp, minHeight, sizes, rootProps.rowSpacingType]);
214
213
  const rowClassNames = apiRef.current.unstable_applyPipeProcessors('rowClassName', [], rowId);
214
+ const ariaAttributes = rowNode ? getRowAriaAttributes(rowNode, index) : undefined;
215
215
  if (typeof rootProps.getRowClassName === 'function') {
216
216
  const indexRelativeToCurrentPage = index - (currentPage.range?.firstRowIndex || 0);
217
217
  const rowParams = _extends({}, apiRef.current.getRowParams(rowId), {
@@ -308,10 +308,8 @@ const GridRow = /*#__PURE__*/React.forwardRef(function GridRow(props, refProp) {
308
308
  "data-rowindex": index,
309
309
  role: "row",
310
310
  className: clsx(...rowClassNames, classes.root, className),
311
- "aria-rowindex": ariaRowIndex,
312
- "aria-selected": selected,
313
311
  style: style
314
- }, eventHandlers, other, {
312
+ }, ariaAttributes, eventHandlers, other, {
315
313
  children: [leftCells, /*#__PURE__*/_jsx("div", {
316
314
  role: "presentation",
317
315
  className: gridClasses.cellOffsetLeft,
@@ -3,6 +3,7 @@ import * as React from 'react';
3
3
  import clsx from 'clsx';
4
4
  import { unstable_composeClasses as composeClasses, unstable_useEventCallback as useEventCallback } from '@mui/utils';
5
5
  import { styled } from '@mui/system';
6
+ import { fastMemo } from '@mui/x-internals/fastMemo';
6
7
  import { useGridRootProps } from '../hooks/utils/useGridRootProps';
7
8
  import { getDataGridUtilityClass, gridClasses } from '../constants';
8
9
  import { useGridApiContext } from '../hooks/utils/useGridApiContext';
@@ -13,7 +14,6 @@ import { gridDensityFactorSelector } from '../hooks/features/density/densitySele
13
14
  import { gridColumnsTotalWidthSelector } from '../hooks/features/columns/gridColumnsSelector';
14
15
  import { useTimeout } from '../hooks/utils/useTimeout';
15
16
  import { getTotalHeaderHeight } from '../hooks/features/columns/gridColumnsUtils';
16
- import { fastMemo } from '../utils/fastMemo';
17
17
  import { jsx as _jsx } from "react/jsx-runtime";
18
18
  const CLIFF = 1;
19
19
  const SLOP = 1.5;
@@ -119,7 +119,7 @@ const GridSkeletonLoadingOverlay = /*#__PURE__*/React.forwardRef(function GridSk
119
119
  if (hasScrollbarFiller) {
120
120
  rowCells.push( /*#__PURE__*/_jsx(GridScrollbarFillerCell, {
121
121
  pinnedRight: pinnedColumns.right.length > 0
122
- }));
122
+ }, `skeleton-scrollbar-filler-${i}`));
123
123
  }
124
124
  }
125
125
  array.push( /*#__PURE__*/_jsx("div", {
@@ -6,7 +6,7 @@ import * as React from 'react';
6
6
  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
- import { fastMemo } from '../../utils/fastMemo';
9
+ import { fastMemo } from '@mui/x-internals/fastMemo';
10
10
  import { doesSupportPreventScroll } from '../../utils/doesSupportPreventScroll';
11
11
  import { getDataGridUtilityClass, gridClasses } from '../../constants/gridClasses';
12
12
  import { GridCellModes } from '../../models';
@@ -3,10 +3,10 @@ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWith
3
3
  const _excluded = ["field", "type", "align", "width", "height", "empty", "style", "className"];
4
4
  import * as React from 'react';
5
5
  import PropTypes from 'prop-types';
6
+ import clsx from 'clsx';
6
7
  import Skeleton from '@mui/material/Skeleton';
7
8
  import { unstable_composeClasses as composeClasses, unstable_capitalize as capitalize } from '@mui/utils';
8
- import clsx from 'clsx';
9
- import { fastMemo } from '../../utils/fastMemo';
9
+ import { fastMemo } from '@mui/x-internals/fastMemo';
10
10
  import { createRandomNumberGenerator } from '../../utils/utils';
11
11
  import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
12
12
  import { getDataGridUtilityClass } from '../../constants/gridClasses';
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import PropTypes from 'prop-types';
4
4
  import clsx from 'clsx';
5
5
  import { unstable_composeClasses as composeClasses, unstable_useId as useId } from '@mui/utils';
6
- import { fastMemo } from '../../utils/fastMemo';
6
+ import { fastMemo } from '@mui/x-internals/fastMemo';
7
7
  import { useGridPrivateApiContext } from '../../hooks/utils/useGridPrivateApiContext';
8
8
  import { ColumnHeaderMenuIcon } from './ColumnHeaderMenuIcon';
9
9
  import { GridColumnHeaderMenu } from '../menu/columnMenu/GridColumnHeaderMenu';
@@ -668,9 +668,16 @@ export const GridRootStyles = styled('div', {
668
668
  [`& .${c['filler--borderTop']}`]: {
669
669
  borderTop: '1px solid var(--DataGrid-rowBorderColor)'
670
670
  },
671
- /* Hide grid rows and vertical scrollbar when skeleton overlay is visible */
671
+ /* Hide grid rows, row filler, and vertical scrollbar when skeleton overlay is visible */
672
672
  [`& .${c['main--hasSkeletonLoadingOverlay']}`]: {
673
- [`& .${c.virtualScrollerContent}, & .${c['scrollbar--vertical']}, & .${c.pinnedRows}`]: {
673
+ [`& .${c.virtualScrollerContent}`]: {
674
+ // We use visibility hidden so that the virtual scroller content retains its height.
675
+ // Position fixed is used to remove the virtual scroller content from the flow.
676
+ // https://github.com/mui/mui-x/issues/14061
677
+ position: 'fixed',
678
+ visibility: 'hidden'
679
+ },
680
+ [`& .${c['scrollbar--vertical']}, & .${c.pinnedRows}, & .${c.virtualScroller} > .${c.filler}`]: {
674
681
  display: 'none'
675
682
  }
676
683
  }