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

[data grid] Row css class for striped rows #13218

Closed
mauro-ni opened this issue May 23, 2024 · 20 comments
Closed

[data grid] Row css class for striped rows #13218

mauro-ni opened this issue May 23, 2024 · 20 comments
Labels
component: data grid This is the name of the generic UI component, not the React module! customization: css Design CSS customizability support: commercial Support request from paid users support: premium standard Support request from a Premium standard plan user. https://mui.com/legal/technical-support-sla/

Comments

@mauro-ni
Copy link

mauro-ni commented May 23, 2024

The problem in depth

Good morning,
at https://mui.com/x/react-data-grid/style/#striped-rows you provide a solution to get striped rows.
You suggest to use getRowClassName as follows and then to apply the desired style using added classes.

getRowClassName={(params) =>
    params.indexRelativeToCurrentPage % 2 === 0 ? "even" : "odd"
}

Is there a way to automatically get even / odd classes by default?
I have around twenty DataGrid instances and I would avoid code repetition.

If I remember correctly, in past versions of mui-x the Mui-even and Mui-odd classes were included automatically. Were they removed for performance reasons?

Many thanks in advance.

Mauro

Your environment

`npx @mui/envinfo`
System:
    OS: macOS 14.5
  Binaries:
    Node: 22.2.0 - /usr/local/bin/node
    npm: 10.7.0 - /usr/local/bin/npm
    pnpm: Not Found
  Browsers:
    Chrome: 124.0.6367.208
    Edge: Not Found
    Safari: 17.5
  npmPackages:
    @emotion/react: ^11.11.4 => 11.11.4 
    @emotion/styled: ^11.11.5 => 11.11.5 
    @mui/base: 5.0.0-beta.44 => 5.0.0-beta.44 
    @mui/core-downloads-tracker:  5.15.17 
    @mui/icons-material: 5.15.17 => 5.15.17 
    @mui/lab: ^5.0.0-alpha.170 => 5.0.0-alpha.170 
    @mui/material: ^5.15.17 => 5.15.17 
    @mui/private-theming:  5.15.14 
    @mui/styled-engine:  5.15.14 
    @mui/system: ^5.15.15 => 5.15.15 
    @mui/types:  7.2.14 
    @mui/utils:  5.15.14 
    @mui/x-data-grid:  7.5.0 
    @mui/x-data-grid-premium: ^7.5.0 => 7.5.0 
    @mui/x-data-grid-pro:  7.5.0 
    @mui/x-date-pickers:  7.5.0 
    @mui/x-date-pickers-pro: ^7.5.0 => 7.5.0 
    @mui/x-license: ^7.2.0 => 7.2.0 
    @mui/x-tree-view: ^7.5.0 => 7.5.0 
    @types/react:  18.0.14 
    react: ^18.3.1 => 18.3.1 
    react-dom: ^18.3.1 => 18.3.1 
    typescript:  5.1.6 

Search keywords: stripe striped zebra
Order ID: 47709

@mauro-ni mauro-ni added status: waiting for maintainer These issues haven't been looked at yet by a maintainer support: commercial Support request from paid users labels May 23, 2024
@michelengelen michelengelen added component: data grid This is the name of the generic UI component, not the React module! customization: css Design CSS customizability support: premium standard Support request from a Premium standard plan user. https://mui.com/legal/technical-support-sla/ labels May 23, 2024
@michelengelen michelengelen changed the title Row css class for striped rows [question] [data grid] Row css class for striped rows May 23, 2024
@michelengelen
Copy link
Member

No, this is not the only way to do this, just one.
You could just as well apply a pure CSS way of doing this.

const StripedDataGrid = styled(DataGridPremium)(({ theme }) => ({
  [`& .${gridClasses.row}:nth-child(even)`]: {
    backgroundColor: theme.palette.grey[200],
    '&:hover': {
      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': {
        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,
          ),
        },
      },
    },
  },
}));

You could also do a global override with a custom theme if that is more convenient.

@michelengelen
Copy link
Member

notice the [`& .${gridClasses.row}:nth-child(even)/`] CSS selector (nth-child)

@michelengelen michelengelen added status: waiting for author Issue with insufficient information and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels May 23, 2024
@flaviendelangle
Copy link
Member

@michelengelen won't that flicker when you scroll due to virtualization?

@mauro-ni
Copy link
Author

mauro-ni commented May 23, 2024

@michelengelen tanks for your reply.
This is exactly the approach I used for a long time, but now with new version 7.50 it flickers and row backgrounds switch.

DataGridPremium-Striped.mov

@github-actions github-actions bot added status: waiting for maintainer These issues haven't been looked at yet by a maintainer and removed status: waiting for author Issue with insufficient information labels May 23, 2024
@mauro-ni
Copy link
Author

mauro-ni commented May 23, 2024

I think it could be useful to define a boolean striped property for DataGrid that automatically adds Mui-even / Mui-odd calsses with default styles when activated. Of course then developers can override and customize the style.

What do you think?

Many thanks,
Mauro

@flaviendelangle
Copy link
Member

You should be able to set `getRowClassName in your theme so it applies on every data grid you have.

@mauro-ni
Copy link
Author

@flaviendelangle how should I put getRowClassName in createTheme({...}) call?
Many thanks for your help.

Mauro

@mauro-ni
Copy link
Author

mauro-ni commented May 23, 2024

Ok, found:

MuiDataGrid: {
    defaultProps: {
        getRowClassName: ({ indexRelativeToCurrentPage }) =>
        indexRelativeToCurrentPage % 2 === 0 ? "even" : "odd",
    },
},

@flaviendelangle
Copy link
Member

Here is a working example

It's pretty much what you have in your last message 👍

@mauro-ni
Copy link
Author

@flaviendelangle many thanks for your help!

@michelengelen
Copy link
Member

Great that we could be of help and thanks @flaviendelangle for providing a great example.
I will close this now, but feel free to reopen if you have follow-up questions! 🙇🏼

@michelengelen michelengelen removed the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label May 23, 2024
Copy link

⚠️ This issue has been closed. If you have a similar problem but not exactly the same, please open a new issue.
Now, if you have additional information related to this issue or things that could help future readers, feel free to leave a comment.

@mauro-ni: How did we do? Your experience with our support team matters to us. If you have a moment, please share your thoughts in this short Support Satisfaction survey.

@mauro-ni
Copy link
Author

mauro-ni commented May 23, 2024

Playing with the new implementation I noticed that on pinned columns the stripe effect is lost.

@flaviendelangle
Copy link
Member

flaviendelangle commented May 23, 2024

@michelengelen can I let you see how to support pinned columns?
It's probably just a question of applying the CSS to the right element, unless we don't apply the row classname to pinned columns at all.

@mauro-ni
Copy link
Author

mauro-ni commented May 24, 2024

@flaviendelangle good morning, regarding the suggested approach for stripes (using alpha), I would like to point out that there is a problem when applying it to pinned columns: on scroll the content this is visible under the pinned columns. It would probably be better to use darken / lighten utilities.

Another styling issue with v 7.5 is on DataGrid used inside Paper component: header and pinned columns get a darker background.

DataGrid-BG

I read about that in https://mui.com/x/migration/migration-data-grid-v6

The column headers and pinned section now require an explicit color. By default, the MUI theme.palette.background.default color will be used. To customize it, see https://mui.com/material-ui/customization/palette/#customization We will be adding a new color name to the palette for additional customization, read #12443 for more details.

Is there a way to globally handle that?

@mauro-ni
Copy link
Author

As a temporary solution I managed the background customizing the theme as follows (inPaper is a prop that I set on DataGrid):

MuiDataGrid: {
    styleOverrides: {
        root: ({ ownerState, theme }) => {
            const paperBackground = theme.palette.background.paper;
            if (ownerState?.inPaper) {
                return {
                    [`--DataGrid-pinnedBackground`]: `${paperBackground} !important`,
                    [`--DataGrid-containerBackground`]: `${paperBackground} !important`,
                };
            }
            return {};
        },
    }
}

I don't like this solution, it is a workaround, but ... seems to work.

Do you have a better solution for that?

@michelengelen
Copy link
Member

@mauro-ni this seems like a good way to handle the pinned background until we come up with a solid solution internally. Interestingly enough I. haven't noticed the header behavior before. Thanks for pointing that out.

@flaviendelangle I had a codesandbox somewhere where I did implement that once ... just cannot find it anymore! 🤷🏼

But it is rather simple. Instead of targeting the row styles you can just as well target the cells:

`& .${gridClasses.row}.even > .${gridClasses.cell}`

@flaviendelangle
Copy link
Member

Maybe we could adapt https://mui.com/x/react-data-grid/style/#striped-rows to handle pinned rows

@mauro-ni
Copy link
Author

@michelengelen thank you for your help.

Targeting the cell instead of the row with the code you suggested partially breaks hover effect.

`& .${gridClasses.row}.even > .${gridClasses.cell}`

@mauro-ni
Copy link
Author

mauro-ni commented May 24, 2024

Here is a temporary solution that, again, I don't like (there was an issue with the implementation with alpha() because pinned columns have forced background, and for now I force the backgrounds I want).

I think that a boolean striped property on DataGrid / DataGridPro / DataGridPremium could be useful (maybe being able to specify hover & selection color).

const ODD_OPACITY = 0.2;

MuiDataGrid: {
    defaultProps: {
      getRowClassName: ({ indexRelativeToCurrentPage }) =>
        indexRelativeToCurrentPage % 2 === 0 ? "even" : "odd",
    },
    styleOverrides: {
      columnHeaderTitle: {
        fontWeight: "bold",
      },
      columnHeader: {
        [`& .MuiFormControl-root`]: {
          flex: 1,
        },
      },
      // HACK to handle DataGrid inside Paper
      root: ({ ownerState, theme }) => {
        const paperBackground = theme.palette.background.paper;
        if (ownerState?.inPaper) {
          return {
            [`--DataGrid-pinnedBackground`]: `${paperBackground} !important`,
            [`--DataGrid-containerBackground`]: `${paperBackground} !important`,
          };
        }
        return {};
      },
      // HACK to make striped rows work with pinned columns
      row: ({ theme }) => ({
        [`&.even, &.even .${gridClasses["cell--pinnedLeft"]}, &.even .${gridClasses["cell--pinnedRight"]}`]:
          {
            backgroundColor:
              theme.palette.mode === "light"
                ? lighten(theme.palette.grey[200], ODD_OPACITY)
                : lighten(theme.palette.grey[900], ODD_OPACITY),
          },
        [`&:hover, &:hover .${gridClasses["cell--pinnedLeft"]}, &:hover .${gridClasses["cell--pinnedRight"]}`]:
          {
            backgroundColor:
              theme.palette.mode === "light"
                ? `rgb(211, 223, 241) !important`
                : `rgb(69, 79, 87) !important`,
            "@media (hover: none)": {
              backgroundColor: "transparent",
            },
          },
        [`&.Mui-selected, &.Mui-selected .${gridClasses["cell--pinnedLeft"]}, &.Mui-selected .${gridClasses["cell--pinnedRight"]}`]:
          {
            backgroundColor:
              theme.palette.mode === "light"
                ? `rgb(196, 213, 237) !important`
                : `rgb(86, 102, 118) !important`,
            [`&:hover, &:hover .${gridClasses["cell--pinnedLeft"]}, &:hover .${gridClasses["cell--pinnedRight"]}`]:
              {
                backgroundColor:
                  theme.palette.mode === "light"
                    ? `rgb(188, 206, 234) !important`
                    : `rgb(96, 115, 134) !important`,
                // Reset on touch devices, it doesn't add specificity
                "@media (hover: none)": {
                  backgroundColor:
                    theme.palette.mode === "light"
                      ? `rgb(196, 213, 237) !important`
                      : `rgb(86, 102, 118) !important`,
                },
              },
          },
      }),
    },
  },

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: data grid This is the name of the generic UI component, not the React module! customization: css Design CSS customizability support: commercial Support request from paid users support: premium standard Support request from a Premium standard plan user. https://mui.com/legal/technical-support-sla/
Projects
None yet
Development

No branches or pull requests

3 participants