Data Table
A feature-rich data grid component with client-side searching, column sorting, and pagination controls.
dataTable.tsx
Core implementation of the DataTable component.
ReactTanStack TableTailwindData Grid
"use client";
import * as React from "react";
import {
ColumnDef,
flexRender,
getCoreRowModel,
useReactTable,
getPaginationRowModel,
getSortedRowModel,
SortingState,
getFilteredRowModel,
} from "@tanstack/react-table";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table/table";
import { Input } from "@/components/ui/input/input";
import { Button } from "@/components/ui/button/button";
interface DataTableProps<TData, TValue> {
columns: ColumnDef<TData, TValue>[];
data: TData[];
searchPlaceholder?: string;
searchColumn?: string;
}
export function DataTable<TData, TValue>({
columns,
data,
searchPlaceholder = "Filter rows...",
searchColumn,
}: DataTableProps<TData, TValue>) {
const [sorting, setSorting] = React.useState<SortingState>([]);
const [globalFilter, setGlobalFilter] = React.useState("");
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
onSortingChange: setSorting,
getSortedRowModel: getSortedRowModel(),
onGlobalFilterChange: setGlobalFilter,
getFilteredRowModel: getFilteredRowModel(),
state: {
sorting,
globalFilter,
},
});
return (
<div className="space-y-4 w-full">
<div className="flex items-center justify-between">
<Input
placeholder={searchPlaceholder}
value={globalFilter ?? ""}
onChange={(e) => setGlobalFilter(e.target.value)}
className="max-w-xs"
size="sm"
/>
</div>
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<TableHead key={header.id}>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
</TableHead>
);
})}
</TableRow>
))}
</TableHeader>
<TableBody>
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
<TableRow
key={row.id}
data-state={row.getIsSelected() && "selected"}
>
{row.getVisibleCells().map((cell) => (
<TableCell key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TableCell>
))}
</TableRow>
))
) : (
<TableRow>
<TableCell colSpan={columns.length} className="h-24 text-center text-muted-foreground">
No results.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
<div className="flex items-center justify-end space-x-2 py-2">
<Button
variant="bordered"
size="sm"
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
>
Previous
</Button>
<Button
variant="bordered"
size="sm"
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
>
Next
</Button>
</div>
</div>
);
}Basic Usage
Filterable and paginated data table.
ID | Name | Email | Role |
|---|---|---|---|
| 1 | Guilherme Santos | gui@example.com | Frontend Lead |
| 2 | Beatriz Lima | bea@example.com | UI Designer |
| 3 | Carlos Eduardo | carlos@example.com | Backend Dev |
Showing 3 records
API Reference
Props — DataTable
Properties to configure the DataTable component.
| Prop | Type | Default | Description |
|---|---|---|---|
| columns | ColumnDef[] | — | TanStack column definitions array. |
| data | TData[] | — | Array of data row objects. |