page.mdx 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. export const metadata = { title: "@json-render/react-pdf API" }
  2. # @json-render/react-pdf
  3. PDF document renderer. Turn JSON specs into PDFs using `@react-pdf/renderer`.
  4. ## Install
  5. ```bash
  6. npm install @json-render/core @json-render/react-pdf
  7. ```
  8. See the [React PDF example](https://github.com/vercel-labs/json-render/tree/main/examples/react-pdf) for a full working example.
  9. ## schema
  10. The PDF element schema for document specs. Use with `defineCatalog` from core.
  11. ```typescript
  12. import { defineCatalog } from '@json-render/core';
  13. import { schema, standardComponentDefinitions } from '@json-render/react-pdf';
  14. const catalog = defineCatalog(schema, {
  15. components: standardComponentDefinitions,
  16. });
  17. ```
  18. ## Render Functions
  19. Server-side functions for producing PDF output. All accept a spec and optional `RenderOptions`.
  20. ```typescript
  21. import { renderToBuffer, renderToStream, renderToFile } from '@json-render/react-pdf';
  22. const buffer = await renderToBuffer(spec);
  23. const stream = await renderToStream(spec);
  24. stream.pipe(res);
  25. await renderToFile(spec, './output.pdf');
  26. ```
  27. ### RenderOptions
  28. ```typescript
  29. interface RenderOptions {
  30. registry?: ComponentRegistry;
  31. includeStandard?: boolean; // default: true
  32. state?: Record<string, unknown>;
  33. }
  34. ```
  35. <table>
  36. <thead>
  37. <tr>
  38. <th>Option</th>
  39. <th>Description</th>
  40. </tr>
  41. </thead>
  42. <tbody>
  43. <tr>
  44. <td><code>registry</code></td>
  45. <td>Custom component map (merged with standard components)</td>
  46. </tr>
  47. <tr>
  48. <td><code>includeStandard</code></td>
  49. <td>Include built-in standard components (default: <code>true</code>)</td>
  50. </tr>
  51. <tr>
  52. <td><code>state</code></td>
  53. <td>Initial state for <code>$state</code> / <code>$cond</code> dynamic prop resolution</td>
  54. </tr>
  55. </tbody>
  56. </table>
  57. ## defineRegistry
  58. Create a type-safe component registry from a catalog. Components receive `{ props, children, emit, bindings, loading }`.
  59. ```tsx
  60. import { defineRegistry } from '@json-render/react-pdf';
  61. import { View, Text } from '@react-pdf/renderer';
  62. const { registry } = defineRegistry(catalog, {
  63. components: {
  64. Badge: ({ props }) => (
  65. <View style={{ backgroundColor: props.color ?? '#e5e7eb', padding: 4, borderRadius: 4 }}>
  66. <Text style={{ fontSize: 10 }}>{props.label}</Text>
  67. </View>
  68. ),
  69. },
  70. });
  71. const buffer = await renderToBuffer(spec, { registry });
  72. ```
  73. ## createRenderer
  74. Create a standalone renderer component wired to state, actions, and validation.
  75. ```typescript
  76. import { createRenderer } from '@json-render/react-pdf';
  77. const PDFRenderer = createRenderer(catalog, components);
  78. ```
  79. ```typescript
  80. interface CreateRendererProps {
  81. spec: Spec | null;
  82. state?: Record<string, unknown>;
  83. onAction?: (actionName: string, params?: Record<string, unknown>) => void;
  84. onStateChange?: (path: string, value: unknown) => void;
  85. loading?: boolean;
  86. fallback?: ComponentRenderer;
  87. }
  88. ```
  89. ## Renderer
  90. The main component that renders a spec to `@react-pdf/renderer` elements.
  91. ```typescript
  92. interface RendererProps {
  93. spec: Spec | null;
  94. registry?: ComponentRegistry;
  95. includeStandard?: boolean; // default: true
  96. loading?: boolean;
  97. fallback?: ComponentRenderer;
  98. }
  99. ```
  100. ## Standard Components
  101. ### Document Structure
  102. #### Document
  103. Top-level PDF wrapper. Must be the root element. Children must be `Page` components.
  104. ```typescript
  105. {
  106. title: string | null;
  107. author: string | null;
  108. subject: string | null;
  109. }
  110. ```
  111. #### Page
  112. A page in the document with configurable size, orientation, and margins.
  113. ```typescript
  114. {
  115. size: "A4" | "A3" | "A5" | "LETTER" | "LEGAL" | "TABLOID" | null;
  116. orientation: "portrait" | "landscape" | null;
  117. marginTop: number | null;
  118. marginBottom: number | null;
  119. marginLeft: number | null;
  120. marginRight: number | null;
  121. backgroundColor: string | null;
  122. }
  123. ```
  124. ### Layout
  125. #### View
  126. Generic container with padding, margin, background, border, and flex alignment.
  127. ```typescript
  128. {
  129. padding: number | null;
  130. paddingTop: number | null;
  131. paddingBottom: number | null;
  132. paddingLeft: number | null;
  133. paddingRight: number | null;
  134. margin: number | null;
  135. backgroundColor: string | null;
  136. borderWidth: number | null;
  137. borderColor: string | null;
  138. borderRadius: number | null;
  139. flex: number | null;
  140. alignItems: "flex-start" | "center" | "flex-end" | "stretch" | null;
  141. justifyContent: "flex-start" | "center" | "flex-end" | "space-between" | "space-around" | null;
  142. }
  143. ```
  144. #### Row
  145. Horizontal flex layout with optional wrapping.
  146. ```typescript
  147. {
  148. gap: number | null;
  149. alignItems: "flex-start" | "center" | "flex-end" | "stretch" | null;
  150. justifyContent: "flex-start" | "center" | "flex-end" | "space-between" | "space-around" | null;
  151. padding: number | null;
  152. flex: number | null;
  153. wrap: boolean | null;
  154. }
  155. ```
  156. #### Column
  157. Vertical flex layout.
  158. ```typescript
  159. {
  160. gap: number | null;
  161. alignItems: "flex-start" | "center" | "flex-end" | "stretch" | null;
  162. justifyContent: "flex-start" | "center" | "flex-end" | "space-between" | "space-around" | null;
  163. padding: number | null;
  164. flex: number | null;
  165. }
  166. ```
  167. ### Content
  168. #### Heading
  169. h1-h4 heading text with configurable color and alignment.
  170. ```typescript
  171. {
  172. text: string;
  173. level: "h1" | "h2" | "h3" | "h4" | null;
  174. color: string | null;
  175. align: "left" | "center" | "right" | null;
  176. }
  177. ```
  178. #### Text
  179. Body text with full styling control.
  180. ```typescript
  181. {
  182. text: string;
  183. fontSize: number | null;
  184. color: string | null;
  185. align: "left" | "center" | "right" | null;
  186. fontWeight: "normal" | "bold" | null;
  187. fontStyle: "normal" | "italic" | null;
  188. lineHeight: number | null;
  189. }
  190. ```
  191. #### Image
  192. Image from a URL with optional dimensions and fit.
  193. ```typescript
  194. {
  195. src: string;
  196. width: number | null;
  197. height: number | null;
  198. objectFit: "contain" | "cover" | "fill" | "none" | null;
  199. }
  200. ```
  201. #### Link
  202. Hyperlink with visible text.
  203. ```typescript
  204. {
  205. text: string;
  206. href: string;
  207. fontSize: number | null;
  208. color: string | null;
  209. }
  210. ```
  211. ### Data
  212. #### Table
  213. Data table with typed columns and string rows. Supports header styling and striped rows.
  214. ```typescript
  215. {
  216. columns: { header: string; width?: string; align?: "left" | "center" | "right" }[];
  217. rows: string[][];
  218. headerBackgroundColor: string | null;
  219. headerTextColor: string | null;
  220. borderColor: string | null;
  221. fontSize: number | null;
  222. striped: boolean | null;
  223. }
  224. ```
  225. #### List
  226. Ordered or unordered list.
  227. ```typescript
  228. {
  229. items: string[];
  230. ordered: boolean | null;
  231. fontSize: number | null;
  232. color: string | null;
  233. spacing: number | null;
  234. }
  235. ```
  236. ### Decorative
  237. #### Divider
  238. Horizontal line separator.
  239. ```typescript
  240. {
  241. color: string | null;
  242. thickness: number | null;
  243. marginTop: number | null;
  244. marginBottom: number | null;
  245. }
  246. ```
  247. #### Spacer
  248. Empty vertical space.
  249. ```typescript
  250. {
  251. height: number | null;
  252. }
  253. ```
  254. ### Page-Level
  255. #### PageNumber
  256. Renders current page number and total pages. Format uses `{pageNumber}` and `{totalPages}` placeholders.
  257. ```typescript
  258. {
  259. format: string | null; // default: "{pageNumber} / {totalPages}"
  260. fontSize: number | null;
  261. color: string | null;
  262. align: "left" | "center" | "right" | null;
  263. }
  264. ```
  265. ## Server-Safe Import
  266. Import schema and catalog definitions without pulling in React or `@react-pdf/renderer`:
  267. ```typescript
  268. import { schema, standardComponentDefinitions } from '@json-render/react-pdf/server';
  269. ```
  270. ## Sub-path Exports
  271. <table>
  272. <thead>
  273. <tr>
  274. <th>Export</th>
  275. <th>Description</th>
  276. </tr>
  277. </thead>
  278. <tbody>
  279. <tr>
  280. <td><code>@json-render/react-pdf</code></td>
  281. <td>Full package: schema, renderer, components, render functions</td>
  282. </tr>
  283. <tr>
  284. <td><code>@json-render/react-pdf/server</code></td>
  285. <td>Schema and catalog definitions only (no React)</td>
  286. </tr>
  287. <tr>
  288. <td><code>@json-render/react-pdf/catalog</code></td>
  289. <td>Standard component definitions and types</td>
  290. </tr>
  291. <tr>
  292. <td><code>@json-render/react-pdf/render</code></td>
  293. <td>Server-side render functions only</td>
  294. </tr>
  295. </tbody>
  296. </table>
  297. ## Types
  298. <table>
  299. <thead>
  300. <tr>
  301. <th>Export</th>
  302. <th>Description</th>
  303. </tr>
  304. </thead>
  305. <tbody>
  306. <tr>
  307. <td><code>ReactPdfSchema</code></td>
  308. <td>Schema type for PDF specs</td>
  309. </tr>
  310. <tr>
  311. <td><code>ReactPdfSpec</code></td>
  312. <td>Spec type for PDF documents</td>
  313. </tr>
  314. <tr>
  315. <td><code>RenderOptions</code></td>
  316. <td>Options for render functions</td>
  317. </tr>
  318. <tr>
  319. <td><code>ComponentContext</code></td>
  320. <td>Typed component render function context</td>
  321. </tr>
  322. <tr>
  323. <td><code>ComponentFn</code></td>
  324. <td>Component render function type</td>
  325. </tr>
  326. <tr>
  327. <td><code>StandardComponentDefinitions</code></td>
  328. <td>Type of the standard component definitions object</td>
  329. </tr>
  330. <tr>
  331. <td><code>StandardComponentProps&lt;K&gt;</code></td>
  332. <td>Inferred props type for a standard component by name</td>
  333. </tr>
  334. </tbody>
  335. </table>