Headers & footers
Repeat bands on every page with page counters.
header and footer accept any node input. They repeat on every page. Bands lay out at full page width and draw in the page margin areas, like Chromium's print templates. Pick a margin at least as tall as the band, or the band overlaps content, exactly as in Chromium.
import { } from "takumi-pdf";
const = await (, {
: (
< ="flex w-full justify-center text-[10px] text-gray-500">
Page < ="pageNumber" /> of < ="totalPages" />
</>
),
});Sizing the margin
A band draws in the page margin, so the margin has to be tall enough to hold it.
margin defaults to "auto", which measures the band and takes the space it needs.
import { } from "takumi-pdf";
const = await (, {
: (
< ="flex w-full justify-center text-[10px] text-gray-500">
Page < ="pageNumber" /> of < ="totalPages" />
</>
),
});An "auto" side comes out at the band height plus the 20px bands are inset from
the paper edge, and never below the 37.8px a page starts with. A short band
leaves the page looking as it did before. Set a side to a number to size it yourself,
and leave out the sides you are happy with:
const margin = { top: 96 };Left and right hold no band. "auto" there is that same 37.8px.
To size a margin yourself, measure lays out a tree the way render measures a
band: full page width, counter hooks filled with three-digit numbers. Leave the
20px inset on top of the height it returns.
import { } from "takumi-pdf";
const { } = await (, { : "a4" });Passing viewport instead of a page size measures the tree as-is. Counter hooks stay empty.
Page counters
Text and container nodes classed pageNumber or totalPages receive counter text. The counter replaces what the node holds, so an empty <span /> is enough. Chromium's print templates use the same two names.
| Class | Value |
|---|---|
pageNumber | The current page, counting from 1 |
totalPages | The number of pages in the document |
A node carrying both classes gets the page number.
Counters outside a band
A hook fills wherever it sits. A fixed box repeats on every page, so it lays out again for each one and its counters count with it. A component can carry its own footer that way, instead of passing one to render.
<div style={{ position: "fixed", bottom: 24, left: 24, right: 24 }}>
Page <span className="pageNumber" /> of <span className="totalPages" />
</div>A fixed box draws over the content rather than in the margin, so leave it room. margin sizes itself to the header and footer alone.
A hook in the page content names the page it lands on, which is what a cover page counting the report's length needs. One laid out inline has no box of its own, so it reads the box that holds it and the flow that closed before it, and takes whichever page is later. Content that paints nowhere, such as a box scaled to zero, closes no flow to read. Content counters lay the document out a second time, since the page a hook sits on is only known once the content is cut into pages, and a document without one pays nothing.
Counter styles
Add a CSS @counter-style name next to the hook class. It formats the number. The first supported name wins. Unsupported names are ignored, and a hook without one counts in decimal.
import { } from "takumi-pdf";
const = await (, {
: (
< ={{ : 12 }}>
第 < ="pageNumber trad-chinese-informal" /> 頁,共{" "}
< ="totalPages trad-chinese-informal" /> 頁
</>
),
});Numbers and numerals
| Style | Page 7 | Page 12 |
|---|---|---|
decimal (default) | 7 | 12 |
decimal-leading-zero | 07 | 12 |
lower-roman | vii | xii |
upper-roman | VII | XII |
cjk-decimal | 七 | 一二 |
trad-chinese-informal | 七 | 十二 |
cjk-ideographic | 七 | 十二 |
Blink defines cjk-ideographic as an extension of trad-chinese-informal, and this renderer follows it. Both read out numbers up to 9999. Past that they fall back to cjk-decimal, so page 10000 formats as 一零零零零.
Alphabets
These styles count the way a spreadsheet names its columns. The letter after z is aa.
| Style | Page 12 |
|---|---|
lower-alpha, lower-latin | l |
upper-alpha, upper-latin | L |
lower-greek | μ |
hiragana | し |
katakana | シ |
Other digits
These styles write the decimal number in another script's digits.
| Style | Page 12 | Style | Page 12 |
|---|---|---|---|
arabic-indic | ١٢ | mongolian | ᠑᠒ |
bengali | ১২ | myanmar | ၁၂ |
cambodian | ១២ | oriya | ୧୨ |
devanagari | १२ | persian | ۱۲ |
gujarati | ૧૨ | tamil | ௧௨ |
gurmukhi | ੧੨ | telugu | ౧౨ |
kannada | ೧೨ | thai | ๑๒ |
khmer | ១២ | tibetan | ༡༢ |
lao | ໑໒ | urdu | ۱۲ |
malayalam | ൧൨ |
khmer and cambodian share their digits, as do persian and urdu.
A registered font has to cover the digits of the style you pick. Latin fonts rarely carry Thai or Tibetan numerals, so pair a script style with a font that has the glyphs.
Band height
Band height is measured once with three-digit counters. Reaching 100 pages does not shift the layout between pages.
Last updated on