Material UI is a Material Design library made for React.
It’s a set of React components that have Material Design styles.
In this article, we’ll look at how to add lists with pinned headings, virtualized lists, and tables with Material UI.
Pinned Subheader List
We can use CSS to make the subheader pinned to the top of the screen until it’s pushed off by the next subheader.
For example, we can write:
import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem";
import ListItemText from "@material-ui/core/ListItemText";
import ListSubheader from "@material-ui/core/ListSubheader";
const useStyles = makeStyles(theme => ({
root: {
width: "100%",
maxWidth: 360,
backgroundColor: theme.palette.background.paper,
position: "relative",
overflow: "auto",
maxHeight: 300
},
listSection: {
backgroundColor: "inherit"
},
ul: {
backgroundColor: "inherit",
padding: 0
}
}));
export default function App() {
const classes = useStyles();
return (
<List className={classes.root} subheader={<li />}>
{Array(10)
.fill()
.map((s, sectionId) => (
<li key={`section-${sectionId}`} className={classes.listSection}>
<ul className={classes.ul}>
<ListSubheader>{`I'm sticky ${sectionId}`}</ListSubheader>
{[0, 1, 2].map(item => (
<ListItem key={`item-${sectionId}-${item}`}>
<ListItemText primary={`Item ${item}`} />
</ListItem>
))}
</ul>
</li>
))}
</List>
);
}
We have the makeStyles
function to set the position of the root to relative
.
Also, we set a maxHeight
so that it will scroll when the content overflows the list.
This way, we set the subheader to stay pinned.
Inset List
We can make list items that have no icon with text that aligns with the ones with icons.
For example, we can write:
import React from "react";
import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem";
import ListItemIcon from "@material-ui/core/ListItemIcon";
import ListItemText from "@material-ui/core/ListItemText";
import StarIcon from "@material-ui/icons/Star";
export default function App() {
return (
<List aria-label="contacts">
<ListItem button>
<ListItemIcon>
<StarIcon />
</ListItemIcon>
<ListItemText primary="james smith" />
</ListItem>
<ListItem button>
<ListItemText inset primary="mary jane" />
</ListItem>
</List>
);
}
We added the inset
prop to make the text in the 2nd list item aligns with the text on the first.
Virtualized List
If we have a list with lots of items, then we’ve to make a virtualized list.
To do that, we can write:
import React from "react";
import ListItem from "@material-ui/core/ListItem";
import ListItemText from "@material-ui/core/ListItemText";
import { FixedSizeList } from "react-window";
function renderRow(props) {
const { index, style } = props;
return (
<ListItem button style={style} key={index}>
<ListItemText primary={`Item ${index + 1}`} />
</ListItem>
);
}
export default function App() {
return (
<FixedSizeList height={300} width={300} itemSize={40} itemCount={300}>
{renderRow}
</FixedSizeList>
);
}
to create a virtualized list with react-window.
We have the renderRow
to render a table row.
And we used the FixedSizedList
instead of a regular List
.
itemCount
sets the item count.
itemSize
has the size of an item.
The height
and width
are the height and width of the list.
Table
Material UI comes with a table component to let us display data in a table.
To create a simple one, we can write the following:
import React from "react";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableContainer from "@material-ui/core/TableContainer";
import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow";
import Paper from "@material-ui/core/Paper";
function createData(firstName, lastName, age) {
return { firstName, lastName, age };
}
const rows = [
createData("james", "smith", 20),
createData("mary", "jones", 30),
createData("may", "wong", 30)
];
export default function App() {
return (
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
<TableCell>first name</TableCell>
<TableCell>last name</TableCell>
<TableCell align="right">age</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map(row => (
<TableRow key={row.name}>
<TableCell component="th" scope="row">
{row.firstName}
</TableCell>
<TableCell>{row.lastName}</TableCell>
<TableCell align="right">{row.age}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
}
We created a table with the TableContainer
, Table
, TableHead
, TableRow
and TableCell
components.
TableContainer
has the container.
Tabke
has the table itself.
TableHead
holds the headings.
TableRow
has the rows.
TableCell
has the cells.
We can set the align
prop of a cell to right
to make the content align to the right.
Also, we can set the component
prop to display as th
if we wish.
The scope
is set to the row to indicate that the cell is for a row and we get different cell formatting than headings.
Conclusion
We can make virtualized lists if our list has lots of items.
List headings can be pinned.
Table components are part of the core Material UI package.