In this tutorial, we will create table in react with material ui (mui 5). We will see mui 5 table, table with filter sorting , table with checkbox example with react material UI 5.
Install & Setup Vite + React + Typescript + MUI 5
React Material UI 5 Table Example
1. Create react mui 5 simple table using react-mui TableContainer, Table, TableHead, TableRow, TableCell component.
import * as React from "react";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import Paper from "@mui/material/Paper";
import { Container } from "@mui/material";
function createData(
name: string,
calories: number,
fat: number,
carbs: number,
protein: number
) {
return { name, calories, fat, carbs, protein };
}
const rows = [
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),
createData("Cupcake", 305, 3.7, 67, 4.3),
createData("Gingerbread", 356, 16.0, 49, 3.9),
];
export default function BasicTable() {
return (
<Container maxWidth="md" sx={{ mt: 8 }}>
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>Dessert (100g serving)</TableCell>
<TableCell align="right">Calories</TableCell>
<TableCell align="right">Fat (g)</TableCell>
<TableCell align="right">Carbs (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => (
<TableRow
key={row.name}
sx={{ "&:last-child td, &:last-child th": { border: 0 } }}
>
<TableCell component="th" scope="row">
{row.name}
</TableCell>
<TableCell align="right">{row.calories}</TableCell>
<TableCell align="right">{row.fat}</TableCell>
<TableCell align="right">{row.carbs}</TableCell>
<TableCell align="right">{row.protein}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</Container>
);
}
To use DataTable in react mui 5 project. you need to install @mui/x-data-grid
Run the command below install @mui/x-data-grid.
// with npm
npm install @mui/x-data-grid
// with yarn
yarn add @mui/x-data-grid
2. react mui 5 table with datatable, filter, sorting, multiple select checkbox.
import * as React from "react";
import { DataGrid, GridColDef, GridValueGetterParams } from "@mui/x-data-grid";
import { Container } from "@mui/material";
const columns: GridColDef[] = [
{ field: "id", headerName: "ID", width: 70 },
{ field: "firstName", headerName: "First name", width: 130 },
{ field: "lastName", headerName: "Last name", width: 130 },
{
field: "age",
headerName: "Age",
type: "number",
width: 90,
},
{
field: "fullName",
headerName: "Full name",
description: "This column has a value getter and is not sortable.",
sortable: false,
width: 160,
valueGetter: (params: GridValueGetterParams) =>
`${params.row.firstName || ""} ${params.row.lastName || ""}`,
},
];
const rows = [
{ id: 1, lastName: "Snow", firstName: "Jon", age: 35 },
{ id: 2, lastName: "Lannister", firstName: "Cersei", age: 42 },
{ id: 3, lastName: "Lannister", firstName: "Jaime", age: 45 },
{ id: 4, lastName: "Stark", firstName: "Arya", age: 16 },
{ id: 5, lastName: "Targaryen", firstName: "Daenerys", age: null },
{ id: 6, lastName: "Melisandre", firstName: null, age: 150 },
{ id: 7, lastName: "Clifford", firstName: "Ferrara", age: 44 },
{ id: 8, lastName: "Frances", firstName: "Rossini", age: 36 },
{ id: 9, lastName: "Roxie", firstName: "Harvey", age: 65 },
];
export default function DataTable() {
return (
<Container maxWidth="md" sx={{ mt: 8 }}>
<div style={{ height: 400, width: "100%" }}>
<DataGrid
rows={rows}
columns={columns}
pageSize={5}
rowsPerPageOptions={[5]}
checkboxSelection
/>
</div>
</Container>
);
}
3. react mui 5 typescript table with sorting multiple select checkbox.
import * as React from "react";
import { alpha } from "@mui/material/styles";
import Box from "@mui/material/Box";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TablePagination from "@mui/material/TablePagination";
import TableRow from "@mui/material/TableRow";
import TableSortLabel from "@mui/material/TableSortLabel";
import Toolbar from "@mui/material/Toolbar";
import Typography from "@mui/material/Typography";
import Paper from "@mui/material/Paper";
import Checkbox from "@mui/material/Checkbox";
import IconButton from "@mui/material/IconButton";
import Tooltip from "@mui/material/Tooltip";
import FormControlLabel from "@mui/material/FormControlLabel";
import Switch from "@mui/material/Switch";
import DeleteIcon from "@mui/icons-material/Delete";
import FilterListIcon from "@mui/icons-material/FilterList";
import { visuallyHidden } from "@mui/utils";
import { Container } from "@mui/material";
interface Data {
calories: number;
carbs: number;
fat: number;
name: string;
protein: number;
}
function createData(
name: string,
calories: number,
fat: number,
carbs: number,
protein: number
): Data {
return {
name,
calories,
fat,
carbs,
protein,
};
}
const rows = [
createData("Cupcake", 305, 3.7, 67, 4.3),
createData("Donut", 452, 25.0, 51, 4.9),
createData("Eclair", 262, 16.0, 24, 6.0),
createData("Frozen yoghurt", 159, 6.0, 24, 4.0),
createData("Gingerbread", 356, 16.0, 49, 3.9),
createData("Honeycomb", 408, 3.2, 87, 6.5),
createData("Ice cream sandwich", 237, 9.0, 37, 4.3),
createData("Jelly Bean", 375, 0.0, 94, 0.0),
createData("KitKat", 518, 26.0, 65, 7.0),
createData("Lollipop", 392, 0.2, 98, 0.0),
createData("Marshmallow", 318, 0, 81, 2.0),
createData("Nougat", 360, 19.0, 9, 37.0),
createData("Oreo", 437, 18.0, 63, 4.0),
];
function descendingComparator<T>(a: T, b: T, orderBy: keyof T) {
if (b[orderBy] < a[orderBy]) {
return -1;
}
if (b[orderBy] > a[orderBy]) {
return 1;
}
return 0;
}
type Order = "asc" | "desc";
function getComparator<Key extends keyof any>(
order: Order,
orderBy: Key
): (
a: { [key in Key]: number | string },
b: { [key in Key]: number | string }
) => number {
return order === "desc"
? (a, b) => descendingComparator(a, b, orderBy)
: (a, b) => -descendingComparator(a, b, orderBy);
}
// Since 2020 all major browsers ensure sort stability with Array.prototype.sort().
// stableSort() brings sort stability to non-modern browsers (notably IE11). If you
// only support modern browsers you can replace stableSort(exampleArray, exampleComparator)
// with exampleArray.slice().sort(exampleComparator)
function stableSort<T>(
array: readonly T[],
comparator: (a: T, b: T) => number
) {
const stabilizedThis = array.map((el, index) => [el, index] as [T, number]);
stabilizedThis.sort((a, b) => {
const order = comparator(a[0], b[0]);
if (order !== 0) {
return order;
}
return a[1] - b[1];
});
return stabilizedThis.map((el) => el[0]);
}
interface HeadCell {
disablePadding: boolean;
id: keyof Data;
label: string;
numeric: boolean;
}
const headCells: readonly HeadCell[] = [
{
id: "name",
numeric: false,
disablePadding: true,
label: "Dessert (100g serving)",
},
{
id: "calories",
numeric: true,
disablePadding: false,
label: "Calories",
},
{
id: "fat",
numeric: true,
disablePadding: false,
label: "Fat (g)",
},
{
id: "carbs",
numeric: true,
disablePadding: false,
label: "Carbs (g)",
},
{
id: "protein",
numeric: true,
disablePadding: false,
label: "Protein (g)",
},
];
const DEFAULT_ORDER = "asc";
const DEFAULT_ORDER_BY = "calories";
const DEFAULT_ROWS_PER_PAGE = 5;
interface EnhancedTableProps {
numSelected: number;
onRequestSort: (
event: React.MouseEvent<unknown>,
newOrderBy: keyof Data
) => void;
onSelectAllClick: (event: React.ChangeEvent<HTMLInputElement>) => void;
order: Order;
orderBy: string;
rowCount: number;
}
function EnhancedTableHead(props: EnhancedTableProps) {
const {
onSelectAllClick,
order,
orderBy,
numSelected,
rowCount,
onRequestSort,
} = props;
const createSortHandler =
(newOrderBy: keyof Data) => (event: React.MouseEvent<unknown>) => {
onRequestSort(event, newOrderBy);
};
return (
<TableHead>
<TableRow>
<TableCell padding="checkbox">
<Checkbox
color="primary"
indeterminate={numSelected > 0 && numSelected < rowCount}
checked={rowCount > 0 && numSelected === rowCount}
onChange={onSelectAllClick}
inputProps={{
"aria-label": "select all desserts",
}}
/>
</TableCell>
{headCells.map((headCell) => (
<TableCell
key={headCell.id}
align={headCell.numeric ? "right" : "left"}
padding={headCell.disablePadding ? "none" : "normal"}
sortDirection={orderBy === headCell.id ? order : false}
>
<TableSortLabel
active={orderBy === headCell.id}
direction={orderBy === headCell.id ? order : "asc"}
onClick={createSortHandler(headCell.id)}
>
{headCell.label}
{orderBy === headCell.id ? (
<Box component="span" sx={visuallyHidden}>
{order === "desc" ? "sorted descending" : "sorted ascending"}
</Box>
) : null}
</TableSortLabel>
</TableCell>
))}
</TableRow>
</TableHead>
);
}
interface EnhancedTableToolbarProps {
numSelected: number;
}
function EnhancedTableToolbar(props: EnhancedTableToolbarProps) {
const { numSelected } = props;
return (
<Toolbar
sx={{
pl: { sm: 2 },
pr: { xs: 1, sm: 1 },
...(numSelected > 0 && {
bgcolor: (theme) =>
alpha(
theme.palette.primary.main,
theme.palette.action.activatedOpacity
),
}),
}}
>
{numSelected > 0 ? (
<Typography
sx={{ flex: "1 1 100%" }}
color="inherit"
variant="subtitle1"
component="div"
>
{numSelected} selected
</Typography>
) : (
<Typography
sx={{ flex: "1 1 100%" }}
variant="h6"
id="tableTitle"
component="div"
>
Nutrition
</Typography>
)}
{numSelected > 0 ? (
<Tooltip title="Delete">
<IconButton>
<DeleteIcon />
</IconButton>
</Tooltip>
) : (
<Tooltip title="Filter list">
<IconButton>
<FilterListIcon />
</IconButton>
</Tooltip>
)}
</Toolbar>
);
}
export default function EnhancedTable() {
const [order, setOrder] = React.useState<Order>(DEFAULT_ORDER);
const [orderBy, setOrderBy] = React.useState<keyof Data>(DEFAULT_ORDER_BY);
const [selected, setSelected] = React.useState<readonly string[]>([]);
const [page, setPage] = React.useState(0);
const [dense, setDense] = React.useState(false);
const [visibleRows, setVisibleRows] = React.useState<Data[] | null>(null);
const [rowsPerPage, setRowsPerPage] = React.useState(DEFAULT_ROWS_PER_PAGE);
const [paddingHeight, setPaddingHeight] = React.useState(0);
React.useEffect(() => {
let rowsOnMount = stableSort(
rows,
getComparator(DEFAULT_ORDER, DEFAULT_ORDER_BY)
);
rowsOnMount = rowsOnMount.slice(
0 * DEFAULT_ROWS_PER_PAGE,
0 * DEFAULT_ROWS_PER_PAGE + DEFAULT_ROWS_PER_PAGE
);
setVisibleRows(rowsOnMount);
}, []);
const handleRequestSort = React.useCallback(
(event: React.MouseEvent<unknown>, newOrderBy: keyof Data) => {
const isAsc = orderBy === newOrderBy && order === "asc";
const toggledOrder = isAsc ? "desc" : "asc";
setOrder(toggledOrder);
setOrderBy(newOrderBy);
const sortedRows = stableSort(
rows,
getComparator(toggledOrder, newOrderBy)
);
const updatedRows = sortedRows.slice(
page * rowsPerPage,
page * rowsPerPage + rowsPerPage
);
setVisibleRows(updatedRows);
},
[order, orderBy, page, rowsPerPage]
);
const handleSelectAllClick = (event: React.ChangeEvent<HTMLInputElement>) => {
if (event.target.checked) {
const newSelected = rows.map((n) => n.name);
setSelected(newSelected);
return;
}
setSelected([]);
};
const handleClick = (event: React.MouseEvent<unknown>, name: string) => {
const selectedIndex = selected.indexOf(name);
let newSelected: readonly string[] = [];
if (selectedIndex === -1) {
newSelected = newSelected.concat(selected, name);
} 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 handleChangePage = React.useCallback(
(event: unknown, newPage: number) => {
setPage(newPage);
const sortedRows = stableSort(rows, getComparator(order, orderBy));
const updatedRows = sortedRows.slice(
newPage * rowsPerPage,
newPage * rowsPerPage + rowsPerPage
);
setVisibleRows(updatedRows);
// Avoid a layout jump when reaching the last page with empty rows.
const numEmptyRows =
newPage > 0
? Math.max(0, (1 + newPage) * rowsPerPage - rows.length)
: 0;
const newPaddingHeight = (dense ? 33 : 53) * numEmptyRows;
setPaddingHeight(newPaddingHeight);
},
[order, orderBy, dense, rowsPerPage]
);
const handleChangeRowsPerPage = React.useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
const updatedRowsPerPage = parseInt(event.target.value, 10);
setRowsPerPage(updatedRowsPerPage);
setPage(0);
const sortedRows = stableSort(rows, getComparator(order, orderBy));
const updatedRows = sortedRows.slice(
0 * updatedRowsPerPage,
0 * updatedRowsPerPage + updatedRowsPerPage
);
setVisibleRows(updatedRows);
// There is no layout jump to handle on the first page.
setPaddingHeight(0);
},
[order, orderBy]
);
const handleChangeDense = (event: React.ChangeEvent<HTMLInputElement>) => {
setDense(event.target.checked);
};
const isSelected = (name: string) => selected.indexOf(name) !== -1;
return (
<Container maxWidth="md" sx={{ mt: 8 }}>
<Box sx={{ width: "100%" }}>
<Paper sx={{ width: "100%", mb: 2 }}>
<EnhancedTableToolbar numSelected={selected.length} />
<TableContainer>
<Table
sx={{ minWidth: 750 }}
aria-labelledby="tableTitle"
size={dense ? "small" : "medium"}
>
<EnhancedTableHead
numSelected={selected.length}
order={order}
orderBy={orderBy}
onSelectAllClick={handleSelectAllClick}
onRequestSort={handleRequestSort}
rowCount={rows.length}
/>
<TableBody>
{visibleRows
? visibleRows.map((row, index) => {
const isItemSelected = isSelected(row.name);
const labelId = `enhanced-table-checkbox-${index}`;
return (
<TableRow
hover
onClick={(event) => handleClick(event, row.name)}
role="checkbox"
aria-checked={isItemSelected}
tabIndex={-1}
key={row.name}
selected={isItemSelected}
sx={{ cursor: "pointer" }}
>
<TableCell padding="checkbox">
<Checkbox
color="primary"
checked={isItemSelected}
inputProps={{
"aria-labelledby": labelId,
}}
/>
</TableCell>
<TableCell
component="th"
id={labelId}
scope="row"
padding="none"
>
{row.name}
</TableCell>
<TableCell align="right">{row.calories}</TableCell>
<TableCell align="right">{row.fat}</TableCell>
<TableCell align="right">{row.carbs}</TableCell>
<TableCell align="right">{row.protein}</TableCell>
</TableRow>
);
})
: null}
{paddingHeight > 0 && (
<TableRow
style={{
height: paddingHeight,
}}
>
<TableCell colSpan={6} />
</TableRow>
)}
</TableBody>
</Table>
</TableContainer>
<TablePagination
rowsPerPageOptions={[5, 10, 25]}
component="div"
count={rows.length}
rowsPerPage={rowsPerPage}
page={page}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
/>
</Paper>
<FormControlLabel
control={<Switch checked={dense} onChange={handleChangeDense} />}
label="Dense padding"
/>
</Box>
</Container>
);
}
4. react mui 5 customize striped rows table.
import * as React from "react";
import { styled } from "@mui/material/styles";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell, { tableCellClasses } from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import Paper from "@mui/material/Paper";
import { Container } from "@mui/material";
const StyledTableCell = styled(TableCell)(({ theme }) => ({
[`&.${tableCellClasses.head}`]: {
backgroundColor: theme.palette.common.black,
color: theme.palette.common.white,
},
[`&.${tableCellClasses.body}`]: {
fontSize: 14,
},
}));
const StyledTableRow = styled(TableRow)(({ theme }) => ({
"&:nth-of-type(odd)": {
backgroundColor: theme.palette.action.hover,
},
// hide last border
"&:last-child td, &:last-child th": {
border: 0,
},
}));
function createData(
name: string,
calories: number,
fat: number,
carbs: number,
protein: number
) {
return { name, calories, fat, carbs, protein };
}
const rows = [
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),
createData("Cupcake", 305, 3.7, 67, 4.3),
createData("Gingerbread", 356, 16.0, 49, 3.9),
];
export default function CustomizedTables() {
return (
<Container maxWidth="md" sx={{ mt: 8 }}>
<TableContainer component={Paper}>
<Table sx={{ minWidth: 700 }} aria-label="customized table">
<TableHead>
<TableRow>
<StyledTableCell>Dessert (100g serving)</StyledTableCell>
<StyledTableCell align="right">Calories</StyledTableCell>
<StyledTableCell align="right">Fat (g)</StyledTableCell>
<StyledTableCell align="right">Carbs (g)</StyledTableCell>
<StyledTableCell align="right">Protein (g)</StyledTableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => (
<StyledTableRow key={row.name}>
<StyledTableCell component="th" scope="row">
{row.name}
</StyledTableCell>
<StyledTableCell align="right">{row.calories}</StyledTableCell>
<StyledTableCell align="right">{row.fat}</StyledTableCell>
<StyledTableCell align="right">{row.carbs}</StyledTableCell>
<StyledTableCell align="right">{row.protein}</StyledTableCell>
</StyledTableRow>
))}
</TableBody>
</Table>
</TableContainer>
</Container>
);
}
5. react mui 5 table with custom pagination options.
* as React from "react";
import { useTheme } from "@mui/material/styles";
import Box from "@mui/material/Box";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableFooter from "@mui/material/TableFooter";
import TablePagination from "@mui/material/TablePagination";
import TableRow from "@mui/material/TableRow";
import Paper from "@mui/material/Paper";
import IconButton from "@mui/material/IconButton";
import FirstPageIcon from "@mui/icons-material/FirstPage";
import KeyboardArrowLeft from "@mui/icons-material/KeyboardArrowLeft";
import KeyboardArrowRight from "@mui/icons-material/KeyboardArrowRight";
import LastPageIcon from "@mui/icons-material/LastPage";
interface TablePaginationActionsProps {
count: number;
page: number;
rowsPerPage: number;
onPageChange: (
event: React.MouseEvent<HTMLButtonElement>,
newPage: number
) => void;
}
function TablePaginationActions(props: TablePaginationActionsProps) {
const theme = useTheme();
const { count, page, rowsPerPage, onPageChange } = props;
const handleFirstPageButtonClick = (
event: React.MouseEvent<HTMLButtonElement>
) => {
onPageChange(event, 0);
};
const handleBackButtonClick = (
event: React.MouseEvent<HTMLButtonElement>
) => {
onPageChange(event, page - 1);
};
const handleNextButtonClick = (
event: React.MouseEvent<HTMLButtonElement>
) => {
onPageChange(event, page + 1);
};
const handleLastPageButtonClick = (
event: React.MouseEvent<HTMLButtonElement>
) => {
onPageChange(event, Math.max(0, Math.ceil(count / rowsPerPage) - 1));
};
return (
<Box sx={{ flexShrink: 0, ml: 2.5 }}>
<IconButton
onClick={handleFirstPageButtonClick}
disabled={page === 0}
aria-label="first page"
>
{theme.direction === "rtl" ? <LastPageIcon /> : <FirstPageIcon />}
</IconButton>
<IconButton
onClick={handleBackButtonClick}
disabled={page === 0}
aria-label="previous page"
>
{theme.direction === "rtl" ? (
<KeyboardArrowRight />
) : (
<KeyboardArrowLeft />
)}
</IconButton>
<IconButton
onClick={handleNextButtonClick}
disabled={page >= Math.ceil(count / rowsPerPage) - 1}
aria-label="next page"
>
{theme.direction === "rtl" ? (
<KeyboardArrowLeft />
) : (
<KeyboardArrowRight />
)}
</IconButton>
<IconButton
onClick={handleLastPageButtonClick}
disabled={page >= Math.ceil(count / rowsPerPage) - 1}
aria-label="last page"
>
{theme.direction === "rtl" ? <FirstPageIcon /> : <LastPageIcon />}
</IconButton>
</Box>
);
}
function createData(name: string, calories: number, fat: number) {
return { name, calories, fat };
}
const rows = [
createData("Cupcake", 305, 3.7),
createData("Donut", 452, 25.0),
createData("Eclair", 262, 16.0),
createData("Frozen yoghurt", 159, 6.0),
createData("Gingerbread", 356, 16.0),
createData("Honeycomb", 408, 3.2),
createData("Ice cream sandwich", 237, 9.0),
createData("Jelly Bean", 375, 0.0),
createData("KitKat", 518, 26.0),
createData("Lollipop", 392, 0.2),
createData("Marshmallow", 318, 0),
createData("Nougat", 360, 19.0),
createData("Oreo", 437, 18.0),
].sort((a, b) => (a.calories < b.calories ? -1 : 1));
export default function CustomPaginationActionsTable() {
const [page, setPage] = React.useState(0);
const [rowsPerPage, setRowsPerPage] = React.useState(5);
// Avoid a layout jump when reaching the last page with empty rows.
const emptyRows =
page > 0 ? Math.max(0, (1 + page) * rowsPerPage - rows.length) : 0;
const handleChangePage = (
event: React.MouseEvent<HTMLButtonElement> | null,
newPage: number
) => {
setPage(newPage);
};
const handleChangeRowsPerPage = (
event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
) => {
setRowsPerPage(parseInt(event.target.value, 10));
setPage(0);
};
return (
<TableContainer component={Paper}>
<Table sx={{ minWidth: 500 }} aria-label="custom pagination table">
<TableBody>
{(rowsPerPage > 0
? rows.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
: rows
).map((row) => (
<TableRow key={row.name}>
<TableCell component="th" scope="row">
{row.name}
</TableCell>
<TableCell style={{ width: 160 }} align="right">
{row.calories}
</TableCell>
<TableCell style={{ width: 160 }} align="right">
{row.fat}
</TableCell>
</TableRow>
))}
{emptyRows > 0 && (
<TableRow style={{ height: 53 * emptyRows }}>
<TableCell colSpan={6} />
</TableRow>
)}
</TableBody>
<TableFooter>
<TableRow>
<TablePagination
rowsPerPageOptions={[5, 10, 25, { label: "All", value: -1 }]}
colSpan={3}
count={rows.length}
rowsPerPage={rowsPerPage}
page={page}
SelectProps={{
inputProps: {
"aria-label": "rows per page",
},
native: true,
}}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
ActionsComponent={TablePaginationActions}
/>
</TableRow>
</TableFooter>
</Table>
</TableContainer>
);
}
6. react mui 5 table with Sticky header.
import * as React from "react";
import Paper from "@mui/material/Paper";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TablePagination from "@mui/material/TablePagination";
import TableRow from "@mui/material/TableRow";
import { Container } from "@mui/material";
interface Column {
id: "name" | "code" | "population" | "size" | "density";
label: string;
minWidth?: number;
align?: "right";
format?: (value: number) => string;
}
const columns: readonly Column[] = [
{ id: "name", label: "Name", minWidth: 170 },
{ id: "code", label: "ISO\u00a0Code", minWidth: 100 },
{
id: "population",
label: "Population",
minWidth: 170,
align: "right",
format: (value: number) => value.toLocaleString("en-US"),
},
{
id: "size",
label: "Size\u00a0(km\u00b2)",
minWidth: 170,
align: "right",
format: (value: number) => value.toLocaleString("en-US"),
},
{
id: "density",
label: "Density",
minWidth: 170,
align: "right",
format: (value: number) => value.toFixed(2),
},
];
interface Data {
name: string;
code: string;
population: number;
size: number;
density: number;
}
function createData(
name: string,
code: string,
population: number,
size: number
): Data {
const density = population / size;
return { name, code, population, size, density };
}
const rows = [
createData("India", "IN", 1324171354, 3287263),
createData("China", "CN", 1403500365, 9596961),
createData("Italy", "IT", 60483973, 301340),
createData("United States", "US", 327167434, 9833520),
createData("Canada", "CA", 37602103, 9984670),
createData("Australia", "AU", 25475400, 7692024),
createData("Germany", "DE", 83019200, 357578),
createData("Ireland", "IE", 4857000, 70273),
createData("Mexico", "MX", 126577691, 1972550),
createData("Japan", "JP", 126317000, 377973),
createData("France", "FR", 67022000, 640679),
createData("United Kingdom", "GB", 67545757, 242495),
createData("Russia", "RU", 146793744, 17098246),
createData("Nigeria", "NG", 200962417, 923768),
createData("Brazil", "BR", 210147125, 8515767),
];
export default function StickyHeadTable() {
const [page, setPage] = React.useState(0);
const [rowsPerPage, setRowsPerPage] = React.useState(10);
const handleChangePage = (event: unknown, newPage: number) => {
setPage(newPage);
};
const handleChangeRowsPerPage = (
event: React.ChangeEvent<HTMLInputElement>
) => {
setRowsPerPage(+event.target.value);
setPage(0);
};
return (
<Container maxWidth="md" sx={{ mt: 8 }}>
<Paper sx={{ width: "100%", overflow: "hidden" }}>
<TableContainer sx={{ maxHeight: 440 }}>
<Table stickyHeader aria-label="sticky table">
<TableHead>
<TableRow>
{columns.map((column) => (
<TableCell
key={column.id}
align={column.align}
style={{ minWidth: column.minWidth }}
>
{column.label}
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{rows
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
.map((row) => {
return (
<TableRow
hover
role="checkbox"
tabIndex={-1}
key={row.code}
>
{columns.map((column) => {
const value = row[column.id];
return (
<TableCell key={column.id} align={column.align}>
{column.format && typeof value === "number"
? column.format(value)
: value}
</TableCell>
);
})}
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
<TablePagination
rowsPerPageOptions={[10, 25, 100]}
component="div"
count={rows.length}
rowsPerPage={rowsPerPage}
page={page}
onPageChange={handleChangePage}
onRowsPerPageChange={handleChangeRowsPerPage}
/>
</Paper>
</Container>
);
}
7. react mui 5 collapsible table.
import * as React from "react";
import Collapse from "@mui/material/Collapse";
import IconButton from "@mui/material/IconButton";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import Typography from "@mui/material/Typography";
import Paper from "@mui/material/Paper";
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp";
import { Box, Container } from "@mui/material";
function createData(
name: string,
calories: number,
fat: number,
carbs: number,
protein: number,
price: number
) {
return {
name,
calories,
fat,
carbs,
protein,
price,
history: [
{
date: "2020-01-05",
customerId: "11091700",
amount: 3,
},
{
date: "2020-01-02",
customerId: "Anonymous",
amount: 1,
},
],
};
}
function Row(props: { row: ReturnType<typeof createData> }) {
const { row } = props;
const [open, setOpen] = React.useState(false);
return (
<React.Fragment>
<TableRow sx={{ "& > *": { borderBottom: "unset" } }}>
<TableCell>
<IconButton
aria-label="expand row"
size="small"
onClick={() => setOpen(!open)}
>
{open ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
</IconButton>
</TableCell>
<TableCell component="th" scope="row">
{row.name}
</TableCell>
<TableCell align="right">{row.calories}</TableCell>
<TableCell align="right">{row.fat}</TableCell>
<TableCell align="right">{row.carbs}</TableCell>
<TableCell align="right">{row.protein}</TableCell>
</TableRow>
<TableRow>
<TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={6}>
<Collapse in={open} timeout="auto" unmountOnExit>
<Box sx={{ margin: 1 }}>
<Typography variant="h6" gutterBottom component="div">
History
</Typography>
<Table size="small" aria-label="purchases">
<TableHead>
<TableRow>
<TableCell>Date</TableCell>
<TableCell>Customer</TableCell>
<TableCell align="right">Amount</TableCell>
<TableCell align="right">Total price ($)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{row.history.map((historyRow) => (
<TableRow key={historyRow.date}>
<TableCell component="th" scope="row">
{historyRow.date}
</TableCell>
<TableCell>{historyRow.customerId}</TableCell>
<TableCell align="right">{historyRow.amount}</TableCell>
<TableCell align="right">
{Math.round(historyRow.amount * row.price * 100) / 100}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Box>
</Collapse>
</TableCell>
</TableRow>
</React.Fragment>
);
}
const rows = [
createData("Frozen yoghurt", 159, 6.0, 24, 4.0, 3.99),
createData("Ice cream sandwich", 237, 9.0, 37, 4.3, 4.99),
createData("Eclair", 262, 16.0, 24, 6.0, 3.79),
createData("Cupcake", 305, 3.7, 67, 4.3, 2.5),
createData("Gingerbread", 356, 16.0, 49, 3.9, 1.5),
];
export default function CollapsibleTable() {
return (
<Container maxWidth="md" sx={{ mt: 8 }}>
<TableContainer component={Paper}>
<Table aria-label="collapsible table">
<TableHead>
<TableRow>
<TableCell />
<TableCell>Dessert (100g serving)</TableCell>
<TableCell align="right">Calories</TableCell>
<TableCell align="right">Fat (g)</TableCell>
<TableCell align="right">Carbs (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => (
<Row key={row.name} row={row} />
))}
</TableBody>
</Table>
</TableContainer>
</Container>
);
}
Related Posts
create a chat ui in react with mui 5
create a blog section in react mui 5
create a footer in react mui 5
create a responsive navbar in react with mui 5
react mui 5 search bar example
react mui 5 login page example
react mui 5 image list example
react mui 5 toggle switch example
react mui 5 registration form example
react mui 5 contact us page example
react mui 5 loading skeleton example
react mui 5 gradient button example
react mui 5 social media icons example
react mui 5 snackbar toast notification example
how to use autocomplete react mui 5
dynamically multiple input fields in react mui 5
how to use dropdown menu in react mui 5
how to use background image in react mui 5
how to use pricing table in react mui 5
how to use dark mode in react mui 5
how to use file upload in react mui 5
how to use sticky navbar in react mui 5
how to use box shadow in react mui 5
how to use multi step form in react mui 5
how to use loading button in react mui 5