hazo_pdf 1.1.0 → 1.2.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 +158 -6
- package/dist/{chunk-2POHPGR3.js → chunk-S3AJUZ7D.js} +33 -1
- package/dist/chunk-S3AJUZ7D.js.map +1 -0
- package/dist/index.d.ts +84 -1
- package/dist/index.js +449 -129
- package/dist/index.js.map +1 -1
- package/dist/{pdf_saver-D2H5SLPN.js → pdf_saver-P2MJN45S.js} +2 -2
- package/dist/styles/full.css +2352 -0
- package/dist/styles/full.css.map +1 -0
- package/dist/styles/index.css +159 -401
- package/dist/styles/index.css.map +1 -1
- package/package.json +3 -2
- package/dist/chunk-2POHPGR3.js.map +0 -1
- /package/dist/{pdf_saver-D2H5SLPN.js.map → pdf_saver-P2MJN45S.js.map} +0 -0
package/README.md
CHANGED
|
@@ -19,6 +19,47 @@ A React component library for viewing and annotating PDF documents with support
|
|
|
19
19
|
npm install hazo_pdf
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
+
## CSS Import Options
|
|
23
|
+
|
|
24
|
+
The library provides two CSS files to choose from:
|
|
25
|
+
|
|
26
|
+
### For apps with existing styles (Recommended)
|
|
27
|
+
|
|
28
|
+
Use `styles.css` - this does NOT include Tailwind preflight/base resets, so it won't interfere with your existing styles:
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
import 'hazo_pdf/styles.css';
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### For standalone apps
|
|
35
|
+
|
|
36
|
+
Use `styles-full.css` - includes Tailwind preflight/base styles for apps without existing CSS resets:
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
import 'hazo_pdf/styles-full.css';
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Container Requirements
|
|
43
|
+
|
|
44
|
+
The PDF viewer requires its parent container to have explicit dimensions:
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
// Good - explicit dimensions
|
|
48
|
+
<div style={{ width: '100%', height: '600px' }}>
|
|
49
|
+
<PdfViewer url="/document.pdf" />
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
// Bad - no explicit height
|
|
53
|
+
<div>
|
|
54
|
+
<PdfViewer url="/document.pdf" />
|
|
55
|
+
</div>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Requirements:**
|
|
59
|
+
- Parent must have explicit `width` and `height` (CSS or inline style)
|
|
60
|
+
- Recommended minimum size: 400x400px
|
|
61
|
+
- Parent should NOT have `overflow: hidden` (the viewer handles its own scrolling)
|
|
62
|
+
|
|
22
63
|
## Quick Start
|
|
23
64
|
|
|
24
65
|
```tsx
|
|
@@ -307,7 +348,7 @@ function ProductionViewer() {
|
|
|
307
348
|
<div style={{ flex: 1, overflow: 'hidden' }}>
|
|
308
349
|
<PdfViewer
|
|
309
350
|
url="/api/documents/contract.pdf"
|
|
310
|
-
config_file="hazo_pdf_config.ini"
|
|
351
|
+
config_file="config/hazo_pdf_config.ini"
|
|
311
352
|
className="h-full w-full"
|
|
312
353
|
scale={initialScale}
|
|
313
354
|
annotations={annotations}
|
|
@@ -327,7 +368,7 @@ function ProductionViewer() {
|
|
|
327
368
|
```
|
|
328
369
|
|
|
329
370
|
**Features demonstrated:**
|
|
330
|
-
- Configuration file integration (`hazo_pdf_config.ini`)
|
|
371
|
+
- Configuration file integration (`config/hazo_pdf_config.ini`)
|
|
331
372
|
- Custom stamps with styling
|
|
332
373
|
- Timestamp and fixed text suffixes
|
|
333
374
|
- Responsive scaling based on screen size
|
|
@@ -340,7 +381,7 @@ function ProductionViewer() {
|
|
|
340
381
|
|
|
341
382
|
## Configuration File
|
|
342
383
|
|
|
343
|
-
The PDF viewer can be configured via an INI file (default: `hazo_pdf_config.ini`). This allows you to customize styling, colors, fonts, and behavior without modifying code.
|
|
384
|
+
The PDF viewer can be configured via an INI file (default: `config/hazo_pdf_config.ini`). This allows you to customize styling, colors, fonts, and behavior without modifying code.
|
|
344
385
|
|
|
345
386
|
**Basic setup:**
|
|
346
387
|
|
|
@@ -357,11 +398,18 @@ freetext_background_opacity = 0.1
|
|
|
357
398
|
freetext_border_color = #003366
|
|
358
399
|
freetext_border_width = 1
|
|
359
400
|
|
|
401
|
+
[toolbar]
|
|
402
|
+
toolbar_background_color = rgb(240, 248, 255)
|
|
403
|
+
toolbar_font_color = rgb(30, 58, 138)
|
|
404
|
+
toolbar_button_background_color = rgb(219, 234, 254)
|
|
405
|
+
toolbar_button_text_color = rgb(30, 64, 175)
|
|
406
|
+
toolbar_button_save_background_color = rgb(34, 197, 94)
|
|
407
|
+
|
|
360
408
|
[context_menu]
|
|
361
409
|
right_click_custom_stamps = [{"name":"Verified","text":"✅","order":1,"time_stamp_suffix_enabled":true,"fixed_text_suffix_enabled":true}]
|
|
362
410
|
```
|
|
363
411
|
|
|
364
|
-
See `hazo_pdf_config.ini` in the project root for all available configuration options.
|
|
412
|
+
See `config/hazo_pdf_config.ini` in the project root for all available configuration options.
|
|
365
413
|
|
|
366
414
|
---
|
|
367
415
|
|
|
@@ -384,7 +432,7 @@ See `hazo_pdf_config.ini` in the project root for all available configuration op
|
|
|
384
432
|
| `className` | `string` | `""` | Additional CSS classes to apply to the viewer container. |
|
|
385
433
|
| `scale` | `number` | `1.0` | Initial zoom level. Values > 1.0 zoom in, < 1.0 zoom out. |
|
|
386
434
|
| `background_color` | `string` | `"#2d2d2d"` | Background color for areas outside PDF pages (hex format: `#RRGGBB`). Overrides config file value. |
|
|
387
|
-
| `config_file` | `string` | `undefined` | Path to configuration INI file (e.g., `"hazo_pdf_config.ini"`). If not provided, uses default configuration. |
|
|
435
|
+
| `config_file` | `string` | `undefined` | Path to configuration INI file (e.g., `"config/hazo_pdf_config.ini"`). If not provided, uses default configuration. |
|
|
388
436
|
|
|
389
437
|
##### Event Callbacks
|
|
390
438
|
|
|
@@ -462,12 +510,50 @@ const stamps = JSON.stringify([
|
|
|
462
510
|
}
|
|
463
511
|
]);
|
|
464
512
|
|
|
465
|
-
<PdfViewer
|
|
513
|
+
<PdfViewer
|
|
466
514
|
url="/document.pdf"
|
|
467
515
|
right_click_custom_stamps={stamps}
|
|
468
516
|
/>
|
|
469
517
|
```
|
|
470
518
|
|
|
519
|
+
##### Toolbar Visibility
|
|
520
|
+
|
|
521
|
+
Props to control toolbar button visibility. These override config file values.
|
|
522
|
+
|
|
523
|
+
| Prop | Type | Default | Description |
|
|
524
|
+
|------|------|---------|-------------|
|
|
525
|
+
| `toolbar_enabled` | `boolean` | `true` | Master toggle to show/hide the entire toolbar. |
|
|
526
|
+
| `show_zoom_controls` | `boolean` | `true` | Show zoom in/out/reset buttons. |
|
|
527
|
+
| `show_square_button` | `boolean` | `true` | Show square annotation button. |
|
|
528
|
+
| `show_undo_button` | `boolean` | `true` | Show undo button. |
|
|
529
|
+
| `show_redo_button` | `boolean` | `true` | Show redo button. |
|
|
530
|
+
| `show_save_button` | `boolean` | `true` | Show save button. |
|
|
531
|
+
| `show_metadata_button` | `boolean` | `true` | Show metadata panel button (only visible when `sidepanel_metadata_enabled` is true). |
|
|
532
|
+
| `on_close` | `() => void` | `undefined` | Callback when close button is clicked. When provided, shows a close button (X) in the toolbar. Useful for modal/dialog usage. |
|
|
533
|
+
|
|
534
|
+
**Example - Minimal toolbar:**
|
|
535
|
+
|
|
536
|
+
```tsx
|
|
537
|
+
<PdfViewer
|
|
538
|
+
url="/document.pdf"
|
|
539
|
+
toolbar_enabled={true}
|
|
540
|
+
show_zoom_controls={true}
|
|
541
|
+
show_square_button={false}
|
|
542
|
+
show_undo_button={false}
|
|
543
|
+
show_redo_button={false}
|
|
544
|
+
show_save_button={false}
|
|
545
|
+
/>
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
**Example - Dialog with close button:**
|
|
549
|
+
|
|
550
|
+
```tsx
|
|
551
|
+
<PdfViewer
|
|
552
|
+
url="/document.pdf"
|
|
553
|
+
on_close={() => setDialogOpen(false)}
|
|
554
|
+
/>
|
|
555
|
+
```
|
|
556
|
+
|
|
471
557
|
### PdfAnnotation Interface
|
|
472
558
|
|
|
473
559
|
Represents a PDF annotation in the standard PDF coordinate space.
|
|
@@ -497,6 +583,72 @@ Type from `pdfjs-dist`. Contains PDF metadata and page proxies.
|
|
|
497
583
|
|
|
498
584
|
---
|
|
499
585
|
|
|
586
|
+
## Toolbar Configuration
|
|
587
|
+
|
|
588
|
+
The toolbar can be fully customized via the `[toolbar]` section in the configuration file. You can configure:
|
|
589
|
+
|
|
590
|
+
- **Colors**: Background, border, font, and button colors (background, hover, active, save)
|
|
591
|
+
- **Fonts**: Font family and size for toolbar text
|
|
592
|
+
- **Visibility**: Show/hide individual button groups (zoom, square, undo, redo, save)
|
|
593
|
+
- **Labels**: Customize all button labels and text
|
|
594
|
+
|
|
595
|
+
**All toolbar settings with defaults:**
|
|
596
|
+
|
|
597
|
+
| Setting | Type | Default | Description |
|
|
598
|
+
|---------|------|---------|-------------|
|
|
599
|
+
| `toolbar_background_color` | Color | `#f9fafb` | Toolbar background color |
|
|
600
|
+
| `toolbar_border_color` | Color | `#e5e7eb` | Toolbar border color |
|
|
601
|
+
| `toolbar_font_family` | String | `system-ui, -apple-system, sans-serif` | Font family for toolbar |
|
|
602
|
+
| `toolbar_font_size` | Number | `14` | Font size in pixels |
|
|
603
|
+
| `toolbar_font_color` | Color | `#111827` | Text color for toolbar |
|
|
604
|
+
| `toolbar_button_background_color` | Color | `#ffffff` | Regular button background |
|
|
605
|
+
| `toolbar_button_background_color_hover` | Color | `#f3f4f6` | Button hover background |
|
|
606
|
+
| `toolbar_button_text_color` | Color | `#374151` | Button text color |
|
|
607
|
+
| `toolbar_button_active_background_color` | Color | `#3b82f6` | Active button background |
|
|
608
|
+
| `toolbar_button_active_text_color` | Color | `#ffffff` | Active button text color |
|
|
609
|
+
| `toolbar_button_save_background_color` | Color | `#10b981` | Save button background |
|
|
610
|
+
| `toolbar_button_save_background_color_hover` | Color | `#059669` | Save button hover background |
|
|
611
|
+
| `toolbar_button_save_text_color` | Color | `#ffffff` | Save button text color |
|
|
612
|
+
| `toolbar_button_disabled_opacity` | Number | `0.5` | Opacity for disabled buttons (0.0-1.0) |
|
|
613
|
+
| `toolbar_show_zoom_controls` | Boolean | `true` | Show zoom controls |
|
|
614
|
+
| `toolbar_show_square_button` | Boolean | `true` | Show square annotation button |
|
|
615
|
+
| `toolbar_show_undo_button` | Boolean | `true` | Show undo button |
|
|
616
|
+
| `toolbar_show_redo_button` | Boolean | `true` | Show redo button |
|
|
617
|
+
| `toolbar_show_save_button` | Boolean | `true` | Show save button |
|
|
618
|
+
| `toolbar_show_metadata_button` | Boolean | `true` | Show metadata panel button (only shown when sidepanel is enabled) |
|
|
619
|
+
| `toolbar_zoom_out_label` | String | `"−"` | Zoom out button label |
|
|
620
|
+
| `toolbar_zoom_in_label` | String | `"+"` | Zoom in button label |
|
|
621
|
+
| `toolbar_zoom_reset_label` | String | `"Reset"` | Reset zoom button label |
|
|
622
|
+
| `toolbar_square_label` | String | `"Square"` | Square button label |
|
|
623
|
+
| `toolbar_undo_label` | String | `"Undo"` | Undo button label |
|
|
624
|
+
| `toolbar_redo_label` | String | `"Redo"` | Redo button label |
|
|
625
|
+
| `toolbar_save_label` | String | `"Save"` | Save button label |
|
|
626
|
+
| `toolbar_saving_label` | String | `"Saving..."` | Saving button label |
|
|
627
|
+
| `toolbar_metadata_label` | String | `"Metadata"` | Metadata panel button label |
|
|
628
|
+
|
|
629
|
+
**Example configuration:**
|
|
630
|
+
|
|
631
|
+
```ini
|
|
632
|
+
[toolbar]
|
|
633
|
+
# Customize colors
|
|
634
|
+
toolbar_background_color = rgb(240, 248, 255)
|
|
635
|
+
toolbar_border_color = rgb(59, 130, 246)
|
|
636
|
+
toolbar_font_color = rgb(30, 58, 138)
|
|
637
|
+
toolbar_button_background_color = rgb(219, 234, 254)
|
|
638
|
+
toolbar_button_text_color = rgb(30, 64, 175)
|
|
639
|
+
toolbar_button_active_background_color = rgb(37, 99, 235)
|
|
640
|
+
toolbar_button_save_background_color = rgb(34, 197, 94)
|
|
641
|
+
|
|
642
|
+
# Hide some controls
|
|
643
|
+
toolbar_show_redo_button = false
|
|
644
|
+
toolbar_show_square_button = false
|
|
645
|
+
toolbar_show_metadata_button = false
|
|
646
|
+
|
|
647
|
+
# Customize labels
|
|
648
|
+
toolbar_save_label = Save PDF
|
|
649
|
+
toolbar_undo_label = ← Undo
|
|
650
|
+
```
|
|
651
|
+
|
|
500
652
|
## Toolbar Controls
|
|
501
653
|
|
|
502
654
|
The PDF viewer includes a toolbar at the top with the following controls:
|
|
@@ -73,6 +73,38 @@ var default_config = {
|
|
|
73
73
|
dialog_button_cancel_color: "#6b7280",
|
|
74
74
|
dialog_button_cancel_color_hover: "#4b5563",
|
|
75
75
|
dialog_button_disabled_opacity: 0.4
|
|
76
|
+
},
|
|
77
|
+
toolbar: {
|
|
78
|
+
toolbar_background_color: "#f9fafb",
|
|
79
|
+
toolbar_border_color: "#e5e7eb",
|
|
80
|
+
toolbar_font_family: "system-ui, -apple-system, sans-serif",
|
|
81
|
+
toolbar_font_size: 14,
|
|
82
|
+
toolbar_font_color: "#111827",
|
|
83
|
+
toolbar_button_background_color: "#ffffff",
|
|
84
|
+
toolbar_button_background_color_hover: "#f3f4f6",
|
|
85
|
+
toolbar_button_text_color: "#374151",
|
|
86
|
+
toolbar_button_active_background_color: "#3b82f6",
|
|
87
|
+
toolbar_button_active_text_color: "#ffffff",
|
|
88
|
+
toolbar_button_save_background_color: "#10b981",
|
|
89
|
+
toolbar_button_save_background_color_hover: "#059669",
|
|
90
|
+
toolbar_button_save_text_color: "#ffffff",
|
|
91
|
+
toolbar_button_disabled_opacity: 0.5,
|
|
92
|
+
toolbar_show_zoom_controls: true,
|
|
93
|
+
toolbar_show_square_button: true,
|
|
94
|
+
toolbar_show_undo_button: true,
|
|
95
|
+
toolbar_show_redo_button: true,
|
|
96
|
+
toolbar_show_save_button: true,
|
|
97
|
+
toolbar_show_metadata_button: true,
|
|
98
|
+
toolbar_show_annotate_button: true,
|
|
99
|
+
toolbar_zoom_out_label: "\u2212",
|
|
100
|
+
toolbar_zoom_in_label: "+",
|
|
101
|
+
toolbar_zoom_reset_label: "Reset",
|
|
102
|
+
toolbar_square_label: "Square",
|
|
103
|
+
toolbar_undo_label: "Undo",
|
|
104
|
+
toolbar_redo_label: "Redo",
|
|
105
|
+
toolbar_save_label: "Save",
|
|
106
|
+
toolbar_saving_label: "Saving...",
|
|
107
|
+
toolbar_metadata_label: "Metadata"
|
|
76
108
|
}
|
|
77
109
|
};
|
|
78
110
|
|
|
@@ -280,4 +312,4 @@ export {
|
|
|
280
312
|
download_pdf,
|
|
281
313
|
save_and_download_pdf
|
|
282
314
|
};
|
|
283
|
-
//# sourceMappingURL=chunk-
|
|
315
|
+
//# sourceMappingURL=chunk-S3AJUZ7D.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config/default_config.ts","../src/utils/pdf_saver.ts"],"sourcesContent":["/**\n * Default configuration values for hazo_pdf\n * All styling defaults organized by category\n */\n\nimport type { PdfViewerConfig } from '../types/config';\n\n/**\n * Default PDF Viewer Configuration\n * These values are used when no config file is provided or when values are missing\n */\nexport const default_config: PdfViewerConfig = {\n fonts: {\n freetext_font_family: 'Arial, sans-serif',\n freetext_font_size_min: 12,\n freetext_font_size_max: 24,\n freetext_font_size_default: 14,\n font_foreground_color: '#000000', // Black by default\n },\n\n highlight_annotation: {\n highlight_fill_color: '#FFFF00',\n highlight_fill_opacity: 0.3,\n highlight_border_color: '#FFD700',\n highlight_border_color_hover: '#FFD700',\n highlight_fill_opacity_hover: 0.4,\n },\n\n square_annotation: {\n square_fill_color: '#FF0000',\n square_fill_opacity: 0.2,\n square_border_color: '#FF0000',\n square_border_color_hover: '#CC0000',\n square_fill_opacity_hover: 0.3,\n },\n\n freetext_annotation: {\n freetext_text_color: '#000000',\n freetext_text_color_hover: '#000000',\n freetext_border_color: '#003366',\n freetext_border_width: 1,\n freetext_background_color: '#E6F3FF',\n freetext_background_opacity: 0.1,\n freetext_font_weight: 'normal',\n freetext_font_style: 'normal',\n freetext_text_decoration: 'none',\n freetext_padding_horizontal: 4,\n freetext_padding_vertical: 2,\n },\n\n page_styling: {\n page_border_color: '#999999',\n page_box_shadow: '0 2px 8px rgba(0, 0, 0, 0.3)',\n page_background_color: '#ffffff',\n },\n\n viewer: {\n viewer_background_color: '#2d2d2d',\n append_timestamp_to_text_edits: false,\n annotation_text_suffix_fixed_text: '',\n add_enclosing_brackets_to_suffixes: true,\n suffix_enclosing_brackets: '[]',\n suffix_text_position: 'below_multi_line',\n },\n\n context_menu: {\n context_menu_background_color: '#ffffff',\n context_menu_border_color: '#d1d5db',\n context_menu_item_hover_background: '#f3f4f6',\n context_menu_item_disabled_opacity: 0.5,\n right_click_custom_stamps: '', // Empty string means no custom stamps\n },\n\n dialog: {\n dialog_backdrop_opacity: 0.2,\n dialog_background_color: '#ffffff',\n dialog_border_color: '#d1d5db',\n dialog_button_submit_color: '#16a34a',\n dialog_button_submit_color_hover: '#15803d',\n dialog_button_cancel_color: '#6b7280',\n dialog_button_cancel_color_hover: '#4b5563',\n dialog_button_disabled_opacity: 0.4,\n },\n\n toolbar: {\n toolbar_background_color: '#f9fafb',\n toolbar_border_color: '#e5e7eb',\n toolbar_font_family: 'system-ui, -apple-system, sans-serif',\n toolbar_font_size: 14,\n toolbar_font_color: '#111827',\n toolbar_button_background_color: '#ffffff',\n toolbar_button_background_color_hover: '#f3f4f6',\n toolbar_button_text_color: '#374151',\n toolbar_button_active_background_color: '#3b82f6',\n toolbar_button_active_text_color: '#ffffff',\n toolbar_button_save_background_color: '#10b981',\n toolbar_button_save_background_color_hover: '#059669',\n toolbar_button_save_text_color: '#ffffff',\n toolbar_button_disabled_opacity: 0.5,\n toolbar_show_zoom_controls: true,\n toolbar_show_square_button: true,\n toolbar_show_undo_button: true,\n toolbar_show_redo_button: true,\n toolbar_show_save_button: true,\n toolbar_show_metadata_button: true,\n toolbar_show_annotate_button: true,\n toolbar_zoom_out_label: '−',\n toolbar_zoom_in_label: '+',\n toolbar_zoom_reset_label: 'Reset',\n toolbar_square_label: 'Square',\n toolbar_undo_label: 'Undo',\n toolbar_redo_label: 'Redo',\n toolbar_save_label: 'Save',\n toolbar_saving_label: 'Saving...',\n toolbar_metadata_label: 'Metadata',\n },\n};\n","/**\n * PDF Saver Utility\n * Saves annotations directly into PDF documents using pdf-lib\n * This allows annotations to be embedded in the PDF file itself\n */\n\nimport type { PdfAnnotation, PdfViewerConfig } from '../types';\nimport { default_config } from '../config/default_config';\n\n/**\n * Save annotations into a PDF document\n * This function fetches the PDF, adds annotations, and downloads the modified PDF\n * @param pdf_url - URL of the PDF file\n * @param annotations - Array of annotations to save\n * @param output_filename - Name for the saved PDF file (default: original filename with '_annotated' suffix)\n * @param config - Optional configuration for styling values\n * @returns Promise that resolves when the PDF is saved\n */\nexport async function save_annotations_to_pdf(\n pdf_url: string,\n annotations: PdfAnnotation[],\n _output_filename?: string, // Currently unused, kept for API compatibility\n config?: PdfViewerConfig | null\n): Promise<Uint8Array> {\n try {\n // Dynamically import pdf-lib\n const { PDFDocument, rgb } = await import('pdf-lib');\n \n // Fetch the original PDF\n console.log('[PDF Saver] Fetching PDF from:', pdf_url);\n const pdf_response = await fetch(pdf_url);\n if (!pdf_response.ok) {\n throw new Error(`Failed to fetch PDF: ${pdf_response.status} ${pdf_response.statusText}`);\n }\n \n const pdf_bytes = await pdf_response.arrayBuffer();\n console.log('[PDF Saver] PDF fetched, size:', pdf_bytes.byteLength, 'bytes');\n \n // Load the PDF document\n const pdf_doc = await PDFDocument.load(pdf_bytes);\n console.log('[PDF Saver] PDF loaded, pages:', pdf_doc.getPageCount());\n \n // Get config values or use defaults\n const fonts_config = config?.fonts || default_config.fonts;\n const highlight_config = config?.highlight_annotation || default_config.highlight_annotation;\n const square_config = config?.square_annotation || default_config.square_annotation;\n const freetext_config = config?.freetext_annotation || default_config.freetext_annotation;\n \n // Add annotations to each page\n for (const annotation of annotations) {\n if (annotation.page_index >= pdf_doc.getPageCount()) {\n console.warn(`[PDF Saver] Annotation ${annotation.id} references page ${annotation.page_index}, but PDF only has ${pdf_doc.getPageCount()} pages. Skipping.`);\n continue;\n }\n \n const page = pdf_doc.getPage(annotation.page_index);\n const [x1, y1, x2, y2] = annotation.rect;\n \n // PDF coordinate system: bottom-left is origin (pdfjs-dist)\n // pdf-lib uses bottom-left as origin too, so coordinates should be fine\n // But we need to ensure rect is normalized\n const rect_x = Math.min(x1, x2);\n const rect_y = Math.min(y1, y2);\n const rect_width = Math.abs(x2 - x1);\n const rect_height = Math.abs(y2 - y1);\n \n // Parse color (hex or rgb to RGB for pdf-lib)\n // Supports both hex (#RRGGBB) and rgb(r, g, b) formats\n let color = rgb(0, 0, 0); // Default black\n if (annotation.color) {\n const color_str = annotation.color.trim();\n \n // Handle rgb(r, g, b) format\n const rgb_pattern = /^rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/i;\n const rgb_match = color_str.match(rgb_pattern);\n if (rgb_match) {\n const r = parseInt(rgb_match[1], 10);\n const g = parseInt(rgb_match[2], 10);\n const b = parseInt(rgb_match[3], 10);\n // Validate RGB values (0-255) and convert to 0-1 range for pdf-lib\n if (r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255) {\n color = rgb(r / 255, g / 255, b / 255);\n } else {\n console.warn(`[PDF Saver] Invalid RGB values for annotation ${annotation.id}: r=${r}, g=${g}, b=${b}`);\n }\n } else if (color_str.startsWith('#')) {\n // Handle hex format (#RRGGBB)\n const hex = color_str.slice(1).trim();\n if (hex.length === 6 && /^[0-9A-Fa-f]{6}$/.test(hex)) {\n const r = parseInt(hex.substring(0, 2), 16) / 255;\n const g = parseInt(hex.substring(2, 4), 16) / 255;\n const b = parseInt(hex.substring(4, 6), 16) / 255;\n color = rgb(r, g, b);\n } else {\n console.warn(`[PDF Saver] Invalid hex color format for annotation ${annotation.id}: ${color_str}`);\n }\n } else {\n console.warn(`[PDF Saver] Unrecognized color format for annotation ${annotation.id}: ${color_str}`);\n }\n }\n \n // Create annotation based on type using pdf-lib's annotation methods\n try {\n switch (annotation.type) {\n case 'Square': {\n // Create a rectangle/square annotation\n page.drawRectangle({\n x: rect_x,\n y: rect_y,\n width: rect_width,\n height: rect_height,\n borderColor: color,\n borderWidth: 2,\n borderOpacity: 0.8,\n });\n \n // Add text comment if present\n if (annotation.contents) {\n const comment_color_str = (annotation.color || square_config.square_border_color).trim();\n let comment_r = 0, comment_g = 0, comment_b = 0;\n \n // Parse color (hex or rgb format)\n const rgb_pattern = /^rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/i;\n const rgb_match = comment_color_str.match(rgb_pattern);\n if (rgb_match) {\n comment_r = parseInt(rgb_match[1], 10) / 255;\n comment_g = parseInt(rgb_match[2], 10) / 255;\n comment_b = parseInt(rgb_match[3], 10) / 255;\n } else if (comment_color_str.startsWith('#')) {\n const hex = comment_color_str.slice(1).trim();\n if (hex.length === 6 && /^[0-9A-Fa-f]{6}$/.test(hex)) {\n comment_r = parseInt(hex.substring(0, 2), 16) / 255;\n comment_g = parseInt(hex.substring(2, 4), 16) / 255;\n comment_b = parseInt(hex.substring(4, 6), 16) / 255;\n }\n }\n \n page.drawText(annotation.contents, {\n x: rect_x,\n y: rect_y + rect_height + 5,\n size: fonts_config.freetext_font_size_default,\n color: rgb(comment_r, comment_g, comment_b),\n });\n }\n break;\n }\n \n case 'Highlight': {\n // Create a highlight annotation (semi-transparent rectangle)\n const highlight_color_str = (annotation.color || highlight_config.highlight_fill_color).trim();\n let highlight_r = 255 / 255, highlight_g = 255 / 255, highlight_b = 0 / 255; // Default yellow\n \n // Parse color (hex or rgb format)\n const rgb_pattern = /^rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/i;\n const rgb_match = highlight_color_str.match(rgb_pattern);\n if (rgb_match) {\n highlight_r = parseInt(rgb_match[1], 10) / 255;\n highlight_g = parseInt(rgb_match[2], 10) / 255;\n highlight_b = parseInt(rgb_match[3], 10) / 255;\n } else if (highlight_color_str.startsWith('#')) {\n const hex = highlight_color_str.slice(1).trim();\n if (hex.length === 6 && /^[0-9A-Fa-f]{6}$/.test(hex)) {\n highlight_r = parseInt(hex.substring(0, 2), 16) / 255;\n highlight_g = parseInt(hex.substring(2, 4), 16) / 255;\n highlight_b = parseInt(hex.substring(4, 6), 16) / 255;\n }\n }\n const highlight_color = rgb(highlight_r, highlight_g, highlight_b);\n \n page.drawRectangle({\n x: rect_x,\n y: rect_y,\n width: rect_width,\n height: rect_height,\n color: highlight_color,\n opacity: highlight_config.highlight_fill_opacity,\n });\n \n // Add text comment if present\n if (annotation.contents) {\n page.drawText(annotation.contents, {\n x: rect_x,\n y: rect_y + rect_height + 5,\n size: fonts_config.freetext_font_size_default,\n color: rgb(0, 0, 0),\n });\n }\n break;\n }\n \n case 'FreeText': {\n // Create a free text annotation\n if (annotation.contents) {\n // Text color priority: annotation.color > freetext_text_color > font_foreground_color > default black\n const text_color_str = (annotation.color || \n freetext_config.freetext_text_color || \n fonts_config.font_foreground_color || \n '#000000').trim();\n let text_r = 0, text_g = 0, text_b = 0;\n \n // Parse color (hex or rgb format)\n const rgb_pattern = /^rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/i;\n const rgb_match = text_color_str.match(rgb_pattern);\n if (rgb_match) {\n text_r = parseInt(rgb_match[1], 10) / 255;\n text_g = parseInt(rgb_match[2], 10) / 255;\n text_b = parseInt(rgb_match[3], 10) / 255;\n } else if (text_color_str.startsWith('#')) {\n const hex = text_color_str.slice(1).trim();\n if (hex.length === 6 && /^[0-9A-Fa-f]{6}$/.test(hex)) {\n text_r = parseInt(hex.substring(0, 2), 16) / 255;\n text_g = parseInt(hex.substring(2, 4), 16) / 255;\n text_b = parseInt(hex.substring(4, 6), 16) / 255;\n }\n }\n \n page.drawText(annotation.contents, {\n x: rect_x,\n y: rect_y,\n size: fonts_config.freetext_font_size_default,\n color: rgb(text_r, text_g, text_b),\n maxWidth: rect_width,\n });\n }\n break;\n }\n \n default:\n console.warn(`[PDF Saver] Unsupported annotation type: ${annotation.type}`);\n }\n } catch (annotation_error) {\n console.error(`[PDF Saver] Error adding annotation ${annotation.id}:`, annotation_error);\n // Continue with other annotations\n }\n }\n \n // Save the PDF\n const modified_pdf_bytes = await pdf_doc.save();\n console.log('[PDF Saver] PDF modified, size:', modified_pdf_bytes.length, 'bytes');\n \n return modified_pdf_bytes;\n } catch (error) {\n if (error && typeof error === 'object' && 'message' in error && \n typeof error.message === 'string' && error.message.includes('pdf-lib')) {\n throw new Error('pdf-lib is required to save annotations to PDF. Please install it: npm install pdf-lib');\n }\n console.error('[PDF Saver] Error saving PDF:', error);\n throw error;\n }\n}\n\n/**\n * Download PDF bytes as a file\n * @param pdf_bytes - PDF file bytes\n * @param filename - Name for the downloaded file\n */\nexport function download_pdf(pdf_bytes: Uint8Array, filename: string): void {\n // Create a new ArrayBuffer view to ensure compatibility with Blob constructor\n // Uint8Array.buffer can be SharedArrayBuffer, which Blob doesn't accept directly\n const buffer = new Uint8Array(pdf_bytes).buffer;\n const blob = new Blob([buffer], { type: 'application/pdf' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = filename;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n}\n\n/**\n * Save annotations to PDF and download\n * @param pdf_url - URL of the PDF file\n * @param annotations - Array of annotations to save\n * @param output_filename - Name for the saved PDF file (default: original filename with '_annotated' suffix)\n * @param config - Optional configuration for styling values\n */\nexport async function save_and_download_pdf(\n pdf_url: string,\n annotations: PdfAnnotation[],\n output_filename?: string,\n config?: PdfViewerConfig | null\n): Promise<void> {\n const pdf_bytes = await save_annotations_to_pdf(pdf_url, annotations, output_filename, config);\n \n // Generate output filename\n const original_filename = pdf_url.split('/').pop() || 'document.pdf';\n const filename_without_ext = original_filename.replace(/\\.pdf$/i, '');\n const final_filename = output_filename || `${filename_without_ext}_annotated.pdf`;\n \n // Download the modified PDF\n download_pdf(pdf_bytes, final_filename);\n console.log('[PDF Saver] PDF saved as:', final_filename);\n}\n\n"],"mappings":"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","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -127,6 +127,68 @@ interface PdfViewerConfig {
|
|
|
127
127
|
/** Opacity for disabled dialog buttons (0.0 to 1.0) */
|
|
128
128
|
dialog_button_disabled_opacity: number;
|
|
129
129
|
};
|
|
130
|
+
toolbar: {
|
|
131
|
+
/** Background color for toolbar (hex format: #RRGGBB or rgb(r, g, b)) */
|
|
132
|
+
toolbar_background_color: string;
|
|
133
|
+
/** Border color for toolbar (hex format: #RRGGBB or rgb(r, g, b)) */
|
|
134
|
+
toolbar_border_color: string;
|
|
135
|
+
/** Font family for toolbar text */
|
|
136
|
+
toolbar_font_family: string;
|
|
137
|
+
/** Font size for toolbar text (pixels) */
|
|
138
|
+
toolbar_font_size: number;
|
|
139
|
+
/** Font color for toolbar text (hex format: #RRGGBB or rgb(r, g, b)) */
|
|
140
|
+
toolbar_font_color: string;
|
|
141
|
+
/** Button background color (hex format: #RRGGBB or rgb(r, g, b)) */
|
|
142
|
+
toolbar_button_background_color: string;
|
|
143
|
+
/** Button background color on hover (hex format: #RRGGBB or rgb(r, g, b)) */
|
|
144
|
+
toolbar_button_background_color_hover: string;
|
|
145
|
+
/** Button text color (hex format: #RRGGBB or rgb(r, g, b)) */
|
|
146
|
+
toolbar_button_text_color: string;
|
|
147
|
+
/** Active button background color (hex format: #RRGGBB or rgb(r, g, b)) */
|
|
148
|
+
toolbar_button_active_background_color: string;
|
|
149
|
+
/** Active button text color (hex format: #RRGGBB or rgb(r, g, b)) */
|
|
150
|
+
toolbar_button_active_text_color: string;
|
|
151
|
+
/** Save button background color (hex format: #RRGGBB or rgb(r, g, b)) */
|
|
152
|
+
toolbar_button_save_background_color: string;
|
|
153
|
+
/** Save button background color on hover (hex format: #RRGGBB or rgb(r, g, b)) */
|
|
154
|
+
toolbar_button_save_background_color_hover: string;
|
|
155
|
+
/** Save button text color (hex format: #RRGGBB or rgb(r, g, b)) */
|
|
156
|
+
toolbar_button_save_text_color: string;
|
|
157
|
+
/** Disabled button opacity (0.0 to 1.0) */
|
|
158
|
+
toolbar_button_disabled_opacity: number;
|
|
159
|
+
/** Whether to show zoom controls (true/false) */
|
|
160
|
+
toolbar_show_zoom_controls: boolean;
|
|
161
|
+
/** Whether to show square annotation button (true/false) */
|
|
162
|
+
toolbar_show_square_button: boolean;
|
|
163
|
+
/** Whether to show undo button (true/false) */
|
|
164
|
+
toolbar_show_undo_button: boolean;
|
|
165
|
+
/** Whether to show redo button (true/false) */
|
|
166
|
+
toolbar_show_redo_button: boolean;
|
|
167
|
+
/** Whether to show save button (true/false) */
|
|
168
|
+
toolbar_show_save_button: boolean;
|
|
169
|
+
/** Whether to show metadata panel button (true/false) */
|
|
170
|
+
toolbar_show_metadata_button: boolean;
|
|
171
|
+
/** Whether to show annotate (FreeText) button (true/false) */
|
|
172
|
+
toolbar_show_annotate_button: boolean;
|
|
173
|
+
/** Label for zoom out button (default: "−") */
|
|
174
|
+
toolbar_zoom_out_label: string;
|
|
175
|
+
/** Label for zoom in button (default: "+") */
|
|
176
|
+
toolbar_zoom_in_label: string;
|
|
177
|
+
/** Label for reset zoom button (default: "Reset") */
|
|
178
|
+
toolbar_zoom_reset_label: string;
|
|
179
|
+
/** Label for square annotation button (default: "Square") */
|
|
180
|
+
toolbar_square_label: string;
|
|
181
|
+
/** Label for undo button (default: "Undo") */
|
|
182
|
+
toolbar_undo_label: string;
|
|
183
|
+
/** Label for redo button (default: "Redo") */
|
|
184
|
+
toolbar_redo_label: string;
|
|
185
|
+
/** Label for save button (default: "Save") */
|
|
186
|
+
toolbar_save_label: string;
|
|
187
|
+
/** Label for saving button (default: "Saving...") */
|
|
188
|
+
toolbar_saving_label: string;
|
|
189
|
+
/** Label for metadata panel button (default: "Metadata") */
|
|
190
|
+
toolbar_metadata_label: string;
|
|
191
|
+
};
|
|
130
192
|
}
|
|
131
193
|
|
|
132
194
|
/**
|
|
@@ -160,7 +222,7 @@ interface PdfViewerProps {
|
|
|
160
222
|
on_save?: (pdf_bytes: Uint8Array, filename: string) => void;
|
|
161
223
|
/** Background color for areas outside PDF pages (default: dark grey) */
|
|
162
224
|
background_color?: string;
|
|
163
|
-
/** Optional path to configuration INI file (e.g., "hazo_pdf_config.ini") */
|
|
225
|
+
/** Optional path to configuration INI file (e.g., "config/hazo_pdf_config.ini") */
|
|
164
226
|
config_file?: string;
|
|
165
227
|
/** Whether to append timestamp to annotated text edits (default: false) */
|
|
166
228
|
append_timestamp_to_text_edits?: boolean;
|
|
@@ -181,6 +243,24 @@ interface PdfViewerProps {
|
|
|
181
243
|
updatedRow: MetadataDataItem;
|
|
182
244
|
allData: MetadataInput;
|
|
183
245
|
};
|
|
246
|
+
/** Whether to show the toolbar at all (default: true) */
|
|
247
|
+
toolbar_enabled?: boolean;
|
|
248
|
+
/** Whether to show zoom controls (default: true) */
|
|
249
|
+
show_zoom_controls?: boolean;
|
|
250
|
+
/** Whether to show square annotation button (default: true) */
|
|
251
|
+
show_square_button?: boolean;
|
|
252
|
+
/** Whether to show undo button (default: true) */
|
|
253
|
+
show_undo_button?: boolean;
|
|
254
|
+
/** Whether to show redo button (default: true) */
|
|
255
|
+
show_redo_button?: boolean;
|
|
256
|
+
/** Whether to show save button (default: true) */
|
|
257
|
+
show_save_button?: boolean;
|
|
258
|
+
/** Whether to show metadata panel button (default: true, only visible when sidepanel_metadata_enabled) */
|
|
259
|
+
show_metadata_button?: boolean;
|
|
260
|
+
/** Whether to show annotate (FreeText) button (default: true) */
|
|
261
|
+
show_annotate_button?: boolean;
|
|
262
|
+
/** Callback when close button is clicked (shows close button in toolbar when provided) */
|
|
263
|
+
on_close?: () => void;
|
|
184
264
|
}
|
|
185
265
|
/**
|
|
186
266
|
* PDF Annotation interface matching PDF standard
|
|
@@ -353,6 +433,7 @@ interface PdfViewerLayoutProps {
|
|
|
353
433
|
on_annotation_create: (annotation: PdfAnnotation) => void;
|
|
354
434
|
on_context_menu: (e: React.MouseEvent, page_index: number, screen_x: number, screen_y: number, mapper: CoordinateMapper) => void;
|
|
355
435
|
on_annotation_click: (annotation: PdfAnnotation, screen_x: number, screen_y: number, mapper: CoordinateMapper) => void;
|
|
436
|
+
on_freetext_click?: (page_index: number, screen_x: number, screen_y: number, mapper: CoordinateMapper) => void;
|
|
356
437
|
background_color?: string;
|
|
357
438
|
config: PdfViewerConfig | null;
|
|
358
439
|
className?: string;
|
|
@@ -419,6 +500,8 @@ interface AnnotationOverlayProps {
|
|
|
419
500
|
on_context_menu?: (event: React.MouseEvent, screen_x: number, screen_y: number) => void;
|
|
420
501
|
/** Callback when annotation is clicked */
|
|
421
502
|
on_annotation_click?: (annotation: PdfAnnotation, screen_x: number, screen_y: number) => void;
|
|
503
|
+
/** Callback when FreeText tool is active and user clicks on empty area */
|
|
504
|
+
on_freetext_click?: (screen_x: number, screen_y: number) => void;
|
|
422
505
|
/** Configuration object for styling */
|
|
423
506
|
config?: PdfViewerConfig | null;
|
|
424
507
|
/** Optional class name */
|