AKrush95
AKrush95

Reputation: 1431

Use ButtonBase for ripple effect on Material UI TableRow

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>

Upvotes: 4

Views: 2419

Answers (2)

Ian Sebastian
Ian Sebastian

Reputation: 444

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>.

Upvotes: 4

Ryan Cogswell
Ryan Cogswell

Reputation: 81066

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

Upvotes: 3

Related Questions