Skip to content

feat(viewer): add datatable content type — sortable, CSV export + copy to Sheets/Excel#178

Merged
ivanmkc merged 1 commit into
masterfrom
feat/datatable-type
Jun 11, 2026
Merged

feat(viewer): add datatable content type — sortable, CSV export + copy to Sheets/Excel#178
ivanmkc merged 1 commit into
masterfrom
feat/datatable-type

Conversation

@ivanmkc

@ivanmkc ivanmkc commented Jun 11, 2026

Copy link
Copy Markdown
Owner

What

A new first-class datatable content type: a clean, sortable table for tabular data the human will read precisely or pull into a spreadsheet — with one-click Copy (→ Excel / Google Sheets) and Download CSV.

Requested: "add a datatable type, where I can export to CSV (or equivalent) and copy-paste directly to Excel, google sheets, etc." Chosen interactivity: sortable columns (no search/pagination in v1).

Schema

{
  "title": "Cloud spend by service",
  "columns": ["Service", "Region", { "label": "Monthly (USD)", "align": "right" }, "Owner"],
  "rows": [["Compute Engine", "us-central1", 18420, "platform"], ...],
  "note": "USD, excludes committed-use discounts."
}
  • columns: string[] or {label, align?}[]. A column with all-numeric cells auto right-aligns.
  • rows: (string|number|boolean|null)[][]; short rows render blank cells.

Behavior

  • Sortable — click a header to cycle asc → desc → unsorted (numeric collation, nulls last; ▲/▼ + aria-sort).
  • Copy → TSV on the clipboard (Excel/Sheets read TSV natively — columns land right, no import step).
  • Download CSV → RFC-4180 file named from the title. Both exports reflect the current sort order.
  • Plain DOM (no React); self-sizing, horizontally scrollable, sticky header, zebra rows. Works standalone and inside panes.

Wiring (mirrors the calltree type)

  • Shared structural validation in core validateContent (validateDataTable, path-pointed) → flows through push/patch/restore + panes recursion; CLI fast-fails offline once republished.
  • Lazy chunk registered in registry.ts; themed in style.css.
  • Recipe cost-table.datatable.json + datatable.md + SKILL/command decision-guide entries.
  • Gallery image + GALLERY.md row; seeded finops/cloud-spend demo board on /w/demo/.

Verification

  • Unit npx vitest run444/444 (new datatable.test.ts: validation + toCSV/toTSV/parse/compareCells, all pure).
  • Build exit 0; new datatable-*.js chunk emits; NUL-byte check clean.
  • e2e test:e2e:nobuild → rich 62/62 (datatable: render 8 rows + header-sort + clipboard-TSV round-trip + CSV download), board-sort 12/12.
  • Visual rendered the example at desktop + iPad — alignment, sort indicator, toolbar, note all correct (screenshot below).

Viewer renders it on deploy; recipe-docs reach plugin installs and --type datatable via the installed CLI on their (user-gated) republish — pushing via the viewer/raw HTTP works immediately.

datatable

…t + copy to Sheets/Excel

A new first-class content type for tabular data the human will read precisely or
pull into a spreadsheet (cost breakdowns, benchmark results, query results).

- **Schema:** `{ title?, columns, rows, note? }` — `columns` is `string[]` or
  `{label, align?}[]`; `rows` is `(string|number|boolean|null)[][]`. Columns with
  all-numeric cells auto right-align.
- **Renderer** (`datatable.ts`, plain DOM — no React): a sortable table (click a
  header to cycle asc→desc→unsorted; numeric collation; nulls last) with a toolbar:
  **Copy** writes TSV to the clipboard (pastes cleanly into Excel/Google Sheets) and
  **Download CSV** saves an RFC-4180 file. Both reflect the current sort order.
  Self-sizing, horizontally scrollable, sticky header, zebra rows.
- **Validation** added to the shared core `validateContent` (path-pointed), so it
  flows through every push/patch/restore path and through `panes` recursion, and the
  CLI fast-fails offline once republished.
- Registered as a lazy chunk in `registry.ts`; themed in `style.css`.
- Recipe (`cost-table.datatable.json`) + `datatable.md` + SKILL/command decision-guide
  entries; gallery image + GALLERY.md row; a seeded `finops/cloud-spend` demo board.

Tests: `datatable.test.ts` (validation + toCSV/toTSV/parse/compareCells, all pure/
node-safe); rich e2e pushes a datatable and asserts render + header-sort + clipboard
TSV round-trip + CSV download.
@ivanmkc ivanmkc merged commit 250e2b2 into master Jun 11, 2026
5 checks passed
@ivanmkc ivanmkc deleted the feat/datatable-type branch June 11, 2026 14:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants