Table, List & Charts

Replace hand-rolled rows with a sortable Table and a chart that never shifts the layout.

This chapter's app is running in your console. Open it with ⌘⌥JCtrl+Shift+J, then try it.
Watch the chapter3:13 · narrated · captions

In this chapter

  • A sortable table
  • A chart above it
  • More components

Replace the hand-rolled rows with components: <Table> with keyboard navigation and sorting, <List> with virtualized scrolling, and charts drawn with eighth blocks and quadrant dots.

A sortable table

Columns are an array of objects. A column without a width shares the remaining space by grow, value is what sorting compares, and render draws the cell.

app/deployments/page.tsx+10-1tsx
Added: import { Table, type SortState, type TableColumn } from "@textjs/next";Added: Added: const COLUMNS: TableColumn<Deployment>[] = [Added:   { key: "status", header: "Status", width: 11, render: (d) => <Status status={d.status} /> },Added:   { key: "commit", header: "Commit", grow: 2 },Added:   { key: "project", header: "Project", width: 10 },Added:   { key: "duration", header: "Build", width: 6, align: "right", value: (d) => d.duration, render: (d) => <Text>{`${d.duration}s`}</Text> },Added: ];export default function DeploymentsPage() {Added:   const [sort, setSort] = useState<SortState | null>(null);  …Removed:   return rows.map((d) => …);Added:   return <Table columns={COLUMNS} rows={rows} getRowKey={(d) => d.id} sortable sort={sort} onSortChange={setSort} autoFocus />;}

With focus on the table, ↑ ↓ move the highlight, s cycles the sort column, S flips the direction and Enter calls onSelect. Long tables only paint the visible rows.

A chart above it

<Sparkline> fills its box with the most recent points. <BarChart> aligns labels and values for you.

app/deployments/page.tsx+15tsx
Added: import { BarChart, Sparkline } from "@textjs/next";Added: Added:   const [chart, setChart] = useState<"spark" | "bars">("spark");Added:   useInput((e) => {Added:     if (e.input === "c") setChart((c) => (c === "spark" ? "bars" : "spark"));Added:   });Added:   return (    <Box className="flex-col grow gap-1">Added:       <Box className="flex-col" height={4}>Added:         <Text color="subtle">Build time, last 24 deployments</Text>Added:         {chart === "spark" ? (Added:           <Sparkline data={buildTimes} height={3} color="accent" />Added:         ) : (Added:           <BarChart data={byProject} formatValue={(v) => `${v}s`} />Added:         )}Added:       </Box>      <Table … />    </Box>  );

The chart box has a fixed height, so switching charts never moves the table, and the table rows are not re-encoded or logged.

More components

<List>, <Tree>, <Tabs>, <Select>, <Input>, <Modal>, <Toaster>, <CommandPalette>, <ProgressBar>, <LineChart> and more are documented under Components.

Try it

This is Acme Deploys at the end of the chapter, running in DevTools. Click the pad, then use the keys below.

▼ 07 · Table, List & Charts

Open the console

⌘⌥J
CtrlShiftJ

The app renders in DevTools. Then click here and press s.

↑↓rowsSsortCchart

Open on a desktop

This demo renders in the Chrome DevTools console, which needs a desktop browser.

Quiz

2 questions

Answer every question to complete the chapter.

With a sortable Table focused, what does s do?

 

Why give the chart box a fixed height?