Table Component
Usage
A simple example of a dense table with no frills.
import { TableContainer } from '@tdcerhverv/table';
import { Table } from '@tdcerhverv/table';
import { TableHead } from '@tdcerhverv/table';
import { TableBody } from '@tdcerhverv/table';
import { TableRow } from '@tdcerhverv/table';
import { TableCell } from '@tdcerhverv/table';
import Paper from '@material-ui/core/Paper';
function createData(
name: string,
calories: number,
fat: number,
carbs: number,
protein: number
) {
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),
];
export default function Example() {
return (
<TableContainer component={Paper}>
<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={`table-${row.name}`}>
<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>
);
}
Advanced Example with Sorting and Pagination
This example uses the custom hooks usePagination
, useFilter
, and useSortable
to have the implementation and/or logic centralized. This gives us the advantage to change the default rowsPerPageOptions
without having to go through all components using TablePagination
import { TableContainer } from '@tdcerhverv/table';
import { Table } from '@tdcerhverv/table';
import { TableHead } from '@tdcerhverv/table';
import { TableBody } from '@tdcerhverv/table';
import { TableRow } from '@tdcerhverv/table';
import { TableCell } from '@tdcerhverv/table';
import { TableSortLabel } from '@tdcerhverv/table';
import { TablePagination } from '@tdcerhverv/table';
import { usePagination } from '@tdcerhverv/table';
import { useFilter } from '@tdcerhverv/table';
import { useSortable } from '@tdcerhverv/table';
import TextField from '@material-ui/core/TextField/TextField';
import Paper from '@material-ui/core/Paper';
interface Data {
calories: number;
carbs: number;
fat: number;
name: string;
protein: number;
}
interface HeadCell {
id: keyof Data;
label: string;
}
function createData(name: string, calories: number, fat: number, carbs: number, protein: number): Data {
return { name, calories, fat, carbs, protein };
}
export default AdvancedExample() {
const { page, setPage, rowsPerPage, setRowsPerPage, rowsPerPageOptions } = usePagination();
const handleChange = event => {
setPage(0);
doQuery(event.target.value);
};
const handleChangePage = (event, newPage) => {
setPage(newPage);
};
const handleChangeRowsPerPage = event => {
setRowsPerPage(event.target.value);
setPage(0);
};
const headCells: HeadCell[] = [
{ id: 'name', label: 'Dessert (100g serving)' },
{ id: 'calories', label: 'Calories' },
{ id: 'fat', label: 'Fat (g)' },
{ id: 'carbs', label: 'Carbs (g)' },
{ id: 'protein', label: 'Protein (g)' },
];
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),
];
const { filtered, query, doQuery } = useFilter(rows);
const { data, order, orderBy, doSort } = useSortable(filtered, {
orderBy: 'name',
});
const handleSort = property => event => doSort(property);
return (
<form>
<Paper>
<TextField
id="query"
name="query"
label="Query"
value={query}
onChange={handleChange}
/>
<TableContainer>
<Table>
<TableHead>
<TableRow>
{headCells.map(headCell => (
<TableCell key={`head-${headCell.id}`}>
<TableSortLabel
onClick={handleSort(headCell.id)}
active={orderBy === headCell.id}
direction={orderBy === headCell.id ? order : 'asc'}
>
{headCell.label}
</TableSortLabel>
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{Boolean(data && data.length === 0) && (
<TableRow>
<TableCell colSpan={headCells.length} align="center">
<TableNoResults>We could not find any results. </TableNoResults>
</TableCell>
</TableRow>
)}
{data
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
.map(row => (
<TableRow key={`row-${row.name}`}>
<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>
<TablePagination
rowsPerPageOptions={rowsPerPageOptions}
component="div"
count={data.length}
rowsPerPage={rowsPerPage}
page={page}
onChangePage={handleChangePage}
onChangeRowsPerPage={handleChangeRowsPerPage}
/>
</Paper>
</form>
);
}
Custom pagination options
It's possible to customize the options shown in the "Rows per page" select using the rowsPerPageOptions
prop.
You should either provide an array of:
-
numbers, each number will be used for the option's label and value.
<TablePagination rowsPerPageOptions={[10, 50]} />
-
objects, the
value
andlabel
keys will be used respectively for the value and label of the option (useful for language strings such as 'All').<TablePagination rowsPerPageOptions={[10, 50, { value: -1, label: 'All' }]} />
usePagination
hook
This hook gives us a centralized place where common config for the TablePagination
is configured:
-
rowsPerPage
:20
-
rowsPerPageOptions
:[5, 10, 20]
The hook takes an options
parameter if, you want to override the defaults:
usePagination = (options?: {
page?: number;
rowsPerPage?: number;
rowsPerPageOptions?: number[];
})
useFilter
hook
This hook can be used to filter rows based on query
, see Advanced Example for example of usage.
useSortable
hook
This hook can be used to sort rows on a given column, see Advanced Example for example of usage.