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

[DataGridPro] Autosize columns #10180

Merged
merged 67 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
58b81d8
feat: setup api typings
romgrk Aug 31, 2023
fbacef8
lint
romgrk Aug 31, 2023
6eb4c33
draft
romgrk Sep 6, 2023
7bb5eed
Merge branch 'master' into feat-auto-sizing
romgrk Sep 6, 2023
fbd645e
feat: calculate widths
romgrk Sep 6, 2023
fec64c5
feat: disable virtualization while getting widths
romgrk Sep 6, 2023
6db3879
draft: first implementation
romgrk Sep 7, 2023
3819972
docs: add demo
romgrk Sep 7, 2023
b423465
lint
romgrk Sep 7, 2023
93b135e
refactor
romgrk Sep 7, 2023
aba5388
lint
romgrk Sep 7, 2023
8d899d0
lint
romgrk Sep 7, 2023
9c723e5
refactor
romgrk Sep 7, 2023
1967163
refactor
romgrk Sep 7, 2023
8b24ed1
docs
romgrk Sep 7, 2023
3e8edb8
lint
romgrk Sep 7, 2023
34142a0
feat: add autosizing props
romgrk Sep 9, 2023
978fbc1
refactor: new approach
romgrk Sep 12, 2023
52986f2
lint
romgrk Sep 12, 2023
310bbe0
lint
romgrk Sep 12, 2023
b8c1a82
lint
romgrk Sep 12, 2023
2ff9ecb
lint
romgrk Sep 12, 2023
1db9646
doc: comments
romgrk Sep 12, 2023
dd165c9
lint
romgrk Sep 12, 2023
1d14a37
fix: types
romgrk Sep 12, 2023
f272533
lint
romgrk Sep 12, 2023
a0cd6bb
lint
romgrk Sep 12, 2023
f9f2d02
lint
romgrk Sep 13, 2023
ae8f7b9
lint
romgrk Sep 13, 2023
e35854b
lint
romgrk Sep 13, 2023
df10cc3
feat: make it work
romgrk Sep 13, 2023
7c5ce54
glork
romgrk Sep 13, 2023
675d094
lint
romgrk Sep 13, 2023
e34ac05
doc
romgrk Sep 13, 2023
9bc48b6
lint
romgrk Sep 13, 2023
2c8af8b
lint
romgrk Sep 13, 2023
bbe3ab4
lint
romgrk Sep 13, 2023
7a08e0a
feat: scrollWidth
romgrk Sep 13, 2023
386ea98
lint
romgrk Sep 13, 2023
0e549df
lint
romgrk Sep 14, 2023
29134e9
feat: double-click implementation
romgrk Sep 14, 2023
3c7fe6a
lint
romgrk Sep 14, 2023
d69754d
fix
romgrk Sep 14, 2023
afea006
fix
romgrk Sep 14, 2023
ea7a6b6
lint
romgrk Sep 14, 2023
6e3df33
doc
romgrk Sep 17, 2023
b427a75
doc
romgrk Sep 17, 2023
9401db1
Merge branch 'master' into feat-auto-sizing
romgrk Sep 17, 2023
8f8261c
fix
romgrk Sep 17, 2023
7bda608
doc
romgrk Sep 17, 2023
c04048f
doc: update
romgrk Sep 18, 2023
1f2b19f
fix: bugs
romgrk Sep 18, 2023
0fdad6d
fix
romgrk Sep 18, 2023
f590190
lint
romgrk Sep 18, 2023
c454521
lint
romgrk Sep 18, 2023
dc5e4c9
refactor
romgrk Sep 18, 2023
c2d66ef
lint
romgrk Sep 18, 2023
4efe879
Update packages/grid/x-data-grid-pro/src/hooks/features/columnResize/…
romgrk Sep 20, 2023
bc7eb22
Update packages/grid/x-data-grid-pro/src/hooks/features/columnResize/…
romgrk Sep 20, 2023
600a4f2
Update docs/data/data-grid/column-dimensions/column-dimensions.md
romgrk Sep 20, 2023
9d5d1de
Update docs/data/data-grid/column-dimensions/ColumnAutosizing.tsx
romgrk Sep 20, 2023
23323c3
lint
romgrk Sep 20, 2023
c8b52c0
lint
romgrk Sep 20, 2023
0556e3f
lint
romgrk Sep 20, 2023
0d5d9a8
fix: tests
romgrk Sep 20, 2023
486b522
lint
romgrk Sep 20, 2023
581e3f6
Merge branch 'master' into feat-auto-sizing
romgrk Sep 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions docs/data/data-grid/column-dimensions/ColumnAutosizing.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import * as React from 'react';
import Button from '@mui/material/Button';
import Checkbox from '@mui/material/Checkbox';
import FormControlLabel from '@mui/material/FormControlLabel';
import Rating from '@mui/material/Rating';
import Stack from '@mui/material/Stack';
import TextField from '@mui/material/TextField';
import { useGridApiRef } from '@mui/x-data-grid';
import { DataGridPro, DEFAULT_GRID_AUTOSIZE_OPTIONS } from '@mui/x-data-grid-pro';
import { randomRating, randomTraderName } from '@mui/x-data-grid-generator';

function renderRating(params) {
return <Rating readOnly value={params.value} />;
}

function useData(length) {
return React.useMemo(() => {
const names = [
'Nike',
'Adidas',
'Puma',
'Reebok',
'Fila',
'Lululemon Athletica Clothing',
'Varley',
];

const rows = Array.from({ length }).map((_, id) => ({
id,
brand: names[id % names.length],
rep: randomTraderName(),
rating: randomRating(),
}));

const columns = [
{ field: 'id', headerName: 'Brand ID' },
{ field: 'brand', headerName: 'Brand name' },
{ field: 'rep', headerName: 'Representative' },
{ field: 'rating', headerName: 'Rating', renderCell: renderRating },
];

return { rows, columns };
}, [length]);
}

export default function ColumnAutosizing() {
const apiRef = useGridApiRef();
const data = useData(100);

const [includeHeaders, setIncludeHeaders] = React.useState(
DEFAULT_GRID_AUTOSIZE_OPTIONS.includeHeaders,
);
const [includeOutliers, setExcludeOutliers] = React.useState(
DEFAULT_GRID_AUTOSIZE_OPTIONS.includeOutliers,
);
const [outliersFactor, setOutliersFactor] = React.useState(
String(DEFAULT_GRID_AUTOSIZE_OPTIONS.outliersFactor),
);
const [expand, setExpand] = React.useState(DEFAULT_GRID_AUTOSIZE_OPTIONS.expand);

const autosizeOptions = {
includeHeaders,
includeOutliers,
outliersFactor: Number.isNaN(parseFloat(outliersFactor))
? 1
: parseFloat(outliersFactor),
expand,
};

return (
<div style={{ width: '100%' }}>
<Stack
spacing={2}
direction="row"
alignItems="center"
sx={{ marginBottom: '1em' }}
>
<Button
variant="outlined"
onClick={() => apiRef.current.autosizeColumns(autosizeOptions)}
>
Autosize columns
</Button>
<FormControlLabel
control={
<Checkbox
checked={includeHeaders}
onChange={(ev) => setIncludeHeaders(ev.target.checked)}
/>
}
label="Include headers"
/>
<FormControlLabel
control={
<Checkbox
checked={includeOutliers}
onChange={(event) => setExcludeOutliers(event.target.checked)}
/>
}
label="Include outliers"
/>
<TextField
size="small"
label="Outliers factor"
value={outliersFactor}
onChange={(ev) => setOutliersFactor(ev.target.value)}
sx={{ width: '12ch' }}
/>
<FormControlLabel
control={
<Checkbox
checked={expand}
onChange={(ev) => setExpand(ev.target.checked)}
/>
}
label="Expand"
/>
</Stack>
<div style={{ height: 400, width: '100%' }}>
<DataGridPro
apiRef={apiRef}
density="compact"
{...data}
autosizeOptions={autosizeOptions}
/>
</div>
</div>
);
}
132 changes: 132 additions & 0 deletions docs/data/data-grid/column-dimensions/ColumnAutosizing.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import * as React from 'react';
import Button from '@mui/material/Button';
import Checkbox from '@mui/material/Checkbox';
import FormControlLabel from '@mui/material/FormControlLabel';
import Rating from '@mui/material/Rating';
import Stack from '@mui/material/Stack';
import TextField from '@mui/material/TextField';
import { useGridApiRef } from '@mui/x-data-grid';
import {
DataGridPro,
GridApiPro,
DEFAULT_GRID_AUTOSIZE_OPTIONS,
} from '@mui/x-data-grid-pro';
import { randomRating, randomTraderName } from '@mui/x-data-grid-generator';

function renderRating(params: any) {
return <Rating readOnly value={params.value} />;
}

function useData(length: number) {
return React.useMemo(() => {
const names = [
'Nike',
'Adidas',
'Puma',
'Reebok',
'Fila',
'Lululemon Athletica Clothing',
'Varley',
];
const rows = Array.from({ length }).map((_, id) => ({
id,
brand: names[id % names.length],
rep: randomTraderName(),
rating: randomRating(),
}));

const columns = [
{ field: 'id', headerName: 'Brand ID' },
{ field: 'brand', headerName: 'Brand name' },
{ field: 'rep', headerName: 'Representative' },
{ field: 'rating', headerName: 'Rating', renderCell: renderRating },
];

return { rows, columns };
}, [length]);
}

export default function ColumnAutosizing() {
const apiRef = useGridApiRef<GridApiPro>();
const data = useData(100);

const [includeHeaders, setIncludeHeaders] = React.useState(
DEFAULT_GRID_AUTOSIZE_OPTIONS.includeHeaders,
);
const [includeOutliers, setExcludeOutliers] = React.useState(
DEFAULT_GRID_AUTOSIZE_OPTIONS.includeOutliers,
);
const [outliersFactor, setOutliersFactor] = React.useState(
String(DEFAULT_GRID_AUTOSIZE_OPTIONS.outliersFactor),
);
const [expand, setExpand] = React.useState(DEFAULT_GRID_AUTOSIZE_OPTIONS.expand);

const autosizeOptions = {
includeHeaders,
includeOutliers,
outliersFactor: Number.isNaN(parseFloat(outliersFactor))
? 1
: parseFloat(outliersFactor),
expand,
};

return (
<div style={{ width: '100%' }}>
<Stack
spacing={2}
direction="row"
alignItems="center"
sx={{ marginBottom: '1em' }}
>
<Button
variant="outlined"
onClick={() => apiRef.current.autosizeColumns(autosizeOptions)}
>
Autosize columns
</Button>
<FormControlLabel
control={
<Checkbox
checked={includeHeaders}
onChange={(ev) => setIncludeHeaders(ev.target.checked)}
/>
}
label="Include headers"
/>
<FormControlLabel
control={
<Checkbox
checked={includeOutliers}
onChange={(event) => setExcludeOutliers(event.target.checked)}
/>
}
label="Include outliers"
/>
<TextField
romgrk marked this conversation as resolved.
Show resolved Hide resolved
size="small"
label="Outliers factor"
value={outliersFactor}
onChange={(ev) => setOutliersFactor(ev.target.value)}
sx={{ width: '12ch' }}
/>
<FormControlLabel
control={
<Checkbox
checked={expand}
onChange={(ev) => setExpand(ev.target.checked)}
/>
}
label="Expand"
/>
</Stack>
<div style={{ height: 400, width: '100%' }}>
<DataGridPro
apiRef={apiRef}
density="compact"
{...data}
autosizeOptions={autosizeOptions}
/>
</div>
</div>
);
}
39 changes: 39 additions & 0 deletions docs/data/data-grid/column-dimensions/column-dimensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,45 @@ To capture changes in the width of a column there are two callbacks that are cal
- `onColumnResize`: Called while a column is being resized.
- `onColumnWidthChange`: Called after the width of a column is changed, but not during resizing.

## Autosizing [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')
romgrk marked this conversation as resolved.
Show resolved Hide resolved
romgrk marked this conversation as resolved.
Show resolved Hide resolved

`DataGridPro` allows to autosize the columns' dimensions based on their content. Autosizing is enabled by default. To turn it off, pass the `disableAutosize` prop to the datagrid.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Autosizing is enabled by default.

This is a bit misleading since it could be understood as "columns are autosized by default", which is not the case.
Should we rephrase it to "Double-clicking a column header separator is enabled by default"?
@romgrk

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, that sounds good.


Autosizing can be used by one of the following methods:

- Adding the `autosizeOnMount` prop,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: We could be more explicit when naming props. For example autosizeColumnsOnMount, disableColumnsAutosize and columnsAutosizeOptions

- Double-clicking a column header separator on the grid,
- Calling the `apiRef.current.autosizeColumns(options)` API method.

You can pass options directly to the API method when you call it. To configure autosize for the other two methods, provide the options in the `autosizeOptions` prop.

Note that for the separator double-click method, the `autosizeOptions.columns` will be replaced by the respective column user double-clicked on.

In all the cases, the `colDef.minWidth` and `colDef.maxWidth` options will be respected.

```tsx
<DataGridPro
{...otherProps}
autosizeOptions={{
columns: ['name', 'status', 'createdBy'],
includeOutliers: true,
includeHeaders: false,
}}
/>
```

romgrk marked this conversation as resolved.
Show resolved Hide resolved
{{"demo": "ColumnAutosizing.js", "disableAd": true, "bg": "inline"}}

romgrk marked this conversation as resolved.
Show resolved Hide resolved
:::warning
Autosizing has no effect if dynamic row height is enabled.
:::

:::warning
The data grid can only autosize based on the currently rendered cells.

DOM access is required to accurately calculate dimensions, so unmounted cells (when [virtualization](/x/react-data-grid/virtualization/) is on) cannot be sized. If you need a bigger row sample, [open an issue](https://github.com/mui/mui-x/issues) to discuss it further.
:::

## API

- [DataGrid](/x/api/data-grid/data-grid/)
Expand Down
1 change: 1 addition & 0 deletions docs/data/data-grid/getting-started/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ The enterprise components come in two plans: Pro and Premium.
| [Column groups](/x/react-data-grid/column-groups/) | ✅ | ✅ | ✅ |
| [Column spanning](/x/react-data-grid/column-spanning/) | ✅ | ✅ | ✅ |
| [Column resizing](/x/react-data-grid/column-dimensions/#resizing) | ❌ | ✅ | ✅ |
| [Column autosizing](/x/react-data-grid/column-dimensions/#autosizing) | ❌ | ✅ | ✅ |
| [Column reorder](/x/react-data-grid/column-ordering/) | ❌ | ✅ | ✅ |
| [Column pinning](/x/react-data-grid/column-pinning/) | ❌ | ✅ | ✅ |
| **Row** | | | |
Expand Down
8 changes: 8 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 @@ -22,6 +22,13 @@
"aria-labelledby": { "type": { "name": "string" } },
"autoHeight": { "type": { "name": "bool" } },
"autoPageSize": { "type": { "name": "bool" } },
"autosizeOnMount": { "type": { "name": "bool" } },
"autosizeOptions": {
"type": {
"name": "shape",
"description": "{ columns?: Array&lt;string&gt;, expand?: bool, includeHeaders?: bool, includeOutliers?: bool, outliersFactor?: number }"
}
},
"cellModesModel": { "type": { "name": "object" } },
"checkboxSelection": { "type": { "name": "bool" } },
"checkboxSelectionVisibleOnly": {
Expand Down Expand Up @@ -56,6 +63,7 @@
"type": { "name": "arrayOf", "description": "Array&lt;number<br>&#124;&nbsp;string&gt;" }
},
"disableAggregation": { "type": { "name": "bool" } },
"disableAutosize": { "type": { "name": "bool" } },
"disableChildrenFiltering": { "type": { "name": "bool" } },
"disableChildrenSorting": { "type": { "name": "bool" } },
"disableClipboardPaste": { "type": { "name": "bool" } },
Expand Down
8 changes: 8 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 @@ -13,6 +13,13 @@
"aria-labelledby": { "type": { "name": "string" } },
"autoHeight": { "type": { "name": "bool" } },
"autoPageSize": { "type": { "name": "bool" } },
"autosizeOnMount": { "type": { "name": "bool" } },
"autosizeOptions": {
"type": {
"name": "shape",
"description": "{ columns?: Array&lt;string&gt;, expand?: bool, includeHeaders?: bool, includeOutliers?: bool, outliersFactor?: number }"
}
},
"cellModesModel": { "type": { "name": "object" } },
"checkboxSelection": { "type": { "name": "bool" } },
"checkboxSelectionVisibleOnly": {
Expand Down Expand Up @@ -46,6 +53,7 @@
"detailPanelExpandedRowIds": {
"type": { "name": "arrayOf", "description": "Array&lt;number<br>&#124;&nbsp;string&gt;" }
},
"disableAutosize": { "type": { "name": "bool" } },
"disableChildrenFiltering": { "type": { "name": "bool" } },
"disableChildrenSorting": { "type": { "name": "bool" } },
"disableColumnFilter": { "type": { "name": "bool" } },
Expand Down
Loading