Data Table

A dashboard table with search, sorting, selection, and pagination.

Overview

Data Table composes Table, Checkbox, Input, Dropdown Menu, Skeleton, and Pagination into a client-side data view. Mark columns as sortable or searchable, then opt into selection, visibility, and pagination as needed.

Preview

Status
VinyaasSarangActive
DashboardPriyaReview
Mobile AppAaravComplete

Showing 1–3 of 8

Rows per page

Customize

Rows Per Page
3
Row Choices
Choices Label
Searchable
Selectable
Column Visibility
Loading

Installation

Add the component with the CLI. It copies the files in and installs anything they depend on.

npx vinyaas add data-table

Usage

import { DataTable, type DataTableColumn } from "@/components/ui/data-table"; type Project = { id: string; name: string; owner: string; status: string; }; const columns: DataTableColumn<Project>[] = [ { id: "name", header: "Project", accessorKey: "name", sortable: true, searchable: true, enableHiding: false, }, { id: "owner", header: "Owner", accessorKey: "owner", sortable: true, searchable: true, }, { id: "status", header: "Status", accessorKey: "status", }, ]; export function ProjectsTable({ data }: { data: Project[] }) { return ( <DataTable columns={columns} data={data} searchable searchPlaceholder="Search projects..." selectable columnVisibility pagination={5} /> ); }

Examples

Basic

Columns and rows from a typed dataset.

Status
VinyaasSarangActive
DashboardPriyaReview
Mobile AppAaravComplete

Sorting

Click a sortable header to cycle ascending, descending, and unsorted. The sort icon has a fixed size and the table layout is fixed, so columns keep their width while the order changes.

Status
VinyaasSarangActive
DashboardPriyaReview
Mobile AppAaravComplete
MarketingAnanyaDraft

Selection

Select rows individually or use the header checkbox for the visible page.

Status
VinyaasSarangActive
DashboardPriyaReview
Mobile AppAaravComplete
MarketingAnanyaDraft

Filter rows across columns marked searchable.

Status
VinyaasSarangActive
DashboardPriyaReview
Mobile AppAaravComplete
MarketingAnanyaDraft
AnalyticsSarangActive
BillingPriyaDraft
OnboardingAaravReview
Docs SiteAnanyaActive

Rows per page

pageSizeOptions renders a toggle group beside the pager, so the reader picks how many rows a page holds. pagination still sets the starting size.

Status
VinyaasSarangActive
DashboardPriyaReview
Mobile AppAaravComplete

Showing 1–3 of 8

Rows per page

Loading

Skeleton rows while data is loading.

Status

Empty

A clear empty state when nothing matches.

Status
No results found.

In practice

A projects board with search, selection, column visibility, pagination, status badges, and row actions.

StatusActions
VinyaasSarangActive2m ago
DashboardPriyaReview1h ago
Mobile AppAaravComplete2d ago
MarketingAnanyaDraft4d ago

Showing 1–4 of 8

API

Other attributes for the underlying element are passed through.

NameTypeDefaultDescription
columnsDataTableColumn<T>[]—Column definitions for headers, cells, sorting, and search.
dataT[]—Row data rendered by the table.
getRowId(row: T, index: number) => string—Stable row id. Defaults to row.id when present.
searchablebooleanfalseShows a search field over searchable columns.
searchPlaceholderstring"Search…"Placeholder and accessible name for the search field.
selectablebooleanfalseAdds row checkboxes and a select-all control.
paginationboolean | numberfalseClient-side pagination. A number sets the page size.
pageSizeOptionsnumber[]—Row-count choices offered beside the pager as a toggle group. Needs pagination, and is hidden below two choices. Picking one returns to page 1.
pageSizeLabelstring"Rows per page"Names the row-count toggle group.
actionsWidthstring | number"7rem"Width of the trailing actions column.
columns[].widthstring | number—Column width. The table uses a fixed layout, so sorting, paging, and search never resize columns. Columns without a width share the remaining space.
columnVisibilitybooleanfalseShows a Columns menu to hide and show columns.
loadingbooleanfalseRenders skeleton rows instead of data.
emptyMessagestring"No results found."Copy shown when there are no rows to display.
renderRowActions(row: T) => ReactNode—Optional trailing actions column renderer.

Accessibility

The table keeps semantic table markup. Sortable headers are buttons with aria-sort on the column header. Selection checkboxes include accessible names for individual rows and select-all, including the partial-selection state.

  • Enter and Space activate sortable headers and row actions.
  • Pagination reuses the accessible Pagination controls.
  • Column visibility items are menuitem checkboxes.
  • Loading and empty states do not leave orphaned interactive controls.