xcs/src/components/DataTable.tsx
2024-04-03 10:15:51 +00:00

86 lines
2.5 KiB
TypeScript

import * as React from 'react';
import { Table, Tbody, Td, Th, Thead, Tr, chakra } from '@chakra-ui/react';
import { TriangleDownIcon, TriangleUpIcon } from '@chakra-ui/icons';
import {
ColumnDef,
SortingState,
flexRender,
getCoreRowModel,
getSortedRowModel,
useReactTable
} from '@tanstack/react-table';
export type DataTableProps<Data extends object> = {
data: Data[];
columns: ColumnDef<Data, any>[];
};
export function DataTable<Data extends object>({ data, columns }: DataTableProps<Data>) {
const [sorting, setSorting] = React.useState<SortingState>([]);
const table = useReactTable({
columns,
data,
getCoreRowModel: getCoreRowModel(),
onSortingChange: setSorting,
getSortedRowModel: getSortedRowModel(),
state: {
sorting
}
});
return (
<Table>
<Thead>
{table.getHeaderGroups().map((headerGroup) => (
<Tr key={headerGroup.id}>
{headerGroup.headers.map((header) => {
// see https://tanstack.com/table/v8/docs/api/core/column-def#meta to type this correctly
const meta: any = header.column.columnDef.meta;
return (
<Th
key={header.id}
onClick={header.column.getToggleSortingHandler()}
isNumeric={meta?.isNumeric}
>
{flexRender(header.column.columnDef.header, header.getContext())}
<chakra.span pl={'4'}>
{header.column.getIsSorted() ? (
header.column.getIsSorted() === 'desc' ? (
<TriangleDownIcon aria-label="sorted descending" />
) : (
<TriangleUpIcon aria-label="sorted ascending" />
)
) : null}
</chakra.span>
</Th>
);
})}
</Tr>
))}
</Thead>
<Tbody>
{table.getRowModel().rows.map((row) => (
<Tr key={row.id}>
{row.getVisibleCells().map((cell) => {
// see https://tanstack.com/table/v8/docs/api/core/column-def#meta to type this correctly
const meta: any = cell.column.columnDef.meta;
return (
<Td
key={cell.id}
isNumeric={meta?.isNumeric}
>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</Td>
);
})}
</Tr>
))}
</Tbody>
</Table>
);
}