@mui/x-data-grid-pro 7.29.5 → 7.29.7

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 (26) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/DataGridPro/useDataGridProComponent.js +9 -5
  3. package/hooks/features/columnPinning/useGridColumnPinningPreProcessors.js +4 -4
  4. package/hooks/features/detailPanel/useGridDetailPanelPreProcessors.js +17 -19
  5. package/hooks/features/rowReorder/useGridRowReorderPreProcessors.js +10 -8
  6. package/hooks/features/serverSideTreeData/useGridDataSourceTreeDataPreProcessors.js +2 -3
  7. package/hooks/features/treeData/useGridTreeDataPreProcessors.js +2 -3
  8. package/index.js +1 -1
  9. package/modern/DataGridPro/useDataGridProComponent.js +9 -5
  10. package/modern/hooks/features/columnPinning/useGridColumnPinningPreProcessors.js +4 -4
  11. package/modern/hooks/features/detailPanel/useGridDetailPanelPreProcessors.js +17 -19
  12. package/modern/hooks/features/rowReorder/useGridRowReorderPreProcessors.js +10 -8
  13. package/modern/hooks/features/serverSideTreeData/useGridDataSourceTreeDataPreProcessors.js +2 -3
  14. package/modern/hooks/features/treeData/useGridTreeDataPreProcessors.js +2 -3
  15. package/modern/index.js +1 -1
  16. package/modern/utils/releaseInfo.js +1 -1
  17. package/node/DataGridPro/useDataGridProComponent.js +9 -5
  18. package/node/hooks/features/columnPinning/useGridColumnPinningPreProcessors.js +3 -3
  19. package/node/hooks/features/detailPanel/useGridDetailPanelPreProcessors.js +17 -19
  20. package/node/hooks/features/rowReorder/useGridRowReorderPreProcessors.js +10 -8
  21. package/node/hooks/features/serverSideTreeData/useGridDataSourceTreeDataPreProcessors.js +1 -2
  22. package/node/hooks/features/treeData/useGridTreeDataPreProcessors.js +1 -2
  23. package/node/index.js +1 -1
  24. package/node/utils/releaseInfo.js +1 -1
  25. package/package.json +2 -2
  26. package/utils/releaseInfo.js +1 -1
package/CHANGELOG.md CHANGED
@@ -3,6 +3,72 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## v7.29.7
7
+
8
+ <!-- generated comparing v7.29.6..v7.x -->
9
+
10
+ _Jun 26, 2025_
11
+
12
+ We'd like to extend a big thank you to the 4 contributors who made this release possible.
13
+
14
+ Special thanks go out to the community members for their valuable contributions:
15
+ @alisasanib
16
+
17
+ Following are all team members who have contributed to this release:
18
+ @mapache-salvaje, @arminmeh, @michelengelen
19
+
20
+ ### Data Grid
21
+
22
+ #### `@mui/x-data-grid@7.29.7`
23
+
24
+ Internal changes.
25
+
26
+ #### `@mui/x-data-grid-pro@7.29.7` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
27
+
28
+ Same changes as in `@mui/x-data-grid@7.29.7`, plus:
29
+
30
+ - [DataGridPro] Fix pinned columns order in column management (#18053) @alisasanib
31
+
32
+ #### `@mui/x-data-grid-premium@7.29.7` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
33
+
34
+ Same changes as in `@mui/x-data-grid-pro@7.29.7`.
35
+
36
+ ### Docs
37
+
38
+ - [docs] Revise the Row Grouping doc (#17494) @mapache-salvaje
39
+ - [docs] Document `GridRenderContext` (#18501) @arminmeh
40
+ - [docs] Prevent stale rows from appearing on sort and filter change in the lazy loading demo (#18463) @arminmeh
41
+
42
+ ### Miscellaneous
43
+
44
+ - [infra] Add automated release PR creation script (#18450) @michelengelen
45
+
46
+ ## 7.29.6
47
+
48
+ _Jun 6, 2025_
49
+
50
+ We'd like to extend a big thank you to @arminmeh, who made this release possible.
51
+
52
+ <!--/ HIGHLIGHT_ABOVE_SEPARATOR /-->
53
+
54
+ ### Data Grid
55
+
56
+ #### `@mui/x-data-grid@7.29.6`
57
+
58
+ - [DataGrid] Keep pipe pre-processors execution order when callback reference changes (#18217) @arminmeh
59
+
60
+ #### `@mui/x-data-grid-pro@7.29.6` [![pro](https://mui.com/r/x-pro-svg)](https://mui.com/r/x-pro-svg-link 'Pro plan')
61
+
62
+ Same changes as in `@mui/x-data-grid@7.29.6`.
63
+
64
+ #### `@mui/x-data-grid-premium@7.29.6` [![premium](https://mui.com/r/x-premium-svg)](https://mui.com/r/x-premium-svg-link 'Premium plan')
65
+
66
+ Same changes as in `@mui/x-data-grid-pro@7.29.6`.
67
+
68
+ ### Docs
69
+
70
+ - [docs] Keep `groupingColDef` reference stable in the grid demos (#17549) @arminmeh
71
+
6
72
  ## 7.29.5
7
73
 
8
74
  _May 29, 2025_
@@ -21,16 +21,20 @@ export const useDataGridProComponent = (inputApiRef, props) => {
21
21
 
22
22
  /**
23
23
  * Register all pre-processors called during state initialization here.
24
+ * Some pre-processors are changing the same part of the state (like the order of the columns).
25
+ * Order them in descending order of priority.
26
+ * For example, left pinned columns should always render first from the left, so the `hydrateColumns` pre-processor from `useGridColumnPinningPreProcessors` should be called last (after all other `hydrateColumns` pre-processors).
27
+ * Similarly, the `hydrateColumns` pre-processor from `useGridRowSelectionPreProcessors` should be called after `useGridTreeDataPreProcessors` because the selection checkboxes should appear before the tree data.
28
+ * Desired autogenerated columns order is:
29
+ * left pinned columns -> row reordering column -> checkbox column -> tree data column -> master detail column -> rest of the columns
24
30
  */
25
- useGridRowSelectionPreProcessors(apiRef, props);
26
- useGridRowReorderPreProcessors(apiRef, props);
31
+ useGridDetailPanelPreProcessors(apiRef, props);
27
32
  useGridTreeDataPreProcessors(apiRef, props);
28
33
  useGridDataSourceTreeDataPreProcessors(apiRef, props);
34
+ useGridRowSelectionPreProcessors(apiRef, props);
29
35
  useGridLazyLoaderPreProcessors(apiRef, props);
30
36
  useGridRowPinningPreProcessors(apiRef);
31
- useGridDetailPanelPreProcessors(apiRef, props);
32
- // The column pinning `hydrateColumns` pre-processor must be after every other `hydrateColumns` pre-processors
33
- // Because it changes the order of the columns.
37
+ useGridRowReorderPreProcessors(apiRef, props);
34
38
  useGridColumnPinningPreProcessors(apiRef, props);
35
39
  useGridRowsPreProcessors(apiRef);
36
40
 
@@ -1,6 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
- import { useGridRegisterPipeProcessor, gridVisiblePinnedColumnDefinitionsSelector } from '@mui/x-data-grid/internals';
3
+ import { useGridRegisterPipeProcessor, gridExistingPinnedColumnSelector } from '@mui/x-data-grid/internals';
4
4
  export const useGridColumnPinningPreProcessors = (apiRef, props) => {
5
5
  const {
6
6
  disableColumnPinning
@@ -20,12 +20,12 @@ export const useGridColumnPinningPreProcessors = (apiRef, props) => {
20
20
  apiRef.current.state = _extends({}, savedState, {
21
21
  columns: columnsState
22
22
  });
23
- const visibleColumns = gridVisiblePinnedColumnDefinitionsSelector(apiRef);
23
+ const pinnedColumns = gridExistingPinnedColumnSelector(apiRef);
24
24
  apiRef.current.state = savedState;
25
25
  // HACK: Ends here //
26
26
 
27
- const leftPinnedColumns = visibleColumns.left.map(c => c.field);
28
- const rightPinnedColumns = visibleColumns.right.map(c => c.field);
27
+ const leftPinnedColumns = pinnedColumns.left;
28
+ const rightPinnedColumns = pinnedColumns.right;
29
29
  let newOrderedFields;
30
30
  const allPinnedColumns = [...leftPinnedColumns, ...rightPinnedColumns];
31
31
  const {
@@ -6,28 +6,26 @@ import { GRID_DETAIL_PANEL_TOGGLE_FIELD, GRID_DETAIL_PANEL_TOGGLE_COL_DEF } from
6
6
  import { gridDetailPanelExpandedRowIdsSelector } from "./gridDetailPanelSelector.js";
7
7
  export const useGridDetailPanelPreProcessors = (privateApiRef, props) => {
8
8
  const addToggleColumn = React.useCallback(columnsState => {
9
- if (props.getDetailPanelContent == null) {
10
- // Remove the toggle column, when it exists
11
- if (columnsState.lookup[GRID_DETAIL_PANEL_TOGGLE_FIELD]) {
12
- delete columnsState.lookup[GRID_DETAIL_PANEL_TOGGLE_FIELD];
13
- columnsState.orderedFields = columnsState.orderedFields.filter(field => field !== GRID_DETAIL_PANEL_TOGGLE_FIELD);
14
- }
15
- return columnsState;
16
- }
17
-
18
- // Don't add the toggle column if there's already one
19
- // The user might have manually added it to have it in a custom position
20
- if (columnsState.lookup[GRID_DETAIL_PANEL_TOGGLE_FIELD]) {
21
- return columnsState;
22
- }
23
-
24
- // Otherwise, add the toggle column at the beginning
25
- columnsState.orderedFields = [GRID_DETAIL_PANEL_TOGGLE_FIELD, ...columnsState.orderedFields];
26
- columnsState.lookup[GRID_DETAIL_PANEL_TOGGLE_FIELD] = _extends({}, GRID_DETAIL_PANEL_TOGGLE_COL_DEF, {
9
+ const detailPanelToggleColumn = _extends({}, GRID_DETAIL_PANEL_TOGGLE_COL_DEF, {
27
10
  headerName: privateApiRef.current.getLocaleText('detailPanelToggle')
28
11
  });
12
+ const shouldHaveToggleColumn = !!props.getDetailPanelContent;
13
+ const hasToggleColumn = columnsState.lookup[GRID_DETAIL_PANEL_TOGGLE_FIELD] != null;
14
+ if (shouldHaveToggleColumn && !hasToggleColumn) {
15
+ columnsState.lookup[GRID_DETAIL_PANEL_TOGGLE_FIELD] = detailPanelToggleColumn;
16
+ columnsState.orderedFields = [GRID_DETAIL_PANEL_TOGGLE_FIELD, ...columnsState.orderedFields];
17
+ } else if (!shouldHaveToggleColumn && hasToggleColumn) {
18
+ delete columnsState.lookup[GRID_DETAIL_PANEL_TOGGLE_FIELD];
19
+ columnsState.orderedFields = columnsState.orderedFields.filter(field => field !== GRID_DETAIL_PANEL_TOGGLE_FIELD);
20
+ } else if (shouldHaveToggleColumn && hasToggleColumn) {
21
+ columnsState.lookup[GRID_DETAIL_PANEL_TOGGLE_FIELD] = _extends({}, detailPanelToggleColumn, columnsState.lookup[GRID_DETAIL_PANEL_TOGGLE_FIELD]);
22
+ // If the column is not in the columns array (not a custom detail panel toggle column), move it to the beginning of the column order
23
+ if (!props.columns.some(col => col.field === GRID_DETAIL_PANEL_TOGGLE_FIELD)) {
24
+ columnsState.orderedFields = [GRID_DETAIL_PANEL_TOGGLE_FIELD, ...columnsState.orderedFields.filter(field => field !== GRID_DETAIL_PANEL_TOGGLE_FIELD)];
25
+ }
26
+ }
29
27
  return columnsState;
30
- }, [privateApiRef, props.getDetailPanelContent]);
28
+ }, [privateApiRef, props.columns, props.getDetailPanelContent]);
31
29
  const addExpandedClassToRow = React.useCallback((classes, id) => {
32
30
  if (props.getDetailPanelContent == null) {
33
31
  return classes;
@@ -28,19 +28,21 @@ export const useGridRowReorderPreProcessors = (privateApiRef, props) => {
28
28
  headerName: privateApiRef.current.getLocaleText('rowReorderingHeaderName')
29
29
  });
30
30
  const shouldHaveReorderColumn = props.rowReordering;
31
- const haveReorderColumn = columnsState.lookup[reorderColumn.field] != null;
32
- if (shouldHaveReorderColumn && haveReorderColumn) {
33
- columnsState.lookup[reorderColumn.field] = _extends({}, reorderColumn, columnsState.lookup[reorderColumn.field]);
34
- return columnsState;
35
- }
36
- if (shouldHaveReorderColumn && !haveReorderColumn) {
31
+ const hasReorderColumn = columnsState.lookup[reorderColumn.field] != null;
32
+ if (shouldHaveReorderColumn && !hasReorderColumn) {
37
33
  columnsState.lookup[reorderColumn.field] = reorderColumn;
38
34
  columnsState.orderedFields = [reorderColumn.field, ...columnsState.orderedFields];
39
- } else if (!shouldHaveReorderColumn && haveReorderColumn) {
35
+ } else if (!shouldHaveReorderColumn && hasReorderColumn) {
40
36
  delete columnsState.lookup[reorderColumn.field];
41
37
  columnsState.orderedFields = columnsState.orderedFields.filter(field => field !== reorderColumn.field);
38
+ } else if (shouldHaveReorderColumn && hasReorderColumn) {
39
+ columnsState.lookup[reorderColumn.field] = _extends({}, reorderColumn, columnsState.lookup[reorderColumn.field]);
40
+ // If the column is not in the columns array (not a custom reorder column), move it to the beginning of the column order
41
+ if (!props.columns.some(col => col.field === GRID_REORDER_COL_DEF.field)) {
42
+ columnsState.orderedFields = [reorderColumn.field, ...columnsState.orderedFields.filter(field => field !== reorderColumn.field)];
43
+ }
42
44
  }
43
45
  return columnsState;
44
- }, [privateApiRef, classes, props.rowReordering]);
46
+ }, [privateApiRef, classes, props.columns, props.rowReordering]);
45
47
  useGridRegisterPipeProcessor(privateApiRef, 'hydrateColumns', updateReorderColumn);
46
48
  };
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
3
  const _excluded = ["hideDescendantCount"];
4
4
  import * as React from 'react';
5
- import { gridRowTreeSelector, useFirstRender, GRID_CHECKBOX_SELECTION_FIELD } from '@mui/x-data-grid';
5
+ import { gridRowTreeSelector, useFirstRender } from '@mui/x-data-grid';
6
6
  import { useGridRegisterPipeProcessor, useGridRegisterStrategyProcessor } from '@mui/x-data-grid/internals';
7
7
  import { GRID_TREE_DATA_GROUPING_COL_DEF, GRID_TREE_DATA_GROUPING_COL_DEF_FORCED_PROPERTIES } from "../treeData/gridTreeDataGroupColDef.js";
8
8
  import { skipFiltering, skipSorting } from "./utils.js";
@@ -56,8 +56,7 @@ export const useGridDataSourceTreeDataPreProcessors = (privateApiRef, props) =>
56
56
  }
57
57
  columnsState.lookup[groupingColDefField] = newGroupingColumn;
58
58
  if (prevGroupingColumn == null) {
59
- const index = columnsState.orderedFields[0] === GRID_CHECKBOX_SELECTION_FIELD ? 1 : 0;
60
- columnsState.orderedFields = [...columnsState.orderedFields.slice(0, index), groupingColDefField, ...columnsState.orderedFields.slice(index)];
59
+ columnsState.orderedFields = [groupingColDefField, ...columnsState.orderedFields];
61
60
  }
62
61
  } else if (!shouldHaveGroupingColumn && prevGroupingColumn) {
63
62
  delete columnsState.lookup[groupingColDefField];
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
3
  const _excluded = ["hideDescendantCount"];
4
4
  import * as React from 'react';
5
- import { gridRowTreeSelector, useFirstRender, GRID_CHECKBOX_SELECTION_FIELD } from '@mui/x-data-grid';
5
+ import { gridRowTreeSelector, useFirstRender } from '@mui/x-data-grid';
6
6
  import { useGridRegisterPipeProcessor, useGridRegisterStrategyProcessor } from '@mui/x-data-grid/internals';
7
7
  import { GRID_TREE_DATA_GROUPING_COL_DEF, GRID_TREE_DATA_GROUPING_COL_DEF_FORCED_PROPERTIES } from "./gridTreeDataGroupColDef.js";
8
8
  import { filterRowTreeFromTreeData, TreeDataStrategy } from "./gridTreeDataUtils.js";
@@ -56,8 +56,7 @@ export const useGridTreeDataPreProcessors = (privateApiRef, props) => {
56
56
  }
57
57
  columnsState.lookup[groupingColDefField] = newGroupingColumn;
58
58
  if (prevGroupingColumn == null) {
59
- const index = columnsState.orderedFields[0] === GRID_CHECKBOX_SELECTION_FIELD ? 1 : 0;
60
- columnsState.orderedFields = [...columnsState.orderedFields.slice(0, index), groupingColDefField, ...columnsState.orderedFields.slice(index)];
59
+ columnsState.orderedFields = [groupingColDefField, ...columnsState.orderedFields];
61
60
  }
62
61
  } else if (!shouldHaveGroupingColumn && prevGroupingColumn) {
63
62
  delete columnsState.lookup[groupingColDefField];
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid-pro v7.29.5
2
+ * @mui/x-data-grid-pro v7.29.7
3
3
  *
4
4
  * @license MUI X Commercial
5
5
  * This source code is licensed under the commercial license found in the
@@ -21,16 +21,20 @@ export const useDataGridProComponent = (inputApiRef, props) => {
21
21
 
22
22
  /**
23
23
  * Register all pre-processors called during state initialization here.
24
+ * Some pre-processors are changing the same part of the state (like the order of the columns).
25
+ * Order them in descending order of priority.
26
+ * For example, left pinned columns should always render first from the left, so the `hydrateColumns` pre-processor from `useGridColumnPinningPreProcessors` should be called last (after all other `hydrateColumns` pre-processors).
27
+ * Similarly, the `hydrateColumns` pre-processor from `useGridRowSelectionPreProcessors` should be called after `useGridTreeDataPreProcessors` because the selection checkboxes should appear before the tree data.
28
+ * Desired autogenerated columns order is:
29
+ * left pinned columns -> row reordering column -> checkbox column -> tree data column -> master detail column -> rest of the columns
24
30
  */
25
- useGridRowSelectionPreProcessors(apiRef, props);
26
- useGridRowReorderPreProcessors(apiRef, props);
31
+ useGridDetailPanelPreProcessors(apiRef, props);
27
32
  useGridTreeDataPreProcessors(apiRef, props);
28
33
  useGridDataSourceTreeDataPreProcessors(apiRef, props);
34
+ useGridRowSelectionPreProcessors(apiRef, props);
29
35
  useGridLazyLoaderPreProcessors(apiRef, props);
30
36
  useGridRowPinningPreProcessors(apiRef);
31
- useGridDetailPanelPreProcessors(apiRef, props);
32
- // The column pinning `hydrateColumns` pre-processor must be after every other `hydrateColumns` pre-processors
33
- // Because it changes the order of the columns.
37
+ useGridRowReorderPreProcessors(apiRef, props);
34
38
  useGridColumnPinningPreProcessors(apiRef, props);
35
39
  useGridRowsPreProcessors(apiRef);
36
40
 
@@ -1,6 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import * as React from 'react';
3
- import { useGridRegisterPipeProcessor, gridVisiblePinnedColumnDefinitionsSelector } from '@mui/x-data-grid/internals';
3
+ import { useGridRegisterPipeProcessor, gridExistingPinnedColumnSelector } from '@mui/x-data-grid/internals';
4
4
  export const useGridColumnPinningPreProcessors = (apiRef, props) => {
5
5
  const {
6
6
  disableColumnPinning
@@ -20,12 +20,12 @@ export const useGridColumnPinningPreProcessors = (apiRef, props) => {
20
20
  apiRef.current.state = _extends({}, savedState, {
21
21
  columns: columnsState
22
22
  });
23
- const visibleColumns = gridVisiblePinnedColumnDefinitionsSelector(apiRef);
23
+ const pinnedColumns = gridExistingPinnedColumnSelector(apiRef);
24
24
  apiRef.current.state = savedState;
25
25
  // HACK: Ends here //
26
26
 
27
- const leftPinnedColumns = visibleColumns.left.map(c => c.field);
28
- const rightPinnedColumns = visibleColumns.right.map(c => c.field);
27
+ const leftPinnedColumns = pinnedColumns.left;
28
+ const rightPinnedColumns = pinnedColumns.right;
29
29
  let newOrderedFields;
30
30
  const allPinnedColumns = [...leftPinnedColumns, ...rightPinnedColumns];
31
31
  const {
@@ -6,28 +6,26 @@ import { GRID_DETAIL_PANEL_TOGGLE_FIELD, GRID_DETAIL_PANEL_TOGGLE_COL_DEF } from
6
6
  import { gridDetailPanelExpandedRowIdsSelector } from "./gridDetailPanelSelector.js";
7
7
  export const useGridDetailPanelPreProcessors = (privateApiRef, props) => {
8
8
  const addToggleColumn = React.useCallback(columnsState => {
9
- if (props.getDetailPanelContent == null) {
10
- // Remove the toggle column, when it exists
11
- if (columnsState.lookup[GRID_DETAIL_PANEL_TOGGLE_FIELD]) {
12
- delete columnsState.lookup[GRID_DETAIL_PANEL_TOGGLE_FIELD];
13
- columnsState.orderedFields = columnsState.orderedFields.filter(field => field !== GRID_DETAIL_PANEL_TOGGLE_FIELD);
14
- }
15
- return columnsState;
16
- }
17
-
18
- // Don't add the toggle column if there's already one
19
- // The user might have manually added it to have it in a custom position
20
- if (columnsState.lookup[GRID_DETAIL_PANEL_TOGGLE_FIELD]) {
21
- return columnsState;
22
- }
23
-
24
- // Otherwise, add the toggle column at the beginning
25
- columnsState.orderedFields = [GRID_DETAIL_PANEL_TOGGLE_FIELD, ...columnsState.orderedFields];
26
- columnsState.lookup[GRID_DETAIL_PANEL_TOGGLE_FIELD] = _extends({}, GRID_DETAIL_PANEL_TOGGLE_COL_DEF, {
9
+ const detailPanelToggleColumn = _extends({}, GRID_DETAIL_PANEL_TOGGLE_COL_DEF, {
27
10
  headerName: privateApiRef.current.getLocaleText('detailPanelToggle')
28
11
  });
12
+ const shouldHaveToggleColumn = !!props.getDetailPanelContent;
13
+ const hasToggleColumn = columnsState.lookup[GRID_DETAIL_PANEL_TOGGLE_FIELD] != null;
14
+ if (shouldHaveToggleColumn && !hasToggleColumn) {
15
+ columnsState.lookup[GRID_DETAIL_PANEL_TOGGLE_FIELD] = detailPanelToggleColumn;
16
+ columnsState.orderedFields = [GRID_DETAIL_PANEL_TOGGLE_FIELD, ...columnsState.orderedFields];
17
+ } else if (!shouldHaveToggleColumn && hasToggleColumn) {
18
+ delete columnsState.lookup[GRID_DETAIL_PANEL_TOGGLE_FIELD];
19
+ columnsState.orderedFields = columnsState.orderedFields.filter(field => field !== GRID_DETAIL_PANEL_TOGGLE_FIELD);
20
+ } else if (shouldHaveToggleColumn && hasToggleColumn) {
21
+ columnsState.lookup[GRID_DETAIL_PANEL_TOGGLE_FIELD] = _extends({}, detailPanelToggleColumn, columnsState.lookup[GRID_DETAIL_PANEL_TOGGLE_FIELD]);
22
+ // If the column is not in the columns array (not a custom detail panel toggle column), move it to the beginning of the column order
23
+ if (!props.columns.some(col => col.field === GRID_DETAIL_PANEL_TOGGLE_FIELD)) {
24
+ columnsState.orderedFields = [GRID_DETAIL_PANEL_TOGGLE_FIELD, ...columnsState.orderedFields.filter(field => field !== GRID_DETAIL_PANEL_TOGGLE_FIELD)];
25
+ }
26
+ }
29
27
  return columnsState;
30
- }, [privateApiRef, props.getDetailPanelContent]);
28
+ }, [privateApiRef, props.columns, props.getDetailPanelContent]);
31
29
  const addExpandedClassToRow = React.useCallback((classes, id) => {
32
30
  if (props.getDetailPanelContent == null) {
33
31
  return classes;
@@ -28,19 +28,21 @@ export const useGridRowReorderPreProcessors = (privateApiRef, props) => {
28
28
  headerName: privateApiRef.current.getLocaleText('rowReorderingHeaderName')
29
29
  });
30
30
  const shouldHaveReorderColumn = props.rowReordering;
31
- const haveReorderColumn = columnsState.lookup[reorderColumn.field] != null;
32
- if (shouldHaveReorderColumn && haveReorderColumn) {
33
- columnsState.lookup[reorderColumn.field] = _extends({}, reorderColumn, columnsState.lookup[reorderColumn.field]);
34
- return columnsState;
35
- }
36
- if (shouldHaveReorderColumn && !haveReorderColumn) {
31
+ const hasReorderColumn = columnsState.lookup[reorderColumn.field] != null;
32
+ if (shouldHaveReorderColumn && !hasReorderColumn) {
37
33
  columnsState.lookup[reorderColumn.field] = reorderColumn;
38
34
  columnsState.orderedFields = [reorderColumn.field, ...columnsState.orderedFields];
39
- } else if (!shouldHaveReorderColumn && haveReorderColumn) {
35
+ } else if (!shouldHaveReorderColumn && hasReorderColumn) {
40
36
  delete columnsState.lookup[reorderColumn.field];
41
37
  columnsState.orderedFields = columnsState.orderedFields.filter(field => field !== reorderColumn.field);
38
+ } else if (shouldHaveReorderColumn && hasReorderColumn) {
39
+ columnsState.lookup[reorderColumn.field] = _extends({}, reorderColumn, columnsState.lookup[reorderColumn.field]);
40
+ // If the column is not in the columns array (not a custom reorder column), move it to the beginning of the column order
41
+ if (!props.columns.some(col => col.field === GRID_REORDER_COL_DEF.field)) {
42
+ columnsState.orderedFields = [reorderColumn.field, ...columnsState.orderedFields.filter(field => field !== reorderColumn.field)];
43
+ }
42
44
  }
43
45
  return columnsState;
44
- }, [privateApiRef, classes, props.rowReordering]);
46
+ }, [privateApiRef, classes, props.columns, props.rowReordering]);
45
47
  useGridRegisterPipeProcessor(privateApiRef, 'hydrateColumns', updateReorderColumn);
46
48
  };
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
3
  const _excluded = ["hideDescendantCount"];
4
4
  import * as React from 'react';
5
- import { gridRowTreeSelector, useFirstRender, GRID_CHECKBOX_SELECTION_FIELD } from '@mui/x-data-grid';
5
+ import { gridRowTreeSelector, useFirstRender } from '@mui/x-data-grid';
6
6
  import { useGridRegisterPipeProcessor, useGridRegisterStrategyProcessor } from '@mui/x-data-grid/internals';
7
7
  import { GRID_TREE_DATA_GROUPING_COL_DEF, GRID_TREE_DATA_GROUPING_COL_DEF_FORCED_PROPERTIES } from "../treeData/gridTreeDataGroupColDef.js";
8
8
  import { skipFiltering, skipSorting } from "./utils.js";
@@ -56,8 +56,7 @@ export const useGridDataSourceTreeDataPreProcessors = (privateApiRef, props) =>
56
56
  }
57
57
  columnsState.lookup[groupingColDefField] = newGroupingColumn;
58
58
  if (prevGroupingColumn == null) {
59
- const index = columnsState.orderedFields[0] === GRID_CHECKBOX_SELECTION_FIELD ? 1 : 0;
60
- columnsState.orderedFields = [...columnsState.orderedFields.slice(0, index), groupingColDefField, ...columnsState.orderedFields.slice(index)];
59
+ columnsState.orderedFields = [groupingColDefField, ...columnsState.orderedFields];
61
60
  }
62
61
  } else if (!shouldHaveGroupingColumn && prevGroupingColumn) {
63
62
  delete columnsState.lookup[groupingColDefField];
@@ -2,7 +2,7 @@ import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
3
  const _excluded = ["hideDescendantCount"];
4
4
  import * as React from 'react';
5
- import { gridRowTreeSelector, useFirstRender, GRID_CHECKBOX_SELECTION_FIELD } from '@mui/x-data-grid';
5
+ import { gridRowTreeSelector, useFirstRender } from '@mui/x-data-grid';
6
6
  import { useGridRegisterPipeProcessor, useGridRegisterStrategyProcessor } from '@mui/x-data-grid/internals';
7
7
  import { GRID_TREE_DATA_GROUPING_COL_DEF, GRID_TREE_DATA_GROUPING_COL_DEF_FORCED_PROPERTIES } from "./gridTreeDataGroupColDef.js";
8
8
  import { filterRowTreeFromTreeData, TreeDataStrategy } from "./gridTreeDataUtils.js";
@@ -56,8 +56,7 @@ export const useGridTreeDataPreProcessors = (privateApiRef, props) => {
56
56
  }
57
57
  columnsState.lookup[groupingColDefField] = newGroupingColumn;
58
58
  if (prevGroupingColumn == null) {
59
- const index = columnsState.orderedFields[0] === GRID_CHECKBOX_SELECTION_FIELD ? 1 : 0;
60
- columnsState.orderedFields = [...columnsState.orderedFields.slice(0, index), groupingColDefField, ...columnsState.orderedFields.slice(index)];
59
+ columnsState.orderedFields = [groupingColDefField, ...columnsState.orderedFields];
61
60
  }
62
61
  } else if (!shouldHaveGroupingColumn && prevGroupingColumn) {
63
62
  delete columnsState.lookup[groupingColDefField];
package/modern/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid-pro v7.29.5
2
+ * @mui/x-data-grid-pro v7.29.7
3
3
  *
4
4
  * @license MUI X Commercial
5
5
  * This source code is licensed under the commercial license found in the
@@ -1,6 +1,6 @@
1
1
  import { ponyfillGlobal } from '@mui/utils';
2
2
  export const getReleaseInfo = () => {
3
- const releaseInfo = "MTc0ODQ2OTYwMDAwMA==";
3
+ const releaseInfo = "MTc1MDg4ODgwMDAwMA==";
4
4
  if (process.env.NODE_ENV !== 'production') {
5
5
  // A simple hack to set the value in the test environment (has no build step).
6
6
  // eslint-disable-next-line no-useless-concat
@@ -28,16 +28,20 @@ const useDataGridProComponent = (inputApiRef, props) => {
28
28
 
29
29
  /**
30
30
  * Register all pre-processors called during state initialization here.
31
+ * Some pre-processors are changing the same part of the state (like the order of the columns).
32
+ * Order them in descending order of priority.
33
+ * For example, left pinned columns should always render first from the left, so the `hydrateColumns` pre-processor from `useGridColumnPinningPreProcessors` should be called last (after all other `hydrateColumns` pre-processors).
34
+ * Similarly, the `hydrateColumns` pre-processor from `useGridRowSelectionPreProcessors` should be called after `useGridTreeDataPreProcessors` because the selection checkboxes should appear before the tree data.
35
+ * Desired autogenerated columns order is:
36
+ * left pinned columns -> row reordering column -> checkbox column -> tree data column -> master detail column -> rest of the columns
31
37
  */
32
- (0, _internals.useGridRowSelectionPreProcessors)(apiRef, props);
33
- (0, _useGridRowReorderPreProcessors.useGridRowReorderPreProcessors)(apiRef, props);
38
+ (0, _useGridDetailPanelPreProcessors.useGridDetailPanelPreProcessors)(apiRef, props);
34
39
  (0, _useGridTreeDataPreProcessors.useGridTreeDataPreProcessors)(apiRef, props);
35
40
  (0, _useGridDataSourceTreeDataPreProcessors.useGridDataSourceTreeDataPreProcessors)(apiRef, props);
41
+ (0, _internals.useGridRowSelectionPreProcessors)(apiRef, props);
36
42
  (0, _useGridLazyLoaderPreProcessors.useGridLazyLoaderPreProcessors)(apiRef, props);
37
43
  (0, _useGridRowPinningPreProcessors.useGridRowPinningPreProcessors)(apiRef);
38
- (0, _useGridDetailPanelPreProcessors.useGridDetailPanelPreProcessors)(apiRef, props);
39
- // The column pinning `hydrateColumns` pre-processor must be after every other `hydrateColumns` pre-processors
40
- // Because it changes the order of the columns.
44
+ (0, _useGridRowReorderPreProcessors.useGridRowReorderPreProcessors)(apiRef, props);
41
45
  (0, _useGridColumnPinningPreProcessors.useGridColumnPinningPreProcessors)(apiRef, props);
42
46
  (0, _internals.useGridRowsPreProcessors)(apiRef);
43
47
 
@@ -28,12 +28,12 @@ const useGridColumnPinningPreProcessors = (apiRef, props) => {
28
28
  apiRef.current.state = (0, _extends2.default)({}, savedState, {
29
29
  columns: columnsState
30
30
  });
31
- const visibleColumns = (0, _internals.gridVisiblePinnedColumnDefinitionsSelector)(apiRef);
31
+ const pinnedColumns = (0, _internals.gridExistingPinnedColumnSelector)(apiRef);
32
32
  apiRef.current.state = savedState;
33
33
  // HACK: Ends here //
34
34
 
35
- const leftPinnedColumns = visibleColumns.left.map(c => c.field);
36
- const rightPinnedColumns = visibleColumns.right.map(c => c.field);
35
+ const leftPinnedColumns = pinnedColumns.left;
36
+ const rightPinnedColumns = pinnedColumns.right;
37
37
  let newOrderedFields;
38
38
  const allPinnedColumns = [...leftPinnedColumns, ...rightPinnedColumns];
39
39
  const {
@@ -14,28 +14,26 @@ var _gridDetailPanelToggleColDef = require("./gridDetailPanelToggleColDef");
14
14
  var _gridDetailPanelSelector = require("./gridDetailPanelSelector");
15
15
  const useGridDetailPanelPreProcessors = (privateApiRef, props) => {
16
16
  const addToggleColumn = React.useCallback(columnsState => {
17
- if (props.getDetailPanelContent == null) {
18
- // Remove the toggle column, when it exists
19
- if (columnsState.lookup[_gridDetailPanelToggleColDef.GRID_DETAIL_PANEL_TOGGLE_FIELD]) {
20
- delete columnsState.lookup[_gridDetailPanelToggleColDef.GRID_DETAIL_PANEL_TOGGLE_FIELD];
21
- columnsState.orderedFields = columnsState.orderedFields.filter(field => field !== _gridDetailPanelToggleColDef.GRID_DETAIL_PANEL_TOGGLE_FIELD);
22
- }
23
- return columnsState;
24
- }
25
-
26
- // Don't add the toggle column if there's already one
27
- // The user might have manually added it to have it in a custom position
28
- if (columnsState.lookup[_gridDetailPanelToggleColDef.GRID_DETAIL_PANEL_TOGGLE_FIELD]) {
29
- return columnsState;
30
- }
31
-
32
- // Otherwise, add the toggle column at the beginning
33
- columnsState.orderedFields = [_gridDetailPanelToggleColDef.GRID_DETAIL_PANEL_TOGGLE_FIELD, ...columnsState.orderedFields];
34
- columnsState.lookup[_gridDetailPanelToggleColDef.GRID_DETAIL_PANEL_TOGGLE_FIELD] = (0, _extends2.default)({}, _gridDetailPanelToggleColDef.GRID_DETAIL_PANEL_TOGGLE_COL_DEF, {
17
+ const detailPanelToggleColumn = (0, _extends2.default)({}, _gridDetailPanelToggleColDef.GRID_DETAIL_PANEL_TOGGLE_COL_DEF, {
35
18
  headerName: privateApiRef.current.getLocaleText('detailPanelToggle')
36
19
  });
20
+ const shouldHaveToggleColumn = !!props.getDetailPanelContent;
21
+ const hasToggleColumn = columnsState.lookup[_gridDetailPanelToggleColDef.GRID_DETAIL_PANEL_TOGGLE_FIELD] != null;
22
+ if (shouldHaveToggleColumn && !hasToggleColumn) {
23
+ columnsState.lookup[_gridDetailPanelToggleColDef.GRID_DETAIL_PANEL_TOGGLE_FIELD] = detailPanelToggleColumn;
24
+ columnsState.orderedFields = [_gridDetailPanelToggleColDef.GRID_DETAIL_PANEL_TOGGLE_FIELD, ...columnsState.orderedFields];
25
+ } else if (!shouldHaveToggleColumn && hasToggleColumn) {
26
+ delete columnsState.lookup[_gridDetailPanelToggleColDef.GRID_DETAIL_PANEL_TOGGLE_FIELD];
27
+ columnsState.orderedFields = columnsState.orderedFields.filter(field => field !== _gridDetailPanelToggleColDef.GRID_DETAIL_PANEL_TOGGLE_FIELD);
28
+ } else if (shouldHaveToggleColumn && hasToggleColumn) {
29
+ columnsState.lookup[_gridDetailPanelToggleColDef.GRID_DETAIL_PANEL_TOGGLE_FIELD] = (0, _extends2.default)({}, detailPanelToggleColumn, columnsState.lookup[_gridDetailPanelToggleColDef.GRID_DETAIL_PANEL_TOGGLE_FIELD]);
30
+ // If the column is not in the columns array (not a custom detail panel toggle column), move it to the beginning of the column order
31
+ if (!props.columns.some(col => col.field === _gridDetailPanelToggleColDef.GRID_DETAIL_PANEL_TOGGLE_FIELD)) {
32
+ columnsState.orderedFields = [_gridDetailPanelToggleColDef.GRID_DETAIL_PANEL_TOGGLE_FIELD, ...columnsState.orderedFields.filter(field => field !== _gridDetailPanelToggleColDef.GRID_DETAIL_PANEL_TOGGLE_FIELD)];
33
+ }
34
+ }
37
35
  return columnsState;
38
- }, [privateApiRef, props.getDetailPanelContent]);
36
+ }, [privateApiRef, props.columns, props.getDetailPanelContent]);
39
37
  const addExpandedClassToRow = React.useCallback((classes, id) => {
40
38
  if (props.getDetailPanelContent == null) {
41
39
  return classes;
@@ -36,20 +36,22 @@ const useGridRowReorderPreProcessors = (privateApiRef, props) => {
36
36
  headerName: privateApiRef.current.getLocaleText('rowReorderingHeaderName')
37
37
  });
38
38
  const shouldHaveReorderColumn = props.rowReordering;
39
- const haveReorderColumn = columnsState.lookup[reorderColumn.field] != null;
40
- if (shouldHaveReorderColumn && haveReorderColumn) {
41
- columnsState.lookup[reorderColumn.field] = (0, _extends2.default)({}, reorderColumn, columnsState.lookup[reorderColumn.field]);
42
- return columnsState;
43
- }
44
- if (shouldHaveReorderColumn && !haveReorderColumn) {
39
+ const hasReorderColumn = columnsState.lookup[reorderColumn.field] != null;
40
+ if (shouldHaveReorderColumn && !hasReorderColumn) {
45
41
  columnsState.lookup[reorderColumn.field] = reorderColumn;
46
42
  columnsState.orderedFields = [reorderColumn.field, ...columnsState.orderedFields];
47
- } else if (!shouldHaveReorderColumn && haveReorderColumn) {
43
+ } else if (!shouldHaveReorderColumn && hasReorderColumn) {
48
44
  delete columnsState.lookup[reorderColumn.field];
49
45
  columnsState.orderedFields = columnsState.orderedFields.filter(field => field !== reorderColumn.field);
46
+ } else if (shouldHaveReorderColumn && hasReorderColumn) {
47
+ columnsState.lookup[reorderColumn.field] = (0, _extends2.default)({}, reorderColumn, columnsState.lookup[reorderColumn.field]);
48
+ // If the column is not in the columns array (not a custom reorder column), move it to the beginning of the column order
49
+ if (!props.columns.some(col => col.field === _gridRowReorderColDef.GRID_REORDER_COL_DEF.field)) {
50
+ columnsState.orderedFields = [reorderColumn.field, ...columnsState.orderedFields.filter(field => field !== reorderColumn.field)];
51
+ }
50
52
  }
51
53
  return columnsState;
52
- }, [privateApiRef, classes, props.rowReordering]);
54
+ }, [privateApiRef, classes, props.columns, props.rowReordering]);
53
55
  (0, _internals.useGridRegisterPipeProcessor)(privateApiRef, 'hydrateColumns', updateReorderColumn);
54
56
  };
55
57
  exports.useGridRowReorderPreProcessors = useGridRowReorderPreProcessors;
@@ -64,8 +64,7 @@ const useGridDataSourceTreeDataPreProcessors = (privateApiRef, props) => {
64
64
  }
65
65
  columnsState.lookup[groupingColDefField] = newGroupingColumn;
66
66
  if (prevGroupingColumn == null) {
67
- const index = columnsState.orderedFields[0] === _xDataGrid.GRID_CHECKBOX_SELECTION_FIELD ? 1 : 0;
68
- columnsState.orderedFields = [...columnsState.orderedFields.slice(0, index), groupingColDefField, ...columnsState.orderedFields.slice(index)];
67
+ columnsState.orderedFields = [groupingColDefField, ...columnsState.orderedFields];
69
68
  }
70
69
  } else if (!shouldHaveGroupingColumn && prevGroupingColumn) {
71
70
  delete columnsState.lookup[groupingColDefField];
@@ -64,8 +64,7 @@ const useGridTreeDataPreProcessors = (privateApiRef, props) => {
64
64
  }
65
65
  columnsState.lookup[groupingColDefField] = newGroupingColumn;
66
66
  if (prevGroupingColumn == null) {
67
- const index = columnsState.orderedFields[0] === _xDataGrid.GRID_CHECKBOX_SELECTION_FIELD ? 1 : 0;
68
- columnsState.orderedFields = [...columnsState.orderedFields.slice(0, index), groupingColDefField, ...columnsState.orderedFields.slice(index)];
67
+ columnsState.orderedFields = [groupingColDefField, ...columnsState.orderedFields];
69
68
  }
70
69
  } else if (!shouldHaveGroupingColumn && prevGroupingColumn) {
71
70
  delete columnsState.lookup[groupingColDefField];
package/node/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/x-data-grid-pro v7.29.5
2
+ * @mui/x-data-grid-pro v7.29.7
3
3
  *
4
4
  * @license MUI X Commercial
5
5
  * This source code is licensed under the commercial license found in the
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.getReleaseInfo = void 0;
7
7
  var _utils = require("@mui/utils");
8
8
  const getReleaseInfo = () => {
9
- const releaseInfo = "MTc0ODQ2OTYwMDAwMA==";
9
+ const releaseInfo = "MTc1MDg4ODgwMDAwMA==";
10
10
  if (process.env.NODE_ENV !== 'production') {
11
11
  // A simple hack to set the value in the test environment (has no build step).
12
12
  // eslint-disable-next-line no-useless-concat
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/x-data-grid-pro",
3
- "version": "7.29.5",
3
+ "version": "7.29.7",
4
4
  "description": "The Pro plan edition of the Data Grid components (MUI X).",
5
5
  "author": "MUI Team",
6
6
  "main": "./node/index.js",
@@ -39,7 +39,7 @@
39
39
  "clsx": "^2.1.1",
40
40
  "prop-types": "^15.8.1",
41
41
  "reselect": "^5.1.1",
42
- "@mui/x-data-grid": "7.29.5",
42
+ "@mui/x-data-grid": "7.29.7",
43
43
  "@mui/x-internals": "7.29.0",
44
44
  "@mui/x-license": "7.29.1"
45
45
  },
@@ -1,6 +1,6 @@
1
1
  import { ponyfillGlobal } from '@mui/utils';
2
2
  export const getReleaseInfo = () => {
3
- const releaseInfo = "MTc0ODQ2OTYwMDAwMA==";
3
+ const releaseInfo = "MTc1MDg4ODgwMDAwMA==";
4
4
  if (process.env.NODE_ENV !== 'production') {
5
5
  // A simple hack to set the value in the test environment (has no build step).
6
6
  // eslint-disable-next-line no-useless-concat