4

I'm looking to add a ripple effect to the Material UI Table. I've tried a whole bunch of solutions but none of them quite seem to work perfectly. They all have their own quirks.

I did find this article, but not much effort was put into a solution. My trials so far seem like they could lead to a possible solution (hopefully)? My table rows either end up being the wrong height (and not taking up multiple columns) or they end up being weirdly centered.. not sure how to handle.

https://codesandbox.io/s/pmry2x11vj

<div className="App">
  <Router>
    <Grid container>
      <Grid item xs={12}>
        <Card>
          <Table>
            <TableBody>
              <TableRow hover>
                <TableCell>test</TableCell>
                <TableCell>Property</TableCell>
              </TableRow>
              <TableRow
                hover
                component={Link}
                to={"/"}
                style={{ textDecoration: "none" }}
              >
                <TableCell>Other</TableCell>
                <TableCell>Row</TableCell>
              </TableRow>
              <ButtonBase style={{ width: "100%", height: "100%" }}>
                <TableRow
                  hover
                  component={Link}
                  to={"/"}
                  style={{ textDecoration: "none" }}
                >
                  <TableCell>row</TableCell>
                  <TableCell>is weirdly centered</TableCell>
                </TableRow>
              </ButtonBase>
              <ButtonBase style={{ width: "100%", height: "100%" }}>
                <TableRow
                  hover
                  component={Link}
                  to={"/"}
                  style={{
                    textDecoration: "none",
                    width: "100%",
                    height: "100%"
                  }}
                >
                  <TableCell>row</TableCell>
                  <TableCell>
                    not right height, missing space on right
                  </TableCell>
                </TableRow>
              </ButtonBase>
              <TableRow
                hover
                component={Link}
                to={"/"}
                style={{
                  textDecoration: "none",
                  width: "100%",
                  height: "100%"
                }}
              >
                <ButtonBase style={{ width: "100%", height: "100%" }}>
                  <TableCell>row</TableCell>
                  <TableCell>
                    not right height, missing space on left / right
                  </TableCell>
                </ButtonBase>
              </TableRow>
              <TableRow>
                <TableCell style={{ width: "100%", height: "100%" }}>
                  <ButtonBase style={{ width: "100%", height: "100%" }}>
                    Extra
                  </ButtonBase>
                </TableCell>
                <TableCell>Normal Row</TableCell>
              </TableRow>
              <TableRow>
                <TableCell>Extra</TableCell>
                <TableCell>Normal Row</TableCell>
              </TableRow>
            </TableBody>
          </Table>
        </Card>
      </Grid>
    </Grid>
  </Router>
</div>
AKrush95
  • 1,381
  • 6
  • 18
  • 35

2 Answers2

3

I don't think there is a workable way to use ButtonBase as a row within a Table (at least not without overriding nearly everything about Table, TableRow, and TableCell such that you aren't using the default table html elements). All of your attempts result in invalid html because of either replacing a tr with some other element or having some other element in between a table and tr or between tr and td.

One way to go about this is to use List and ListItem instead of a Table. ListItem can easily use ButtonBase via the button property.

Here's an example:

Edit Material UI - Grid

Ryan Cogswell
  • 75,046
  • 9
  • 218
  • 198
  • I see your point, the structure of the html table is very rigid and and doesn't like having extra elements present outside of the `td` – AKrush95 Jan 07 '19 at 14:39
3

Here is a solution 2023 updated

I was able to use <ButtonBase> and <TableRow> as follows using Material UI ^5.8.1 for getting the desired effect:

gif


import {
  ButtonBase,
  SxProps,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Card,
} from "@mui/material";

import React from 'react'

const dataRowSX: SxProps = {
  display: "table-row",
  ":hover": {
    backgroundColor: "#f5f5f5",
    cursor: "pointer",
  },
};

export function MyTable({ rows }: { rows: any }) {
  return (
    <Card>
      <TableContainer>
        <Table>
          <TableHead>
            <TableRow>
              <TableCell>ID</TableCell>
              <TableCell>FirstName</TableCell>
              <TableCell>LastName</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {rows.map((row) => {
              const { id, firstName, lastName } = row;
              return (
                <ButtonBase key={id} component={TableRow} sx={dataRowSX}>
                  <TableCell>{id}</TableCell>
                  <TableCell>{firstName}</TableCell>
                  <TableCell>{lastName}</TableCell>
                </ButtonBase>
              );
            })}
          </TableBody>
        </Table>
      </TableContainer>
    </Card>
  );
}

display: "table-row" ensures that the display provided by <ButtonBase> is overrided to match the one of <TableRow>.

Ian Sebastian
  • 390
  • 2
  • 8
  • The only issue here is that I get an error for DOM validation because of the `` tag which gets created inside the `` from the `` component – caweidmann Mar 30 '23 at 13:26