mirror of
https://github.com/Amperra-Group/xcs.git
synced 2025-08-16 13:22:14 -06:00
86 lines
2.5 KiB
TypeScript
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>
|
|
);
|
|
}
|