NAM-APJATEL/src/components/ReactTable.tsx

144 lines
4.4 KiB
TypeScript

import InputAdornment from "@mui/material/InputAdornment";
import Paper from "@mui/material/Paper";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableContainer from "@mui/material/TableContainer";
import TableCell from "@mui/material/TableCell";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import TablePagination from "@mui/material/TablePagination";
import TextField from "@mui/material/TextField";
import Box from "@mui/material/Box";
import {
flexRender,
useReactTable,
ColumnDef,
getCoreRowModel,
getSortedRowModel,
getFilteredRowModel,
getPaginationRowModel,
SortingState,
ColumnFiltersState,
} from "@tanstack/react-table";
import { useState } from "react";
import { SearchNormal } from "iconsax-react";
interface ReactTableProps<T extends object> {
columns: ColumnDef<T>[];
data: T[];
striped?: boolean;
title?: string;
}
function ComponentReactTable<T extends object>({
columns,
data,
striped,
title,
}: ReactTableProps<T>) {
const [sorting, setSorting] = useState<SortingState>([]);
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
const [globalFilter, setGlobalFilter] = useState("");
const table = useReactTable({
data,
columns,
state: {
sorting,
columnFilters,
globalFilter,
},
onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters,
onGlobalFilterChange: setGlobalFilter,
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
getPaginationRowModel: getPaginationRowModel(),
});
return (
<Box>
<Box justifyContent={"space-between"} display="flex">
<Box>
</Box>
<TextField
size="small"
value={globalFilter ?? ""}
onChange={(e) => setGlobalFilter(e.target.value)}
placeholder="Search all columns..."
sx={{ mb: 2 }}
slotProps={{
input: {
startAdornment: <InputAdornment position="start">
<SearchNormal size="20" variant="Linear" color="#808191" />
</InputAdornment>,
},
}}
/>
</Box>
<TableContainer component={Paper}>
<Table>
<TableHead>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<TableCell
key={header.id}
onClick={header.column.getToggleSortingHandler()}
sx={{ cursor: "pointer" }}
>
{header.isPlaceholder ? null : (
<Box sx={{ display: "flex", alignItems: "center" }}>
{flexRender(
header.column.columnDef.header,
header.getContext()
)}
{{
asc: " 🔼",
desc: " 🔽",
}[header.column.getIsSorted() as string] ?? null}
</Box>
)}
</TableCell>
))}
</TableRow>
))}
</TableHead>
<TableBody className={striped ? "striped" : undefined}>
{table.getRowModel().rows.map((row) => (
<TableRow key={row.id}>
{row.getVisibleCells().map((cell) => (
<TableCell key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
<TablePagination
component="div"
count={table.getFilteredRowModel().rows.length}
page={table.getState().pagination.pageIndex}
onPageChange={(_, page) => table.setPageIndex(page)}
rowsPerPage={table.getState().pagination.pageSize}
onRowsPerPageChange={(e) => table.setPageSize(Number(e.target.value))}
rowsPerPageOptions={[5, 10, 25, 50]}
/>
</Box>
);
}
export default function ReactTable<T extends object>({
striped,
title,
data,
columns,
}: ReactTableProps<T>) {
return <ComponentReactTable {...{ data, columns, title, striped }} />;
}