Documentation
Components
Every component maps to one engine element, and its props are typed - <Text :size :color bold>
autocompletes and type-checks, and a wrong value (say a fit that does not exist) goes red in your
editor. Boolean props have a shorthand: <Text bold> is <Text :bold="true">.
The full set:
Document · Page · Column · Row · Box · Padding · Expanded · Spacer · Divider ·
Image · Text · Paragraph · Span · Table / TableRow / TableCell · Positioned ·
DefaultTextStyle.
Structure
Document
The root of every PDF component. Its text props (font, size, color, lineHeight, align, bold,
italic) set the document-wide defaults that everything inside inherits.
| Prop | Type |
|---|---|
size, color, font, bold, italic | default text style |
align, lineHeight | default paragraph style |
meta | { title?, author? } |
fonts | custom fonts, see Data & assets |
Page
One physical page. Lays its children out as a column, so gap, justify and align work here too.
| Prop | Type |
|---|---|
size | "A4", "Letter", ... or a custom size |
orientation | "portrait" | "landscape" |
margin | a number, or per-side insets |
gap | space between children |
justify | "start" | "center" | "end" | "between" | "around" |
align | "start" | "center" | "end" | "stretch" |
<Page> also takes #header and #footer slots. They are laid out once and repeat on every physical
page the content flows onto:
<template>
<Document>
<Page :size="'A4'" :margin="48">
<template #header>
<Text :size="9" color="#94a3b8">ACME GmbH - Invoice</Text>
</template>
<Text>... long content that paginates across pages ...</Text>
<template #footer>
<Row :justify="'between'">
<Text :size="9" color="#94a3b8">acme.example</Text>
<Text :size="9" color="#94a3b8">Page footer</Text>
</Row>
</template>
</Page>
</Document>
</template>
Layout
Column and Row
Stack children vertically (Column) or horizontally (Row). Both share gap, justify and align.
<template>
<Row :gap="12" :justify="'between'" :align="'center'">
<Text bold>Item</Text>
<Text>Value</Text>
</Row>
</template>
Box
A sized, decorated container: background, border, padding, rounded corners.
| Prop | Type |
|---|---|
bg, border | a color |
borderTop / borderRight / borderBottom / borderLeft, borderWidth | per-side border control |
padding | a number, or per-side insets |
width, height, radius | numbers (points) |
relative | make it a positioning frame |
overflow | "hidden" clips children to the box |
Padding, Spacer, Expanded, Divider
<Padding :insets="16">- wraps a child in space (a number or per-side insets).<Spacer :flex="1">- flexible empty space that pushes siblings apart.<Expanded :flex="1">- a flex child that fills the remaining main-axis space.<Divider color="#e2e8f0" :thickness="1" />- a rule line.
Text
Text, Paragraph and Span
Text and Paragraph render text; Span styles a run inside them.
| Prop | Type |
|---|---|
size, font, color | the basics |
bold, italic | boolean shorthands |
align | "left" | "center" | "right" |
lineHeight | line spacing multiplier |
maxLines, overflow | overflow is "clip" | "ellipsis" |
<template>
<Paragraph>
Plain text, then a <Span bold color="#1450aa">styled run</Span> in the middle.
</Paragraph>
</template>
bold and italic are left unset by default, so a <Text> inside a bold <DefaultTextStyle> stays
bold unless you override it. <DefaultTextStyle> re-defaults the text style for a whole subtree, the
per-section counterpart to the <Document> defaults.
Image
<template>
<Image :src="bytes" :width="120" :height="120" :fit="'contain'" :radius="8" />
</template>
fit is "none", "contain", "cover" or "fill". src takes image bytes (a Uint8Array); see
Data & assets for loading them in the browser.
Table
<Table :columns> holds <TableRow>s of <TableCell>s. Mark a row header to repeat it on every page
the table paginates onto. Columns are widths: a number is fixed points, a string like "1fr" is a
flexible share.
<template>
<Table :columns="['1fr', 120]" cell-border="#e2e8f0" :cell-padding="9">
<TableRow header>
<TableCell><Text bold>Description</Text></TableCell>
<TableCell><Text bold>Amount</Text></TableCell>
</TableRow>
<TableRow v-for="line in lines" :key="line.id">
<TableCell
><Text>{{ line.name }}</Text></TableCell
>
<TableCell
><Text>{{ line.total }} EUR</Text></TableCell
>
</TableRow>
</Table>
</template>
Table also takes gap / rowGap / colGap, cellPadding, cellBorder and a rule color.
Positioned
Out-of-flow placement, anchored to the nearest <Box relative> (or the page). Give it edges
(top / right / bottom / left) or an alignment (h / v) plus an x / y offset.
<template>
<Box relative :height="200">
<Positioned :top="8" :right="8">
<Text :size="9" color="#94a3b8">draft</Text>
</Positioned>
</Box>
</template>