Data Table Variants
21 production-ready patterns — pick one, see the live preview, copy the code
Simple Contact List
Basic table with search and pagination — ideal starter.
Install with:
npx afnoui add tables/tables-simple-listSimple Contact List
Contacts
A simple list of contacts.
| Phone | ||
|---|---|---|
| Alice Johnson | alice@example.com | +1 555-0101 |
| Bob Smith | bob@example.com | +1 555-0102 |
| Carol White | carol@example.com | +1 555-0103 |
| David Brown | david@example.com | +1 555-0104 |
| Eva Martinez | eva@example.com | +1 555-0105 |
| Frank Lee | frank@example.com | +1 555-0106 |
| Grace Hop | grace@example.com | +1 555-0107 |
| Henry Ford | henry@example.com | +1 555-0108 |
Showing 1–8 of 8
1 / 1
JSON Configuration
3 columns · 8 rowsSource Code
Required Dependencies & Files
Install packages and copy 14 files to get this table running.
Runtime deps
npm install @radix-ui/react-avatar @radix-ui/react-checkbox @radix-ui/react-collapsible @radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react-progress @radix-ui/react-radio-group @radix-ui/react-scroll-area @radix-ui/react-select @radix-ui/react-switch @radix-ui/react-tabs @radix-ui/react-tooltip @tanstack/react-virtual class-variance-authority clsx lucide-react react tailwind-mergeDev deps
npm install -D @types/react typescript Variant-specific (regenerated per table) Shared (copy once)
Variant-specific
Strongly-typed config object + Row interface for this table.
src/components/tables/tableConfig.ts
src/components/tables/tableConfig.ts
import type { TableBuilderConfig, TableRow } from "./types";
export interface Row extends TableRow {
"name": string;
"email": string;
"phone": string;
}
export const tableConfig: TableBuilderConfig = {
"title": "Contacts",
"description": "A simple list of contacts.",
"direction": "ltr",
"density": "comfortable",
"pageSize": 8,
"sortMode": "client",
"paginationMode": "client",
"expandableLayout": "details",
"expandableIconStyle": "chevron",
"expandableIconPosition": "first",
"paginationLayout": "full",
"pageSizeOptions": [
5,
10,
20,
50,
100
],
"virtualRowHeight": 44,
"virtualMaxHeight": 520,
"enableSearch": true,
"enablePagination": true,
"enableRowSelection": false,
"enableDnD": false,
"enableColumnVisibility": false,
"enableExport": false,
"enableStriped": false,
"enableHover": true,
"enableBordered": false,
"enableStickyHeader": false,
"enableExpandableRows": false,
"enableInlineEdit": false,
"enableBulkActions": false,
"enableColumnResize": false,
"enableMultiSort": false,
"enableColumnFilters": false,
"enableRowGrouping": false,
"enableAggregation": false,
"enableFooter": false,
"columns": [
{
"id": "c1",
"key": "name",
"label": "Name",
"type": "text",
"sortable": true,
"filterable": true,
"visible": true,
"align": "left"
},
{
"id": "c2",
"key": "email",
"label": "Email",
"type": "email",
"sortable": true,
"filterable": true,
"visible": true,
"align": "left"
},
{
"id": "c3",
"key": "phone",
"label": "Phone",
"type": "text",
"sortable": false,
"filterable": false,
"visible": true,
"align": "left"
}
]
} as const satisfies TableBuilderConfig;