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] Support pinned columns and dynamic row height #5782

Merged
merged 10 commits into from
Sep 1, 2022
172 changes: 172 additions & 0 deletions docs/data/data-grid/column-pinning/ColumnPinningDynamicRowHeight.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import * as React from 'react';
import DeleteIcon from '@mui/icons-material/Delete';
import EditIcon from '@mui/icons-material/Edit';
import PrintIcon from '@mui/icons-material/Print';
import Stack from '@mui/material/Stack';
import Button from '@mui/material/Button';
import { DataGridPro, useGridApiRef } from '@mui/x-data-grid-pro';
import {
randomCreatedDate,
randomTraderName,
randomEmail,
randomUpdatedDate,
} from '@mui/x-data-grid-generator';

export default function ColumnPinningDynamicRowHeight() {
const apiRef = useGridApiRef();
const [showEditDelete, setShowEditDelete] = React.useState(true);

const columns = React.useMemo(
() => [
{ field: 'name', headerName: 'Name', width: 160, editable: true },
{ field: 'email', headerName: 'Email', width: 200, editable: true },
{ field: 'age', headerName: 'Age', type: 'number', editable: true },
{
field: 'dateCreated',
headerName: 'Date Created',
type: 'date',
width: 180,
editable: true,
},
{
field: 'lastLogin',
headerName: 'Last Login',
type: 'dateTime',
width: 220,
editable: true,
},
{
field: 'actions',
headerName: 'Actions',
width: 100,
renderCell: () => (
<Stack spacing={1} sx={{ width: 1, py: 1 }}>
{showEditDelete && (
<React.Fragment>
<Button variant="outlined" size="small" startIcon={<EditIcon />}>
Edit
</Button>
<Button variant="outlined" size="small" startIcon={<DeleteIcon />}>
Delete
</Button>
</React.Fragment>
)}

<Button variant="outlined" size="small" startIcon={<PrintIcon />}>
Print
</Button>
</Stack>
),
},
],
[showEditDelete],
);

const handleToggleClick = React.useCallback(() => {
setShowEditDelete((prevShowEditDelete) => !prevShowEditDelete);
}, []);

React.useLayoutEffect(() => {
apiRef.current.resetRowHeights();
}, [apiRef, showEditDelete]);

return (
<div style={{ width: '100%' }}>
<Button sx={{ mb: 2 }} onClick={handleToggleClick}>
Toggle edit & delete
</Button>
<div style={{ height: 400 }}>
<DataGridPro
apiRef={apiRef}
rows={rows}
columns={columns}
getRowHeight={() => 'auto'}
initialState={{ pinnedColumns: { left: ['name'], right: ['actions'] } }}
/>
</div>
</div>
);
}

const rows = [
{
id: 1,
name: randomTraderName(),
email: randomEmail(),
age: 25,
dateCreated: randomCreatedDate(),
lastLogin: randomUpdatedDate(),
},
{
id: 2,
name: randomTraderName(),
email: randomEmail(),
age: 36,
dateCreated: randomCreatedDate(),
lastLogin: randomUpdatedDate(),
},
{
id: 3,
name: randomTraderName(),
email: randomEmail(),
age: 19,
dateCreated: randomCreatedDate(),
lastLogin: randomUpdatedDate(),
},
{
id: 4,
name: randomTraderName(),
email: randomEmail(),
age: 28,
dateCreated: randomCreatedDate(),
lastLogin: randomUpdatedDate(),
},
{
id: 5,
name: randomTraderName(),
email: randomEmail(),
age: 23,
dateCreated: randomCreatedDate(),
lastLogin: randomUpdatedDate(),
},
{
id: 6,
name: randomTraderName(),
email: randomEmail(),
age: 27,
dateCreated: randomCreatedDate(),
lastLogin: randomUpdatedDate(),
},
{
id: 7,
name: randomTraderName(),
email: randomEmail(),
age: 18,
dateCreated: randomCreatedDate(),
lastLogin: randomUpdatedDate(),
},
{
id: 8,
name: randomTraderName(),
email: randomEmail(),
age: 31,
dateCreated: randomCreatedDate(),
lastLogin: randomUpdatedDate(),
},
{
id: 9,
name: randomTraderName(),
email: randomEmail(),
age: 24,
dateCreated: randomCreatedDate(),
lastLogin: randomUpdatedDate(),
},
{
id: 10,
name: randomTraderName(),
email: randomEmail(),
age: 35,
dateCreated: randomCreatedDate(),
lastLogin: randomUpdatedDate(),
},
];
176 changes: 176 additions & 0 deletions docs/data/data-grid/column-pinning/ColumnPinningDynamicRowHeight.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
import * as React from 'react';
import DeleteIcon from '@mui/icons-material/Delete';
import EditIcon from '@mui/icons-material/Edit';
import PrintIcon from '@mui/icons-material/Print';
import Stack from '@mui/material/Stack';
import Button from '@mui/material/Button';
import {
DataGridPro,
GridColumns,
GridRowsProp,
useGridApiRef,
} from '@mui/x-data-grid-pro';
import {
randomCreatedDate,
randomTraderName,
randomEmail,
randomUpdatedDate,
} from '@mui/x-data-grid-generator';

export default function ColumnPinningDynamicRowHeight() {
const apiRef = useGridApiRef();
const [showEditDelete, setShowEditDelete] = React.useState(true);

const columns: GridColumns = React.useMemo(
() => [
{ field: 'name', headerName: 'Name', width: 160, editable: true },
{ field: 'email', headerName: 'Email', width: 200, editable: true },
{ field: 'age', headerName: 'Age', type: 'number', editable: true },
{
field: 'dateCreated',
headerName: 'Date Created',
type: 'date',
width: 180,
editable: true,
},
{
field: 'lastLogin',
headerName: 'Last Login',
type: 'dateTime',
width: 220,
editable: true,
},
{
field: 'actions',
headerName: 'Actions',
width: 100,
renderCell: () => (
<Stack spacing={1} sx={{ width: 1, py: 1 }}>
{showEditDelete && (
<React.Fragment>
<Button variant="outlined" size="small" startIcon={<EditIcon />}>
Edit
</Button>
<Button variant="outlined" size="small" startIcon={<DeleteIcon />}>
Delete
</Button>
</React.Fragment>
)}
<Button variant="outlined" size="small" startIcon={<PrintIcon />}>
Print
</Button>
</Stack>
),
},
],
[showEditDelete],
);

const handleToggleClick = React.useCallback(() => {
setShowEditDelete((prevShowEditDelete) => !prevShowEditDelete);
}, []);

React.useLayoutEffect(() => {
apiRef.current.resetRowHeights();
}, [apiRef, showEditDelete]);

return (
<div style={{ width: '100%' }}>
<Button sx={{ mb: 2 }} onClick={handleToggleClick}>
Toggle edit & delete
</Button>
<div style={{ height: 400 }}>
<DataGridPro
apiRef={apiRef}
rows={rows}
columns={columns}
getRowHeight={() => 'auto'}
initialState={{ pinnedColumns: { left: ['name'], right: ['actions'] } }}
/>
</div>
</div>
);
}

const rows: GridRowsProp = [
{
id: 1,
name: randomTraderName(),
email: randomEmail(),
age: 25,
dateCreated: randomCreatedDate(),
lastLogin: randomUpdatedDate(),
},
{
id: 2,
name: randomTraderName(),
email: randomEmail(),
age: 36,
dateCreated: randomCreatedDate(),
lastLogin: randomUpdatedDate(),
},
{
id: 3,
name: randomTraderName(),
email: randomEmail(),
age: 19,
dateCreated: randomCreatedDate(),
lastLogin: randomUpdatedDate(),
},
{
id: 4,
name: randomTraderName(),
email: randomEmail(),
age: 28,
dateCreated: randomCreatedDate(),
lastLogin: randomUpdatedDate(),
},
{
id: 5,
name: randomTraderName(),
email: randomEmail(),
age: 23,
dateCreated: randomCreatedDate(),
lastLogin: randomUpdatedDate(),
},
{
id: 6,
name: randomTraderName(),
email: randomEmail(),
age: 27,
dateCreated: randomCreatedDate(),
lastLogin: randomUpdatedDate(),
},
{
id: 7,
name: randomTraderName(),
email: randomEmail(),
age: 18,
dateCreated: randomCreatedDate(),
lastLogin: randomUpdatedDate(),
},
{
id: 8,
name: randomTraderName(),
email: randomEmail(),
age: 31,
dateCreated: randomCreatedDate(),
lastLogin: randomUpdatedDate(),
},
{
id: 9,
name: randomTraderName(),
email: randomEmail(),
age: 24,
dateCreated: randomCreatedDate(),
lastLogin: randomUpdatedDate(),
},
{
id: 10,
name: randomTraderName(),
email: randomEmail(),
age: 35,
dateCreated: randomCreatedDate(),
lastLogin: randomUpdatedDate(),
},
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Button sx={{ mb: 2 }} onClick={handleToggleClick}>
Toggle edit & delete
</Button>
<div style={{ height: 400 }}>
<DataGridPro
apiRef={apiRef}
rows={rows}
columns={columns}
getRowHeight={() => 'auto'}
initialState={{ pinnedColumns: { left: ['name'], right: ['actions'] } }}
/>
</div>
10 changes: 10 additions & 0 deletions docs/data/data-grid/column-pinning/column-pinning.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,16 @@ To pin the checkbox column added when using `checkboxSelection`, add `GRID_CHECK

{{"demo": "ColumnPinningWithCheckboxSelection.js", "disableAd": true, "bg": "inline"}}

## Usage with dynamic row height

You can have both pinned columns and [dynamic row height](/x/react-data-grid/row-height/#dynamic-row-height) enabled at the same time.
However, if the rows change their content after the initial calculation, you may need to trigger a manual recalculation to avoid incorrect measurements.
You can do this by calling `apiRef.current.resetRowHeights()` every time that the content changes.

The demo below contains an example of both features enabled:

{{"demo": "ColumnPinningDynamicRowHeight.js", "disableAd": true, "bg": "inline"}}

## apiRef

{{"demo": "ColumnPinningApiNoSnap.js", "bg": "inline", "hideToolbar": true}}
Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/data-grid/grid-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ import { GridApi } from '@mui/x-data-grid-pro';
| <span class="prop-name">pinColumn [<span class="plan-pro" title="Pro plan"></span>](/x/introduction/licensing/#pro-plan)</span> | <span class="prop-type">(field: string, side: GridPinnedPosition) =&gt; void</span> | Pins a column to the left or right side of the grid. |
| <span class="prop-name">publishEvent</span> | <span class="prop-type">GridEventPublisher</span> | Emits an event. |
| <span class="prop-name">removeRowGroupingCriteria [<span class="plan-premium" title="Premium plan"></span>](https://mui.com/store/items/material-ui-premium/)</span> | <span class="prop-type">(groupingCriteriaField: string) =&gt; void</span> | Remove the field from the row grouping model. |
| <span class="prop-name">resetRowHeights</span> | <span class="prop-type">() =&gt; void</span> | Forces the recalculation of the heights of all rows. |
| <span class="prop-name">resize</span> | <span class="prop-type">() =&gt; void</span> | Triggers a resize of the component and recalculation of width and height. |
| <span class="prop-name">restoreState</span> | <span class="prop-type">(stateToRestore: InitialState) =&gt; void</span> | Inject the given values into the state of the DataGrid. |
| <span class="prop-name">scroll</span> | <span class="prop-type">(params: Partial&lt;GridScrollParams&gt;) =&gt; void</span> | Triggers the viewport to scroll to the given positions (in pixels). |
Expand Down
Loading