import { type ColumnFiltersState, type ColumnDef, flexRender, getCoreRowModel, getFilteredRowModel, getSortedRowModel, type SortingState, useReactTable, } from "@tanstack/react-table"; import { ArrowDown, ArrowUp, ChevronsUpDown, X } from "lucide-react"; import { useState } from "react"; import { cn } from "../lib"; import { Empty } from "../ui"; function columnClass(meta: unknown): string | undefined { if (!meta || typeof meta !== "object" || !("className" in meta)) return undefined; const className = meta.className; return typeof className === "string" ? className : undefined; } export function DataTable({ columns, data, empty = "No records found", rowClassName, }: { columns: ColumnDef[]; data: T[]; empty?: string; rowClassName?(row: T): string | undefined; }) { const [sorting, setSorting] = useState([]); const [columnFilters, setColumnFilters] = useState([]); const table = useReactTable({ data, columns, defaultColumn: { filterFn: "includesString" }, state: { columnFilters, sorting }, onColumnFiltersChange: setColumnFilters, onSortingChange: setSorting, getCoreRowModel: getCoreRowModel(), getFilteredRowModel: getFilteredRowModel(), getSortedRowModel: getSortedRowModel(), }); if (data.length === 0) return {empty}; const rows = table.getRowModel().rows; return (
{rows.length === data.length ? `${data.length} ${data.length === 1 ? "row" : "rows"}` : `${rows.length} of ${data.length} rows`} {columnFilters.length > 0 ? ( ) : null}
{table.getHeaderGroups().map((group) => ( {group.headers.map((header) => ( ))} ))} {rows.length > 0 ? ( rows.map((row) => ( {row.getVisibleCells().map((cell) => ( ))} )) ) : ( )}
{header.isPlaceholder ? null : (
{header.column.getCanFilter() ? ( header.column.setFilterValue(event.target.value) } onClick={(event) => event.stopPropagation()} /> ) : null}
)}
{flexRender(cell.column.columnDef.cell, cell.getContext())}
No rows match these filters
); }