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.
Radio Groups In Material UI V5
Introduction Hello everyone! Material UI has long been one of my favorite UI libraries, and with the recent release of version 5, I thought it would be a great time to explore one of its fundamental components: Radio Groups. In this article, we’ll dive into what Radio Groups are, how they can be used in […]
Slider Component In Material UI V5
Introduction Hey, everyone! If you’ve been following Material UI, you’re probably aware of how frequently this UI kit is updated. Recently, they released the version V5, which came with lots of new features and updates. One of the components that received great attention is the slider component. In this article, we’ll discuss everything you need […]
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 […]
Icons In Material UI V5
Introduction: Material UI is a popular open-source framework for building web applications. Built on top of React, it provides a set of pre-built and customizable components, including typography, forms, and icons. In Material UI, icons play a crucial role in designing visually appealing interfaces and enabling smooth user experience. With the recent release of Material […]
Switch Component In Material UI V5
Hey there, fellow developers! Are you excited about exploring the latest version of Material UI and all the new features it brings? If so, you’ve landed in the right place because today we’re going to dive deep into the Switch Component in Material UI v5. Introduction Before we get into the nitty-gritty of the Switch […]