Pro Components
Base Components
Data Table
Powerful table and datagrids built using TanStack Table, with sorting, filtering, pagination, and row actions.
Example
| Status | Amount | ||
|---|---|---|---|
| pending | alex.morgan@blakeui.com | $100.00 | |
| processing | sam.rivera@blakeui.com | $125.00 | |
| success | jordan.hale@blakeui.com | $316.00 | |
| success | casey.moore@blakeui.com | $242.00 | |
| processing | morgan.reid@blakeui.com | $837.00 | |
| success | avery.blake@blakeui.com | $874.00 | |
| failed | riley.chen@blakeui.com | $721.00 |
Introduction
The Data Table is built with the base Table component and TanStack Table. It gives you a flexible, headless way to build tables with:- Column definitions and custom cells
- Pagination
- Row actions (e.g. dropdown menu per row)
- Optional sorting and filtering (you can extend the example below)
<DataTable />.
Prerequisites
Define the shape of your data and the column definitions. Example:type Payment = {
id: string;
amount: number;
status: "pending" | "processing" | "success" | "failed";
email: string;
};
const columns: ColumnDef<Payment>[] = [
{ accessorKey: "status", header: "Status" },
{ accessorKey: "email", header: "Email" },
{
accessorKey: "amount",
header: () => <div className="text-right">Amount</div>,
cell: ({ row }) => {
const amount = parseFloat(row.getValue("amount"));
return (
<div className="text-right font-medium">
{new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
}).format(amount)}
</div>
);
},
},
];Usage
import { DataTable } from "@/components/ui/data-table";
<DataTable columns={columns} data={data} />;DataTable component accepts:
- columns – Array of TanStack
ColumnDef<TData, TValue> - data – Array of row data
Basic Table
A minimal table only needs column definitions and data. UseaccessorKey to bind a column to a field and optional header and cell for custom rendering.
| Status | Amount | |
|---|---|---|
| success | jordan.hale@blakeui.com | $316.00 |
| processing | morgan.reid@blakeui.com | $837.00 |
Row Actions
Add anid: "actions" column with a custom cell that renders a dropdown (or buttons) for each row. Use row.original to access the row data.
{
id: "actions",
cell: ({ row }) => {
const payment = row.original;
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="secondary" size="sm" className="h-8 w-8 p-0">
<MoreHorizontal className="h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => navigator.clipboard.writeText(payment.id)}>
Copy payment ID
</DropdownMenuItem>
<DropdownMenuItem>View customer</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
},
}Pagination
The includedDataTable component uses getPaginationRowModel() so rows are paginated (default page size 10). It renders Previous/Next buttons; you can extend it with page size selector and page count using the same TanStack patterns described in this page.
Extending
You can add:- Sorting –
getSortedRowModel(),onSortingChange, and sortable header cells - Filtering –
getFilteredRowModel(),onColumnFiltersChange, and an input that callstable.getColumn("email")?.setFilterValue(value) - Row selection – checkbox column and
getFilteredSelectedRowModel()
API Reference
DataTable
columns*ColumnDef<TData, TValue>[]
Default: -
data*TData[]
Default: -
| Prop | Type | Default | Description |
|---|---|---|---|
| columns* | ColumnDef<TData, TValue>[] | - | - |
| data* | TData[] | - | - |