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
| File | Path |
|---|---|
| data-table.tsx | components/data/data-table/data-table.tsx |
| data-table-filters.tsx | components/data/data-table/data-table-filters.tsx |
| data-table-pagination.tsx | components/data/data-table/data-table-pagination.tsx |
| data-table-empty.tsx | components/data/data-table/data-table-empty.tsx |
| types.ts | components/data/data-table/types.ts |
| index.ts | components/data/data-table/index.ts |
Utility Files
| File | Path |
|---|---|
| design-tokens.ts | lib/design-tokens.ts |
Dependencies
Install these dependencies before using the component:
Terminal
bash
npx shadcn@latest add skeleton input selectTerminal
bash
npm install @phosphor-icons/reactInstallation
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
| Prop | Type | Default |
|---|---|---|
| data | T[] | required |
| columns | Column<T>[] | required |
| filterKey | keyof T | - |
| statusKey | keyof T | - |
| statusOptions | StatusOption[] | - |
| pageSize | number | 10 |
| loading | boolean | false |
| emptyMessage | string | "No results found" |
| onRowClick | (row: T) => void | - |
Column Configuration
| Property | Type | Description |
|---|---|---|
| key | keyof T | Property key to access from data row |
| label | string | Column header text |
| sortable | boolean | Enable sorting for this column |
| render | (value, row) => ReactNode | Custom cell renderer |