Data Table
A powerful data table component with sorting, filtering, pagination, row selection and faceted filters.
Loading...
"use client"
import { ColumnDef } from "@tanstack/react-table"About
The DataTable component is built on top of TanStack Table and provides a powerful, flexible data table with:
- Column sorting with dropdown (Asc/Desc/Hide)
- Text filtering and faceted filters
- Pagination with page numbers or simple navigation
- Row selection with callbacks
- Column visibility toggle
- Loading skeleton state
- Custom empty state
- Row click handler
- Controlled state for URL sync
Installation
pnpmnpmyarnbun
Usage
import { ColumnDef } from "@tanstack/react-table"
import { DataTable } from "@/components/ui/data-table"type User = {
id: string
name: string
email: string
}
const columns: ColumnDef<User>[] = [
{ accessorKey: "name", header: "Name" },
{ accessorKey: "email", header: "Email" },
]
const data: User[] = [
{ id: "1", name: "John", email: "john@example.com" },
{ id: "2", name: "Jane", email: "jane@example.com" },
]
return <DataTable columns={columns} data={data} />Examples
Basic Table
Loading...
"use client"
import { ColumnDef } from "@tanstack/react-table"Advanced with Faceted Filters
This example shows faceted filters, row selection, page numbers, and sortable column headers.
Loading...
"use client"
import * as React from "react"Loading State
Use isLoading to show a skeleton while data is loading.
Loading...
"use client"
import * as React from "react"Exported Components
The data-table exports multiple components you can use:
Using DataTableColumnHeader
import { DataTableColumnHeader } from "@/components/ui/data-table"
const columns: ColumnDef<Task>[] = [
{
accessorKey: "title",
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Title" />
),
},
]Faceted Filters
import { DataTable, FacetedFilterConfig } from "@/components/ui/data-table"
const facetedFilters: FacetedFilterConfig[] = [
{
column: "status",
title: "Status",
options: [
{ label: "Todo", value: "todo" },
{ label: "Done", value: "done" },
],
},
]
return (
<DataTable columns={columns} data={data} facetedFilters={facetedFilters} />
)Column Definitions
Columns are defined using TanStack Table's ColumnDef type:
const columns: ColumnDef<Payment>[] = [
{
accessorKey: "email",
header: "Email",
},
{
accessorKey: "amount",
header: () => <div className="text-right">Amount</div>,
cell: ({ row }) => {
const amount = parseFloat(row.getValue("amount"))
const formatted = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
}).format(amount)
return <div className="text-right font-medium">{formatted}</div>
},
},
]Row Selection Column
Add a selection column using the Checkbox component:
import { Checkbox } from "@/components/ui/checkbox"
// In your columns array:
{
id: "select",
header: ({ table }) => (
<Checkbox
checked={table.getIsAllPageRowsSelected()}
onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
/>
),
cell: ({ row }) => (
<Checkbox
checked={row.getIsSelected()}
onCheckedChange={(value) => row.toggleSelected(!!value)}
/>
),
enableSorting: false,
enableHiding: false,
}Controlled State
For URL sync or external state management, you can control the table state from outside the component.
Basic Example
const [sorting, setSorting] = useState<SortingState>([])
const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 })
return (
<DataTable
columns={columns}
data={data}
sorting={sorting}
onSortingChange={setSorting}
pagination={pagination}
onPaginationChange={setPagination}
/>
)With nuqs (URL State)
Use nuqs to sync table state with URL query parameters:
import { SortingState } from "@tanstack/react-table"
import { parseAsInteger, parseAsJson, useQueryState } from "nuqs"
export function UsersTable({ data, columns }) {
const [page, setPage] = useQueryState("page", parseAsInteger.withDefault(0))
const [pageSize, setPageSize] = useQueryState(
"size",
parseAsInteger.withDefault(10)
)
const [sorting, setSorting] = useQueryState<SortingState>(
"sort",
parseAsJson<SortingState>().withDefault([])
)
return (
<DataTable
columns={columns}
data={data}
pagination={{ pageIndex: page, pageSize }}
onPaginationChange={(state) => {
setPage(state.pageIndex)
setPageSize(state.pageSize)
}}
sorting={sorting}
onSortingChange={setSorting}
/>
)
}This enables:
- Shareable URLs:
/users?page=2&size=20&sort=[{"id":"name","desc":false}] - Browser history: Back/forward navigation works with table state
- Bookmarks: Users can save filtered/sorted views