@servicetitan/dte-pdf-editor 1.0.0

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.
Files changed (179) hide show
  1. package/README.md +356 -0
  2. package/dist/components/data-model-field-type-list.d.ts +11 -0
  3. package/dist/components/data-model-field-type-list.d.ts.map +1 -0
  4. package/dist/components/data-model-field-type-list.js +23 -0
  5. package/dist/components/data-model-field-type-list.js.map +1 -0
  6. package/dist/components/e-sign-field-type-list.d.ts +9 -0
  7. package/dist/components/e-sign-field-type-list.d.ts.map +1 -0
  8. package/dist/components/e-sign-field-type-list.js +12 -0
  9. package/dist/components/e-sign-field-type-list.js.map +1 -0
  10. package/dist/components/field-config-panel-overlay.d.ts +13 -0
  11. package/dist/components/field-config-panel-overlay.d.ts.map +1 -0
  12. package/dist/components/field-config-panel-overlay.js +8 -0
  13. package/dist/components/field-config-panel-overlay.js.map +1 -0
  14. package/dist/components/field-config-panel.d.ts +12 -0
  15. package/dist/components/field-config-panel.d.ts.map +1 -0
  16. package/dist/components/field-config-panel.js +38 -0
  17. package/dist/components/field-config-panel.js.map +1 -0
  18. package/dist/components/field-sidebar.d.ts +10 -0
  19. package/dist/components/field-sidebar.d.ts.map +1 -0
  20. package/dist/components/field-sidebar.js +25 -0
  21. package/dist/components/field-sidebar.js.map +1 -0
  22. package/dist/components/field-type.d.ts +9 -0
  23. package/dist/components/field-type.d.ts.map +1 -0
  24. package/dist/components/field-type.js +12 -0
  25. package/dist/components/field-type.js.map +1 -0
  26. package/dist/components/fillable-field-type-list.d.ts +10 -0
  27. package/dist/components/fillable-field-type-list.d.ts.map +1 -0
  28. package/dist/components/fillable-field-type-list.js +17 -0
  29. package/dist/components/fillable-field-type-list.js.map +1 -0
  30. package/dist/components/pdf-canvas.d.ts +22 -0
  31. package/dist/components/pdf-canvas.d.ts.map +1 -0
  32. package/dist/components/pdf-canvas.js +14 -0
  33. package/dist/components/pdf-canvas.js.map +1 -0
  34. package/dist/components/pdf-document-renderer.d.ts +16 -0
  35. package/dist/components/pdf-document-renderer.d.ts.map +1 -0
  36. package/dist/components/pdf-document-renderer.js +28 -0
  37. package/dist/components/pdf-document-renderer.js.map +1 -0
  38. package/dist/components/pdf-editor.d.ts +21 -0
  39. package/dist/components/pdf-editor.d.ts.map +1 -0
  40. package/dist/components/pdf-editor.js +108 -0
  41. package/dist/components/pdf-editor.js.map +1 -0
  42. package/dist/components/pdf-field-overlay.d.ts +14 -0
  43. package/dist/components/pdf-field-overlay.d.ts.map +1 -0
  44. package/dist/components/pdf-field-overlay.js +32 -0
  45. package/dist/components/pdf-field-overlay.js.map +1 -0
  46. package/dist/constants/field.constants.d.ts +16 -0
  47. package/dist/constants/field.constants.d.ts.map +1 -0
  48. package/dist/constants/field.constants.js +28 -0
  49. package/dist/constants/field.constants.js.map +1 -0
  50. package/dist/constants/index.d.ts +3 -0
  51. package/dist/constants/index.d.ts.map +1 -0
  52. package/dist/constants/index.js +3 -0
  53. package/dist/constants/index.js.map +1 -0
  54. package/dist/constants/pdf-editor.constants.d.ts +2 -0
  55. package/dist/constants/pdf-editor.constants.d.ts.map +1 -0
  56. package/dist/constants/pdf-editor.constants.js +2 -0
  57. package/dist/constants/pdf-editor.constants.js.map +1 -0
  58. package/dist/hooks/index.d.ts +4 -0
  59. package/dist/hooks/index.d.ts.map +1 -0
  60. package/dist/hooks/index.js +4 -0
  61. package/dist/hooks/index.js.map +1 -0
  62. package/dist/hooks/useFieldDrag.d.ts +24 -0
  63. package/dist/hooks/useFieldDrag.d.ts.map +1 -0
  64. package/dist/hooks/useFieldDrag.js +34 -0
  65. package/dist/hooks/useFieldDrag.js.map +1 -0
  66. package/dist/hooks/useFieldResize.d.ts +17 -0
  67. package/dist/hooks/useFieldResize.d.ts.map +1 -0
  68. package/dist/hooks/useFieldResize.js +58 -0
  69. package/dist/hooks/useFieldResize.js.map +1 -0
  70. package/dist/hooks/usePdfDocumentRenderer.d.ts +9 -0
  71. package/dist/hooks/usePdfDocumentRenderer.d.ts.map +1 -0
  72. package/dist/hooks/usePdfDocumentRenderer.js +13 -0
  73. package/dist/hooks/usePdfDocumentRenderer.js.map +1 -0
  74. package/dist/index.d.ts +3 -0
  75. package/dist/index.d.ts.map +1 -0
  76. package/dist/index.js +2 -0
  77. package/dist/index.js.map +1 -0
  78. package/dist/interface/pdf-editor.d.ts +64 -0
  79. package/dist/interface/pdf-editor.d.ts.map +1 -0
  80. package/dist/interface/pdf-editor.js +14 -0
  81. package/dist/interface/pdf-editor.js.map +1 -0
  82. package/dist/utils/calculate-drop-coordinates.utils.d.ts +15 -0
  83. package/dist/utils/calculate-drop-coordinates.utils.d.ts.map +1 -0
  84. package/dist/utils/calculate-drop-coordinates.utils.js +48 -0
  85. package/dist/utils/calculate-drop-coordinates.utils.js.map +1 -0
  86. package/dist/utils/extract-grouped-fields-from-data-model.utils.d.ts +7 -0
  87. package/dist/utils/extract-grouped-fields-from-data-model.utils.d.ts.map +1 -0
  88. package/dist/utils/extract-grouped-fields-from-data-model.utils.js +57 -0
  89. package/dist/utils/extract-grouped-fields-from-data-model.utils.js.map +1 -0
  90. package/dist/utils/generate-e-sign-path.d.ts +3 -0
  91. package/dist/utils/generate-e-sign-path.d.ts.map +1 -0
  92. package/dist/utils/generate-e-sign-path.js +4 -0
  93. package/dist/utils/generate-e-sign-path.js.map +1 -0
  94. package/dist/utils/get-page-dimensions.utils.d.ts +12 -0
  95. package/dist/utils/get-page-dimensions.utils.d.ts.map +1 -0
  96. package/dist/utils/get-page-dimensions.utils.js +31 -0
  97. package/dist/utils/get-page-dimensions.utils.js.map +1 -0
  98. package/dist/utils/get-page-number-from-client-y.utils.d.ts +9 -0
  99. package/dist/utils/get-page-number-from-client-y.utils.d.ts.map +1 -0
  100. package/dist/utils/get-page-number-from-client-y.utils.js +24 -0
  101. package/dist/utils/get-page-number-from-client-y.utils.js.map +1 -0
  102. package/dist/utils/get-page-position.utils.d.ts +12 -0
  103. package/dist/utils/get-page-position.utils.d.ts.map +1 -0
  104. package/dist/utils/get-page-position.utils.js +22 -0
  105. package/dist/utils/get-page-position.utils.js.map +1 -0
  106. package/dist/utils/handle-field-drag-start.utils.d.ts +16 -0
  107. package/dist/utils/handle-field-drag-start.utils.d.ts.map +1 -0
  108. package/dist/utils/handle-field-drag-start.utils.js +41 -0
  109. package/dist/utils/handle-field-drag-start.utils.js.map +1 -0
  110. package/dist/utils/handle-field-drag.utils.d.ts +19 -0
  111. package/dist/utils/handle-field-drag.utils.d.ts.map +1 -0
  112. package/dist/utils/handle-field-drag.utils.js +36 -0
  113. package/dist/utils/handle-field-drag.utils.js.map +1 -0
  114. package/dist/utils/handle-field-resize.utils.d.ts +35 -0
  115. package/dist/utils/handle-field-resize.utils.d.ts.map +1 -0
  116. package/dist/utils/handle-field-resize.utils.js +66 -0
  117. package/dist/utils/handle-field-resize.utils.js.map +1 -0
  118. package/dist/utils/index.d.ts +13 -0
  119. package/dist/utils/index.d.ts.map +1 -0
  120. package/dist/utils/index.js +13 -0
  121. package/dist/utils/index.js.map +1 -0
  122. package/dist/utils/is-drag-over-canvas.utils.d.ts +9 -0
  123. package/dist/utils/is-drag-over-canvas.utils.d.ts.map +1 -0
  124. package/dist/utils/is-drag-over-canvas.utils.js +26 -0
  125. package/dist/utils/is-drag-over-canvas.utils.js.map +1 -0
  126. package/dist/utils/map-colors-to-recipients.d.ts +3 -0
  127. package/dist/utils/map-colors-to-recipients.d.ts.map +1 -0
  128. package/dist/utils/map-colors-to-recipients.js +35 -0
  129. package/dist/utils/map-colors-to-recipients.js.map +1 -0
  130. package/dist/utils/pdfjs-init.d.ts +6 -0
  131. package/dist/utils/pdfjs-init.d.ts.map +1 -0
  132. package/dist/utils/pdfjs-init.js +25 -0
  133. package/dist/utils/pdfjs-init.js.map +1 -0
  134. package/package.json +28 -0
  135. package/src/components/data-model-field-type-list.tsx +58 -0
  136. package/src/components/e-sign-field-type-list.tsx +27 -0
  137. package/src/components/field-config-panel-overlay.tsx +51 -0
  138. package/src/components/field-config-panel.tsx +142 -0
  139. package/src/components/field-sidebar.tsx +93 -0
  140. package/src/components/field-type.tsx +28 -0
  141. package/src/components/fillable-field-type-list.tsx +42 -0
  142. package/src/components/pdf-canvas.tsx +81 -0
  143. package/src/components/pdf-document-renderer.tsx +78 -0
  144. package/src/components/pdf-editor.tsx +216 -0
  145. package/src/components/pdf-field-overlay.tsx +83 -0
  146. package/src/constants/field.constants.ts +31 -0
  147. package/src/constants/index.ts +2 -0
  148. package/src/constants/pdf-editor.constants.ts +1 -0
  149. package/src/hooks/index.ts +3 -0
  150. package/src/hooks/useFieldDrag.ts +56 -0
  151. package/src/hooks/useFieldResize.ts +95 -0
  152. package/src/hooks/usePdfDocumentRenderer.ts +21 -0
  153. package/src/index.ts +2 -0
  154. package/src/interface/pdf-editor.ts +74 -0
  155. package/src/styles/field-config-panel-overlay.css +33 -0
  156. package/src/styles/field-sidebar.css +31 -0
  157. package/src/styles/field-type-list.css +8 -0
  158. package/src/styles/field-type.css +10 -0
  159. package/src/styles/generic.css +3 -0
  160. package/src/styles/index.css +10 -0
  161. package/src/styles/pdf-canvas.css +9 -0
  162. package/src/styles/pdf-document-renderer.css +4 -0
  163. package/src/styles/pdf-editor.css +14 -0
  164. package/src/styles/pdf-field-overlay.css +54 -0
  165. package/src/styles/variables.css +26 -0
  166. package/src/utils/calculate-drop-coordinates.utils.ts +68 -0
  167. package/src/utils/extract-grouped-fields-from-data-model.utils.ts +73 -0
  168. package/src/utils/generate-e-sign-path.ts +5 -0
  169. package/src/utils/get-page-dimensions.utils.ts +39 -0
  170. package/src/utils/get-page-number-from-client-y.utils.ts +31 -0
  171. package/src/utils/get-page-position.utils.ts +30 -0
  172. package/src/utils/handle-field-drag-start.utils.ts +52 -0
  173. package/src/utils/handle-field-drag.utils.ts +55 -0
  174. package/src/utils/handle-field-resize.utils.ts +102 -0
  175. package/src/utils/index.ts +12 -0
  176. package/src/utils/is-drag-over-canvas.utils.ts +35 -0
  177. package/src/utils/map-colors-to-recipients.ts +37 -0
  178. package/src/utils/pdfjs-init.ts +27 -0
  179. package/src/vite-env.d.ts +16 -0
@@ -0,0 +1,52 @@
1
+ import { DragEvent, RefObject } from 'react';
2
+ import { PdfField } from '../interface/pdf-editor';
3
+ import { getPagePosition } from './get-page-position.utils';
4
+
5
+ /**
6
+ * Handles the drag start event for a PDF field
7
+ * Calculates drag offset and sets up drag data transfer
8
+ * @param e - The drag event
9
+ * @param field - The field being dragged
10
+ * @param pdfWrapperRef - Reference to the PDF wrapper element
11
+ * @returns The drag offset object or null if wrapper is not available
12
+ */
13
+ export const handleFieldDragStart = (
14
+ e: DragEvent<HTMLDivElement>,
15
+ field: PdfField,
16
+ pdfWrapperRef: RefObject<HTMLDivElement>,
17
+ ): { x: number; y: number; page: number } | null => {
18
+ if (!pdfWrapperRef.current) {
19
+ return null;
20
+ }
21
+
22
+ /*
23
+ * Calculate drag offset in page-relative coordinates
24
+ */
25
+ const startPagePos = getPagePosition(field.page, pdfWrapperRef);
26
+ const wrapperRect = pdfWrapperRef.current.getBoundingClientRect();
27
+ const cursorXInPage = e.clientX - wrapperRect.left - startPagePos.left;
28
+ const cursorYInPage = e.clientY - wrapperRect.top - startPagePos.top;
29
+
30
+ const dragOffset = {
31
+ x: cursorXInPage - field.x,
32
+ y: cursorYInPage - field.y,
33
+ page: field.page,
34
+ };
35
+
36
+ // Mark that we're dragging an existing field, not a new field type
37
+ e.dataTransfer.effectAllowed = 'move';
38
+ e.dataTransfer.setData('text/plain', 'existing-field');
39
+
40
+ // Create a transparent drag image to hide the default browser drag image
41
+ const dragImage = document.createElement('div');
42
+ dragImage.style.position = 'absolute';
43
+ dragImage.style.top = '-9999px';
44
+ dragImage.style.width = '1px';
45
+ dragImage.style.height = '1px';
46
+ dragImage.style.opacity = '0';
47
+ document.body.appendChild(dragImage);
48
+ e.dataTransfer.setDragImage(dragImage, 0, 0);
49
+ setTimeout(() => document.body.removeChild(dragImage), 0);
50
+
51
+ return dragOffset;
52
+ };
@@ -0,0 +1,55 @@
1
+ import { DragEvent, RefObject } from 'react';
2
+ import { PdfField } from '../interface/pdf-editor';
3
+ import { getPageDimensions } from './get-page-dimensions.utils';
4
+ import { getPageNumberFromClientY } from './get-page-number-from-client-y.utils';
5
+ import { getPagePosition } from './get-page-position.utils';
6
+
7
+ interface DragOffset {
8
+ x: number;
9
+ y: number;
10
+ page: number;
11
+ }
12
+
13
+ /**
14
+ * Handles the drag event for a PDF field
15
+ * Calculates new position and clamps it to page boundaries
16
+ * @param e - The drag event
17
+ * @param field - The field being dragged
18
+ * @param dragOffset - The drag offset from drag start
19
+ * @param pdfWrapperRef - Reference to the PDF wrapper element
20
+ * @param onFieldMove - Callback to update field position
21
+ */
22
+ export const handleFieldDrag = (
23
+ e: DragEvent<HTMLDivElement>,
24
+ field: PdfField,
25
+ dragOffset: DragOffset,
26
+ pdfWrapperRef: RefObject<HTMLDivElement>,
27
+ onFieldMove: (fieldId: string, newX: number, newY: number, pageNumber: number) => void,
28
+ ): void => {
29
+ if (!pdfWrapperRef.current || e.clientX === 0 || e.clientY === 0) {
30
+ return;
31
+ }
32
+
33
+ const currentPage = getPageNumberFromClientY(e.clientY, pdfWrapperRef);
34
+ const currentPagePos = getPagePosition(currentPage, pdfWrapperRef);
35
+ const wrapperRect = pdfWrapperRef.current.getBoundingClientRect();
36
+ const pageDimensions = getPageDimensions(currentPage, pdfWrapperRef);
37
+
38
+ // Calculate position in page coordinates
39
+ const x = e.clientX - wrapperRect.left - currentPagePos.left - dragOffset.x;
40
+ const y = e.clientY - wrapperRect.top - currentPagePos.top - dragOffset.y;
41
+
42
+ /*
43
+ * Clamp x and y to stay within page boundaries.
44
+ * Account for field width and height to prevent dragging outside.
45
+ */
46
+ const minX = 0;
47
+ const minY = 0;
48
+ const maxX = Math.max(0, pageDimensions.width - field.width);
49
+ const maxY = Math.max(0, pageDimensions.height - field.height);
50
+
51
+ const clampedX = Math.max(minX, Math.min(maxX, x));
52
+ const clampedY = Math.max(minY, Math.min(maxY, y));
53
+
54
+ onFieldMove(field.id, clampedX, clampedY, currentPage);
55
+ };
@@ -0,0 +1,102 @@
1
+ import { RefObject } from 'react';
2
+ import { FIELD_CONSTANTS } from '../constants';
3
+ import { PdfField } from '../interface/pdf-editor';
4
+ import { getPageDimensions } from './get-page-dimensions.utils';
5
+ import { getPagePosition } from './get-page-position.utils';
6
+
7
+ interface ResizeStartData {
8
+ startX: number;
9
+ startY: number;
10
+ startWidth: number;
11
+ startHeight: number;
12
+ page: number;
13
+ }
14
+
15
+ /**
16
+ * Calculates the initial resize data when user starts resizing
17
+ * @param e - Mouse event
18
+ * @param field - The field being resized
19
+ * @param pdfWrapperRef - Reference to the PDF wrapper element
20
+ * @returns Resize start data or null if calculation fails
21
+ */
22
+ export const handleFieldResizeStart = (
23
+ e: { clientX: number; clientY: number },
24
+ field: PdfField,
25
+ pdfWrapperRef: RefObject<HTMLDivElement>,
26
+ ): ResizeStartData | null => {
27
+ if (!pdfWrapperRef.current) {
28
+ return null;
29
+ }
30
+
31
+ const pagePos = getPagePosition(field.page, pdfWrapperRef);
32
+ const wrapperRect = pdfWrapperRef.current.getBoundingClientRect();
33
+
34
+ // Calculate mouse position relative to the page
35
+ const startX = e.clientX - wrapperRect.left - pagePos.left;
36
+ const startY = e.clientY - wrapperRect.top - pagePos.top;
37
+
38
+ return {
39
+ startX,
40
+ startY,
41
+ startWidth: field.width,
42
+ startHeight: field.height,
43
+ page: field.page,
44
+ };
45
+ };
46
+
47
+ /**
48
+ * Handles the resize event for a PDF field from bottom-right corner
49
+ * Only changes width and height, keeping x and y coordinates unchanged
50
+ * @param e - Mouse event
51
+ * @param field - The field being resized
52
+ * @param resizeStartData - Data from resize start
53
+ * @param pdfWrapperRef - Reference to the PDF wrapper element
54
+ * @param onFieldResize - Callback to update field dimensions
55
+ */
56
+ export const handleFieldResize = (
57
+ e: { clientX: number; clientY: number },
58
+ field: PdfField,
59
+ resizeStartData: ResizeStartData,
60
+ pdfWrapperRef: RefObject<HTMLDivElement>,
61
+ onFieldResize: (
62
+ fieldId: string,
63
+ newWidth: number,
64
+ newHeight: number,
65
+ pageNumber: number,
66
+ ) => void,
67
+ ): void => {
68
+ if (!pdfWrapperRef.current) {
69
+ return;
70
+ }
71
+
72
+ const pageDimensions = getPageDimensions(resizeStartData.page, pdfWrapperRef);
73
+ const pagePos = getPagePosition(resizeStartData.page, pdfWrapperRef);
74
+ const wrapperRect = pdfWrapperRef.current.getBoundingClientRect();
75
+
76
+ // Calculate mouse position relative to the page
77
+ const mouseX = e.clientX - wrapperRect.left - pagePos.left;
78
+ const mouseY = e.clientY - wrapperRect.top - pagePos.top;
79
+
80
+ // Calculate delta from the start position
81
+ const deltaX = mouseX - resizeStartData.startX;
82
+ const deltaY = mouseY - resizeStartData.startY;
83
+
84
+ /*
85
+ * Calculate new width and height based on which handle is being used
86
+ * x and y always stay the same
87
+ */
88
+ let newWidth = resizeStartData.startWidth + deltaX;
89
+ let newHeight = resizeStartData.startHeight + deltaY;
90
+
91
+ // Clamp to minimum dimensions
92
+ newWidth = Math.max(FIELD_CONSTANTS.minWidth, newWidth);
93
+ newHeight = Math.max(FIELD_CONSTANTS.minHeight, newHeight);
94
+
95
+ // Clamp to page boundaries (ensure the field doesn't go outside the page)
96
+ const maxWidth = pageDimensions.width - field.x;
97
+ const maxHeight = pageDimensions.height - field.y;
98
+ newWidth = Math.min(newWidth, maxWidth);
99
+ newHeight = Math.min(newHeight, maxHeight);
100
+
101
+ onFieldResize(field.id, newWidth, newHeight, resizeStartData.page);
102
+ };
@@ -0,0 +1,12 @@
1
+ export * from './calculate-drop-coordinates.utils';
2
+ export * from './extract-grouped-fields-from-data-model.utils';
3
+ export * from './get-page-dimensions.utils';
4
+ export * from './get-page-number-from-client-y.utils';
5
+ export * from './get-page-position.utils';
6
+ export * from './handle-field-drag.utils';
7
+ export * from './handle-field-drag-start.utils';
8
+ export * from './handle-field-resize.utils';
9
+ export * from './is-drag-over-canvas.utils';
10
+ export * from './map-colors-to-recipients';
11
+ export * from './pdfjs-init';
12
+ export * from './generate-e-sign-path';
@@ -0,0 +1,35 @@
1
+ import { DragEvent, RefObject } from 'react';
2
+
3
+ /**
4
+ * Checks if a drag event is over any PDF canvas within the wrapper
5
+ * @param e - The drag event
6
+ * @param pdfWrapperRef - Reference to the PDF wrapper element
7
+ * @returns true if the drag is over a canvas, false otherwise
8
+ */
9
+ export const isDragOverCanvas = (
10
+ e: DragEvent<HTMLDivElement>,
11
+ pdfWrapperRef: RefObject<HTMLDivElement>,
12
+ ): boolean => {
13
+ if (!pdfWrapperRef.current) {
14
+ return false;
15
+ }
16
+
17
+ const pageElements = pdfWrapperRef.current.querySelectorAll('[data-page-number]');
18
+
19
+ for (const pageElement of pageElements) {
20
+ const canvas = pageElement.querySelector('canvas');
21
+ if (canvas) {
22
+ const canvasRect = canvas.getBoundingClientRect();
23
+ if (
24
+ e.clientX >= canvasRect.left &&
25
+ e.clientX <= canvasRect.right &&
26
+ e.clientY >= canvasRect.top &&
27
+ e.clientY <= canvasRect.bottom
28
+ ) {
29
+ return true;
30
+ }
31
+ }
32
+ }
33
+
34
+ return false;
35
+ };
@@ -0,0 +1,37 @@
1
+ import { RecipientInfo } from '../components/pdf-editor';
2
+
3
+ const colors = [
4
+ '#1F77B41f',
5
+ '#FF7F0E1f',
6
+ '#2CA02C1f',
7
+ '#9467BD1f',
8
+ '#8C564B1f',
9
+ '#E377C21f',
10
+ '#7F7F7F1f',
11
+ '#BCBD221f',
12
+ '#17BECF1f',
13
+ '#D627281f',
14
+ '#98DF8A1f',
15
+ '#FFBB781f',
16
+ '#C5B0D51f',
17
+ '#C49C941f',
18
+ '#F7B6D21f',
19
+ '#C7C7C71f',
20
+ '#DBDB8D1f',
21
+ '#9EDAE51f',
22
+ '#E5E5E51f',
23
+ '#393B791f',
24
+ '#5254A31f',
25
+ '#6B6EBD1f',
26
+ '#9C9EDA1f',
27
+ ];
28
+
29
+ export const mapColorsToRecipients = (recipients?: RecipientInfo[]): Record<string, string> => {
30
+ if (!recipients) {
31
+ return {};
32
+ }
33
+ return recipients.reduce<Record<string, string>>((acc, curr, i) => {
34
+ acc[curr.name] = colors[i];
35
+ return acc;
36
+ }, {});
37
+ };
@@ -0,0 +1,27 @@
1
+ /*
2
+ * Initialize PDF.js worker - centralized configuration
3
+ * This ensures the worker is configured once and can be imported by any component
4
+ */
5
+ import * as pdfjsLib from 'pdfjs-dist';
6
+ import workerSrc from 'pdfjs-dist/build/pdf.worker.min.js?url';
7
+
8
+ let isInitialized = false;
9
+
10
+ /**
11
+ * Initializes PDF.js worker if not already initialized
12
+ * Safe to call multiple times - will only initialize once
13
+ */
14
+ export const initializePdfJsWorker = (): void => {
15
+ if (isInitialized || typeof window === 'undefined') {
16
+ return;
17
+ }
18
+
19
+ try {
20
+ pdfjsLib.GlobalWorkerOptions.workerSrc = workerSrc;
21
+ isInitialized = true;
22
+ } catch (error) {
23
+ throw new Error('Failed to initialize PDF.js worker:' + (error as Error).message);
24
+ }
25
+ };
26
+
27
+ initializePdfJsWorker();
@@ -0,0 +1,16 @@
1
+ /*
2
+ * Declare module for Vite's ?url import syntax
3
+ * This tells TypeScript that imports ending with ?url return a string URL
4
+ */
5
+ declare module '*?url' {
6
+ const src: string;
7
+ // eslint-disable-next-line import/no-default-export
8
+ export default src;
9
+ }
10
+
11
+ // More specific declaration for pdfjs-dist worker
12
+ declare module 'pdfjs-dist/build/pdf.worker.min.js?url' {
13
+ const src: string;
14
+ // eslint-disable-next-line import/no-default-export
15
+ export default src;
16
+ }