Quick Start
Minimal Working Example
Getting a fully functional table onto the screen requires four steps: define your data interface, declare your column definitions using ColumnDef, provide a static or fetched data array, and pass both to ClientSideTable. The component handles sorting, pagination, row numbering, and column visibility automatically with no additional configuration.
"use client"
import { ColumnDef } from "@tanstack/react-table"
import { ClientSideTable } from "@/components/table/client-side-table"
import { DataTableColumnHeader } from "@/components/table/data-table-column-header"
interface User {
id: number
name: string
email: string
status: "active" | "inactive"
}
const columns: ColumnDef<User>[] = [
{
accessorKey: "name",
header: ({ column }) => <DataTableColumnHeader column={column} title="Name" />,
},
{
accessorKey: "email",
header: ({ column }) => <DataTableColumnHeader column={column} title="Email" />,
},
{
accessorKey: "status",
header: ({ column }) => <DataTableColumnHeader column={column} title="Status" />,
},
]
const data: User[] = [
{ id: 1, name: "Alice", email: "alice@example.com", status: "active" },
{ id: 2, name: "Bob", email: "bob@example.com", status: "inactive" },
]
export default function UsersPage() {
return (
<ClientSideTable
data={data}
columns={columns}
pageCount={Math.ceil(data.length / 10)}
/>
)
}Adding Search
Pass a searchableColumns array to enable a global search input in the toolbar. Each entry maps a column id to a human-readable title. The table filters rows client-side as the user types, with no debounce configuration required.
"use client"
import { ColumnDef } from "@tanstack/react-table"
import { ClientSideTable } from "@/components/table/client-side-table"
import { DataTableColumnHeader } from "@/components/table/data-table-column-header"
interface User {
id: number
name: string
email: string
status: "active" | "inactive"
}
const columns: ColumnDef<User>[] = [
{
accessorKey: "name",
header: ({ column }) => <DataTableColumnHeader column={column} title="Name" />,
},
{
accessorKey: "email",
header: ({ column }) => <DataTableColumnHeader column={column} title="Email" />,
},
{
accessorKey: "status",
header: ({ column }) => <DataTableColumnHeader column={column} title="Status" />,
},
]
// Pass searchableColumns to enable the global search input.
// Each entry maps a column id to its display label.
export default function UsersPage() {
return (
<ClientSideTable
data={data}
columns={columns}
pageCount={Math.ceil(data.length / 10)}
searchableColumns={[
{ id: "name", title: "Name" },
{ id: "email", title: "Email" },
]}
/>
)
}Adding Filters
Pass a filterableColumns array to render faceted filter dropdowns next to the search input. Each entry declares the target column id, a display title, and an options array of { label, value } pairs. Active filters are shown as dismissible badge chips and can be cleared individually or all at once via the reset button.
"use client"
import { ColumnDef } from "@tanstack/react-table"
import { ClientSideTable } from "@/components/table/client-side-table"
import { DataTableColumnHeader } from "@/components/table/data-table-column-header"
interface User {
id: number
name: string
email: string
status: "active" | "inactive"
}
const columns: ColumnDef<User>[] = [
{
accessorKey: "name",
header: ({ column }) => <DataTableColumnHeader column={column} title="Name" />,
},
{
accessorKey: "email",
header: ({ column }) => <DataTableColumnHeader column={column} title="Email" />,
},
{
accessorKey: "status",
header: ({ column }) => <DataTableColumnHeader column={column} title="Status" />,
},
]
// filterableColumns enables faceted filter dropdowns in the toolbar.
// Each entry needs an id, a label, and the list of selectable options.
export default function UsersPage() {
return (
<ClientSideTable
data={data}
columns={columns}
pageCount={Math.ceil(data.length / 10)}
filterableColumns={[
{
id: "status",
title: "Status",
options: [
{ label: "Active", value: "active" },
{ label: "Inactive", value: "inactive" },
],
},
]}
/>
)
}Adding Row Actions
Use the reserved "actions" column id together with the TableActionsRow component to render a per-row dropdown menu. Each action entry accepts a label, an onClick handler, and an optional variant ("default" or "destructive") that controls the text color of the menu item.
"use client"
import { ColumnDef } from "@tanstack/react-table"
import { ClientSideTable } from "@/components/table/client-side-table"
import { DataTableColumnHeader } from "@/components/table/data-table-column-header"
import { TableActionsRow } from "@/components/table/table-actions-row"
interface User {
id: number
name: string
email: string
status: "active" | "inactive"
}
const columns: ColumnDef<User>[] = [
{
accessorKey: "name",
header: ({ column }) => <DataTableColumnHeader column={column} title="Name" />,
},
{
accessorKey: "email",
header: ({ column }) => <DataTableColumnHeader column={column} title="Email" />,
},
{
accessorKey: "status",
header: ({ column }) => <DataTableColumnHeader column={column} title="Status" />,
},
// The "actions" column id is reserved and renders a dropdown menu per row.
{
id: "actions",
cell: ({ row }) => (
<TableActionsRow
actions={[
{
label: "Edit",
onClick: () => console.log("edit", row.original.id),
},
{
label: "Delete",
onClick: () => console.log("delete", row.original.id),
variant: "destructive",
},
]}
/>
),
},
]