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] Add indexes relative to the filtered rows and the current page to the getRowClassName and getRowSpacing props #3882

Merged
merged 46 commits into from
Apr 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
a3ba7be
[DataGrid] Pass the indexes relative to the row and the virtualizatio…
flaviendelangle Feb 7, 2022
178b28f
Work
flaviendelangle Feb 7, 2022
e745fbf
Work
flaviendelangle Feb 7, 2022
051becd
[DataGrid] Add support for margin between rows
m4theushw Feb 5, 2022
802bd07
No 'margin'
m4theushw Feb 8, 2022
8ad38da
Fix
flaviendelangle Feb 8, 2022
e6dd0df
Fix
flaviendelangle Feb 8, 2022
bfc8fdd
Adapt to dark mode
m4theushw Feb 8, 2022
24088b0
Add unstable_getRowIndexRelativeToCurrentPage
m4theushw Feb 8, 2022
1574c19
Update descriptions
m4theushw Feb 8, 2022
c1cdd8a
Merge branch 'master' into striped-rows
flaviendelangle Feb 8, 2022
092be63
Work
flaviendelangle Feb 8, 2022
d2ac798
Fix
flaviendelangle Feb 8, 2022
effc3f8
Merge branch 'master' into margin-between-rows
m4theushw Feb 25, 2022
138c722
Move getRowSpacing call to hydrateRowsMeta
m4theushw Feb 25, 2022
80995ee
José's review
m4theushw Feb 25, 2022
c2c5cdc
Remove ignored method from docs
m4theushw Feb 25, 2022
f218e40
Merge branch 'master' into margin-between-rows
m4theushw Mar 4, 2022
cbd5383
Make it apply real margin
m4theushw Mar 4, 2022
eec647c
Add rowSpacingType
m4theushw Mar 4, 2022
5aba750
Abstract params
m4theushw Mar 4, 2022
ee1307a
Rerun argos
m4theushw Mar 4, 2022
f4bca92
Merge branch 'master' into margin-between-rows
m4theushw Mar 7, 2022
8c8f3a3
Remove 'as'
m4theushw Mar 7, 2022
0429fee
Make getRowIndexRelativeToCurrentPage public
m4theushw Mar 7, 2022
187de11
Use gridClasses
m4theushw Mar 7, 2022
2ab6e6a
Merge
flaviendelangle Mar 8, 2022
0e5b557
merge
flaviendelangle Mar 8, 2022
f0bd4d3
Merge
flaviendelangle Mar 10, 2022
1e73cfd
Work
flaviendelangle Mar 10, 2022
37981a3
Fix
flaviendelangle Mar 10, 2022
f70e677
Work
flaviendelangle Mar 11, 2022
5fa769b
Merge
flaviendelangle Mar 15, 2022
affe84d
Merge branch 'master' into striped-rows
flaviendelangle Mar 21, 2022
475d7da
Merge branch 'master' into striped-rows
flaviendelangle Mar 24, 2022
3b25265
Merge
flaviendelangle Mar 29, 2022
3f3c77c
Merge branch 'master' into striped-rows
flaviendelangle Mar 29, 2022
8b95d8c
Work
flaviendelangle Mar 29, 2022
9d4d980
Work
flaviendelangle Mar 29, 2022
4632d69
Work
flaviendelangle Mar 29, 2022
d551b17
Update docs/data/data-grid/style/style.md
flaviendelangle Apr 6, 2022
d6b1323
Work
flaviendelangle Apr 6, 2022
edb129b
Merge branch 'master' into striped-rows
flaviendelangle Apr 6, 2022
ef7c982
Remove expanded index
flaviendelangle Apr 6, 2022
0cac80d
Work
flaviendelangle Apr 6, 2022
36069be
Merge
flaviendelangle Apr 11, 2022
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
58 changes: 58 additions & 0 deletions docs/data/data-grid/style/StripedGrid.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import * as React from 'react';
import { alpha, styled } from '@mui/material/styles';
import { DataGrid, gridClasses } from '@mui/x-data-grid';
import { useDemoData } from '@mui/x-data-grid-generator';

const ODD_OPACITY = 0.2;

const StripedDataGrid = styled(DataGrid)(({ theme }) => ({
[`& .${gridClasses.row}.even`]: {
backgroundColor: theme.palette.grey[200],
'&:hover, &.Mui-hovered': {
backgroundColor: alpha(theme.palette.primary.main, ODD_OPACITY),
'@media (hover: none)': {
backgroundColor: 'transparent',
},
},
'&.Mui-selected': {
backgroundColor: alpha(
theme.palette.primary.main,
ODD_OPACITY + theme.palette.action.selectedOpacity,
),
'&:hover, &.Mui-hovered': {
backgroundColor: alpha(
theme.palette.primary.main,
ODD_OPACITY +
theme.palette.action.selectedOpacity +
theme.palette.action.hoverOpacity,
),
// Reset on touch devices, it doesn't add specificity
'@media (hover: none)': {
backgroundColor: alpha(
theme.palette.primary.main,
ODD_OPACITY + theme.palette.action.selectedOpacity,
),
},
},
},
},
}));

export default function StripedGrid() {
const { data, loading } = useDemoData({
dataSet: 'Employee',
rowLength: 200,
});

return (
<div style={{ height: 400, width: '100%' }}>
<StripedDataGrid
loading={loading}
{...data}
getRowClassName={(params) =>
params.indexRelativeToCurrentPage % 2 === 0 ? 'even' : 'odd'
}
/>
</div>
);
}
58 changes: 58 additions & 0 deletions docs/data/data-grid/style/StripedGrid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import * as React from 'react';
import { alpha, styled } from '@mui/material/styles';
import { DataGrid, gridClasses } from '@mui/x-data-grid';
import { useDemoData } from '@mui/x-data-grid-generator';

const ODD_OPACITY = 0.2;

const StripedDataGrid = styled(DataGrid)(({ theme }) => ({
[`& .${gridClasses.row}.even`]: {
backgroundColor: theme.palette.grey[200],
'&:hover, &.Mui-hovered': {
backgroundColor: alpha(theme.palette.primary.main, ODD_OPACITY),
'@media (hover: none)': {
backgroundColor: 'transparent',
},
},
'&.Mui-selected': {
backgroundColor: alpha(
theme.palette.primary.main,
ODD_OPACITY + theme.palette.action.selectedOpacity,
),
'&:hover, &.Mui-hovered': {
backgroundColor: alpha(
theme.palette.primary.main,
ODD_OPACITY +
theme.palette.action.selectedOpacity +
theme.palette.action.hoverOpacity,
),
// Reset on touch devices, it doesn't add specificity
'@media (hover: none)': {
backgroundColor: alpha(
theme.palette.primary.main,
ODD_OPACITY + theme.palette.action.selectedOpacity,
),
},
},
},
},
}));

export default function StripedGrid() {
const { data, loading } = useDemoData({
dataSet: 'Employee',
rowLength: 200,
});

return (
<div style={{ height: 400, width: '100%' }}>
<StripedDataGrid
loading={loading}
{...data}
getRowClassName={(params) =>
params.indexRelativeToCurrentPage % 2 === 0 ? 'even' : 'odd'
}
/>
</div>
);
}
7 changes: 7 additions & 0 deletions docs/data/data-grid/style/StripedGrid.tsx.preview
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<StripedDataGrid
loading={loading}
{...data}
getRowClassName={(params) =>
params.indexRelativeToCurrentPage % 2 === 0 ? 'even' : 'odd'
}
/>
10 changes: 9 additions & 1 deletion docs/data/data-grid/style/style.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,17 @@ Choose between one of the following values: 'left' | 'right' | 'center'.

**Note**: You must use `headerAlign` to align the content of the header.

## Striped rows

The following demo illustrates how the rows of the grid can be stripped.
flaviendelangle marked this conversation as resolved.
Show resolved Hide resolved

{{"demo": "StripedGrid.js", "bg": "inline"}}

## Custom theme

The following demo leverages the CSS customization API to match the Ant Design specification.
You can use the `indexRelativeToCurrentPage` param passed to `getRowClassName` to apply alternating styles to the rows.

The following demo illustrates how this can be achieved.

{{"demo": "AntDesignGrid.js", "defaultCodeOpen": false}}

Expand Down
17 changes: 9 additions & 8 deletions docs/pages/x/api/data-grid/grid-row-class-name-params.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ import { GridRowClassNameParams } from '@mui/x-data-grid';

## Properties

| Name | Type | Description |
| :-------------------------------------------- | :---------------------------------------------------------------------- | :--------------------------------------------------------- |
| <span class="prop-name">columns</span> | <span class="prop-type">GridColumns</span> | All grid columns. |
| <span class="prop-name">getValue</span> | <span class="prop-type">(id: GridRowId, field: string) =&gt; any</span> | Get the cell value of a row and field. |
| <span class="prop-name">id</span> | <span class="prop-type">GridRowId</span> | The grid row id. |
| <span class="prop-name">isFirstVisible</span> | <span class="prop-type">boolean</span> | Whether this row is the first visible or not. |
| <span class="prop-name">isLastVisible</span> | <span class="prop-type">boolean</span> | Whether this row is the last visible or not. |
| <span class="prop-name">row</span> | <span class="prop-type">R</span> | The row model of the row that the current cell belongs to. |
| Name | Type | Description |
| :-------------------------------------------------------- | :---------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------- |
| <span class="prop-name">columns</span> | <span class="prop-type">GridColumns</span> | All grid columns. |
| <span class="prop-name">getValue</span> | <span class="prop-type">(id: GridRowId, field: string) =&gt; any</span> | Get the cell value of a row and field. |
| <span class="prop-name">id</span> | <span class="prop-type">GridRowId</span> | The grid row id. |
| <span class="prop-name">indexRelativeToCurrentPage</span> | <span class="prop-type">number</span> | Index of the row in the current page.<br />If the pagination is disabled, it will be the index relative to all filtered rows. |
| <span class="prop-name">isFirstVisible</span> | <span class="prop-type">boolean</span> | Whether this row is the first visible or not. |
| <span class="prop-name">isLastVisible</span> | <span class="prop-type">boolean</span> | Whether this row is the last visible or not. |
| <span class="prop-name">row</span> | <span class="prop-type">R</span> | The row model of the row that the current cell belongs to. |
13 changes: 7 additions & 6 deletions docs/pages/x/api/data-grid/grid-row-spacing-params.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ import { GridRowSpacingParams } from '@mui/x-data-grid';

## Properties

| Name | Type | Description |
| :-------------------------------------------- | :--------------------------------------- | :-------------------------------------------- |
| <span class="prop-name">id</span> | <span class="prop-type">GridRowId</span> | The row id. |
| <span class="prop-name">isFirstVisible</span> | <span class="prop-type">boolean</span> | Whether this row is the first visible or not. |
| <span class="prop-name">isLastVisible</span> | <span class="prop-type">boolean</span> | Whether this row is the last visible or not. |
| <span class="prop-name">model</span> | <span class="prop-type">R</span> | The row model. |
| Name | Type | Description |
| :-------------------------------------------------------- | :--------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------- |
| <span class="prop-name">id</span> | <span class="prop-type">GridRowId</span> | The row id. |
| <span class="prop-name">indexRelativeToCurrentPage</span> | <span class="prop-type">number</span> | Index of the row in the current page.<br />If the pagination is disabled, it will be the index relative to all filtered rows. |
| <span class="prop-name">isFirstVisible</span> | <span class="prop-type">boolean</span> | Whether this row is the first visible or not. |
| <span class="prop-name">isLastVisible</span> | <span class="prop-type">boolean</span> | Whether this row is the last visible or not. |
| <span class="prop-name">model</span> | <span class="prop-type">R</span> | The row model. |
17 changes: 16 additions & 1 deletion packages/grid/x-data-grid/src/components/GridRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,15 @@ import { useGridVisibleRows } from '../hooks/utils/useGridVisibleRows';
import { findParentElementFromClassName } from '../utils/domUtils';
import { GRID_CHECKBOX_SELECTION_COL_DEF } from '../colDef/gridCheckboxSelectionColDef';
import { GRID_ACTIONS_COLUMN_TYPE } from '../colDef/gridActionsColDef';
import { GridRenderEditCellParams } from '../models/params/gridCellParams';

export interface GridRowProps {
rowId: GridRowId;
selected: boolean;
/**
* Index of the row in the whole sorted and filtered dataset.
* If some rows above have expanded children, this index also take those children into account.
*/
index: number;
rowHeight: number;
containerWidth: number;
Expand Down Expand Up @@ -214,6 +219,7 @@ function GridRow(props: React.HTMLAttributes<HTMLDivElement> & GridRowProps) {
...apiRef.current.getRowParams(rowId),
isFirstVisible: indexRelativeToCurrentPage === 0,
isLastVisible: indexRelativeToCurrentPage === currentPage.rows.length - 1,
indexRelativeToCurrentPage,
};

rowClassName = rootProps.getRowClassName(rowParams);
Expand Down Expand Up @@ -257,7 +263,12 @@ function GridRow(props: React.HTMLAttributes<HTMLDivElement> & GridRowProps) {
}

if (editCellState != null && column.renderEditCell) {
const params = { ...cellParams, ...editCellState, api: apiRef.current };
const params: GridRenderEditCellParams = {
...cellParams,
...editCellState,
api: apiRef.current,
};

content = column.renderEditCell(params);
// TODO move to GridCell
classNames.push(clsx(gridClasses['cell--editing'], rootProps.classes?.['cell--editing']));
Expand Down Expand Up @@ -336,6 +347,10 @@ GridRow.propTypes = {
containerWidth: PropTypes.number.isRequired,
editRowsState: PropTypes.object.isRequired,
firstColumnToRender: PropTypes.number.isRequired,
/**
* Index of the row in the whole sorted and filtered dataset.
* If some rows above have expanded children, this index also take those children into account.
*/
index: PropTypes.number.isRequired,
isLastVisible: PropTypes.bool,
lastColumnToRender: PropTypes.number.isRequired,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,15 @@ export const useGridRowsMeta = (
const initialHeights: Record<string, number> = { base: baseRowHeight };

if (getRowSpacing) {
const index = apiRef.current.getRowIndexRelativeToVisibleRows(row.id);
const indexRelativeToCurrentPage = apiRef.current.getRowIndexRelativeToVisibleRows(
row.id,
);

const spacing = getRowSpacing({
...row,
isFirstVisible: index === 0,
isLastVisible: index === currentPage.rows.length - 1,
isFirstVisible: indexRelativeToCurrentPage === 0,
isLastVisible: indexRelativeToCurrentPage === currentPage.rows.length - 1,
indexRelativeToCurrentPage,
});

initialHeights.spacingTop = spacing.top ?? 0;
Expand Down
5 changes: 5 additions & 0 deletions packages/grid/x-data-grid/src/models/params/gridRowParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ interface GridRowVisibilityParams {
* Whether this row is the last visible or not.
*/
isLastVisible: boolean;
/**
* Index of the row in the current page.
* If the pagination is disabled, it will be the index relative to all filtered rows.
*/
indexRelativeToCurrentPage: number;
}

/**
Expand Down
5 changes: 4 additions & 1 deletion packages/grid/x-data-grid/src/tests/rows.DataGrid.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -374,16 +374,17 @@ describe('<DataGrid /> - Rows', () => {
it('should be called with the correct params', () => {
const getRowSpacing = stub().returns({});
render(<TestCase getRowSpacing={getRowSpacing} pageSize={2} rowsPerPageOptions={[2]} />);

expect(getRowSpacing.args[0][0]).to.deep.equal({
isFirstVisible: true,
isLastVisible: false,
indexRelativeToCurrentPage: 0,
id: 0,
model: rows[0],
});
expect(getRowSpacing.args[1][0]).to.deep.equal({
isFirstVisible: false,
isLastVisible: true,
indexRelativeToCurrentPage: 1,
id: 1,
model: rows[1],
});
Expand All @@ -394,12 +395,14 @@ describe('<DataGrid /> - Rows', () => {
expect(getRowSpacing.args[0][0]).to.deep.equal({
isFirstVisible: true,
isLastVisible: false,
indexRelativeToCurrentPage: 0,
id: 2,
model: rows[2],
});
expect(getRowSpacing.args[1][0]).to.deep.equal({
isFirstVisible: false,
isLastVisible: true,
indexRelativeToCurrentPage: 1,
id: 3,
model: rows[3],
});
Expand Down