hazo_pdf 1.5.5 → 1.5.7

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
@@ -6,6 +6,7 @@ A React component library for viewing and annotating PDF documents with support
6
6
 
7
7
  - 📄 **PDF Viewing** - Render PDF documents with customizable zoom levels
8
8
  - ✏️ **Annotations** - Square and FreeText annotation tools
9
+ - ✨ **Auto-Highlighting** - Automatically highlight extracted field values in PDFs
9
10
  - 🔍 **Programmatic Highlights** - Ref-based API for creating and managing highlights programmatically
10
11
  - 🎨 **Customizable Styling** - Extensive configuration options via INI file
11
12
  - ⏰ **Timestamp Support** - Automatic timestamp appending to annotations
@@ -516,9 +517,155 @@ See `config/hazo_pdf_config.ini` in the project root for all available configura
516
517
 
517
518
  ---
518
519
 
520
+ ## Auto-Highlighting
521
+
522
+ The PDF viewer can automatically highlight extracted field values in your PDFs. Simply provide field names and values via the `highlight_fields_info` prop, and the viewer will search for and highlight them automatically.
523
+
524
+ ### Basic Usage
525
+
526
+ ```tsx
527
+ import { PdfViewer } from 'hazo_pdf';
528
+ import 'hazo_pdf/styles.css';
529
+
530
+ function AutoHighlightExample() {
531
+ const extracted_data = {
532
+ document_date: '30 June 2024',
533
+ total_amount: '$29,696.60',
534
+ vendor_name: 'ACME Corporation',
535
+ };
536
+
537
+ return (
538
+ <div style={{ width: '100%', height: '800px' }}>
539
+ <PdfViewer
540
+ url="/invoice.pdf"
541
+ highlight_fields_info={[
542
+ { field_name: 'document_date', value: '30 June 2024', page_index: 0 },
543
+ { field_name: 'total_amount', value: '$29,696.60', page_index: 0 },
544
+ { field_name: 'vendor_name', value: 'ACME Corporation', page_index: 0 },
545
+ ]}
546
+ show_file_info_button={true}
547
+ />
548
+ </div>
549
+ );
550
+ }
551
+ ```
552
+
553
+ **That's it!** The viewer will:
554
+ 1. Search for each value in the PDF text layer
555
+ 2. Create visual highlight boxes at the found positions
556
+ 3. Display field names and values in the File Info sidepanel
557
+
558
+ ### How It Works
559
+
560
+ - **Smart Text Search**: Exact match first, then partial match with normalization (removes commas/spaces)
561
+ - **Automatic Cleanup**: Highlights are removed when the PDF changes or component unmounts
562
+ - **Non-Blocking**: Text search runs asynchronously without freezing the UI
563
+ - **Configurable**: Customize colors, opacity, padding, and search behavior
564
+
565
+ ### HighlightFieldInfo Type
566
+
567
+ ```typescript
568
+ interface HighlightFieldInfo {
569
+ field_name: string; // Field identifier (auto-formatted to Title Case in sidepanel)
570
+ value: string; // The text to search for and highlight
571
+ page_index?: number; // Page to search on (0-based, default: 0)
572
+ }
573
+ ```
574
+
575
+ ### Customization Options
576
+
577
+ #### Custom Highlight Colors
578
+
579
+ ```tsx
580
+ <PdfViewer
581
+ url="/document.pdf"
582
+ highlight_fields_info={highlight_fields}
583
+ auto_highlight_options={{
584
+ border_color: '#0066CC',
585
+ background_color: '#E6F2FF',
586
+ background_opacity: 0.4,
587
+ border_width: 2,
588
+ }}
589
+ />
590
+ ```
591
+
592
+ #### Custom Search Options
593
+
594
+ ```tsx
595
+ <PdfViewer
596
+ url="/document.pdf"
597
+ highlight_fields_info={highlight_fields}
598
+ auto_highlight_search_options={{
599
+ normalize: false, // Disable text normalization (exact match only)
600
+ padding_x: 5, // More horizontal padding
601
+ padding_y: 2, // More vertical padding
602
+ y_offset: -5, // Adjust vertical position
603
+ }}
604
+ />
605
+ ```
606
+
607
+ #### Disable Auto-Highlighting (Sidepanel Only)
608
+
609
+ ```tsx
610
+ <PdfViewer
611
+ url="/document.pdf"
612
+ highlight_fields_info={highlight_fields}
613
+ auto_highlight_enabled={false} // Only show in sidepanel, no visual highlights
614
+ />
615
+ ```
616
+
617
+ ### Configuration via INI File
618
+
619
+ You can set default auto-highlight styling in your config file:
620
+
621
+ ```ini
622
+ [auto_highlight]
623
+ auto_highlight_border_color = #FF6B00
624
+ auto_highlight_background_color = #FFF3E0
625
+ auto_highlight_background_opacity = 0.3
626
+ auto_highlight_border_width = 1
627
+ auto_highlight_normalize_text = true
628
+ auto_highlight_padding_x = 2
629
+ auto_highlight_padding_y = 1
630
+ auto_highlight_y_offset = -3
631
+ ```
632
+
633
+ ### Props
634
+
635
+ | Prop | Type | Default | Description |
636
+ |------|------|---------|-------------|
637
+ | `highlight_fields_info` | `HighlightFieldInfo[]` | `undefined` | Fields to highlight and display in sidepanel |
638
+ | `auto_highlight_enabled` | `boolean` | `true` | Enable/disable auto-highlighting feature |
639
+ | `auto_highlight_options` | `HighlightOptions` | From config | Custom highlight styling |
640
+ | `auto_highlight_search_options` | `Partial<TextSearchOptions>` | From config | Custom search behavior |
641
+
642
+ ### Advanced: Custom Text Search
643
+
644
+ For advanced use cases, you can use the text search utility directly:
645
+
646
+ ```tsx
647
+ import { find_text_in_pdf, type TextSearchOptions } from 'hazo_pdf';
648
+
649
+ const search_result = await find_text_in_pdf(pdf_document, 'Invoice #12345', {
650
+ page_index: 0,
651
+ normalize: true,
652
+ padding_x: 10,
653
+ padding_y: 5,
654
+ });
655
+
656
+ if (search_result) {
657
+ console.log('Found at:', search_result.x, search_result.y);
658
+ console.log('Match type:', search_result.match_type); // 'exact' | 'partial'
659
+ }
660
+ ```
661
+
662
+ ---
663
+
519
664
  ## Programmatic Highlight API
520
665
 
521
- The PDF viewer exposes a ref-based API for programmatically creating, removing, and managing highlights. This allows external code to control highlights without user interaction.
666
+ The PDF viewer also exposes a ref-based API for programmatically creating, removing, and managing highlights. This is useful when you need manual control over highlights or want to create highlights from coordinates.
667
+
668
+ **Note**: For most use cases, the [Auto-Highlighting](#auto-highlighting) feature is recommended as it's simpler and requires less code.
522
669
 
523
670
  ### Basic Usage
524
671
 
@@ -615,6 +615,51 @@ toolbar_show_metadata_button = false
615
615
  # Default: 36 (0.5 inch)
616
616
  # margin = 36
617
617
 
618
+ # =============================================================================
619
+ # [auto_highlight] - Auto-highlighting configuration
620
+ # =============================================================================
621
+ [auto_highlight]
622
+
623
+ # Border color for auto-created highlights (hex format: #RRGGBB)
624
+ # Color of the highlight border when using auto-highlighting feature
625
+ # Default: "#FF6B00" (orange)
626
+ # auto_highlight_border_color = #FF6B00
627
+
628
+ # Background color for auto-created highlights (hex format: #RRGGBB)
629
+ # Fill color inside the highlight box
630
+ # Default: "#FFF3E0" (light orange)
631
+ # auto_highlight_background_color = #FFF3E0
632
+
633
+ # Background opacity for auto-created highlights (0.0 to 1.0)
634
+ # Transparency level of the highlight background
635
+ # Default: 0.3
636
+ # auto_highlight_background_opacity = 0.3
637
+
638
+ # Border width for auto-created highlights in pixels
639
+ # Thickness of the highlight border
640
+ # Default: 1
641
+ # auto_highlight_border_width = 1
642
+
643
+ # Whether to normalize text during search (true/false)
644
+ # When enabled, removes commas and spaces from text before matching
645
+ # Default: true
646
+ # auto_highlight_normalize_text = true
647
+
648
+ # Horizontal padding around highlighted text (in PDF units)
649
+ # Extra space to add on left/right sides of the text box
650
+ # Default: 2
651
+ # auto_highlight_padding_x = 2
652
+
653
+ # Vertical padding around highlighted text (in PDF units)
654
+ # Extra space to add on top/bottom of the text box
655
+ # Default: 1
656
+ # auto_highlight_padding_y = 1
657
+
658
+ # Y-axis offset to adjust highlight position (in PDF units)
659
+ # Negative values move highlight down, positive values move up
660
+ # Default: -3
661
+ # auto_highlight_y_offset = -3
662
+
618
663
  # =============================================================================
619
664
  # [file_button] - File manager button configuration
620
665
  # =============================================================================
@@ -0,0 +1,12 @@
1
+ "use client";
2
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
3
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
4
+ }) : x)(function(x) {
5
+ if (typeof require !== "undefined") return require.apply(this, arguments);
6
+ throw Error('Dynamic require of "' + x + '" is not supported');
7
+ });
8
+
9
+ export {
10
+ __require
11
+ };
12
+ //# sourceMappingURL=chunk-AOSHQP7D.js.map
@@ -1,10 +1,4 @@
1
1
  "use client";
2
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
3
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
4
- }) : x)(function(x) {
5
- if (typeof require !== "undefined") return require.apply(this, arguments);
6
- throw Error('Dynamic require of "' + x + '" is not supported');
7
- });
8
2
 
9
3
  // src/config/default_config.ts
10
4
  var default_config = {
@@ -137,6 +131,16 @@ var default_config = {
137
131
  image_fit: "fit",
138
132
  margin: 36
139
133
  },
134
+ auto_highlight: {
135
+ auto_highlight_border_color: "#FF6B00",
136
+ auto_highlight_background_color: "#FFF3E0",
137
+ auto_highlight_background_opacity: 0.3,
138
+ auto_highlight_border_width: 1,
139
+ auto_highlight_normalize_text: true,
140
+ auto_highlight_padding_x: 2,
141
+ auto_highlight_padding_y: 1,
142
+ auto_highlight_y_offset: -3
143
+ },
140
144
  file_button: {
141
145
  icon_size: 24,
142
146
  icon_color: "#6b7280",
@@ -148,7 +152,6 @@ var default_config = {
148
152
  };
149
153
 
150
154
  export {
151
- __require,
152
155
  default_config
153
156
  };
154
- //# sourceMappingURL=chunk-GFRC6LEG.js.map
157
+ //# sourceMappingURL=chunk-CXHR3TT6.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config/default_config.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_rotation_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_show_file_info_button: true,\n toolbar_show_extract_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 file_manager: {\n file_manager_enabled: false,\n show_file_list: true,\n allow_delete: true,\n show_popout_button: true,\n file_list_height: 60,\n selected_color: '#3b82f6',\n file_list_background_color: '#f9fafb',\n file_list_border_color: '#e5e7eb',\n },\n\n file_upload: {\n upload_enabled: true,\n allowed_types: 'application/pdf,image/jpeg,image/png,image/gif,image/webp,text/plain,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel',\n max_file_size: 10485760, // 10MB\n max_files: 10,\n show_add_button: true,\n dropzone_border_color: '#d1d5db',\n dropzone_border_color_active: '#3b82f6',\n dropzone_background_color: '#f9fafb',\n },\n\n pdf_conversion: {\n conversion_enabled: true,\n page_size: 'letter',\n image_quality: 0.85,\n image_fit: 'fit',\n margin: 36,\n },\n\n file_button: {\n icon_size: 24,\n icon_color: '#6b7280',\n icon_color_hover: '#374151',\n icon_color_with_files: '#3b82f6',\n badge_background: '#3b82f6',\n badge_text_color: '#ffffff',\n },\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/config/default_config.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_rotation_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_show_file_info_button: true,\n toolbar_show_extract_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 file_manager: {\n file_manager_enabled: false,\n show_file_list: true,\n allow_delete: true,\n show_popout_button: true,\n file_list_height: 60,\n selected_color: '#3b82f6',\n file_list_background_color: '#f9fafb',\n file_list_border_color: '#e5e7eb',\n },\n\n file_upload: {\n upload_enabled: true,\n allowed_types: 'application/pdf,image/jpeg,image/png,image/gif,image/webp,text/plain,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel',\n max_file_size: 10485760, // 10MB\n max_files: 10,\n show_add_button: true,\n dropzone_border_color: '#d1d5db',\n dropzone_border_color_active: '#3b82f6',\n dropzone_background_color: '#f9fafb',\n },\n\n pdf_conversion: {\n conversion_enabled: true,\n page_size: 'letter',\n image_quality: 0.85,\n image_fit: 'fit',\n margin: 36,\n },\n\n auto_highlight: {\n auto_highlight_border_color: '#FF6B00',\n auto_highlight_background_color: '#FFF3E0',\n auto_highlight_background_opacity: 0.3,\n auto_highlight_border_width: 1,\n auto_highlight_normalize_text: true,\n auto_highlight_padding_x: 2,\n auto_highlight_padding_y: 1,\n auto_highlight_y_offset: -3,\n },\n\n file_button: {\n icon_size: 24,\n icon_color: '#6b7280',\n icon_color_hover: '#374151',\n icon_color_with_files: '#3b82f6',\n badge_background: '#3b82f6',\n badge_text_color: '#ffffff',\n },\n};\n"],"mappings":"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","names":[]}
@@ -1,8 +1,10 @@
1
1
  "use client";
2
2
  import {
3
- __require,
4
3
  default_config
5
- } from "./chunk-GFRC6LEG.js";
4
+ } from "./chunk-CXHR3TT6.js";
5
+ import {
6
+ __require
7
+ } from "./chunk-AOSHQP7D.js";
6
8
 
7
9
  // src/components/pdf_viewer/pdf_viewer.tsx
8
10
  import { useState as useState13, useEffect as useEffect10, useRef as useRef11, useCallback as useCallback4, forwardRef, useImperativeHandle } from "react";
@@ -2790,6 +2792,40 @@ function build_config_from_ini(get_value) {
2790
2792
  default_config.pdf_conversion.margin
2791
2793
  )
2792
2794
  },
2795
+ auto_highlight: {
2796
+ auto_highlight_border_color: parse_color(
2797
+ get_value("auto_highlight", "auto_highlight_border_color"),
2798
+ default_config.auto_highlight.auto_highlight_border_color
2799
+ ),
2800
+ auto_highlight_background_color: parse_color(
2801
+ get_value("auto_highlight", "auto_highlight_background_color"),
2802
+ default_config.auto_highlight.auto_highlight_background_color
2803
+ ),
2804
+ auto_highlight_background_opacity: parse_opacity(
2805
+ get_value("auto_highlight", "auto_highlight_background_opacity"),
2806
+ default_config.auto_highlight.auto_highlight_background_opacity
2807
+ ),
2808
+ auto_highlight_border_width: parse_number(
2809
+ get_value("auto_highlight", "auto_highlight_border_width"),
2810
+ default_config.auto_highlight.auto_highlight_border_width
2811
+ ),
2812
+ auto_highlight_normalize_text: parse_boolean(
2813
+ get_value("auto_highlight", "auto_highlight_normalize_text"),
2814
+ default_config.auto_highlight.auto_highlight_normalize_text
2815
+ ),
2816
+ auto_highlight_padding_x: parse_number(
2817
+ get_value("auto_highlight", "auto_highlight_padding_x"),
2818
+ default_config.auto_highlight.auto_highlight_padding_x
2819
+ ),
2820
+ auto_highlight_padding_y: parse_number(
2821
+ get_value("auto_highlight", "auto_highlight_padding_y"),
2822
+ default_config.auto_highlight.auto_highlight_padding_y
2823
+ ),
2824
+ auto_highlight_y_offset: parse_number(
2825
+ get_value("auto_highlight", "auto_highlight_y_offset"),
2826
+ default_config.auto_highlight.auto_highlight_y_offset
2827
+ )
2828
+ },
2793
2829
  file_button: {
2794
2830
  icon_size: parse_number(
2795
2831
  get_value("file_button", "icon_size"),
@@ -4434,7 +4470,11 @@ var PdfViewer = forwardRef(({
4434
4470
  save_path,
4435
4471
  // File info sidepanel data props
4436
4472
  doc_data,
4437
- highlight_fields_info
4473
+ highlight_fields_info,
4474
+ // Auto-highlight props
4475
+ auto_highlight_enabled,
4476
+ auto_highlight_options,
4477
+ auto_highlight_search_options
4438
4478
  }, ref) => {
4439
4479
  const [pdf_document, setPdfDocument] = useState13(null);
4440
4480
  const [loading, setLoading] = useState13(true);
@@ -4451,6 +4491,7 @@ var PdfViewer = forwardRef(({
4451
4491
  const [file_info_sidepanel_open, setFileInfoSidepanelOpen] = useState13(false);
4452
4492
  const [file_info_sidepanel_width, setFileInfoSidepanelWidth] = useState13(300);
4453
4493
  const [hazo_files_available, setHazoFilesAvailable] = useState13(null);
4494
+ const [auto_highlight_ids, setAutoHighlightIds] = useState13(/* @__PURE__ */ new Set());
4454
4495
  const [page_rotations, setPageRotations] = useState13(/* @__PURE__ */ new Map());
4455
4496
  const [current_visible_page, setCurrentVisiblePage] = useState13(0);
4456
4497
  const [current_file, setCurrentFile] = useState13(
@@ -5099,6 +5140,107 @@ ${suffix_line}`;
5099
5140
  console.error("PdfViewer: Failed to popout:", err);
5100
5141
  }
5101
5142
  }, [files, current_file, viewer_title, on_popout, popout_route]);
5143
+ useEffect10(() => {
5144
+ const should_auto_highlight = auto_highlight_enabled !== false && // Default true
5145
+ highlight_fields_info && highlight_fields_info.length > 0 && pdf_document;
5146
+ if (!should_auto_highlight) {
5147
+ return;
5148
+ }
5149
+ const logger2 = get_logger();
5150
+ auto_highlight_ids.forEach((id) => {
5151
+ const annotation = annotations.find((a) => a.id === id);
5152
+ if (annotation) {
5153
+ handle_annotation_delete(id);
5154
+ }
5155
+ });
5156
+ setAutoHighlightIds(/* @__PURE__ */ new Set());
5157
+ const perform_auto_highlights = async () => {
5158
+ const { find_text_in_pdf } = await import("./text_search-GW2VYMU6.js");
5159
+ const new_ids = /* @__PURE__ */ new Set();
5160
+ const auto_config = config_ref.current?.auto_highlight || default_config.auto_highlight;
5161
+ const search_opts = {
5162
+ normalize: auto_config.auto_highlight_normalize_text,
5163
+ padding_x: auto_config.auto_highlight_padding_x,
5164
+ padding_y: auto_config.auto_highlight_padding_y,
5165
+ y_offset: auto_config.auto_highlight_y_offset,
5166
+ ...auto_highlight_search_options
5167
+ };
5168
+ const highlight_opts = auto_highlight_options || {
5169
+ border_color: auto_config.auto_highlight_border_color,
5170
+ background_color: auto_config.auto_highlight_background_color,
5171
+ background_opacity: auto_config.auto_highlight_background_opacity,
5172
+ border_width: auto_config.auto_highlight_border_width
5173
+ };
5174
+ for (const field of highlight_fields_info) {
5175
+ try {
5176
+ const page_idx = field.page_index ?? 0;
5177
+ const result = await find_text_in_pdf(pdf_document, field.value, {
5178
+ page_index: page_idx,
5179
+ ...search_opts
5180
+ });
5181
+ if (result) {
5182
+ logger2.debug("[AutoHighlight] Found text", {
5183
+ field: field.field_name,
5184
+ value: field.value,
5185
+ match_type: result.match_type,
5186
+ position: { x: result.x, y: result.y }
5187
+ });
5188
+ const rect = [
5189
+ result.x,
5190
+ result.y,
5191
+ result.x + result.width,
5192
+ result.y + result.height
5193
+ ];
5194
+ const highlight_config = config_ref.current?.highlight_annotation || default_config.highlight_annotation;
5195
+ const annotation = {
5196
+ id: `auto_highlight_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
5197
+ type: "Highlight",
5198
+ page_index: page_idx,
5199
+ rect,
5200
+ author: "AutoHighlight",
5201
+ date: (/* @__PURE__ */ new Date()).toISOString(),
5202
+ contents: field.field_name,
5203
+ // Store field name in contents
5204
+ color: highlight_opts.background_color || highlight_config.highlight_fill_color,
5205
+ flags: "api_highlight"
5206
+ // Marker to identify API-created highlights
5207
+ };
5208
+ annotation.subject = JSON.stringify({
5209
+ border_color: highlight_opts.border_color,
5210
+ background_color: highlight_opts.background_color,
5211
+ background_opacity: highlight_opts.background_opacity,
5212
+ border_width: highlight_opts.border_width
5213
+ });
5214
+ handle_annotation_create(annotation);
5215
+ new_ids.add(annotation.id);
5216
+ } else {
5217
+ logger2.warn("[AutoHighlight] Text not found in PDF", {
5218
+ field: field.field_name,
5219
+ value: field.value,
5220
+ page: page_idx
5221
+ });
5222
+ }
5223
+ } catch (err) {
5224
+ logger2.error("[AutoHighlight] Search failed", {
5225
+ field: field.field_name,
5226
+ error: err instanceof Error ? err.message : String(err)
5227
+ });
5228
+ }
5229
+ }
5230
+ setAutoHighlightIds(new_ids);
5231
+ };
5232
+ perform_auto_highlights();
5233
+ }, [pdf_document, highlight_fields_info, auto_highlight_enabled]);
5234
+ useEffect10(() => {
5235
+ return () => {
5236
+ auto_highlight_ids.forEach((id) => {
5237
+ const annotation = annotations.find((a) => a.id === id);
5238
+ if (annotation) {
5239
+ handle_annotation_delete(id);
5240
+ }
5241
+ });
5242
+ };
5243
+ }, []);
5102
5244
  const has_changes_to_save = annotations.length > 0 || page_rotations.size > 0;
5103
5245
  const handle_save = async () => {
5104
5246
  if (!has_changes_to_save) {
@@ -5115,7 +5257,7 @@ ${suffix_line}`;
5115
5257
  const original_filename = is_multi_file_mode && current_file ? current_file.name : effective_url.split("/").pop() || "document.pdf";
5116
5258
  const filename_without_ext = original_filename.replace(/\.pdf$/i, "");
5117
5259
  const output_filename = `${filename_without_ext}_annotated.pdf`;
5118
- const { save_annotations_to_pdf, download_pdf } = await import("./pdf_saver-IOWST6TO.js");
5260
+ const { save_annotations_to_pdf, download_pdf } = await import("./pdf_saver-JXAIRQVL.js");
5119
5261
  const pdf_source = cached_pdf_data || effective_url;
5120
5262
  logger2.debug("[PdfViewer] Saving PDF", { source_type: cached_pdf_data ? "cached ArrayBuffer" : "URL" });
5121
5263
  const pdf_bytes = await save_annotations_to_pdf(pdf_source, annotations, output_filename, config_ref.current, page_rotations);
@@ -5995,4 +6137,4 @@ export {
5995
6137
  PdfViewer,
5996
6138
  pdf_viewer_default
5997
6139
  };
5998
- //# sourceMappingURL=chunk-HT7OPS2V.js.map
6140
+ //# sourceMappingURL=chunk-FMZPXAJT.js.map