Data Table

Filterable, sortable data table with search, status filters, and pagination.

Preview

Features

  • Generic TypeScript support with custom column definitions
  • Filter chips with search input and status popover (Vercel style)
  • Clickable column headers for sorting (asc/desc)
  • Simple pagination with Previous/Next buttons
  • Custom cell rendering via render function
  • Loading skeleton state
  • Empty state with icon
  • Optional row click handler

Install Summary

This kit will add the following files and dependencies to your project. Download the bundle and extract it into your project root.

Component Files

FilePath
data-table.tsxcomponents/data/data-table/data-table.tsx
data-table-filters.tsxcomponents/data/data-table/data-table-filters.tsx
data-table-pagination.tsxcomponents/data/data-table/data-table-pagination.tsx
data-table-empty.tsxcomponents/data/data-table/data-table-empty.tsx
types.tscomponents/data/data-table/types.ts
index.tscomponents/data/data-table/index.ts

Utility Files

FilePath
design-tokens.tslib/design-tokens.ts

Dependencies

Install these dependencies before using the component:

Terminal
bash
npx shadcn@latest add skeleton input select
Terminal
bash
npm install @phosphor-icons/react

Installation

Download the complete bundle as a ZIP file, or copy the text bundle to your clipboard:

Component Files

The component consists of the following files:

1. data-table.tsx

data-table.tsx
tsx
"use client";

import { useState, useMemo } from "react";
import { CaretUp as ChevronUp, CaretDown as ChevronDown } from "@phosphor-icons/react";
import { Skeleton } from "@/components/ui/skeleton";

2. data-table-filters.tsx

data-table-filters.tsx
tsx
"use client";

import { MagnifyingGlass as Search, CaretDown as ChevronDown, X } from "@phosphor-icons/react";
import {
  Popover,

3. data-table-pagination.tsx

data-table-pagination.tsx
tsx
"use client";

import { Button } from "@/components/ui/button";

interface DataTablePaginationProps {

4. data-table-empty.tsx

data-table-empty.tsx
tsx
"use client";

import { TrayArrowDown as Inbox } from "@phosphor-icons/react";

interface DataTableEmptyProps {

5. types.ts

types.ts
tsx
export type SortDirection = "asc" | "desc" | null;

export interface Column<T> {
  key: keyof T;
  label: string;

6. index.ts

index.ts
tsx
export { DataTable } from "./data-table";
export { DataTableFilters } from "./data-table-filters";
export { DataTablePagination } from "./data-table-pagination";
export { DataTableEmpty } from "./data-table-empty";
export type {
  Column,
  SortDirection,
  SortState,
  FilterState,
  StatusOption,
  DataTableProps,
} from "./types";

Shared Utilities

This component uses shared utility functions. These are included in the bundle above:

design-tokens.ts

design-tokens.ts
tsx
// Border radius
export const radius = {
  card: "rounded-xl",
  badge: "rounded-full",
  button: "rounded-lg",

Usage

app/users.tsx
tsx
import { DataTable, type Column } from "@/components/data/data-table";

type User = {
  id: string;
  name: string;

DataTable Props

PropTypeDefault
dataT[]required
columnsColumn<T>[]required
filterKeykeyof T-
statusKeykeyof T-
statusOptionsStatusOption[]-
pageSizenumber10
loadingbooleanfalse
emptyMessagestring"No results found"
onRowClick(row: T) => void-

Column Configuration

PropertyTypeDescription
keykeyof TProperty key to access from data row
labelstringColumn header text
sortablebooleanEnable sorting for this column
render(value, row) => ReactNodeCustom cell renderer