Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DataGrid] Allow to control the grid density #12332

Merged
merged 16 commits into from
Mar 19, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ function CustomToolbar() {
}

export default function DensitySelectorSmallGrid() {
const [density, setDensity] = React.useState('compact');

const { data } = useDemoData({
dataSet: 'Commodity',
rowLength: 4,
Expand All @@ -25,7 +27,11 @@ export default function DensitySelectorSmallGrid() {
<div style={{ height: 300, width: '100%' }}>
<DataGrid
{...data}
density="compact"
density={density}
onDensityChange={(newDensity) => {
console.info(`Density updated to: ${newDensity}`);
MBilalShafi marked this conversation as resolved.
Show resolved Hide resolved
setDensity(newDensity);
}}
slots={{
toolbar: CustomToolbar,
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
DataGrid,
GridToolbarContainer,
GridToolbarDensitySelector,
GridDensity,
} from '@mui/x-data-grid';
import { useDemoData } from '@mui/x-data-grid-generator';

Expand All @@ -15,6 +16,8 @@ function CustomToolbar() {
}

export default function DensitySelectorSmallGrid() {
const [density, setDensity] = React.useState<GridDensity>('compact');

const { data } = useDemoData({
dataSet: 'Commodity',
rowLength: 4,
Expand All @@ -25,7 +28,11 @@ export default function DensitySelectorSmallGrid() {
<div style={{ height: 300, width: '100%' }}>
<DataGrid
{...data}
density="compact"
density={density}
onDensityChange={(newDensity) => {
console.info(`Density updated to: ${newDensity}`);
setDensity(newDensity);
}}
slots={{
toolbar: CustomToolbar,
}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
<DataGrid
{...data}
density="compact"
density={density}
onDensityChange={(newDensity) => {
console.info(`Density updated to: ${newDensity}`);
setDensity(newDensity);
}}
slots={{
toolbar: CustomToolbar,
}}
Expand Down
50 changes: 42 additions & 8 deletions docs/data/data-grid/accessibility/accessibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
<DataGrid
initialState={{
density: 'compact',
}}
/>
```

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<GridDensity>('compact');

### Density prop
return (
<DataGrid
density={density}
onDensityChange={(newDensity) => 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"}}

Expand Down
7 changes: 7 additions & 0 deletions docs/data/data-grid/events/events.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
<DataGrid
- density="compact"
+ initialState={{ density: "compact" }}
/>
```

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<GridDensity>('compact');
<DataGrid
- density="compact"
+ density={density}
+ onDensityChange={(newDensity) => setDensity(newDensity)}
/>
```

- The selector `gridDensityValueSelector` was removed, use the `gridDensitySelector` instead.

<!-- ### Rows

- -->
Expand Down
7 changes: 7 additions & 0 deletions docs/pages/x/api/data-grid/data-grid-premium.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
7 changes: 7 additions & 0 deletions docs/pages/x/api/data-grid/data-grid-pro.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
7 changes: 7 additions & 0 deletions docs/pages/x/api/data-grid/data-grid.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
8 changes: 1 addition & 7 deletions docs/pages/x/api/data-grid/selectors.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,15 +124,9 @@
},
{
"name": "gridDensitySelector",
"returnType": "GridDensityState",
"description": "",
"supportsApiRef": false
},
{
"name": "gridDensityValueSelector",
"returnType": "GridDensity",
"description": "",
"supportsApiRef": true
"supportsApiRef": false
},
{
"name": "gridDetailPanelExpandedRowIdsSelector",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
4 changes: 4 additions & 0 deletions docs/translations/api-docs/data-grid/data-grid/data-grid.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
5 changes: 5 additions & 0 deletions packages/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
5 changes: 5 additions & 0 deletions packages/x-data-grid/src/DataGrid/DataGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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]].
Expand Down
1 change: 0 additions & 1 deletion packages/x-data-grid/src/DataGrid/useDataGridProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 3 additions & 3 deletions packages/x-data-grid/src/components/containers/GridRoot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -55,13 +55,13 @@ const GridRoot = React.forwardRef<HTMLDivElement, GridRootProps>(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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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();

Expand All @@ -60,15 +60,15 @@ const GridToolbarDensitySelector = React.forwardRef<
];

const startIcon = React.useMemo<React.ReactElement>(() => {
switch (densityValue) {
switch (density) {
case 'compact':
return <rootProps.slots.densityCompactIcon />;
case 'comfortable':
return <rootProps.slots.densityComfortableIcon />;
default:
return <rootProps.slots.densityStandardIcon />;
}
}, [densityValue, rootProps]);
}, [density, rootProps]);

const handleDensitySelectorOpen = (event: React.MouseEvent<HTMLButtonElement>) => {
setOpen((prevOpen) => !prevOpen);
Expand Down Expand Up @@ -100,7 +100,7 @@ const GridToolbarDensitySelector = React.forwardRef<
<MenuItem
key={index}
onClick={() => handleDensityUpdate(option.value)}
selected={option.value === densityValue}
selected={option.value === density}
>
<ListItemIcon>{option.icon}</ListItemIcon>
{option.label}
Expand Down