diff --git a/docs/data/data-grid/accessibility/DensitySelectorSmallGrid.js b/docs/data/data-grid/accessibility/DensitySelectorSmallGrid.js
index d9d61b7c7433f..9fe1c320f95be 100644
--- a/docs/data/data-grid/accessibility/DensitySelectorSmallGrid.js
+++ b/docs/data/data-grid/accessibility/DensitySelectorSmallGrid.js
@@ -15,6 +15,8 @@ function CustomToolbar() {
}
export default function DensitySelectorSmallGrid() {
+ const [density, setDensity] = React.useState('compact');
+
const { data } = useDemoData({
dataSet: 'Commodity',
rowLength: 4,
@@ -25,7 +27,11 @@ export default function DensitySelectorSmallGrid() {
{
+ console.info(`Density updated to: ${newDensity}`);
+ setDensity(newDensity);
+ }}
slots={{
toolbar: CustomToolbar,
}}
diff --git a/docs/data/data-grid/accessibility/DensitySelectorSmallGrid.tsx b/docs/data/data-grid/accessibility/DensitySelectorSmallGrid.tsx
index d9d61b7c7433f..d7d04073e9425 100644
--- a/docs/data/data-grid/accessibility/DensitySelectorSmallGrid.tsx
+++ b/docs/data/data-grid/accessibility/DensitySelectorSmallGrid.tsx
@@ -3,6 +3,7 @@ import {
DataGrid,
GridToolbarContainer,
GridToolbarDensitySelector,
+ GridDensity,
} from '@mui/x-data-grid';
import { useDemoData } from '@mui/x-data-grid-generator';
@@ -15,6 +16,8 @@ function CustomToolbar() {
}
export default function DensitySelectorSmallGrid() {
+ const [density, setDensity] = React.useState('compact');
+
const { data } = useDemoData({
dataSet: 'Commodity',
rowLength: 4,
@@ -25,7 +28,11 @@ export default function DensitySelectorSmallGrid() {
{
+ console.info(`Density updated to: ${newDensity}`);
+ setDensity(newDensity);
+ }}
slots={{
toolbar: CustomToolbar,
}}
diff --git a/docs/data/data-grid/accessibility/DensitySelectorSmallGrid.tsx.preview b/docs/data/data-grid/accessibility/DensitySelectorSmallGrid.tsx.preview
index 9d198ee8add6a..cd87eee43b444 100644
--- a/docs/data/data-grid/accessibility/DensitySelectorSmallGrid.tsx.preview
+++ b/docs/data/data-grid/accessibility/DensitySelectorSmallGrid.tsx.preview
@@ -1,6 +1,10 @@
{
+ console.info(`Density updated to: ${newDensity}`);
+ setDensity(newDensity);
+ }}
slots={{
toolbar: CustomToolbar,
}}
diff --git a/docs/data/data-grid/accessibility/accessibility.md b/docs/data/data-grid/accessibility/accessibility.md
index 3a54c27b73b07..afb47c68a23a7 100644
--- a/docs/data/data-grid/accessibility/accessibility.md
+++ b/docs/data/data-grid/accessibility/accessibility.md
@@ -22,22 +22,56 @@ The [WAI-ARIA Authoring Practices](https://www.w3.org/WAI/ARIA/apg/patterns/grid
You can change the density of the rows and the column header.
-### Density selector
+### Density selection from the toolbar
-To enable the density selector, create a toolbar containing the `GridToolbarDensitySelector` component and apply it using the `toolbar` property in the Data Grid's `slots` prop.
-The user can then change the density of the Data Grid by using the density selector from the toolbar, as the following demo illustrates:
+To enable the density selection from the toolbar, you can do one of the following:
+
+1. Enable the default toolbar component by passing the `slots.toolbar` prop to the Data Grid.
+2. Create a specific toolbar containing only the `GridToolbarDensitySelector` component and apply it using the `toolbar` property in the Data Grid's `slots` prop.
+
+The user can then change the density of the Data Grid by using the density selection menu from the toolbar, as the following demo illustrates:
{{"demo": "DensitySelectorGrid.js", "bg": "inline"}}
-To hide the density selector, add the `disableDensitySelector` prop to the Data Grid.
+To disable the density selection menu, pass the `disableDensitySelector` prop to the Data Grid.
+
+### Set the density programmatically
+
+The Data Grid exposes the `density` prop which supports the following values:
+
+- `standard` (default)
+- `compact`
+- `comfortable`
+
+You can set the density programmatically in one of the following ways:
+
+1. Uncontrolled – initialize the density with the `initialState.density` prop.
+
+ ```tsx
+
+ ```
+
+2. Controlled – pass the `density` and `onDensityChange` props. For more advanced use cases, you can also subscribe to the `densityChange` grid event.
+
+ ```tsx
+ const [density, setDensity] = React.useState('compact');
-### Density prop
+ return (
+ setDensity(newDensity)}
+ />
+ );
+ ```
-Set the vertical density of the Data Grid using the `density` prop.
-This prop applies the values determined by the `rowHeight` and `columnHeaderHeight` props, if supplied.
+The `density` prop applies the values determined by the `rowHeight` and `columnHeaderHeight` props, if supplied.
The user can override this setting with the optional toolbar density selector.
-The following demo shows a Data Grid with the default density set to `compact`:
+The following demo shows a Data Grid with the controlled density set to `compact` and outputs the current density to the console when the user changes it using the density selector from the toolbar:
{{"demo": "DensitySelectorSmallGrid.js", "bg": "inline"}}
diff --git a/docs/data/data-grid/events/events.json b/docs/data/data-grid/events/events.json
index 6bb6029718fa7..64c820e1c397d 100644
--- a/docs/data/data-grid/events/events.json
+++ b/docs/data/data-grid/events/events.json
@@ -202,6 +202,13 @@
"event": "MuiEvent<{}>",
"componentProp": "onResize"
},
+ {
+ "projects": ["x-data-grid", "x-data-grid-pro", "x-data-grid-premium"],
+ "name": "densityChange",
+ "description": "Fired when the density changes.",
+ "params": "GridDensity",
+ "event": "MuiEvent<{}>"
+ },
{
"projects": ["x-data-grid-premium"],
"name": "excelExportStateChange",
diff --git a/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md b/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md
index 8e693b6e8e61c..fd89b82c9ecda 100644
--- a/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md
+++ b/docs/data/migration/migration-data-grid-v6/migration-data-grid-v6.md
@@ -303,6 +303,32 @@ See the [Direct state access](/x/react-data-grid/state/#direct-selector-access)
+ groupingValueGetter: (value: { name: string }) => value.name,
```
+### Density
+
+- The `density` is a [controlled prop](/x/react-data-grid/accessibility/#set-the-density-programmatically) now, if you were previously passing the `density` prop to the Data Grid, you will need to do one of the following:
+
+1. Move it to the `initialState.density` to initialize it.
+
+```diff
+
+```
+
+2. Move it to the state and use `onDensityChange` callback to update the `density` prop accordingly for it to work as expected.
+
+```diff
+ const [density, setDensity] = React.useState('compact');
+ setDensity(newDensity)}
+ />
+```
+
+- The selector `gridDensityValueSelector` was removed, use the `gridDensitySelector` instead.
+
diff --git a/docs/pages/x/api/data-grid/data-grid-premium.json b/docs/pages/x/api/data-grid/data-grid-premium.json
index 559aa75b2e3f4..4c43103ed7e0b 100644
--- a/docs/pages/x/api/data-grid/data-grid-premium.json
+++ b/docs/pages/x/api/data-grid/data-grid-premium.json
@@ -361,6 +361,13 @@
"describedArgs": ["params", "event", "details"]
}
},
+ "onDensityChange": {
+ "type": { "name": "func" },
+ "signature": {
+ "type": "function(density: GridDensity) => void",
+ "describedArgs": ["density"]
+ }
+ },
"onDetailPanelExpandedRowIdsChange": {
"type": { "name": "func" },
"signature": {
diff --git a/docs/pages/x/api/data-grid/data-grid-pro.json b/docs/pages/x/api/data-grid/data-grid-pro.json
index 198c5f68c6da7..6c2382cfa2982 100644
--- a/docs/pages/x/api/data-grid/data-grid-pro.json
+++ b/docs/pages/x/api/data-grid/data-grid-pro.json
@@ -318,6 +318,13 @@
"describedArgs": ["params", "event", "details"]
}
},
+ "onDensityChange": {
+ "type": { "name": "func" },
+ "signature": {
+ "type": "function(density: GridDensity) => void",
+ "describedArgs": ["density"]
+ }
+ },
"onDetailPanelExpandedRowIdsChange": {
"type": { "name": "func" },
"signature": {
diff --git a/docs/pages/x/api/data-grid/data-grid.json b/docs/pages/x/api/data-grid/data-grid.json
index 468423143dd70..9fd2b885eb548 100644
--- a/docs/pages/x/api/data-grid/data-grid.json
+++ b/docs/pages/x/api/data-grid/data-grid.json
@@ -278,6 +278,13 @@
"describedArgs": ["params", "event", "details"]
}
},
+ "onDensityChange": {
+ "type": { "name": "func" },
+ "signature": {
+ "type": "function(density: GridDensity) => void",
+ "describedArgs": ["density"]
+ }
+ },
"onFilterModelChange": {
"type": { "name": "func" },
"signature": {
diff --git a/docs/pages/x/api/data-grid/selectors.json b/docs/pages/x/api/data-grid/selectors.json
index fc2fa812d4817..1140b1bf1d946 100644
--- a/docs/pages/x/api/data-grid/selectors.json
+++ b/docs/pages/x/api/data-grid/selectors.json
@@ -124,15 +124,9 @@
},
{
"name": "gridDensitySelector",
- "returnType": "GridDensityState",
- "description": "",
- "supportsApiRef": false
- },
- {
- "name": "gridDensityValueSelector",
"returnType": "GridDensity",
"description": "",
- "supportsApiRef": true
+ "supportsApiRef": false
},
{
"name": "gridDetailPanelExpandedRowIdsSelector",
diff --git a/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json b/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json
index 96b941032c92d..55da4f984364f 100644
--- a/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json
+++ b/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json
@@ -394,6 +394,10 @@
"details": "Additional details for this callback."
}
},
+ "onDensityChange": {
+ "description": "Callback fired when the density changes.",
+ "typeDescriptions": { "density": "New density value." }
+ },
"onDetailPanelExpandedRowIdsChange": {
"description": "Callback fired when the detail panel of a row is opened or closed.",
"typeDescriptions": {
diff --git a/docs/translations/api-docs/data-grid/data-grid-pro/data-grid-pro.json b/docs/translations/api-docs/data-grid/data-grid-pro/data-grid-pro.json
index c4f04eb81c606..32c54712411fd 100644
--- a/docs/translations/api-docs/data-grid/data-grid-pro/data-grid-pro.json
+++ b/docs/translations/api-docs/data-grid/data-grid-pro/data-grid-pro.json
@@ -351,6 +351,10 @@
"details": "Additional details for this callback."
}
},
+ "onDensityChange": {
+ "description": "Callback fired when the density changes.",
+ "typeDescriptions": { "density": "New density value." }
+ },
"onDetailPanelExpandedRowIdsChange": {
"description": "Callback fired when the detail panel of a row is opened or closed.",
"typeDescriptions": {
diff --git a/docs/translations/api-docs/data-grid/data-grid/data-grid.json b/docs/translations/api-docs/data-grid/data-grid/data-grid.json
index c6d25a3f35a80..a9dd4e497f260 100644
--- a/docs/translations/api-docs/data-grid/data-grid/data-grid.json
+++ b/docs/translations/api-docs/data-grid/data-grid/data-grid.json
@@ -295,6 +295,10 @@
"details": "Additional details for this callback."
}
},
+ "onDensityChange": {
+ "description": "Callback fired when the density changes.",
+ "typeDescriptions": { "density": "New density value." }
+ },
"onFilterModelChange": {
"description": "Callback fired when the Filter model changes before the filters are applied.",
"typeDescriptions": {
diff --git a/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx b/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx
index a411583a776c3..8991449eda96b 100644
--- a/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx
+++ b/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx
@@ -678,6 +678,11 @@ DataGridPremiumRaw.propTypes = {
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onColumnWidthChange: PropTypes.func,
+ /**
+ * Callback fired when the density changes.
+ * @param {GridDensity} density New density value.
+ */
+ onDensityChange: PropTypes.func,
/**
* Callback fired when the detail panel of a row is opened or closed.
* @param {GridRowId[]} ids The ids of the rows which have the detail panel open.
diff --git a/packages/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx b/packages/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx
index 55bae26091799..df1e21319472d 100644
--- a/packages/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx
+++ b/packages/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx
@@ -591,6 +591,11 @@ DataGridProRaw.propTypes = {
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onColumnWidthChange: PropTypes.func,
+ /**
+ * Callback fired when the density changes.
+ * @param {GridDensity} density New density value.
+ */
+ onDensityChange: PropTypes.func,
/**
* Callback fired when the detail panel of a row is opened or closed.
* @param {GridRowId[]} ids The ids of the rows which have the detail panel open.
diff --git a/packages/x-data-grid/src/DataGrid/DataGrid.tsx b/packages/x-data-grid/src/DataGrid/DataGrid.tsx
index 475dc646e981f..fe0f14bbb9d6c 100644
--- a/packages/x-data-grid/src/DataGrid/DataGrid.tsx
+++ b/packages/x-data-grid/src/DataGrid/DataGrid.tsx
@@ -506,6 +506,11 @@ DataGridRaw.propTypes = {
* @param {GridCallbackDetails} details Additional details for this callback.
*/
onColumnWidthChange: PropTypes.func,
+ /**
+ * Callback fired when the density changes.
+ * @param {GridDensity} density New density value.
+ */
+ onDensityChange: PropTypes.func,
/**
* Callback fired when the Filter model changes before the filters are applied.
* @param {GridFilterModel} model With all properties from [[GridFilterModel]].
diff --git a/packages/x-data-grid/src/DataGrid/useDataGridProps.ts b/packages/x-data-grid/src/DataGrid/useDataGridProps.ts
index b0f91d49cf291..3759d21e04241 100644
--- a/packages/x-data-grid/src/DataGrid/useDataGridProps.ts
+++ b/packages/x-data-grid/src/DataGrid/useDataGridProps.ts
@@ -36,7 +36,6 @@ export const DATA_GRID_PROPS_DEFAULT_VALUES: DataGridPropsWithDefaultValues = {
columnThreshold: 3,
rowThreshold: 3,
rowSelection: true,
- density: 'standard',
disableColumnFilter: false,
disableColumnMenu: false,
disableColumnSelector: false,
diff --git a/packages/x-data-grid/src/components/containers/GridRoot.tsx b/packages/x-data-grid/src/components/containers/GridRoot.tsx
index b42fcb4341ed4..a8e56cecfc30a 100644
--- a/packages/x-data-grid/src/components/containers/GridRoot.tsx
+++ b/packages/x-data-grid/src/components/containers/GridRoot.tsx
@@ -14,7 +14,7 @@ import { useGridSelector } from '../../hooks/utils/useGridSelector';
import { useGridPrivateApiContext } from '../../hooks/utils/useGridPrivateApiContext';
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
import { getDataGridUtilityClass } from '../../constants/gridClasses';
-import { gridDensityValueSelector } from '../../hooks/features/density/densitySelector';
+import { gridDensitySelector } from '../../hooks/features/density/densitySelector';
import { DataGridProcessedProps } from '../../models/props/DataGridProps';
import { GridDensity } from '../../models/gridDensity';
@@ -55,13 +55,13 @@ const GridRoot = React.forwardRef(function GridRo
const rootProps = useGridRootProps();
const { children, className, ...other } = props;
const apiRef = useGridPrivateApiContext();
- const densityValue = useGridSelector(apiRef, gridDensityValueSelector);
+ const density = useGridSelector(apiRef, gridDensitySelector);
const rootElementRef = apiRef.current.rootElementRef;
const handleRef = useForkRef(rootElementRef, ref);
const ownerState = {
...rootProps,
- density: densityValue,
+ density,
};
const classes = useUtilityClasses(ownerState);
diff --git a/packages/x-data-grid/src/components/toolbar/GridToolbarDensitySelector.tsx b/packages/x-data-grid/src/components/toolbar/GridToolbarDensitySelector.tsx
index 1c4b0b6a63511..4c790f2ee720b 100644
--- a/packages/x-data-grid/src/components/toolbar/GridToolbarDensitySelector.tsx
+++ b/packages/x-data-grid/src/components/toolbar/GridToolbarDensitySelector.tsx
@@ -6,7 +6,7 @@ import { ButtonProps } from '@mui/material/Button';
import { TooltipProps } from '@mui/material/Tooltip';
import MenuItem from '@mui/material/MenuItem';
import ListItemIcon from '@mui/material/ListItemIcon';
-import { gridDensityValueSelector } from '../../hooks/features/density/densitySelector';
+import { gridDensitySelector } from '../../hooks/features/density/densitySelector';
import { GridDensity } from '../../models/gridDensity';
import { isHideMenuKey, isTabKey } from '../../utils/keyboardUtils';
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
@@ -33,7 +33,7 @@ const GridToolbarDensitySelector = React.forwardRef<
const tooltipProps = slotProps.tooltip || {};
const apiRef = useGridApiContext();
const rootProps = useGridRootProps();
- const densityValue = useGridSelector(apiRef, gridDensityValueSelector);
+ const density = useGridSelector(apiRef, gridDensitySelector);
const densityButtonId = useId();
const densityMenuId = useId();
@@ -60,7 +60,7 @@ const GridToolbarDensitySelector = React.forwardRef<
];
const startIcon = React.useMemo(() => {
- switch (densityValue) {
+ switch (density) {
case 'compact':
return ;
case 'comfortable':
@@ -68,7 +68,7 @@ const GridToolbarDensitySelector = React.forwardRef<
default:
return ;
}
- }, [densityValue, rootProps]);
+ }, [density, rootProps]);
const handleDensitySelectorOpen = (event: React.MouseEvent) => {
setOpen((prevOpen) => !prevOpen);
@@ -100,7 +100,7 @@ const GridToolbarDensitySelector = React.forwardRef<