A table an assistant produced, shown as a real sortable table with a title and summary, numbers aligned, long results cut to a few rows, and a CSV download.
Bring your own model.
These components only show what you give them, in one message shape, and report what the person does. They never call a model or a server, so they work with any backend. They are built for how assistive technology handles streaming text, tool steps and approvals.
import { GeneratedTable } from "@rdloom/react";
export default function GeneratedTableExample() {
return (
<div className="w-[34rem] max-w-full">
<GeneratedTable
title="Sales by region, last month"
fileName="sales-by-region.csv"
data={{
columns: ["Region", "Orders", "Revenue ($)", "Growth (%)"],
rows: [
["Europe", 1240, 412000, 9],
["Americas", 1985, 655000, 14],
["Asia Pacific", 870, 281500, 21],
["Africa", 210, 64300, 4],
],
}}
/>
</div>
);
}Installation
npx rdloom add generated-tableCopies the source into src/components/rdloom. Edit it freely: rdloom upgrade merges later versions into your changes. It needs react-aria-components; add --install to install them.
Use another registry client
npx shadcn@latest add https://rdloom.vimalbhatt.com/r/generated-table.jsonWorks, but without upgrade tracking.
Usage
import { GeneratedTable } from "@rdloom/react";
<div className="w-[34rem] max-w-full">
<GeneratedTable
title="Sales by region, last month"
fileName="sales-by-region.csv"
data={{
columns: ["Region", "Orders", "Revenue ($)", "Growth (%)"],
rows: [
["Europe", 1240, 412000, 9],
["Americas", 1985, 655000, 14],
["Asia Pacific", 870, 281500, 21],
["Africa", 210, 64300, 4],
],
}}
/>
</div>Long
import { GeneratedTable } from "@rdloom/react";
const rows = Array.from({ length: 24 }, (_, i) => [`Customer ${String(i + 1).padStart(2, "0")}`, 120 + ((i * 37) % 400), i % 3 === 0 ? "Overdue" : "Paid"]);
// Long results show the first rows with a Show all button, so a reply doesn't become a wall of data.
export default function GeneratedTableLongExample() {
return (
<div className="w-[34rem] max-w-full">
<GeneratedTable title="Invoices" maxRows={6} data={{ columns: ["Customer", "Amount ($)", "Status"], rows }} />
</div>
);
}API Reference
Defined by the spec. Components also accept the props of the React Aria component they wrap.
| Prop | Type | Default |
|---|---|---|
datarequiredThe columns and rows. | TableData | none |
titlerequiredWhat the table shows. It is also the table's accessible name. | string | none |
summaryOne line under the title. Defaults to the row and column count. | string | none |
maxRowsRows shown before a Show all button. 0 shows every row. | number | 10 |
isSortableLet people sort by a column. Numbers sort by value, text in natural order. | boolean | true |
fileNameName of the downloaded file. | string | "table.csv" |
onExportReplaces the built-in CSV download, e.g. to save on the server. | (data: TableData) => void | none |
Accessibility
Role grid, WCAG 2.2 AA. Tested with axe and keyboard tests; screen reader checks are in the audit checklist.
Keyboard
- Arrow keys: move between cells
- Enter / Space on a column header: sorts
- Tab: moves to the Download and Show all buttons
Screen readers announce
- Announced as a table named by the title, with its row and column count
- Sorting reads as "sorted ascending"
- "Downloaded table.csv" after export
What your code must do
- A real table with a named header row and the first column as row header
- Sort direction is exposed (aria-sort) and drawn with an arrow
- Number columns are right-aligned and use tabular figures
- The summary says how many rows are shown when the list is cut
- CSV export prefixes cells starting with = + - or @ so a spreadsheet can't run them as formulas, and says when a file was downloaded
Guidelines
Use it when
- Showing rows of data an assistant looked up or built
Avoid it when
- Thousands of rows or editing: use DataGrid
Don't
- Dumping a hundred rows with no limit
- Exporting without escaping spreadsheet formulas
Design tokens
The semantic tokens this component uses. Change them once and every component follows; see Design tokens.
--rd-color-text-default--rd-color-text-muted--rd-color-surface-default--rd-color-border-default--rd-color-focus-ring