DataTable
Sortable table with rich column formatting — currency, percent, delta, status badges, dates, links, and booleans. Client-side sorting with staggered row animations.
Theme
State
Installation
Terminal
npx shadcn@latest add "https://taw-ui.com/r/data-table.json"This copies the component source and schema into your project. You own the code — customize anything.
Usage
server — define tool
import { tool } from "ai"
import { DataTableSchema } from "@/components/taw/data-table"
export const showTable = tool({
description: "Show data in a sortable table",
parameters: z.object({ query: z.string() }),
outputSchema: DataTableSchema,
execute: async ({ query }) => {
const result = await queryDatabase(query)
return {
id: slugify(query),
title: result.title,
columns: result.columns.map(c => ({
key: c.key,
label: c.label,
type: c.type,
sortable: true,
})),
rows: result.rows,
total: result.total,
defaultSort: { key: "revenue", direction: "desc" },
source: { label: "Database", freshness: "just now" },
}
},
})client — render
import { DataTable } from "@/components/taw/data-table"
import type { ToolPart } from "@/components/taw/lib/types"
function ToolOutput({ part }: { part: ToolPart }) {
// Handles loading, error, and success states
return <DataTable part={part} />
}Column Types
9 built-in column types handle formatting without custom renderers.
| Field | Type | Description |
|---|---|---|
| text | default | Plain string |
| number | format | Locale-formatted number with optional decimals |
| currency | format | Currency-formatted with symbol (configurable via format.currency) |
| percent | format | Signed percentage with color coding (green/red) |
| delta | format | Arrow + signed number with color coding |
| date | format | Locale-formatted date (short month, day, year) |
| badge | visual | Pill badge with accent color |
| link | visual | Clickable link with dotted underline |
| boolean | visual | Checkmark (true) or cross (false) |
Props
| Field | Type | Description |
|---|---|---|
| part* | ToolPart | Tool call lifecycle state — handles loading, error, and success |
| animate | boolean | Enable stagger row animations (default: true) |
| className | string | Additional CSS classes on the wrapper |
Schema
Cross-field validation ensures defaultSort.key exists in your columns — caught at parse time, not at render.
DataTableSchema
| Field | Type | Description |
|---|---|---|
| id* | string | Stable identifier |
| title | string | Table header title |
| description | string | Subtitle below the title |
| columns* | Column[] | Column definitions (min 1) |
| rows* | Record[] | Row data as key-value objects |
| total | number | Total row count (for pagination context) |
| defaultSort | { key, direction } | Initial sort column and direction |
| confidence | number (0-1) | AI confidence badge |
| caveat | string | Uncertainty note |
| source | Source | Data provenance (label + freshness) |
Column
| Field | Type | Description |
|---|---|---|
| key* | string | Maps to row data keys |
| label* | string | Column header text |
| type | ColumnType | One of 9 types (default: "text") |
| align | "left" | "center" | "right" | Text alignment (default: "left") |
| sortable | boolean | Enable sort on this column (default: false) |
| width | string | CSS width (e.g. "120px", "20%") |
| format | { currency?, decimals? } | Extra formatting options for currency/number types |
Features
Client-side sorting
Click column headers to toggle asc/desc/none
9 column format types
Rich formatting without custom renderers
Cross-field validation
defaultSort.key must exist in columns, caught at parse time
Row count + source
Footer shows row count and data provenance
Staggered entrance
Rows animate in sequence on first render
Helpful errors
Invalid columns show field-level details with suggestions