Introduction
As a web developer, I often find myself struggling to create functional and visually appealing tables for my web applications. When I discovered Material UI V5, I was intrigued by the promise of a streamlined and customizable table component. In this article, I’ll delve into the world of Material UI V5 Tables and share my insights, tips, and tricks for getting the most out of this powerful tool.
Let’s start with the basics. To get started with Material UI V5 Tables, you’ll need to install and set up the Material UI library. This can be done using npm, yarn, or a direct download. Once you have Material UI set up, you’re ready to create your first table.
import { Table, TableBody, TableCell, TableContainer,
TableHead, TableRow, Paper } from '@mui/material';
function BasicTable() {
return (
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
<TableCell>First Name</TableCell>
<TableCell>Last Name</TableCell>
<TableCell>Email</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>John</TableCell>
<TableCell>Doe</TableCell>
<TableCell>[email protected]</TableCell>
</TableRow>
<TableRow>
<TableCell>Jane</TableCell>
<TableCell>Doe</TableCell>
<TableCell>[email protected]</TableCell>
</TableRow>
</TableBody>
</Table>
</TableContainer>
);
}
Here we have a basic table component with two rows of data, each containing a first name, last name and email address. The TableContainer component is used to provide the paper background for the table, while the TableHead and TableBody components provide the structure for the headers and data respectively. The TableCell component is used to display individual cells within the table, while the TableRow component is used for grouping cells into rows.
Of course, this is just a starting point. Material UI V5 Tables are highly customizable, and there are a number of ways to style and enhance the default table. Let’s explore some of these options in more detail.
Customizing Material UI V5 Tables
Styling the Table
One of the great advantages of using Material UI V5 Tables is the ease with which you can style them to fit seamlessly into your application’s design. Here’s an example of how to add some custom styling to our previous table:
import { makeStyles } from '@mui/styles';
const useStyles = makeStyles({
table: {
minWidth: 650,
'& th': {
fontWeight: 'bold',
backgroundColor: '#f2f2f2',
color: '#090909'
},
'& tbody tr:nth-of-type(even)': {
backgroundColor: '#f2f2f2'
}
},
});
function StyledTable() {
const classes = useStyles();
return (
<TableContainer component={Paper}>
<Table className={classes.table}>
<TableHead>
<TableRow>
<TableCell>First Name</TableCell>
<TableCell>Last Name</TableCell>
<TableCell>Email</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>John</TableCell>
<TableCell>Doe</TableCell>
<TableCell>[email protected]</TableCell>
</TableRow>
<TableRow>
<TableCell>Jane</TableCell>
<TableCell>Doe</TableCell>
<TableCell>[email protected]</TableCell>
</TableRow>
</TableBody>
</Table>
</TableContainer>
);
}
Notice the makeStyles hook and the associated table style object. We then add the class classes.table
to the Table component to apply our custom styling. In this example, we’ve set a minimum width for the table, added a background color to the header row, and alternating background colors to rows to improve readability.
Adding Pagination
Another useful feature of Material UI V5 Tables is the built-in ability to paginate data. Here’s how to add pagination to our previous example:
import { useState } from 'react';
import { TablePagination } from '@mui/material';
function PaginatedTable() {
const [page, setPage] = useState(0);
const [rowsPerPage, setRowsPerPage] = useState(5);
const handleChangePage = (event, newPage) => {
setPage(newPage);
};
const handleChangeRowsPerPage = (event) => {
setRowsPerPage(parseInt(event.target.value, 10));
setPage(0);
};
return (
<div>
<TableContainer component={Paper}>
<Table className={classes.table}>
<TableHead>
<TableRow>
<TableCell>First Name</TableCell>
<TableCell>Last Name</TableCell>
<TableCell>Email</TableCell>
</TableRow>
</TableHead>
<TableBody>
{data.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map((row) => (
<TableRow key={row.id}>
<TableCell>{row.firstName}</TableCell>
<TableCell>{row.lastName}</TableCell>
<TableCell>{row.email}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
<TablePagination
rowsPerPageOptions={[5, 10, 25]}
component="div"
count={data.length}
rowsPerPage={rowsPerPage}
page={page}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
/>
</div>
);
}
Here we’ve added a TablePagination component below the table to control the number of rows displayed per page and handle pagination. Notice the useState hook used to keep track of the current page and number of rows per page. The handleChangePage
and handleChangeRowsPerPage
functions are called when the user interacts with the pagination controls. We’ve also changed the TableBody component to display a slice of data based on the current page and number of rows per page.
Filtering and Sorting the Table
Filtering and sorting data is another powerful feature provided by Material UI V5 Tables. Here’s an example of how to add filtering and sorting to our previous example:
import { useState } from 'react';
import { TableHead, TableRow, TableSortLabel } from '@mui/material';
const createData = (id, firstName, lastName, email) => {
return { id, firstName, lastName, email };
};
const rows = [
createData(1, 'John', 'Doe', '[email protected]'),
createData(2, 'Jane', 'Doe', '[email protected]'),
createData(3, 'Bruce', 'Wayne', '[email protected]'),
createData(4, 'Tony', 'Stark', '[email protected]'),
createData(5, 'Diana', 'Prince', '[email protected]'),
createData(6, 'Clark', 'Kent', '[email protected]')
];
function EnhancedTable() {
const [order, setOrder] = useState('asc');
const [orderBy, setOrderBy] = useState('firstName');
const handleRequestSort = (event, property) => {
const isAsc = orderBy === property && order === 'asc';
setOrder(isAsc ? 'desc' : 'asc');
setOrderBy(property);
};
return (
<TableContainer component={Paper}>
<Table className={classes.table}>
<TableHead>
<TableRow>
<TableCell>
<TableSortLabel
active={orderBy === 'firstName'}
direction={orderBy === 'firstName' ? order : 'asc'}
onClick={(event) => handleRequestSort(event, 'firstName')}
>
First Name
</TableSortLabel>
</TableCell>
<TableCell>
<TableSortLabel
active={orderBy === 'lastName'}
direction={orderBy === 'lastName' ? order : 'asc'}
onClick={(event) => handleRequestSort(event, 'lastName')}
>
Last Name
</TableSortLabel>
</TableCell>
<TableCell>
<TableSortLabel
active={orderBy === 'email'}
direction={orderBy === 'email' ? order : 'asc'}
onClick={(event) => handleRequestSort(event, 'email')}
>
Email
</TableSortLabel>
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{stableSort(rows, getComparator(order, orderBy)).map((row) => (
<TableRow key={row.id}>
<TableCell>{row.firstName}</TableCell>
<TableCell>{row.lastName}</TableCell>
<TableCell>{row.email}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
}
We’ve added a createData
function to create our data rows, and a stableSort
function to sort the data. The handleRequestSort
function is called when a user clicks on a TableSortLabel component to sort the data by the clicked column. Notice how we use the useState hooks to maintain the current sort order and sorted column.
Advanced Functionality of Material UI V5 Tables
Handling Click Events
Material UI V5 Tables provide a way to handle click events for rows, cells and headers. Here’s an example of how to handle a click event for a row:
import { TableRow } from '@mui/material';
function ClickableRowTable() {
const handleClick = (event, id) => {
console.log(`Row with id ${id} clicked!`);
};
return (
<TableContainer component={Paper}>
<Table className={classes.table}>
<TableHead>
<TableRow>
<TableCell>First Name</TableCell>
<TableCell>Last Name</TableCell>
<TableCell>Email</TableCell>
</TableRow>
</TableHead>
<TableBody>
{data.map((row) => (
<TableRow key={row.id} hover onClick={(event) => handleClick(event, row.id)}>
<TableCell>{row.firstName}</TableCell>
<TableCell>{row.lastName}</TableCell>
<TableCell>{row.email}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
}
Here we’ve added a handleClick
function that logs a message containing the id of the clicked row. We’ve also added the hover
prop to the TableRow component to highlight the row on hover.
Implementing Row Selection
You can also implement row selection within Material UI V5 Tables, using the TableBodyProps and TableRowProps components. Here’s an example of how to select rows:
import { Checkbox, TableBodyProps } from '@mui/material';
function SelectableRowsTable() {
const [selected, setSelected] = useState([]);
const handleSelectAllClick = (event) => {
if (event.target.checked) {
const newSelected = data.map((n) => n.id);
setSelected(newSelected);
return;
}
setSelected([]);
};
const handleClick = (event, id) => {
const selectedIndex = selected.indexOf(id);
let newSelected = [];
if (selectedIndex === -1) {
newSelected = newSelected.concat(selected, id);
} else if (selectedIndex === 0) {
newSelected = newSelected.concat(selected.slice(1));
} else if (selectedIndex === selected.length - 1) {
newSelected = newSelected.concat(selected.slice(0, -1));
} else if (selectedIndex > 0) {
newSelected = newSelected.concat(
selected.slice(0, selectedIndex),
selected.slice(selectedIndex + 1),
);
}
setSelected(newSelected);
};
const isSelected = (id) => selected.indexOf(id) !== -1;
return (
<TableContainer component={Paper}>
<Table className={classes.table}>
<TableHead>
<TableRow>
<TableCell padding="checkbox">
<Checkbox
indeterminate={selected.length > 0 && selected.length < data.length}
checked={selected.length === data.length}
onChange={handleSelectAllClick}
inputProps={{ 'aria-label': 'select all desserts' }}
/>
</TableCell>
<TableCell>First Name</TableCell>
<TableCell>Last Name</TableCell>
<TableCell>Email</TableCell>
</TableRow>
</TableHead>
<TableBody component={TableBodyProps}>
{data.map((row) => {
const isItemSelected = isSelected(row.id);
const labelId = `enhanced-table-checkbox-${row.id}`;
return (
<TableRow
hover
onClick={(event) => handleClick(event, row.id)}
role="checkbox"
aria-checked={isItemSelected}
tabIndex={-1}
key={row.id}
selected={isItemSelected}
{...TableRowProps}
>
<TableCell padding="checkbox">
<Checkbox
checked={isItemSelected}
inputProps={{ 'aria-labelledby': labelId }}
/>
</TableCell>
<TableCell>{row.firstName}</TableCell>
<TableCell>{row.lastName}</TableCell>
<TableCell>{row.email}</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
);
}
Here, the selected
state stores an array of ids for the currently selected rows. The handleSelectAllClick
function is called when the user clicks the “Select All” checkbox, which either selects all rows or clears the selection. The handleClick
function is called when the user clicks on a row, and it either selects or deselects the row depending on its current state. The isSelected
function checks whether a particular row is selected or not. Finally, we’ve added the selected
and TableRowProps
props to the TableRow component to visually highlight the selected rows.
Implementing Custom Cell Rendering
Material UI V5 Tables also provide the ability to customize the rendering of table cells, by using the TableCell
component’s component
prop.
function CustomCellTable() {
const data = [
{ id: 1, firstName: 'John', lastName: 'Doe', email: '[email protected]', phone: '123-456-7890' },
{ id: 2, firstName: 'Jane', lastName: 'Doe', email: '[email protected]', phone: '234-567-8901' },
{ id: 3, firstName: 'Clark', lastName: 'Kent', email: '[email protected]', phone: '345-678-9012' },
{ id: 4, firstName: 'Diana', lastName: 'Prince', email: '[email protected]', phone: '456-789-0123' },
{ id: 5, firstName: 'Bruce', lastName: 'Wayne', email: '[email protected]', phone: '567-890-1234' },
{ id: 6, firstName: 'Tony', lastName: 'Stark', email: '[email protected]', phone: '678-901-2345' }
];
const renderCell = (value, rowIndex, columnIndex) => {
if (columnIndex === 4) {
return <a href={`tel:${value}`}>{value}</a>;
}
return value;
};
return (
<TableContainer component={Paper}>
<Table className={classes.table}>
<TableHead>
<TableRow>
<TableCell>First Name</TableCell>
<TableCell>Last Name</TableCell>
<TableCell>Email</TableCell>
<TableCell>Phone</TableCell>
</TableRow>
</TableHead>
<TableBody>
{data.map((row) => (
<TableRow key={row.id}>
<TableCell>{row.firstName}</TableCell>
<TableCell>{row.lastName}</TableCell>
<TableCell>{row.email}</TableCell>
<TableCell>
<TableCell component="th" scope="row">
{renderCell(row.phone, row.id, 4)}
</TableCell>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
}
In this example, we’ve defined a data
array, each object representing a row of data. We’ve also defined a renderCell
function that takes in a cell value, row index, and column index, and returns the appropriate JSX to render the cell. Here, we’re rendering a hyperlink for cell values in the “Phone” column.
Conclusion
Material UI V5 Tables provide a powerful and flexible way to display data in a web application. They offer sophisticated sorting, filtering, and pagination functionality that can be customized to meet specific requirements. Additionally, by leveraging the component-based architecture, developers can build complex and accessible user interfaces quickly and maintain them efficiently. With a solid understanding of the fundamentals, developers can build rich, responsive, and accessible data tables with Material UI V5 Tables.
Use Material UI V5 With Typescript
Introduction Hello everyone! In this article, we are going to talk about Material UI V5 with Typescript. If you are a React developer, you must have heard of Material UI. It is one of the most popular React UI component libraries out there. On the other hand, Typescript is a superset of JavaScript that provides […]
Rating Component In Material UI V5
Hello and welcome to this exciting article about the Rating Component in Material UI V5! As a web developer, I have come to really appreciate the simplicity and flexibility that this UI library provides, especially when it comes to components that add interactivity to user interfaces. In this article, I’m going to walk you through […]
Toggle Buttons In Material UI V5
As a developer, I’ll be the first to admit that sometimes I find myself perplexed by certain UI design choices. As someone who spends a lot of time within the realm of code, I focus more on functionality and less on design. But the more I learn about UI design, the more I realize the […]
Transfer Lists In Material UI V5
Introduction I remember the first time I stumbled upon transfer lists while working on a project. I was perplexed by the concept, but as I delved deeper, I realized the tremendous benefits of using transfer lists in web development. With the release of Material UI v5, the developers have made it even easier to incorporate […]
Datatables With Material V5
Introduction Material UI V5 is a popular, open-source library that provides pre-built UI components, themes, and styles for building user interfaces with React. Data tables are a common component used in web development to display data in a tabular format. In this article, I’ll show you how to use Material UI V5 to create stylish […]
Material UI V5 Theming
Introduction: Popular React UI framework Material UI provides a large selection of pre-built components to easily build responsive user interfaces. The library’s design approach, which is based on Google’s Material Design principles, has helped it become more well-liked among developers. The design framework of Material UI is crucial to the creation of user interfaces since […]