Skip to content

Interactive Answers

Data Table

Tabular results — sortable columns, filter, pagination, row selection and copy as CSV.

2 variantsMIT

Preview

Top customers by MRR

9 rows

Top customers by MRR
Northwind LabsEnterprise
Halcyon HealthEnterprise
Brightline FreightTeam
Copperleaf StudioTeam
Ostrava RoboticsEnterprise
Pinecrest SchoolsPro
1–6 of 91 / 2

9 rows

Installation

Copies the component into components/ui and installs its dependencies and theme tokens.

pnpm dlx shadcn@latest add https://tuffui.com/r/data-table.json

Usage

Pass your own data and wire the callbacks to your agent runtime.

import { DataTable, type DataColumn } from "@/components/ui/data-table";

const columns: DataColumn<Customer>[] = [
  { key: "name", label: "Customer", sortable: true },
  { key: "mrr", label: "MRR", align: "right", sortable: true, format: (v) => `$${v}` },
];

// Render a table when a tool returns rows.
export function CustomersAnswer({ rows }: { rows: Customer[] }) {
  return (
    <DataTable
      title="Top customers by MRR"
      data={rows}
      columns={columns}
      selectable
      actions={(ids) => <Button onClick={() => agent.followUp(ids)}>Draft follow-up</Button>}
    />
  );
}

Props

PropTypeDefaultDescription
data*R[]—Rows. Each needs a unique `id`; other fields are strings, numbers or null.
columns*DataColumn<R>[]—Column order, labels, alignment, display format and which ones sort.
title*string—Header title and table caption.
subtitlestring—Replaces the default row count under the title.
pageSizenumber6Rows per page.
searchablebooleantrueShows the filter field above the table.
selectablebooleanfalseAdds row checkboxes and a bulk action bar.
selectedstring[]—Controlled selection by row id.
onSelectedChange(ids: string[]) => void—Called when the selection changes.
actions(ids: string[]) => ReactNode—Buttons in the bulk bar for the selected rows.
onRowClick(row: R) => void—Makes rows clickable.
classNamestring—Extra classes for the root element.
type DataRow = { id: string } & Record<string, string | number | null>;

type DataColumn<R> = {
  key: keyof R & string;
  label: string;
  align?: "left" | "right"; // right-aligned columns use tabular mono figures
  format?: (value, row: R) => ReactNode; // sort, filter and CSV use the raw value
  sortable?: boolean; // click cycles descending → ascending → off
  width?: string;
  priority?: 1 | 2 | 3; // 1 always, 2 hidden below a 28rem table, 3 below 36rem
};