Sometimes, we want to make React Material UI table row and columns sticky.
In this article, we’ll look at how to make React Material UI table row and columns sticky.
How to make React Material UI table row and columns sticky?
To make React Material UI table row and columns sticky, we can add our own styles to the existing table cell components and return the new component with the styles.
For instance, we write:
import React from "react";
import {
makeStyles,
TableContainer,
TableBody,
TableCell,
TableHead,
TableRow,
Table,
withStyles
} from "@material-ui/core";
const useStyles = makeStyles((theme) => ({
root: {
width: "100%",
marginTop: theme.spacing(3)
},
head: {
backgroundColor: "#fff",
minWidth: "50px"
},
tableContainer: {
maxHeight: "400px"
},
cell: {
minWidth: "100px"
}
}));
const StickyTableCell = withStyles((theme) => ({
head: {
backgroundColor: theme.palette.common.black,
color: theme.palette.common.white,
left: 0,
position: "sticky",
zIndex: theme.zIndex.appBar + 2
},
body: {
backgroundColor: "#ddd",
minWidth: "50px",
left: 0,
position: "sticky",
zIndex: theme.zIndex.appBar + 1
}
}))(TableCell);
const StyledTableCell = withStyles((theme) => ({
head: {
backgroundColor: theme.palette.common.black,
color: theme.palette.common.white
},
body: {
fontSize: 14
}
}))(TableCell);
const StyledTableRow = withStyles((theme) => ({
root: {
"&:nth-of-type(odd)": {
backgroundColor: theme.palette.action.hover
}
}
}))(TableRow);
let id = 0;
const createData = (name, calories, fat, carbs, protein) => {
id += 1;
return { id, name, calories, fat, carbs, protein };
};
const data = [
createData("Frozen yoghurt", 159, 6.0, 24, 4.0),
createData("Ice cream sandwich", 237, 9.0, 37, 4.3),
createData("Eclair", 262, 16.0, 24, 6.0)
];
export default function App() {
const classes = useStyles();
return (
<div>
<TableContainer className={classes.tableContainer}>
<Table stickyHeader>
<TableHead>
<TableRow>
<StickyTableCell className={classes.head}>
<StyledTableCell className={classes.head} numeric>
Dessert (100g serving)
</StyledTableCell>
<StyledTableCell className={classes.head} numeric>
Calories
</StyledTableCell>
</StickyTableCell>
<StyledTableCell className={classes.head} numeric>
Calories
</StyledTableCell>
<StyledTableCell className={classes.head} numeric>
Fat (g)
</StyledTableCell>
<StyledTableCell className={classes.head} numeric>
Carbs (g)
</StyledTableCell>
<StyledTableCell className={classes.head} numeric>
Protein (g)
</StyledTableCell>
<StyledTableCell className={classes.head} numeric>
Protein (g)
</StyledTableCell>
<StyledTableCell className={classes.head} numeric>
Protein (g)
</StyledTableCell>
<StyledTableCell className={classes.head} numeric>
Protein (g)
</StyledTableCell>
<StyledTableCell className={classes.head} numeric>
Protein (g)
</StyledTableCell>
<StyledTableCell className={classes.head} numeric>
Protein (g)
</StyledTableCell>
<StyledTableCell className={classes.head} numeric>
Protein (g)
</StyledTableCell>
<StyledTableCell className={classes.head} numeric>
Protein (g)
</StyledTableCell>
</TableRow>
</TableHead>
<TableBody>
{data.map((n) => {
return (
<StyledTableRow key={n.id}>
<StickyTableCell>
<StyledTableCell
numeric
align="right"
className={classes.cell}
>
{n.name}
</StyledTableCell>
<StyledTableCell
numeric
align="right"
className={classes.cell}
>
{n.calories}
</StyledTableCell>
</StickyTableCell>
<StyledTableCell
numeric
align="center"
className={classes.cell}
>
{n.fat}
</StyledTableCell>
<StyledTableCell
numeric
align="center"
className={classes.cell}
>
{n.carbs}
</StyledTableCell>
<StyledTableCell
numeric
align="center"
className={classes.cell}
>
{n.protein}
</StyledTableCell>
<StyledTableCell
numeric
align="center"
className={classes.cell}
>
{n.calories}
</StyledTableCell>
<StyledTableCell
numeric
align="center"
className={classes.cell}
>
{n.fat}
</StyledTableCell>
<StyledTableCell
numeric
align="center"
className={classes.cell}
>
{n.carbs}
</StyledTableCell>
<StyledTableCell
numeric
align="center"
className={classes.cell}
>
{n.protein}
</StyledTableCell>
<StyledTableCell
numeric
align="center"
className={classes.cell}
>
{n.calories}
</StyledTableCell>
<StyledTableCell
numeric
align="center"
className={classes.cell}
>
{n.fat}
</StyledTableCell>
<StyledTableCell
numeric
align="center"
className={classes.cell}
>
{n.carbs}
</StyledTableCell>
<StyledTableCell
numeric
align="center"
className={classes.cell}
>
{n.protein}
</StyledTableCell>
</StyledTableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
</div>
);
}
We call makeStyles
with a function that returns some styles for various parts of the table.
Next, we call withStyles
with a function with the styles for the cells.
We set the position
CSS property to 'sticky'
to make the component that we apply the styles to sticky.
Then we call the returned higher order component with TableCell
and assign the returned component to StickyTableCell
.
Similarly, we call withStyles
with TableCell
again and TableRow
to return styled table cells and table row components.
Next, in App
, we call the useStyles
hook to return the classes
object.
And we apply the styles that we added with makeStyles
to various components.
We add the stickyHeader
to Table
to make the table header row sticky.
And then we use the StickyTableCell
we created earlier to add sticky columns.
As a result, we see that the header row of the table and the leftmost 2 columns of the table being sticky.
Conclusion
To make React Material UI table row and columns sticky, we can add our own styles to the existing table cell components and return the new component with the styles.