"use client"; import * as React from "react"; import { ColumnDef, SortingState, flexRender, getCoreRowModel, getPaginationRowModel, getSortedRowModel, getFilteredRowModel, useReactTable, } from "@tanstack/react-table"; import { cn } from "../../lib/utils"; import { Button } from "./button"; import { Input } from "./input"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "./table"; import { ChevronLeft, ChevronRight, ArrowUpDown, ArrowUp, ArrowDown, Search, } from "lucide-react"; /** * Basic DataTable Component * * A simple data table with sorting, filtering, and pagination. * For advanced features, upgrade to MoonUI Pro. */ interface DataTableBasicProps { /** * The table columns definition */ columns: ColumnDef[]; /** * The data to display */ data: TData[]; /** * Enable/disable sorting */ enableSorting?: boolean; /** * Enable/disable pagination */ enablePagination?: boolean; /** * Enable/disable global search */ enableSearch?: boolean; /** * Default page size */ pageSize?: number; /** * Search placeholder text */ searchPlaceholder?: string; /** * Empty state message */ emptyMessage?: string; /** * Class name */ className?: string; } export function DataTableBasic({ columns, data, enableSorting = true, enablePagination = true, enableSearch = true, pageSize = 10, searchPlaceholder = "Search...", emptyMessage = "No results found.", className, }: DataTableBasicProps) { const [sorting, setSorting] = React.useState([]); const [globalFilter, setGlobalFilter] = React.useState(""); const table = useReactTable({ data, columns, onSortingChange: enableSorting ? setSorting : undefined, onGlobalFilterChange: enableSearch ? setGlobalFilter : undefined, getCoreRowModel: getCoreRowModel(), getPaginationRowModel: enablePagination ? getPaginationRowModel() : undefined, getSortedRowModel: enableSorting ? getSortedRowModel() : undefined, getFilteredRowModel: enableSearch ? getFilteredRowModel() : undefined, state: { sorting, globalFilter, }, initialState: { pagination: { pageSize, }, }, }); return (
{/* Search */} {enableSearch && (
setGlobalFilter(event.target.value)} className="pl-8" />
)} {/* Table */}
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( {header.isPlaceholder ? null : (
{flexRender( header.column.columnDef.header, header.getContext() )} {enableSorting && header.column.getCanSort() && (
{header.column.getIsSorted() === "desc" ? ( ) : header.column.getIsSorted() === "asc" ? ( ) : ( )}
)}
)}
); })}
))}
{table.getRowModel().rows?.length ? ( table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => ( {flexRender( cell.column.columnDef.cell, cell.getContext() )} ))} )) ) : ( {emptyMessage} )}
{/* Pagination */} {enablePagination && (
{table.getFilteredRowModel().rows.length} row(s)
Page {table.getState().pagination.pageIndex + 1} of{" "} {table.getPageCount()}
)}
); } /** * Simple sortable header helper */ export function createSortableHeader(label: string) { return ({ column }: any) => ( ); } // Export utilities export { type ColumnDef } from "@tanstack/react-table";