TableLast updated on
Last updated on
A list field as rows, with a header that repeats on every page it continues onto.
Table is the one component whose header can outlive its own page: when a
table's rows continue past a page break, the page plan copies its header
onto the next page so the columns stay legible, and marks that copy
data-keep-repeat so it is never confused with the header's one real place
in the flow. A continuedLabel reads on that copy alone; a footer
evaluates rows from the artifact's own definitions and stays with the
table's last row; and a column's render can replace one cell's plain text
with markup of its own, without changing how the row paginates.
Preview
Installation
npx shadcn@4 add @paradoc/tableOr, with the Paradoc CLI, which writes the namespace into components.json for you:
npx paradoc-cli add tableInstalls to components/paradoc/table.tsx and brings along keep-together.
Usage
import { Table } from "@/components/paradoc/table";<Table path="lineItems" columns={[{ field: "description" }, { field: "amount", align: "right" }]}/>| Prop | Type | Default | Description |
|---|---|---|---|
| path | string | — | Path to the list field this table reads its rows from. |
| columns | readonly TableColumn[] | — | Column definitions: each names a list-item field, its header, width, and alignment. |
| id? | string | — | Prefix for the header's and each row's pagination id; falls back to path. |
| className? | string | — | Classes for the table's wrapping element. |
| continuedLabel? | string | — | Shown on the repeated header when the table continues onto a later page, never on the first. Kept to one line. |
| footer? | readonly TableFooterRow[] | — | Footer rows evaluated from the artifact's definitions; the page plan never opens a page on them without the table's last row. |
Composition
A Table needs the same Document context every
other component here does, and its path names a list field in the
artifact — the same convention Field uses, just pointed at an array.
Each columns entry
names one field of the list's items and gets a Tailwind basis-* share of
the row's width, so together they should sum to the whole row rather than
leave columns floating loose.
Table renders as flex rows, not <table> markup, because the default PDF
engine has no table support: a document using real table markup on screen
could not be the same tree the PDF renders. What it brings along is
Keep Together for both
the header row and every data row — each is its own pagination unit — which
is also what makes header repetition possible: the plan can place a copy of
the header keep wherever a continued row needs one.
A Table normally lives inside a Section alongside
the Fields around it, though nothing requires
that — the Preview above renders one directly inside Document.
The header's size follows the document's typography token; the cells inherit the root's.
Variants
Table's columns each take a field, an optional header override, a
width, and an align.
Compact
A two-column subset of the same lineItems table.
Left-aligned
Every column left-aligned, instead of the default's right-aligned numeric ones.
Custom headers
header overrides the artifact's own field labels.
Continued
continuedLabel shows on the repeated header once the table's rows carry it
past a page break, and only there — the table's own, first header never
shows it. This variant is the page's only one that self-wraps in
Pages: every other table on this page fits one page,
which is exactly where the label has nothing to show.
Footer
footer takes rows shaped like Totals's: a def,
an optional label, and emphasis. Each is evaluated from the artifact's
own definitions and printed as one more keep after the last row. When the
footer does not fit on the last row's page, the last row moves to the next
page with it, so the totals never print without a row above them.
Cell renderer
A column's render receives the cell's already-formatted text and the row
it belongs to, and returns the markup to print instead. The row underneath
still paginates as one unit.