react-vector-pdf 0.3.8 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -14,16 +14,18 @@
14
14
  - **Auto-Paging**: Content that exceeds the page height automatically moves to the next page.
15
15
  - **Flow & Absolute Positioning**: Stack elements naturally or place them at fixed coordinates.
16
16
  - **Advanced Components**:
17
- - **PdfTable**: Supports auto-wrapping, **row spans**, **col spans**, **vertical alignment**, custom cell styling, and **intelligent page breaking** (keeps spanned rows together).
17
+ - **PdfTable**: Supports auto-wrapping, **row spans**, **col spans**, **vertical alignment**, custom cell styling, **striped rows**, and **intelligent page breaking** (keeps spanned rows together).
18
18
  - **PdfImage**: Renders images from URLs with options for flow or absolute positioning. Automatically handles page breaks in flow mode.
19
19
  - **PdfList**: Bullet and numbered lists with auto-wrapping.
20
- - **PdfView/PdfBox**: Container components with support for borders, background colors, and granular **padding/margin** (e.g., `paddingTop`, `marginBottom`).
20
+ - **PdfView**: Container components with support for borders, background colors, and granular **padding/margin** (e.g., `paddingTop`, `marginBottom`).
21
21
  - **Global Document Options**:
22
- - **Formatting**: A4, Letter, distinct margins, base fonts.
23
- - **Headers & Footers**: Custom render functions.
22
+ - **Formatting**: A4, Letter, custom sizes, portrait/landscape orientation, distinct margins, base fonts.
23
+ - **Headers & Footers**: Custom render functions with full control.
24
24
  - **Page Numbering**: Highly configurable (presets, templates, scopes, formats like Roman/Arabic).
25
25
  - **Center Labels**: Watermarks or classification labels in header/footer.
26
26
  - **Metadata**: Set PDF title, author, subject, and keywords.
27
+ - **Recurring Elements**: Make any component appear on all pages or specific pages using `showInAllPages` and `scope`.
28
+ - **TypeScript**: Written in TypeScript with complete type definitions.
27
29
 
28
30
  ## Installation
29
31
 
@@ -48,10 +50,18 @@ const MyPdf = () => {
48
50
  <PdfDocument
49
51
  onReady={handleSave}
50
52
  options={{
53
+ format: "a4", // or "letter", or [width, height] in mm
54
+ orientation: "p", // "p" for portrait, "l" for landscape
51
55
  margin: { top: 20, right: 15, bottom: 15, left: 15 },
52
- font: { size: 12, name: "helvetica" }, // default font
56
+ font: { size: 12, name: "helvetica" },
53
57
  lineHeight: 1.25,
54
58
  }}
59
+ metadata={{
60
+ title: "My Document",
61
+ author: "Your Name",
62
+ subject: "Document Subject",
63
+ keywords: ["pdf", "react"],
64
+ }}
55
65
  >
56
66
  <PdfText fontSize={18} fontStyle="bold" spacingBelow={10}>
57
67
  Hello World
@@ -82,14 +92,28 @@ import { PdfPreview, PdfText } from "react-vector-pdf";
82
92
  - `height` (string | number): Height of the container (default "100%").
83
93
  - `className` / `style`: Styling for the wrapper div.
84
94
  - `iframeClassName` / `iframeStyle`: Styling for the internal iframe.
85
- 83:
86
- 84: **Note:** Changing props (like options, colors, fonts) will automatically regenerate and update the preview.
87
- 85:
88
- 86: ## Components
95
+
96
+ **Note:** Changing props (like options, colors, fonts) will automatically regenerate and update the preview.
89
97
 
90
98
  ## Components
91
99
 
92
- ### 1. `PdfText`
100
+ ### 1. `PdfDocument`
101
+
102
+ The main wrapper component that provides context and handles PDF generation.
103
+
104
+ **Props:**
105
+
106
+ - `options`: PDF configuration (format, margins, fonts, etc.)
107
+ - `metadata`: Document metadata (title, author, subject, keywords)
108
+ - `header`: Custom header render function `(renderer, page, total) => void`
109
+ - `footer`: Custom footer render function `(renderer, page, total) => void`
110
+ - `pageNumbers`: Page numbering configuration
111
+ - `centerLabel`: Center label/watermark configuration
112
+ - `onReady`: Callback when PDF is ready `(renderer) => void`
113
+ - `filename`: Filename for auto-save
114
+ - `autoSave`: Automatically save PDF when rendered (default: false)
115
+
116
+ ### 2. `PdfText`
93
117
 
94
118
  Renders a paragraph of text. Automatically wraps to the content width.
95
119
 
@@ -97,10 +121,12 @@ Renders a paragraph of text. Automatically wraps to the content width.
97
121
 
98
122
  - `fontSize` (number): Font size in points.
99
123
  - `fontStyle` ('normal' | 'bold' | 'italic' | 'bolditalic'): Font style.
100
- - `color` (string): Hex color code (e.g., "#FF0000").
124
+ - `color` (string): Hex color (e.g., "#FF0000") or RGBA (e.g., "rgba(255, 0, 0, 0.5)").
101
125
  - `align` ('left' | 'center' | 'right' | 'justify'): Text alignment.
102
126
  - `lineHeight` (number): Line height multiplier.
103
127
  - `spacingBelow` (number): Vertical space (mm) to add after the paragraph.
128
+ - `showInAllPages` (boolean): Make this text appear on multiple pages.
129
+ - `scope` ('all' | 'first-only' | 'except-first' | number[]): Which pages to show on.
104
130
 
105
131
  ```tsx
106
132
  <PdfText
@@ -111,10 +137,17 @@ Renders a paragraph of text. Automatically wraps to the content width.
111
137
  spacingBelow={5}
112
138
  >
113
139
  I am a centered, bold heading.
114
- </PdfText>
140
+ </PdfText>;
141
+
142
+ {
143
+ /* Recurring header on all pages except first */
144
+ }
145
+ <PdfText showInAllPages scope="except-first" fontSize={10} color="#666">
146
+ Document Header
147
+ </PdfText>;
115
148
  ```
116
149
 
117
- ### 2. `PdfTable`
150
+ ### 3. `PdfTable`
118
151
 
119
152
  A robust table component designed for dynamic data.
120
153
 
@@ -125,6 +158,8 @@ A robust table component designed for dynamic data.
125
158
  - **Page Breaking**: Smartly handles page breaks, ensuring rows with rowspans are kept together if possible.
126
159
  - **Styling**: Supports granular padding (`paddingTop`, `paddingLeft`, etc.) and borders.
127
160
  - **Alignment**: Supports both horizontal (`align`) and vertical (`verticalAlign`) alignment.
161
+ - **Striped Rows**: Alternating row colors for better readability.
162
+ - **Header Repeat**: Optionally repeat header row on each page.
128
163
 
129
164
  **Props:**
130
165
 
@@ -134,12 +169,18 @@ A robust table component designed for dynamic data.
134
169
  - `borderWidth`, `borderColor`: Global table border settings.
135
170
  - `headerStyle`, `rowStyle`: Default styles for headers and rows.
136
171
  - `cellPadding`: Default padding for cells (number or object).
172
+ - `striped` (boolean): Enable alternating row colors.
173
+ - `repeatHeader` (boolean): Repeat header on each page (default: true).
137
174
 
138
175
  **Complex Cell Example:**
139
176
 
140
177
  ```tsx
141
178
  <PdfTable
142
179
  width="100%"
180
+ striped={true}
181
+ repeatHeader={true}
182
+ borderWidth={0.5}
183
+ headerStyle={{ fillColor: "#f3f4f6", fontStyle: "bold" }}
143
184
  columns={[
144
185
  { header: "ID", accessor: "id", width: 10 },
145
186
  { header: "Description", accessor: "desc", width: "auto" },
@@ -151,7 +192,7 @@ A robust table component designed for dynamic data.
151
192
 
152
193
  // Row with Spans and Custom Styles
153
194
  {
154
- id: "2", // Simple cell
195
+ id: "2",
155
196
  desc: {
156
197
  content: "I span 2 rows and am vertically centered",
157
198
  rowSpan: 2,
@@ -170,7 +211,7 @@ A robust table component designed for dynamic data.
170
211
  />
171
212
  ```
172
213
 
173
- ### 3. `PdfImage`
214
+ ### 4. `PdfImage`
174
215
 
175
216
  Embed images (JPEG/PNG).
176
217
 
@@ -180,26 +221,42 @@ Embed images (JPEG/PNG).
180
221
  - `x`, `y` (number): Optional fixed coordinates. If omitted, uses **flow layout**.
181
222
  - `w`, `h` (number): Explicit dimensions. If only one is provided, aspect ratio is maintained.
182
223
  - `align` ('left' | 'center' | 'right'): Horizontal alignment (flow mode only).
183
- - `flow` (boolean): Force flow mode if necessary.
224
+ - `layout` ('fixed' | 'flow'): Layout mode (default: 'fixed').
225
+ - `sizing` ('fit' | 'fill' | 'auto'): How to size the image (default: 'fit').
226
+ - `showInAllPages` (boolean): Make this image appear on multiple pages.
227
+ - `scope` ('all' | 'first-only' | 'except-first' | number[]): Which pages to show on.
184
228
 
185
229
  **Flow Behavior**: In flow mode, if an image is too tall for the remaining page space, it will automatically trigger a page break and render on the next page.
186
230
 
187
231
  ```tsx
188
- <PdfImage src="https://example.com/logo.png" h={20} align="center" />
232
+ {
233
+ /* Flow layout with auto-sizing */
234
+ }
235
+ <PdfImage
236
+ src="https://example.com/logo.png"
237
+ h={20}
238
+ align="center"
239
+ layout="flow"
240
+ sizing="fit"
241
+ />;
242
+
243
+ {
244
+ /* Recurring logo on all pages */
245
+ }
246
+ <PdfImage src="logo.png" h={15} showInAllPages scope="all" x={10} y={10} />;
189
247
  ```
190
248
 
191
- ### 4. `PdfView` & `PdfBox`
249
+ ### 5. `PdfView`
192
250
 
193
- Containers for grouping content, adding borders, backgrounds, or margins/padding.
251
+ A container component for grouping content, adding borders, backgrounds, or margins/padding. It is the primary container for both flow and absolute layouts.
194
252
 
195
- `PdfView` is akin to a block-level `div`, and `PdfBox` is similar but allows explicit positioning.
196
-
197
- **Styling Support:**
253
+ **Props:**
198
254
 
199
- - `margin` / `padding`: Shorthand (number or object `{top, right...}`).
200
- - **Granular Props**: `marginTop`, `marginBottom`, `paddingLeft`, `paddingRight`, etc.
201
- - `borderWidth`, `borderColor`: Draw borders.
202
- - `fillColor`: Background color.
255
+ - `style`: Object with `margin`, `padding` (granular: `marginTop`, `paddingLeft` etc.), `borderWidth`, `borderColor`, `fillColor`, `radius`.
256
+ - `x`, `y`, `w`, `h`: Optional props for **absolute positioning**. If provided, the view will be placed at exactly these coordinates.
257
+ - `children`: Nested components to render inside the view.
258
+ - `showInAllPages` (boolean): Make this view appear on multiple pages.
259
+ - `scope` ('all' | 'first-only' | 'except-first' | number[]): Which pages to show on.
203
260
 
204
261
  ```tsx
205
262
  <PdfView
@@ -209,13 +266,14 @@ Containers for grouping content, adding borders, backgrounds, or margins/padding
209
266
  padding: 5,
210
267
  borderWidth: 0.2,
211
268
  borderColor: "#ccc",
269
+ fillColor: "rgba(240, 240, 240, 0.5)",
212
270
  }}
213
271
  >
214
272
  <PdfText>Content inside a styled box.</PdfText>
215
273
  </PdfView>
216
274
  ```
217
275
 
218
- ### 5. `PdfList`
276
+ ### 6. `PdfList`
219
277
 
220
278
  Renders bulleted or numbered lists.
221
279
 
@@ -233,7 +291,7 @@ Renders bulleted or numbered lists.
233
291
  ordered={true}
234
292
  indent={10}
235
293
  spacing={3}
236
- items={["First item", "Second item"]}
294
+ items={["First item", "Second item", "Third item"]}
237
295
  />
238
296
  ```
239
297
 
@@ -250,10 +308,13 @@ Automatically adds page numbers to every page (or specific pages) with full cust
250
308
  pageNumbers={{
251
309
  enabled: true,
252
310
  position: "footer", // 'header' | 'footer'
253
- align: "right",
254
- format: "page-slash-total", // 'Page 1/10', '1/10', 'Page 1 of 10'
255
- scope: "except-first", // 'all' | 'first-only' | 'except-first' | 'custom'
256
- template: "Pg {page} / {total}", // Custom template support
311
+ align: "right", // 'left' | 'center' | 'right'
312
+ preset: "page-slash-total", // 'Page 1/10', '1/10', 'Page 1 of 10'
313
+ scope: "except-first", // 'all' | 'first-only' | 'except-first' | [2,3,5]
314
+ template: "Pg {page} / {total}", // Custom template (overrides preset)
315
+ format: "arabic", // 'arabic' | 'roman-upper' | 'roman-lower'
316
+ y: 285, // Custom Y position (optional)
317
+ offsetX: 0, // X offset from alignment (optional)
257
318
  style: { fontSize: 9, color: "#666" }
258
319
  }}
259
320
  >
@@ -268,13 +329,171 @@ Adds a centered label (e.g., "CONFIDENTIAL") to the header or footer area.
268
329
  centerLabel={{
269
330
  enabled: true,
270
331
  text: "CONFIDENTIAL",
271
- position: "header",
272
- scope: "all",
332
+ position: "header", // 'header' | 'footer'
333
+ scope: "all", // 'all' | 'first-only' | 'except-first' | [2,3,5]
334
+ y: 10, // Custom Y position (optional)
335
+ offsetX: 0, // X offset (optional)
273
336
  style: { color: "red", fontSize: 12 }
274
337
  }}
275
338
  >
276
339
  ```
277
340
 
341
+ ### Custom Headers & Footers
342
+
343
+ For complete control, use custom render functions:
344
+
345
+ ```tsx
346
+ <PdfDocument
347
+ header={(renderer, page, total) => {
348
+ const pdf = renderer.instance;
349
+
350
+ // Set font and color
351
+ pdf.setFontSize(10);
352
+ pdf.setTextColor("#333");
353
+
354
+ // Draw custom header
355
+ pdf.text("My Company", renderer.contentLeft, 10);
356
+ pdf.text(`Page ${page}`, renderer.contentRight, 10, { align: 'right' });
357
+
358
+ // Draw a line
359
+ pdf.setDrawColor("#e5e7eb");
360
+ pdf.setLineWidth(0.5);
361
+ pdf.line(renderer.contentLeft, 12, renderer.contentRight, 12);
362
+ }}
363
+ footer={(renderer, page, total) => {
364
+ const pdf = renderer.instance;
365
+ const y = renderer.height - 10;
366
+
367
+ pdf.setFontSize(9);
368
+ pdf.setTextColor("#666");
369
+ pdf.text("© 2024 My Company", renderer.contentLeft, y);
370
+ }}
371
+ >
372
+ ```
373
+
374
+ ### Metadata
375
+
376
+ Set PDF document metadata for better organization and searchability:
377
+
378
+ ```tsx
379
+ <PdfDocument
380
+ metadata={{
381
+ title: "Annual Report 2024",
382
+ author: "John Doe",
383
+ subject: "Financial Analysis",
384
+ keywords: ["finance", "report", "2024", "analysis"]
385
+ }}
386
+ >
387
+ ```
388
+
389
+ ### Page Format & Orientation
390
+
391
+ Configure page size and orientation:
392
+
393
+ ```tsx
394
+ <PdfDocument
395
+ options={{
396
+ format: "a4", // "a4", "letter", or custom [width, height] in mm
397
+ orientation: "p", // "p" for portrait, "l" for landscape
398
+ margin: { top: 20, right: 15, bottom: 15, left: 15 },
399
+ }}
400
+ >
401
+
402
+ {/* Custom page size */}
403
+ <PdfDocument
404
+ options={{
405
+ format: [210, 297], // Custom size in mm (width, height)
406
+ orientation: "p",
407
+ }}
408
+ >
409
+ ```
410
+
411
+ ## Advanced Features
412
+
413
+ ### Recurring Items
414
+
415
+ Make any component appear on multiple pages using `showInAllPages` and `scope`:
416
+
417
+ ```tsx
418
+ {
419
+ /* Appear on all pages */
420
+ }
421
+ <PdfText showInAllPages scope="all">
422
+ This appears on every page
423
+ </PdfText>;
424
+
425
+ {
426
+ /* Appear on all pages except the first */
427
+ }
428
+ <PdfImage
429
+ src="logo.png"
430
+ showInAllPages
431
+ scope="except-first"
432
+ x={10}
433
+ y={10}
434
+ h={15}
435
+ />;
436
+
437
+ {
438
+ /* Appear only on first page */
439
+ }
440
+ <PdfView showInAllPages scope="first-only">
441
+ <PdfText>Cover page content</PdfText>
442
+ </PdfView>;
443
+
444
+ {
445
+ /* Appear on specific pages */
446
+ }
447
+ <PdfText showInAllPages scope={[2, 3, 5]}>
448
+ This appears only on pages 2, 3, and 5
449
+ </PdfText>;
450
+ ```
451
+
452
+ ### RGBA Color Support
453
+
454
+ All color props support both hex and RGBA formats:
455
+
456
+ ```tsx
457
+ <PdfText color="#FF0000">Red text</PdfText>
458
+ <PdfText color="rgba(255, 0, 0, 0.5)">Semi-transparent red text</PdfText>
459
+
460
+ <PdfView style={{ fillColor: "rgba(0, 0, 255, 0.1)" }}>
461
+ <PdfText>Content with semi-transparent blue background</PdfText>
462
+ </PdfView>
463
+ ```
464
+
465
+ ### Auto-Save
466
+
467
+ Automatically save the PDF when it's generated:
468
+
469
+ ```tsx
470
+ <PdfDocument filename="my-document.pdf" autoSave={true}>
471
+ {/* PDF will automatically download when rendered */}
472
+ </PdfDocument>
473
+ ```
474
+
475
+ ## TypeScript Support
476
+
477
+ This library is written in TypeScript and includes complete type definitions. All components and props are fully typed for the best developer experience.
478
+
479
+ ```tsx
480
+ import { PdfDocument, PdfText, PdfDocumentProps } from "react-vector-pdf";
481
+
482
+ const MyComponent: React.FC = () => {
483
+ const pdfOptions: PdfDocumentProps["options"] = {
484
+ format: "a4",
485
+ orientation: "p",
486
+ margin: { top: 20, right: 15, bottom: 15, left: 15 },
487
+ };
488
+
489
+ return (
490
+ <PdfDocument options={pdfOptions}>
491
+ <PdfText>Fully typed!</PdfText>
492
+ </PdfDocument>
493
+ );
494
+ };
495
+ ```
496
+
278
497
  ## License
279
498
 
280
499
  MIT
package/dist/index.d.ts CHANGED
@@ -47,16 +47,6 @@ export declare interface PageNumberOptions {
47
47
 
48
48
  export declare type PageNumberPreset = "page-slash-total" | "slash" | "page-of-total";
49
49
 
50
- export declare const PdfBox: default_2.FC<PdfBoxProps>;
51
-
52
- declare interface PdfBoxProps extends BoxStyle {
53
- x?: number;
54
- y?: number;
55
- w?: number;
56
- h?: number;
57
- children?: default_2.ReactNode;
58
- }
59
-
60
50
  export declare const PdfDocument: default_2.FC<PdfDocumentProps>;
61
51
 
62
52
  declare interface PdfDocumentProps {
@@ -89,7 +79,11 @@ declare interface PdfImageProps {
89
79
  h?: number;
90
80
  mime?: "PNG" | "JPEG";
91
81
  flow?: boolean;
82
+ layout?: "fixed" | "flow";
83
+ sizing?: "fit" | "fill" | "auto";
92
84
  align?: "left" | "center" | "right";
85
+ showInAllPages?: boolean;
86
+ scope?: "all" | "first-only" | "except-first" | number[];
93
87
  }
94
88
 
95
89
  export declare const PdfList: default_2.FC<PdfListProps>;
@@ -150,6 +144,7 @@ export declare class PdfRenderer {
150
144
  private pendingTasks;
151
145
  private opQueue;
152
146
  private generation;
147
+ private recurringItems;
153
148
  constructor(opts?: PDFOptions);
154
149
  get instance(): jsPDF;
155
150
  get width(): number;
@@ -201,6 +196,12 @@ export declare class PdfRenderer {
201
196
  y: number;
202
197
  };
203
198
  getPageCount(): number;
199
+ registerRecurringItem(item: {
200
+ draw: () => void;
201
+ scope: any;
202
+ y: number;
203
+ height: number;
204
+ }): void;
204
205
  applyHeaderFooter(): void;
205
206
  measureText(text: string, style?: TextStyle, maxWidth?: number): {
206
207
  width: number;
@@ -234,6 +235,8 @@ declare interface PdfTableProps {
234
235
  rowStyle?: TextStyle & BoxStyle;
235
236
  alternateRowStyle?: TextStyle & BoxStyle;
236
237
  headerHeight?: number;
238
+ repeatHeader?: boolean;
239
+ striped?: boolean;
237
240
  }
238
241
 
239
242
  export declare const PdfText: default_2.FC<PdfTextProps>;
@@ -252,6 +255,10 @@ declare interface PdfViewProps {
252
255
  style?: ViewStyle;
253
256
  children?: default_2.ReactNode;
254
257
  debug?: boolean;
258
+ x?: number;
259
+ y?: number;
260
+ w?: number;
261
+ h?: number;
255
262
  }
256
263
 
257
264
  declare interface TableColumn {
@@ -269,6 +276,8 @@ export declare interface TextStyle {
269
276
  align?: Align;
270
277
  verticalAlign?: "top" | "middle" | "bottom";
271
278
  lineHeight?: number;
279
+ showInAllPages?: boolean;
280
+ scope?: "all" | "first-only" | "except-first" | number[];
272
281
  }
273
282
 
274
283
  export declare interface ViewStyle extends BoxStyle {
@@ -284,6 +293,8 @@ export declare interface ViewStyle extends BoxStyle {
284
293
  marginLeft?: number;
285
294
  width?: number | string;
286
295
  height?: number;
296
+ showInAllPages?: boolean;
297
+ scope?: "all" | "first-only" | "except-first" | number[];
287
298
  }
288
299
 
289
300
  export { }