react-pdfjs-multi 1.0.0-rc.4 → 1.0.0-rc.5
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 +153 -48
- package/dist/components/PdfMultiViewer/PdfMultiViewer.d.ts +7 -1
- package/dist/components/PdfMultiViewer/PdfMultiViewerView.d.ts +6 -1
- package/dist/components/PdfMultiViewer/usePdfMultiViewer.d.ts +2 -2
- package/dist/components/PdfRenderer/PdfRenderer.d.ts +3 -0
- package/dist/components/PdfRenderer/PdfRendererControls.d.ts +3 -1
- package/dist/components/PdfRenderer/PdfRendererView.d.ts +2 -1
- package/dist/index.js +142 -76
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +143 -77
- package/dist/index.mjs.map +1 -1
- package/dist/react-pdfjs-multi.css +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -124,8 +124,9 @@ var ZoomSelectBox_default = ZoomSelectBox;
|
|
|
124
124
|
|
|
125
125
|
//#endregion
|
|
126
126
|
//#region src/components/PdfRenderer/PdfRendererControls.tsx
|
|
127
|
-
const PdfControls = ({ autoZoom, downloadBtn, onDownload, onZoomIn, onZoomOut, onRotateRight, onRotateLeft, scale, setScale }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
127
|
+
const PdfControls = ({ autoZoom, downloadBtn, iconStyles, onDownload, onZoomIn, onZoomOut, onRotateRight, onRotateLeft, scale, setScale }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
128
128
|
className: "renderer-controls",
|
|
129
|
+
style: iconStyles,
|
|
129
130
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [
|
|
130
131
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(I18nContext.Consumer, { children: ({ scaleDown, scaleUp }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
131
132
|
className: "button-group",
|
|
@@ -202,37 +203,41 @@ var PdfRendererControls_default = PdfControls;
|
|
|
202
203
|
|
|
203
204
|
//#endregion
|
|
204
205
|
//#region src/components/PdfRenderer/PdfRendererView.tsx
|
|
205
|
-
const PdfRendererView = ({ autoZoom, containerRef, controls, downloadBtn, iconStyles, i18nData, isLoading, scale, setScale, onDownload, onRotateLeft, onRotateRight, onZoomIn, onZoomOut }) =>
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
className:
|
|
206
|
+
const PdfRendererView = ({ autoZoom, className, containerRef, controls, downloadBtn, iconStyles, i18nData, isLoading, scale, setScale, onDownload, onRotateLeft, onRotateRight, onZoomIn, onZoomOut }) => {
|
|
207
|
+
const i18nValue = (0, react.useMemo)(() => ({
|
|
208
|
+
...defaultI18n,
|
|
209
|
+
...i18nData ?? {}
|
|
210
|
+
}), [i18nData]);
|
|
211
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
212
|
+
className: `pdfjs-multi renderer-container${className ? ` ${className}` : ""}`,
|
|
213
|
+
style: iconStyles,
|
|
214
|
+
children: [controls && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(I18nContext.Provider, {
|
|
215
|
+
value: i18nValue,
|
|
216
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PdfRendererControls_default, {
|
|
217
|
+
autoZoom,
|
|
218
|
+
downloadBtn,
|
|
219
|
+
iconStyles,
|
|
220
|
+
scale,
|
|
221
|
+
setScale,
|
|
222
|
+
onDownload,
|
|
223
|
+
onZoomIn,
|
|
224
|
+
onZoomOut,
|
|
225
|
+
onRotateRight,
|
|
226
|
+
onRotateLeft
|
|
227
|
+
})
|
|
228
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
229
|
+
className: "renderer-stage",
|
|
229
230
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
230
|
-
|
|
231
|
-
className: `
|
|
231
|
+
ref: containerRef,
|
|
232
|
+
className: `renderer-target-container ${!controls ? "no-controls" : ""} `,
|
|
233
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
234
|
+
id: "viewer",
|
|
235
|
+
className: `pdfViewer ${isLoading ? "hidden" : ""}`
|
|
236
|
+
})
|
|
232
237
|
})
|
|
233
|
-
})
|
|
234
|
-
})
|
|
235
|
-
}
|
|
238
|
+
})]
|
|
239
|
+
});
|
|
240
|
+
};
|
|
236
241
|
var PdfRendererView_default = PdfRendererView;
|
|
237
242
|
|
|
238
243
|
//#endregion
|
|
@@ -507,7 +512,7 @@ const buildIconStyles = (icons) => {
|
|
|
507
512
|
|
|
508
513
|
//#endregion
|
|
509
514
|
//#region src/components/PdfRenderer/PdfRenderer.tsx
|
|
510
|
-
const PdfRenderer = (0, react.forwardRef)(({ pdfDoc, activeIndex = "0", autoZoom = true, controls = true, downloadBtn = true, icons, i18nData = defaultI18n, pdfChangeHook = null, zoom, rotation = 0, scrollTop = 0, scrollLeft = 0 }, ref) => {
|
|
515
|
+
const PdfRenderer = (0, react.forwardRef)(({ pdfDoc, activeIndex = "0", autoZoom = true, className, controls = true, downloadBtn = true, icons, i18nData = defaultI18n, pdfChangeHook = null, style, zoom, rotation = 0, scrollTop = 0, scrollLeft = 0 }, ref) => {
|
|
511
516
|
const { containerRef, download, isLoading, pdfViewerRef, rotateLeft, rotateRight, scale, setScale, zoomIn, zoomOut } = usePdfRenderer({
|
|
512
517
|
activeIndex,
|
|
513
518
|
autoZoom,
|
|
@@ -521,12 +526,20 @@ const PdfRenderer = (0, react.forwardRef)(({ pdfDoc, activeIndex = "0", autoZoom
|
|
|
521
526
|
(0, react.useImperativeHandle)(ref, () => ({ get pdfViewer() {
|
|
522
527
|
return pdfViewerRef.current;
|
|
523
528
|
} }));
|
|
529
|
+
const iconStyles = (0, react.useMemo)(() => buildIconStyles(icons), [icons]);
|
|
524
530
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PdfRendererView_default, {
|
|
525
531
|
autoZoom,
|
|
532
|
+
className,
|
|
526
533
|
containerRef,
|
|
527
534
|
controls,
|
|
528
535
|
downloadBtn,
|
|
529
|
-
iconStyles:
|
|
536
|
+
iconStyles: (0, react.useMemo)(() => {
|
|
537
|
+
if (!iconStyles && !style) return void 0;
|
|
538
|
+
return {
|
|
539
|
+
...iconStyles ?? {},
|
|
540
|
+
...style ?? {}
|
|
541
|
+
};
|
|
542
|
+
}, [iconStyles, style]),
|
|
530
543
|
i18nData,
|
|
531
544
|
isLoading,
|
|
532
545
|
scale,
|
|
@@ -543,8 +556,51 @@ var PdfRenderer_default = PdfRenderer;
|
|
|
543
556
|
|
|
544
557
|
//#endregion
|
|
545
558
|
//#region src/components/PdfMultiViewer/PdfMultiViewerView.tsx
|
|
546
|
-
const
|
|
547
|
-
|
|
559
|
+
const PdfMultiViewerListItem = (0, react.memo)(({ file, i18nData, index, isActive, onSelectPdf }) => {
|
|
560
|
+
const handleSelect = (0, react.useMemo)(() => onSelectPdf(String(index), file), [
|
|
561
|
+
file,
|
|
562
|
+
index,
|
|
563
|
+
onSelectPdf
|
|
564
|
+
]);
|
|
565
|
+
const isLoading = Boolean(file.isLoading && !file.pdfProxy);
|
|
566
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
|
|
567
|
+
className: `pdf-viewer-list-item${file.pdfProxy ? " loaded" : ""}${isLoading ? " loading" : ""}${isActive ? " active" : ""}`,
|
|
568
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
569
|
+
className: "pdf-viewer-list-item-button",
|
|
570
|
+
onClick: handleSelect,
|
|
571
|
+
type: "button",
|
|
572
|
+
children: [
|
|
573
|
+
file.title || file.source,
|
|
574
|
+
file.pdfProxy && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
575
|
+
className: "pdf-viewer-list-item-meta",
|
|
576
|
+
children: [
|
|
577
|
+
i18nData?.pages ?? "Pages",
|
|
578
|
+
": ",
|
|
579
|
+
file.pdfProxy.numPages
|
|
580
|
+
]
|
|
581
|
+
}),
|
|
582
|
+
isLoading && !file.pdfProxy && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
583
|
+
className: "pdf-viewer-list-item-meta",
|
|
584
|
+
children: i18nData?.loading ?? "Loading..."
|
|
585
|
+
})
|
|
586
|
+
]
|
|
587
|
+
})
|
|
588
|
+
});
|
|
589
|
+
});
|
|
590
|
+
PdfMultiViewerListItem.displayName = "PdfMultiViewerListItem";
|
|
591
|
+
const PdfMultiViewerList = (0, react.memo)(({ activeIndex, files, i18nData, listVisible, overlayMode, onSelectPdf }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
592
|
+
className: `pdf-viewer-list${!listVisible ? " hidden" : ""}${overlayMode ? " overlay" : ""}`,
|
|
593
|
+
children: files.map((file, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PdfMultiViewerListItem, {
|
|
594
|
+
file,
|
|
595
|
+
i18nData,
|
|
596
|
+
index,
|
|
597
|
+
isActive: String(index) === String(activeIndex),
|
|
598
|
+
onSelectPdf
|
|
599
|
+
}, file.source))
|
|
600
|
+
}));
|
|
601
|
+
PdfMultiViewerList.displayName = "PdfMultiViewerList";
|
|
602
|
+
const PdfMultiViewerView = ({ activeIndex, autoZoom, className, controls, files, iconStyles, i18nData, listVisible, overlayMode, pdfToShow, rendererIcons, rendererClassName, rendererStyle, viewerContainerRef, onRememberPosition, onSelectPdf, onToggleList }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
603
|
+
className: `pdfjs-multi pdf-multi-viewer${className ? ` ${className}` : ""}`,
|
|
548
604
|
ref: viewerContainerRef,
|
|
549
605
|
style: iconStyles,
|
|
550
606
|
children: [
|
|
@@ -561,42 +617,23 @@ const PdfMultiViewerView = ({ activeIndex, autoZoom, controls, files, iconStyles
|
|
|
561
617
|
})
|
|
562
618
|
})
|
|
563
619
|
}),
|
|
564
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
572
|
-
className: "pdf-viewer-list-item-button",
|
|
573
|
-
onClick: handleSelect,
|
|
574
|
-
type: "button",
|
|
575
|
-
children: [
|
|
576
|
-
file.title || file.source,
|
|
577
|
-
file.pdfProxy && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
578
|
-
className: "pdf-viewer-list-item-meta",
|
|
579
|
-
children: [
|
|
580
|
-
i18nData?.pages ?? "Pages",
|
|
581
|
-
": ",
|
|
582
|
-
file.pdfProxy.numPages
|
|
583
|
-
]
|
|
584
|
-
}),
|
|
585
|
-
isLoading && !file.pdfProxy && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
586
|
-
className: "pdf-viewer-list-item-meta",
|
|
587
|
-
children: i18nData?.loading ?? "Loading..."
|
|
588
|
-
})
|
|
589
|
-
]
|
|
590
|
-
})
|
|
591
|
-
}, file.source);
|
|
592
|
-
})
|
|
620
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PdfMultiViewerList, {
|
|
621
|
+
activeIndex,
|
|
622
|
+
files,
|
|
623
|
+
i18nData,
|
|
624
|
+
listVisible,
|
|
625
|
+
overlayMode,
|
|
626
|
+
onSelectPdf
|
|
593
627
|
}),
|
|
594
628
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
595
629
|
className: "pdf-viewer-multi-renderer",
|
|
596
630
|
children: pdfToShow?.pdfProxy ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PdfRenderer_default, {
|
|
597
631
|
activeIndex,
|
|
598
632
|
autoZoom,
|
|
633
|
+
className: rendererClassName,
|
|
599
634
|
controls,
|
|
635
|
+
icons: rendererIcons,
|
|
636
|
+
style: rendererStyle,
|
|
600
637
|
pdfDoc: pdfToShow.pdfProxy,
|
|
601
638
|
i18nData,
|
|
602
639
|
pdfChangeHook: onRememberPosition,
|
|
@@ -639,12 +676,14 @@ const usePdfMultiViewer = ({ pdfs, startIndex, i18nData, lazyLoad, initialLoadIn
|
|
|
639
676
|
const workerRef = (0, react.useRef)(null);
|
|
640
677
|
const loadingIndicesRef = (0, react.useRef)(/* @__PURE__ */ new Set());
|
|
641
678
|
const initialLoadDoneRef = (0, react.useRef)(false);
|
|
679
|
+
const positionsRef = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
642
680
|
const [files, setFiles] = (0, react.useState)(() => {
|
|
643
681
|
const mapped = pdfs.map(createPdfFile);
|
|
644
682
|
initialFilesRef.current = mapped;
|
|
645
683
|
return mapped;
|
|
646
684
|
});
|
|
647
685
|
const [activeIndex, setActiveIndex] = (0, react.useState)(() => `${startIndex}`);
|
|
686
|
+
const [_pendingIndex, setPendingIndex] = (0, react.useState)(null);
|
|
648
687
|
const [listVisible, setListVisible] = (0, react.useState)(true);
|
|
649
688
|
const [overlayMode, setOverlayMode] = (0, react.useState)(false);
|
|
650
689
|
const resolveIndex = (0, react.useCallback)((index) => {
|
|
@@ -693,6 +732,13 @@ const usePdfMultiViewer = ({ pdfs, startIndex, i18nData, lazyLoad, initialLoadIn
|
|
|
693
732
|
pdfProxy: pdfDoc
|
|
694
733
|
};
|
|
695
734
|
}));
|
|
735
|
+
setPendingIndex((current) => {
|
|
736
|
+
if (current === String(index)) {
|
|
737
|
+
setActiveIndex(current);
|
|
738
|
+
return null;
|
|
739
|
+
}
|
|
740
|
+
return current;
|
|
741
|
+
});
|
|
696
742
|
} catch (_error) {
|
|
697
743
|
setFileLoading(index, false);
|
|
698
744
|
} finally {
|
|
@@ -700,8 +746,13 @@ const usePdfMultiViewer = ({ pdfs, startIndex, i18nData, lazyLoad, initialLoadIn
|
|
|
700
746
|
}
|
|
701
747
|
}, [setFileLoading]);
|
|
702
748
|
const selectPdf = (0, react.useCallback)((nextIndex, file) => () => {
|
|
703
|
-
|
|
704
|
-
|
|
749
|
+
if (lazyLoad && !file.pdfProxy) {
|
|
750
|
+
setPendingIndex(nextIndex);
|
|
751
|
+
loadPdfDocument(file, Number(nextIndex));
|
|
752
|
+
} else {
|
|
753
|
+
setPendingIndex(null);
|
|
754
|
+
setActiveIndex(nextIndex);
|
|
755
|
+
}
|
|
705
756
|
if (overlayMode && listVisible) toggleList();
|
|
706
757
|
}, [
|
|
707
758
|
lazyLoad,
|
|
@@ -727,13 +778,7 @@ const usePdfMultiViewer = ({ pdfs, startIndex, i18nData, lazyLoad, initialLoadIn
|
|
|
727
778
|
});
|
|
728
779
|
}, [loadPdfDocument]);
|
|
729
780
|
const rememberPosition = (0, react.useCallback)((index, position) => {
|
|
730
|
-
|
|
731
|
-
if (pdfIndex !== Number(index)) return pdfFile;
|
|
732
|
-
return {
|
|
733
|
-
...pdfFile,
|
|
734
|
-
...position
|
|
735
|
-
};
|
|
736
|
-
}));
|
|
781
|
+
positionsRef.current.set(Number(index), position);
|
|
737
782
|
}, []);
|
|
738
783
|
(0, react.useEffect)(() => {
|
|
739
784
|
window.addEventListener("resizeAutoZoom", onResizeEvent);
|
|
@@ -783,7 +828,16 @@ const usePdfMultiViewer = ({ pdfs, startIndex, i18nData, lazyLoad, initialLoadIn
|
|
|
783
828
|
i18nData,
|
|
784
829
|
listVisible,
|
|
785
830
|
overlayMode,
|
|
786
|
-
pdfToShow:
|
|
831
|
+
pdfToShow: (0, react.useMemo)(() => {
|
|
832
|
+
const resolvedIndex = Number(activeIndex);
|
|
833
|
+
const file = files[resolvedIndex];
|
|
834
|
+
if (!file) return void 0;
|
|
835
|
+
const position = positionsRef.current.get(resolvedIndex);
|
|
836
|
+
return position ? {
|
|
837
|
+
...file,
|
|
838
|
+
...position
|
|
839
|
+
} : file;
|
|
840
|
+
}, [activeIndex, files]),
|
|
787
841
|
rememberPosition,
|
|
788
842
|
selectPdf,
|
|
789
843
|
toggleList,
|
|
@@ -793,10 +847,11 @@ const usePdfMultiViewer = ({ pdfs, startIndex, i18nData, lazyLoad, initialLoadIn
|
|
|
793
847
|
|
|
794
848
|
//#endregion
|
|
795
849
|
//#region src/components/PdfMultiViewer/PdfMultiViewer.tsx
|
|
796
|
-
const
|
|
850
|
+
const DEFAULT_I18N_DATA = {
|
|
797
851
|
loading: "Loading...",
|
|
798
852
|
pages: "Pages"
|
|
799
|
-
}
|
|
853
|
+
};
|
|
854
|
+
const PdfMultiViewer = ({ pdfs, autoZoom = true, className, controls = true, icons, lazyLoad = true, initialLoadIndex, rendererIcons, rendererClassName, rendererStyle, style, startIndex = "0", i18nData = DEFAULT_I18N_DATA, workerSrc }) => {
|
|
800
855
|
const { activeIndex, files, listVisible, overlayMode, pdfToShow, rememberPosition, selectPdf, toggleList, viewerContainerRef } = usePdfMultiViewer({
|
|
801
856
|
i18nData,
|
|
802
857
|
pdfs,
|
|
@@ -805,12 +860,20 @@ const PdfMultiViewer = ({ pdfs, autoZoom = true, controls = true, icons, lazyLoa
|
|
|
805
860
|
initialLoadIndex,
|
|
806
861
|
workerSrc
|
|
807
862
|
});
|
|
863
|
+
const iconStyles = (0, react.useMemo)(() => buildIconStyles(icons), [icons]);
|
|
808
864
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PdfMultiViewerView_default, {
|
|
809
865
|
activeIndex,
|
|
810
866
|
autoZoom,
|
|
867
|
+
className,
|
|
811
868
|
controls,
|
|
812
869
|
files,
|
|
813
|
-
iconStyles:
|
|
870
|
+
iconStyles: (0, react.useMemo)(() => {
|
|
871
|
+
if (!iconStyles && !style) return void 0;
|
|
872
|
+
return {
|
|
873
|
+
...iconStyles ?? {},
|
|
874
|
+
...style ?? {}
|
|
875
|
+
};
|
|
876
|
+
}, [iconStyles, style]),
|
|
814
877
|
i18nData,
|
|
815
878
|
listVisible,
|
|
816
879
|
onRememberPosition: rememberPosition,
|
|
@@ -818,6 +881,9 @@ const PdfMultiViewer = ({ pdfs, autoZoom = true, controls = true, icons, lazyLoa
|
|
|
818
881
|
onToggleList: toggleList,
|
|
819
882
|
overlayMode,
|
|
820
883
|
pdfToShow,
|
|
884
|
+
rendererIcons,
|
|
885
|
+
rendererClassName,
|
|
886
|
+
rendererStyle,
|
|
821
887
|
viewerContainerRef
|
|
822
888
|
});
|
|
823
889
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["React","ZoomSelectBox","Fragment","PdfRendererControls","PdfRendererView","PdfRenderer","PdfjsLib","PdfMultiViewerView"],"sources":["../src/lib/resizeAutoZoomEvent.ts","../src/contexts/I18nContext.tsx","../src/components/PdfRenderer/ZoomSelectBox.tsx","../src/components/PdfRenderer/PdfRendererControls.tsx","../src/components/PdfRenderer/PdfRendererView.tsx","../src/lib/filenameHelper.ts","../src/components/PdfRenderer/usePdfRenderer.ts","../src/lib/iconStyles.ts","../src/components/PdfRenderer/PdfRenderer.tsx","../src/components/PdfMultiViewer/PdfMultiViewerView.tsx","../src/components/PdfMultiViewer/usePdfMultiViewer.ts","../src/components/PdfMultiViewer/PdfMultiViewer.tsx"],"sourcesContent":["(() => {\n const throttle = (type: string, name: string) => {\n let running = false;\n const func = () => {\n if (running) {\n return;\n }\n running = true;\n requestAnimationFrame(() => {\n window.dispatchEvent(new Event(name));\n running = false;\n });\n };\n window.addEventListener(type, func);\n };\n\n throttle('resize', 'resizeAutoZoom');\n})();\n","import React from 'react';\n\nexport type I18nDataRenderer = {\n zoom?: string;\n originalSize?: string;\n scaleUp?: string;\n scaleDown?: string;\n rotateLeft?: string;\n rotateRight?: string;\n download?: string;\n};\n\nexport const defaultI18n: I18nDataRenderer = {\n zoom: 'Automatic zoom',\n originalSize: 'Original size',\n scaleUp: 'Scale up',\n scaleDown: 'Scale down',\n rotateLeft: 'Rotate left',\n rotateRight: 'Rotate right',\n download: 'Download',\n};\n\nexport const I18nContext = React.createContext(defaultI18n);\n","import { useContext } from 'react';\nimport '@/lib/resizeAutoZoomEvent';\nimport '@/components/PdfRenderer/ZoomSelectBox.css';\nimport { I18nContext, type I18nDataRenderer } from '@/contexts';\n\ntype Props = {\n autoZoom?: boolean;\n scale: number;\n setScale: (scale: number) => void;\n};\n\nconst createSelectOptions = ({ originalSize, zoom }: I18nDataRenderer) => [\n {\n id: 'automated',\n text: `${zoom}`,\n },\n {\n id: '50-percent',\n text: '50%',\n value: 50,\n },\n {\n id: '75-percent',\n text: '75%',\n value: 75,\n },\n {\n id: 'original',\n text: `${originalSize} (100%)`,\n value: 100,\n },\n {\n id: '125-percent',\n text: '125%',\n value: 125,\n },\n {\n id: '150-percent',\n text: '150%',\n value: 150,\n },\n {\n id: '200-percent',\n text: '200%',\n value: 200,\n },\n {\n id: '300-percent',\n text: '300%',\n value: 300,\n },\n {\n id: '400-percent',\n text: '400%',\n value: 400,\n },\n {\n id: 'calculated',\n },\n];\n\nconst showCalculatedScale = (scale: number, i18nData: I18nDataRenderer) => {\n return createSelectOptions(i18nData).filter(\n (option) => option.value === scale,\n ).length === 0 && scale % 10 === 0\n ? scale\n : 0;\n};\n\nconst ZoomSelectBox = ({ autoZoom, scale, setScale }: Props) => {\n const i18nData = useContext(I18nContext);\n\n return (\n <div className=\"dropdown-toolbar-container\">\n <span className=\"dropdown-toolbar\">\n <select\n value={scale}\n onChange={(e) => {\n setScale(parseInt(e.target.value, 10));\n }}\n >\n {createSelectOptions(i18nData).map(({ id, text, value }) => {\n switch (id) {\n case 'calculated':\n return (\n <option\n key={`${id}-${scale}`}\n value={showCalculatedScale(scale, i18nData)}\n hidden={true}\n disabled={true}\n >\n {`${scale}%`}\n </option>\n );\n case 'automated':\n return (\n autoZoom && (\n <option key={`${id}-${scale}`} value={-1}>\n {text}\n </option>\n )\n );\n default:\n return (\n <option key={id} value={value}>\n {text}\n </option>\n );\n }\n })}\n </select>\n </span>\n </div>\n );\n};\n\nexport default ZoomSelectBox;\n","import { Fragment } from 'react';\nimport ZoomSelectBox from '@/components/PdfRenderer/ZoomSelectBox';\nimport '@/components/PdfRenderer/PdfRendererControls.css';\nimport { I18nContext } from '@/contexts';\n\ntype Props = {\n autoZoom?: boolean;\n downloadBtn?: boolean;\n onDownload: () => void;\n onZoomIn: () => void;\n onZoomOut: () => void;\n onRotateRight: () => void;\n onRotateLeft: () => void;\n scale: number;\n setScale: (scale: number) => void;\n};\n\nconst PdfControls = ({\n autoZoom,\n downloadBtn,\n onDownload,\n onZoomIn,\n onZoomOut,\n onRotateRight,\n onRotateLeft,\n scale,\n setScale,\n}: Props) => (\n <div className=\"renderer-controls\">\n <div>\n <I18nContext.Consumer>\n {({ scaleDown, scaleUp }) => (\n <div className=\"button-group\">\n <button\n className=\"renderer-controls-button\"\n type=\"button\"\n onClick={onZoomOut}\n aria-label={scaleDown}\n >\n <span className=\"zoom-out-label\" aria-hidden=\"true\" />\n </button>\n <div className=\"split-button-seperator\" />\n <button\n className=\"renderer-controls-button\"\n type=\"button\"\n onClick={onZoomIn}\n aria-label={scaleUp}\n >\n <span className=\"zoom-in-label\" aria-hidden=\"true\" />\n </button>\n </div>\n )}\n </I18nContext.Consumer>\n <ZoomSelectBox autoZoom={autoZoom} scale={scale} setScale={setScale} />\n <I18nContext.Consumer>\n {({ rotateLeft, rotateRight, download }) => (\n <Fragment>\n <div className=\"button-group\">\n <button\n className=\"renderer-controls-button\"\n type=\"button\"\n onClick={onRotateLeft}\n aria-label={rotateLeft}\n >\n <span className=\"rotate-left-label\" aria-hidden=\"true\" />\n </button>\n <div className=\"split-button-seperator\" />\n <button\n className=\"renderer-controls-button\"\n type=\"button\"\n onClick={onRotateRight}\n aria-label={rotateRight}\n >\n <span className=\"rotate-right-label\" aria-hidden=\"true\" />\n </button>\n </div>\n {downloadBtn && (\n <div className=\"button-group\">\n <button\n className=\"renderer-controls-button\"\n type=\"button\"\n onClick={onDownload}\n aria-label={download}\n >\n <span className=\"download-label\" aria-hidden=\"true\" />\n </button>\n </div>\n )}\n </Fragment>\n )}\n </I18nContext.Consumer>\n </div>\n </div>\n);\n\nexport default PdfControls;\n","import type { CSSProperties, RefObject } from 'react';\nimport PdfRendererControls from '@/components/PdfRenderer/PdfRendererControls';\nimport { defaultI18n, I18nContext, type I18nDataRenderer } from '@/contexts';\n\ntype Props = {\n autoZoom: boolean;\n containerRef: RefObject<HTMLDivElement>;\n controls: boolean;\n downloadBtn: boolean;\n iconStyles?: CSSProperties;\n i18nData?: I18nDataRenderer;\n isLoading: boolean;\n scale: number;\n setScale: (scale: number) => void;\n onDownload: () => void;\n onRotateLeft: () => void;\n onRotateRight: () => void;\n onZoomIn: () => void;\n onZoomOut: () => void;\n};\n\nconst PdfRendererView = ({\n autoZoom,\n containerRef,\n controls,\n downloadBtn,\n iconStyles,\n i18nData,\n isLoading,\n scale,\n setScale,\n onDownload,\n onRotateLeft,\n onRotateRight,\n onZoomIn,\n onZoomOut,\n}: Props) => (\n <div className=\"pdfjs-multi renderer-container\" style={iconStyles}>\n {controls && (\n <I18nContext.Provider value={{ ...defaultI18n, ...(i18nData ?? {}) }}>\n <PdfRendererControls\n autoZoom={autoZoom}\n downloadBtn={downloadBtn}\n scale={scale}\n setScale={setScale}\n onDownload={onDownload}\n onZoomIn={onZoomIn}\n onZoomOut={onZoomOut}\n onRotateRight={onRotateRight}\n onRotateLeft={onRotateLeft}\n />\n </I18nContext.Provider>\n )}\n <div className=\"renderer-stage\">\n <div\n ref={containerRef}\n className={`renderer-target-container ${!controls ? 'no-controls' : ''} `}\n >\n <div id=\"viewer\" className={`pdfViewer ${isLoading ? 'hidden' : ''}`} />\n </div>\n </div>\n </div>\n);\n\nexport default PdfRendererView;\n","const isDataSchema = (url: string) => {\n let i = 0,\n ii = url.length;\n\n while (i < ii && url[i].trim() === '') {\n i++;\n }\n\n return url.substring(i, i + 5).toLowerCase() === 'data:';\n};\n\nexport const getPDFFileNameFromURL = (\n url: string,\n defaultFilename = 'document.pdf',\n) => {\n if (typeof url !== 'string') {\n return defaultFilename;\n }\n\n if (isDataSchema(url)) {\n console.warn(\n 'getPDFFileNameFromURL: ' +\n 'ignoring \"data:\" URL for performance reasons.',\n );\n return defaultFilename;\n }\n\n const reURI = /^(?:(?:[^:]+:)?\\/\\/[^/]+)?([^?#]*)(\\?[^#]*)?(#.*)?$/;\n const reFilename = /[^/?#=]+\\.pdf\\b(?!.*\\.pdf\\b)/i;\n const splitURI = reURI.exec(url);\n let suggestedFilename: RegExpExecArray | string | null = null;\n\n if (splitURI) {\n suggestedFilename =\n reFilename.exec(splitURI[1]) ||\n reFilename.exec(splitURI[2]) ||\n reFilename.exec(splitURI[3]);\n }\n\n if (suggestedFilename) {\n suggestedFilename = suggestedFilename[0];\n\n if (suggestedFilename.includes('%')) {\n try {\n const suggestedFilenameResult = reFilename.exec(\n decodeURIComponent(suggestedFilename),\n );\n\n if (suggestedFilenameResult) {\n suggestedFilename = suggestedFilenameResult[0];\n }\n } catch (_ex) {}\n }\n }\n\n return suggestedFilename || defaultFilename;\n};\n","import type { PDFDocumentProxy } from 'pdfjs-dist';\nimport type { DownloadManager, PDFViewer } from 'pdfjs-dist/web/pdf_viewer.mjs';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { getPDFFileNameFromURL } from '@/lib';\n\nconst SCALE = {\n percent: 100,\n min: 10,\n max: 1000,\n roundTo: 10,\n auto: -1,\n default: 100,\n};\n\nconst AUTO_FIT = {\n maxContainerWidth: 1020,\n padding: 56,\n fallbackWidth: 1019,\n};\n\nconst ZOOM = {\n largeStepMin: 110,\n largeStepMax: 990,\n specialSteps: new Set([75, 125]),\n roundingExceptions: new Set([125]),\n stepLarge: 20,\n stepDefault: 10,\n stepSmall: 5,\n};\n\nconst ROTATION_STEP = 90;\nconst SCROLL_DEFAULT = 0;\n\nconst roundToNearest = (numToRound: number, numToRoundTo: number) =>\n Math.round(numToRound / numToRoundTo) * numToRoundTo;\n\nexport type RendererDocumentPosition = {\n zoom: number;\n rotation: number;\n scrollTop: number | null;\n scrollLeft?: number | null;\n};\n\nexport type PdfChangeHook = (\n documentIndex: string,\n position: RendererDocumentPosition,\n) => void;\n\ntype UsePdfRendererArgs = {\n activeIndex: string;\n autoZoom: boolean;\n pdfChangeHook?: PdfChangeHook | null;\n pdfDoc: PDFDocumentProxy;\n rotation: number;\n scrollLeft?: number | null;\n scrollTop?: number | null;\n zoom?: number;\n};\n\nexport const usePdfRenderer = ({\n activeIndex,\n autoZoom,\n pdfChangeHook,\n pdfDoc,\n rotation,\n scrollLeft,\n scrollTop,\n zoom,\n}: UsePdfRendererArgs) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const pdfViewerRef = useRef<PDFViewer | null>(null);\n const downloadManagerRef = useRef<DownloadManager | null>(null);\n const initialAutoZoomRef = useRef(autoZoom);\n const latestPdfDocRef = useRef(pdfDoc);\n const [scale, setScaleState] = useState(SCALE.default);\n const [isLoading, setIsLoading] = useState(true);\n\n const scaleRef = useRef(scale);\n useEffect(() => {\n scaleRef.current = scale;\n }, [scale]);\n\n useEffect(() => {\n latestPdfDocRef.current = pdfDoc;\n }, [pdfDoc]);\n\n const applyScale = useCallback((nextScaleValue: number) => {\n const nextScale = nextScaleValue >= SCALE.min ? nextScaleValue : SCALE.min;\n setScaleState(nextScale);\n if (pdfViewerRef.current) {\n pdfViewerRef.current.currentScaleValue = String(\n nextScale / SCALE.percent,\n );\n }\n }, []);\n\n const autoFitScale = useCallback(() => {\n const firstPage = pdfViewerRef.current?._pages?.[0];\n if (!firstPage) return;\n\n const firstPageWidth = firstPage.viewport.width;\n const currentScale = firstPage.scale;\n const originalWidth = firstPageWidth / currentScale;\n const offsetWidth = containerRef.current?.offsetWidth;\n const containerWidth =\n offsetWidth && offsetWidth < AUTO_FIT.maxContainerWidth\n ? offsetWidth - AUTO_FIT.padding\n : AUTO_FIT.fallbackWidth;\n let nextScale = SCALE.auto;\n\n if (containerRef.current) {\n nextScale = Math.abs(containerWidth) / originalWidth;\n }\n applyScale(nextScale * SCALE.percent);\n }, [applyScale]);\n\n const setScale = useCallback(\n (nextScaleValue: number) => {\n if (autoZoom && nextScaleValue < 0) {\n autoFitScale();\n return;\n }\n\n applyScale(nextScaleValue);\n },\n [applyScale, autoFitScale, autoZoom],\n );\n\n const setScrollTop = useCallback((nextScrollTop: number | null) => {\n if (containerRef.current) {\n containerRef.current.scrollTop = nextScrollTop ?? SCROLL_DEFAULT;\n }\n }, []);\n\n const setScrollLeft = useCallback((nextScrollLeft: number | null) => {\n if (containerRef.current) {\n containerRef.current.scrollLeft = nextScrollLeft ?? SCROLL_DEFAULT;\n }\n }, []);\n\n const rePosition = useCallback(async () => {\n if (!pdfViewerRef.current) return;\n\n await pdfViewerRef.current.firstPagePromise;\n\n if (rotation) {\n pdfViewerRef.current.pagesRotation = rotation;\n }\n\n if (zoom) {\n setScale(zoom);\n } else if (!zoom && autoZoom) {\n autoFitScale();\n }\n\n if (typeof scrollTop !== 'undefined') {\n setScrollTop(scrollTop ?? null);\n }\n\n if (typeof scrollLeft !== 'undefined') {\n setScrollLeft(scrollLeft ?? null);\n }\n }, [\n autoFitScale,\n autoZoom,\n rotation,\n scrollLeft,\n scrollTop,\n setScale,\n setScrollLeft,\n setScrollTop,\n zoom,\n ]);\n\n const rePositionRef = useRef(rePosition);\n useEffect(() => {\n rePositionRef.current = rePosition;\n }, [rePosition]);\n\n useEffect(() => {\n let cancelled = false;\n\n const setupViewer = async () => {\n const { PdfjsLib } = await import('@/lib/pdfjsLib');\n if (cancelled) return;\n globalThis.pdfjsLib = PdfjsLib;\n\n const viewerModule =\n (\n globalThis as {\n __pdfjsViewer?: typeof import('pdfjs-dist/web/pdf_viewer.mjs');\n }\n ).__pdfjsViewer ?? (await import('pdfjs-dist/web/pdf_viewer.mjs'));\n const { PDFViewer, DownloadManager, EventBus } = viewerModule;\n\n downloadManagerRef.current = new DownloadManager();\n\n if (!containerRef.current) {\n return;\n }\n\n pdfViewerRef.current = new PDFViewer({\n container: containerRef.current,\n eventBus: new EventBus(),\n });\n\n pdfViewerRef.current.setDocument(latestPdfDocRef.current);\n\n if (initialAutoZoomRef.current) {\n window.addEventListener('resizeAutoZoom', autoFitScale);\n }\n\n await rePositionRef.current();\n if (!cancelled) {\n setIsLoading(false);\n }\n };\n\n setupViewer();\n\n return () => {\n cancelled = true;\n if (initialAutoZoomRef.current) {\n window.removeEventListener('resizeAutoZoom', autoFitScale);\n }\n pdfViewerRef.current = null;\n downloadManagerRef.current = null;\n };\n }, [autoFitScale]);\n\n const prevPdfDocRef = useRef(pdfDoc);\n const prevActiveIndexRef = useRef(activeIndex);\n\n useEffect(() => {\n if (!pdfViewerRef.current) {\n prevPdfDocRef.current = pdfDoc;\n prevActiveIndexRef.current = activeIndex;\n return;\n }\n\n if (prevPdfDocRef.current !== pdfDoc) {\n if (typeof pdfChangeHook === 'function') {\n pdfChangeHook(String(prevActiveIndexRef.current), {\n zoom: scaleRef.current,\n rotation: pdfViewerRef.current.pagesRotation,\n scrollTop: containerRef.current?.scrollTop ?? null,\n scrollLeft: containerRef.current?.scrollLeft ?? null,\n });\n }\n\n pdfViewerRef.current.setDocument(pdfDoc);\n rePosition();\n }\n\n prevPdfDocRef.current = pdfDoc;\n prevActiveIndexRef.current = activeIndex;\n }, [activeIndex, pdfChangeHook, pdfDoc, rePosition]);\n\n const zoomIn = useCallback(() => {\n const nextScale = roundToNearest(scaleRef.current, SCALE.roundTo);\n let newScale = nextScale;\n\n if (nextScale >= ZOOM.largeStepMin && nextScale < ZOOM.largeStepMax) {\n newScale = nextScale + ZOOM.stepLarge;\n } else if (ZOOM.specialSteps.has(nextScale)) {\n newScale = nextScale + ZOOM.stepSmall;\n } else {\n newScale = nextScale + ZOOM.stepDefault;\n }\n\n if (newScale > SCALE.max) return;\n\n setScale(newScale);\n }, [setScale]);\n\n const zoomOut = useCallback(() => {\n let nextScale = scaleRef.current;\n nextScale = ZOOM.roundingExceptions.has(nextScale)\n ? nextScale\n : roundToNearest(nextScale, SCALE.roundTo);\n let newScale = nextScale;\n\n if (nextScale > ZOOM.largeStepMin && !ZOOM.specialSteps.has(nextScale)) {\n newScale = nextScale - ZOOM.stepLarge;\n } else if (ZOOM.specialSteps.has(nextScale)) {\n newScale = nextScale - ZOOM.stepSmall;\n } else {\n newScale = nextScale - ZOOM.stepDefault;\n }\n\n if (newScale <= 0) return;\n\n setScale(newScale);\n }, [setScale]);\n\n const rotateRight = useCallback(() => {\n if (!pdfViewerRef.current) return;\n\n const currentRotation = pdfViewerRef.current.pagesRotation;\n pdfViewerRef.current.pagesRotation = currentRotation + ROTATION_STEP;\n }, []);\n\n const rotateLeft = useCallback(() => {\n if (!pdfViewerRef.current) return;\n\n const currentRotation = pdfViewerRef.current.pagesRotation;\n pdfViewerRef.current.pagesRotation = currentRotation - ROTATION_STEP;\n }, []);\n\n const download = useCallback(async () => {\n if (!downloadManagerRef.current) return;\n\n const pdfDocWithTransport = pdfDoc as PDFDocumentProxy & {\n _transport?: { _params?: { url?: string } };\n };\n const url = pdfDocWithTransport._transport?._params?.url;\n let filename = getPDFFileNameFromURL(url ?? '');\n\n if (typeof pdfDoc.getMetadata === 'function') {\n try {\n const metadata = await pdfDoc.getMetadata();\n const contentDispositionFilename = (\n metadata as { contentDispositionFilename?: string | null }\n ).contentDispositionFilename;\n\n if (\n typeof contentDispositionFilename === 'string' &&\n contentDispositionFilename.trim()\n ) {\n filename = contentDispositionFilename;\n }\n } catch (_error) {}\n }\n\n const downloadByUrl = () => {\n if (!url) return;\n (\n downloadManagerRef.current as DownloadManager & {\n downloadUrl: (downloadUrl: string, downloadFilename: string) => void;\n }\n ).downloadUrl(url, filename);\n };\n\n try {\n const data = await pdfDoc.getData();\n downloadManagerRef.current.download(data, url ?? '', filename);\n } catch (_e) {\n downloadByUrl();\n }\n }, [pdfDoc]);\n\n return {\n containerRef,\n download,\n isLoading,\n pdfViewerRef,\n rotateLeft,\n rotateRight,\n scale,\n setScale,\n zoomIn,\n zoomOut,\n };\n};\n","import type { CSSProperties } from 'react';\nimport type { IconConfig } from '@/types/iconConfig';\n\nconst iconVarMap = {\n zoomIn: '--pdfjs-multi-control-icon-zoom-in',\n zoomOut: '--pdfjs-multi-control-icon-zoom-out',\n rotateLeft: '--pdfjs-multi-control-icon-rotate-left',\n rotateRight: '--pdfjs-multi-control-icon-rotate-right',\n download: '--pdfjs-multi-control-icon-download',\n selectArrow: '--pdfjs-multi-select-icon',\n toggleList: '--pdfjs-multi-control-icon-toggle-list',\n texture: '--pdfjs-multi-texture',\n} as const;\n\nconst toCssValue = (value: string) => {\n const trimmed = value.trim();\n if (!trimmed) return undefined;\n if (trimmed === 'none') return 'none';\n if (/^[a-z-]+\\(/i.test(trimmed)) return trimmed;\n return `url(\"${trimmed.replaceAll('\"', '\\\\\"')}\")`;\n};\n\nexport const buildIconStyles = (\n icons?: IconConfig,\n): CSSProperties | undefined => {\n if (!icons) return undefined;\n\n const style: Record<string, string> = {};\n\n for (const [key, cssVar] of Object.entries(iconVarMap)) {\n const iconValue = icons[key as keyof IconConfig];\n if (!iconValue) continue;\n\n const cssValue = toCssValue(iconValue);\n if (!cssValue) continue;\n\n style[cssVar] = cssValue;\n }\n\n return Object.keys(style).length ? (style as CSSProperties) : undefined;\n};\n","import type { PDFDocumentProxy } from 'pdfjs-dist';\nimport type { PDFViewer } from 'pdfjs-dist/web/pdf_viewer.mjs';\nimport { forwardRef, useImperativeHandle } from 'react';\nimport 'pdfjs-dist/web/pdf_viewer.css';\nimport '@/components/PdfRenderer/PdfRenderer.css';\nimport PdfRendererView from '@/components/PdfRenderer/PdfRendererView';\nimport {\n type PdfChangeHook,\n usePdfRenderer,\n} from '@/components/PdfRenderer/usePdfRenderer';\nimport { defaultI18n, type I18nDataRenderer } from '@/contexts';\nimport { buildIconStyles } from '@/lib/iconStyles';\nimport type { IconConfig } from '@/types/iconConfig';\n\nexport type { RendererDocumentPosition } from '@/components/PdfRenderer/usePdfRenderer';\n\ntype DefaultProps = {\n activeIndex?: string;\n autoZoom?: boolean;\n controls?: boolean;\n downloadBtn: boolean;\n icons?: IconConfig;\n i18nData?: I18nDataRenderer;\n pdfChangeHook?: PdfChangeHook | null;\n zoom?: number;\n rotation?: number;\n scrollTop?: number | null;\n scrollLeft?: number | null;\n};\n\ntype Props = {\n pdfDoc: PDFDocumentProxy;\n} & Partial<DefaultProps>;\n\nexport type PdfRendererHandle = {\n pdfViewer: PDFViewer | null;\n};\n\nconst PdfRenderer = forwardRef<PdfRendererHandle, Props>(\n (\n {\n pdfDoc,\n activeIndex = '0',\n autoZoom = true,\n controls = true,\n downloadBtn = true,\n icons,\n i18nData = defaultI18n,\n pdfChangeHook = null,\n zoom,\n rotation = 0,\n scrollTop = 0,\n scrollLeft = 0,\n },\n ref,\n ) => {\n const {\n containerRef,\n download,\n isLoading,\n pdfViewerRef,\n rotateLeft,\n rotateRight,\n scale,\n setScale,\n zoomIn,\n zoomOut,\n } = usePdfRenderer({\n activeIndex,\n autoZoom,\n pdfChangeHook,\n pdfDoc,\n rotation,\n scrollLeft,\n scrollTop,\n zoom,\n });\n\n useImperativeHandle(ref, () => ({\n get pdfViewer() {\n return pdfViewerRef.current;\n },\n }));\n\n const iconStyles = buildIconStyles(icons);\n\n return (\n <PdfRendererView\n autoZoom={autoZoom}\n containerRef={containerRef}\n controls={controls}\n downloadBtn={downloadBtn}\n iconStyles={iconStyles}\n i18nData={i18nData}\n isLoading={isLoading}\n scale={scale}\n setScale={setScale}\n onDownload={download}\n onRotateLeft={rotateLeft}\n onRotateRight={rotateRight}\n onZoomIn={zoomIn}\n onZoomOut={zoomOut}\n />\n );\n },\n);\n\nPdfRenderer.displayName = 'PdfRenderer';\n\nexport default PdfRenderer;\n","import type { PDFDocumentProxy } from 'pdfjs-dist';\nimport type { CSSProperties, RefObject } from 'react';\nimport type {\n I18nData,\n PdfFile,\n} from '@/components/PdfMultiViewer/usePdfMultiViewer';\nimport PdfRenderer from '@/components/PdfRenderer/PdfRenderer';\nimport type { RendererDocumentPosition } from '@/components/PdfRenderer/usePdfRenderer';\n\ntype Props = {\n activeIndex: string;\n autoZoom: boolean;\n controls: boolean;\n files: PdfFile[];\n iconStyles?: CSSProperties;\n i18nData: I18nData;\n listVisible: boolean;\n overlayMode: boolean;\n pdfToShow?: PdfFile;\n viewerContainerRef: RefObject<HTMLDivElement>;\n onRememberPosition: (\n index: string,\n position: RendererDocumentPosition,\n ) => void;\n onSelectPdf: (nextIndex: string, file: PdfFile) => () => void;\n onToggleList: () => void;\n};\n\nconst PdfMultiViewerView = ({\n activeIndex,\n autoZoom,\n controls,\n files,\n iconStyles,\n i18nData,\n listVisible,\n overlayMode,\n pdfToShow,\n viewerContainerRef,\n onRememberPosition,\n onSelectPdf,\n onToggleList,\n}: Props) => (\n <div\n className=\"pdfjs-multi pdf-multi-viewer\"\n ref={viewerContainerRef}\n style={iconStyles}\n >\n <div className=\"pdf-multi-viewer-option-bar\">\n <button\n className={`viewer-controls-button${listVisible ? ' toggled' : ''}`}\n onClick={onToggleList}\n type=\"button\"\n aria-label=\"Toggle list\"\n >\n <span className=\"toggle-list-label\" aria-hidden=\"true\" />\n </button>\n </div>\n <ul\n className={`pdf-viewer-list${!listVisible ? ' hidden' : ''}${\n overlayMode ? ' overlay' : ''\n }`}\n >\n {files.map((file, index) => {\n const handleSelect = onSelectPdf(String(index), file);\n const isLoading = Boolean(file.isLoading && !file.pdfProxy);\n\n return (\n <li\n className={`pdf-viewer-list-item${file.pdfProxy ? ' loaded' : ''}${\n isLoading ? ' loading' : ''\n }${activeIndex === String(index) ? ' active' : ''}`}\n key={file.source}\n >\n <button\n className=\"pdf-viewer-list-item-button\"\n onClick={handleSelect}\n type=\"button\"\n >\n {file.title || file.source}\n {file.pdfProxy && (\n <div className=\"pdf-viewer-list-item-meta\">\n {i18nData?.pages ?? 'Pages'}: {file.pdfProxy.numPages}\n </div>\n )}\n {isLoading && !file.pdfProxy && (\n <div className=\"pdf-viewer-list-item-meta\">\n {i18nData?.loading ?? 'Loading...'}\n </div>\n )}\n </button>\n </li>\n );\n })}\n </ul>\n <div className=\"pdf-viewer-multi-renderer\">\n {pdfToShow?.pdfProxy ? (\n <PdfRenderer\n activeIndex={activeIndex}\n autoZoom={autoZoom}\n controls={controls}\n pdfDoc={pdfToShow.pdfProxy as PDFDocumentProxy}\n i18nData={i18nData}\n pdfChangeHook={onRememberPosition}\n zoom={pdfToShow.zoom}\n rotation={pdfToShow.rotation}\n scrollTop={pdfToShow.scrollTop}\n scrollLeft={pdfToShow.scrollLeft}\n />\n ) : pdfToShow ? (\n <output className=\"pdf-viewer-loading\" aria-live=\"polite\">\n <span className=\"pdf-viewer-loading-spinner\" aria-hidden=\"true\" />\n <span className=\"pdf-viewer-loading-text\">\n {i18nData?.loading ?? 'Loading...'}\n </span>\n </output>\n ) : null}\n </div>\n </div>\n);\n\nexport default PdfMultiViewerView;\n","import type { PDFDocumentProxy, PDFWorker } from 'pdfjs-dist';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport type { RendererDocumentPosition } from '@/components/PdfRenderer/usePdfRenderer';\nimport type { I18nDataRenderer } from '@/contexts';\nimport { PdfjsLib } from '@/lib';\n\nexport type PdfDefinition = {\n title: string;\n source: string;\n};\n\nexport type PdfSource = string | PdfDefinition;\n\nexport type PdfFile = {\n index?: number;\n title?: string;\n zoom?: number;\n rotation?: number;\n scrollTop?: number | null;\n scrollLeft?: number | null;\n isLoading?: boolean;\n source: string;\n pdfProxy: PDFDocumentProxy | null;\n};\n\nexport type I18nData = {\n loading?: string;\n pages?: string;\n} & I18nDataRenderer;\n\ntype UsePdfMultiViewerArgs = {\n pdfs: PdfSource[];\n startIndex: string;\n i18nData: I18nData;\n lazyLoad: boolean;\n initialLoadIndex?: string | number;\n workerSrc?: string;\n};\n\nconst createPdfFile = (pdf: PdfSource): PdfFile => {\n return typeof pdf === 'object'\n ? { ...pdf, isLoading: false, pdfProxy: null }\n : {\n isLoading: false,\n source: pdf,\n pdfProxy: null,\n };\n};\n\nexport const usePdfMultiViewer = ({\n pdfs,\n startIndex,\n i18nData,\n lazyLoad,\n initialLoadIndex,\n workerSrc,\n}: UsePdfMultiViewerArgs) => {\n const viewerContainerRef = useRef<HTMLDivElement>(null);\n const initialFilesRef = useRef<PdfFile[] | null>(null);\n const workerRef = useRef<PDFWorker | null>(null);\n const loadingIndicesRef = useRef<Set<number>>(new Set());\n const initialLoadDoneRef = useRef(false);\n\n const [files, setFiles] = useState<PdfFile[]>(() => {\n const mapped = pdfs.map(createPdfFile);\n initialFilesRef.current = mapped;\n return mapped;\n });\n const [activeIndex, setActiveIndex] = useState<string>(() => `${startIndex}`);\n const [listVisible, setListVisible] = useState(true);\n const [overlayMode, setOverlayMode] = useState(false);\n\n const resolveIndex = useCallback((index?: string | number) => {\n const resolved = Number(index);\n return Number.isNaN(resolved) ? 0 : resolved;\n }, []);\n\n useEffect(() => {\n if (workerSrc) {\n PdfjsLib.GlobalWorkerOptions.workerSrc = workerSrc;\n const worker = PdfjsLib.PDFWorker.create({});\n workerRef.current = worker;\n return () => {\n worker.destroy();\n if (workerRef.current === worker) {\n workerRef.current = null;\n }\n };\n }\n return undefined;\n }, [workerSrc]);\n\n const toggleList = useCallback(() => {\n setListVisible((state) => !state);\n }, []);\n\n const setFileLoading = useCallback((index: number, isLoading: boolean) => {\n setFiles((state) =>\n state.map((pdfFile, pdfIndex) => {\n if (pdfIndex !== index) return pdfFile;\n return {\n ...pdfFile,\n isLoading,\n };\n }),\n );\n }, []);\n\n const loadPdfDocument = useCallback(\n async (file: PdfFile, index: number) => {\n if (file.pdfProxy) return;\n if (loadingIndicesRef.current.has(index)) return;\n\n loadingIndicesRef.current.add(index);\n setFileLoading(index, true);\n\n try {\n const worker = workerRef.current;\n const pdfDoc = await PdfjsLib.getDocument({\n url: file.source,\n ...(worker ? { worker } : {}),\n }).promise;\n\n setFiles((state) =>\n state.map((pdfFile, pdfIndex) => {\n if (pdfIndex !== index) return pdfFile;\n return {\n ...pdfFile,\n isLoading: false,\n pdfProxy: pdfDoc,\n };\n }),\n );\n } catch (_error) {\n setFileLoading(index, false);\n } finally {\n loadingIndicesRef.current.delete(index);\n }\n },\n [setFileLoading],\n );\n\n const selectPdf = useCallback(\n (nextIndex: string, file: PdfFile) => () => {\n setActiveIndex(nextIndex);\n if (lazyLoad && !file.pdfProxy) {\n void loadPdfDocument(file, Number(nextIndex));\n }\n if (overlayMode && listVisible) toggleList();\n },\n [lazyLoad, listVisible, loadPdfDocument, overlayMode, toggleList],\n );\n\n const updateOverlayMode = useCallback((currentContainerWidth?: number) => {\n const containerWidth =\n currentContainerWidth || viewerContainerRef.current?.offsetWidth;\n\n setOverlayMode((current) => {\n if (\n containerWidth &&\n containerWidth >= 330 &&\n containerWidth <= 667 &&\n !current\n ) {\n return true;\n }\n\n if (current && containerWidth && containerWidth > 667) {\n return false;\n }\n\n return current;\n });\n }, []);\n\n const onResizeEvent = useCallback(() => {\n updateOverlayMode(viewerContainerRef.current?.offsetWidth);\n }, [updateOverlayMode]);\n\n const loadPdfDocuments = useCallback(() => {\n const currentFiles = initialFilesRef.current ?? [];\n currentFiles.forEach(async (file, index) => {\n await loadPdfDocument(file, index);\n });\n }, [loadPdfDocument]);\n\n const rememberPosition = useCallback(\n (index: string, position: RendererDocumentPosition) => {\n setFiles((state) =>\n state.map((pdfFile, pdfIndex) => {\n if (pdfIndex !== Number(index)) return pdfFile;\n return {\n ...pdfFile,\n ...position,\n };\n }),\n );\n },\n [],\n );\n\n useEffect(() => {\n window.addEventListener('resizeAutoZoom', onResizeEvent);\n updateOverlayMode(viewerContainerRef.current?.offsetWidth);\n if (!lazyLoad) {\n loadPdfDocuments();\n }\n\n return () => {\n window.removeEventListener('resizeAutoZoom', onResizeEvent);\n };\n }, [lazyLoad, loadPdfDocuments, onResizeEvent, updateOverlayMode]);\n\n useEffect(() => {\n if (!lazyLoad) return;\n const initialIndex = resolveIndex(initialLoadIndex ?? startIndex);\n const nextFile = files[initialIndex];\n if (!nextFile) return;\n if (initialLoadDoneRef.current) return;\n initialLoadDoneRef.current = true;\n void loadPdfDocument(nextFile, initialIndex);\n }, [\n files,\n initialLoadIndex,\n lazyLoad,\n loadPdfDocument,\n resolveIndex,\n startIndex,\n ]);\n\n useEffect(() => {\n if (!lazyLoad) return;\n const nextIndex = resolveIndex(activeIndex);\n const nextFile = files[nextIndex];\n if (!nextFile) return;\n void loadPdfDocument(nextFile, nextIndex);\n }, [activeIndex, files, lazyLoad, loadPdfDocument, resolveIndex]);\n\n const pdfToShow = files[Number(activeIndex)];\n\n return {\n activeIndex,\n files,\n i18nData,\n listVisible,\n overlayMode,\n pdfToShow,\n rememberPosition,\n selectPdf,\n toggleList,\n viewerContainerRef,\n };\n};\n","import '@/components/PdfMultiViewer/PdfMultiViewer.css';\nimport PdfMultiViewerView from '@/components/PdfMultiViewer/PdfMultiViewerView';\nimport {\n type I18nData,\n type PdfSource,\n usePdfMultiViewer,\n} from '@/components/PdfMultiViewer/usePdfMultiViewer';\nimport { buildIconStyles } from '@/lib/iconStyles';\nimport type { IconConfig } from '@/types/iconConfig';\n\ntype DefaultProps = {\n autoZoom?: boolean;\n controls?: boolean;\n icons?: IconConfig;\n lazyLoad?: boolean;\n initialLoadIndex?: string | number;\n startIndex?: string;\n i18nData?: I18nData;\n workerSrc?: string;\n};\n\ntype Props = {\n pdfs: PdfSource[];\n} & Partial<DefaultProps>;\n\nconst PdfMultiViewer = ({\n pdfs,\n autoZoom = true,\n controls = true,\n icons,\n lazyLoad = true,\n initialLoadIndex,\n startIndex = '0',\n i18nData = { loading: 'Loading...', pages: 'Pages' },\n workerSrc,\n}: Props) => {\n const {\n activeIndex,\n files,\n listVisible,\n overlayMode,\n pdfToShow,\n rememberPosition,\n selectPdf,\n toggleList,\n viewerContainerRef,\n } = usePdfMultiViewer({\n i18nData,\n pdfs,\n startIndex,\n lazyLoad,\n initialLoadIndex,\n workerSrc,\n });\n\n const iconStyles = buildIconStyles(icons);\n\n return (\n <PdfMultiViewerView\n activeIndex={activeIndex}\n autoZoom={autoZoom}\n controls={controls}\n files={files}\n iconStyles={iconStyles}\n i18nData={i18nData}\n listVisible={listVisible}\n onRememberPosition={rememberPosition}\n onSelectPdf={selectPdf}\n onToggleList={toggleList}\n overlayMode={overlayMode}\n pdfToShow={pdfToShow}\n viewerContainerRef={viewerContainerRef}\n />\n );\n};\n\nexport default PdfMultiViewer;\n\nexport type { I18nData };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["React","ZoomSelectBox","Fragment","PdfRendererControls","PdfRendererView","PdfRenderer","PdfjsLib","PdfMultiViewerView"],"sources":["../src/lib/resizeAutoZoomEvent.ts","../src/contexts/I18nContext.tsx","../src/components/PdfRenderer/ZoomSelectBox.tsx","../src/components/PdfRenderer/PdfRendererControls.tsx","../src/components/PdfRenderer/PdfRendererView.tsx","../src/lib/filenameHelper.ts","../src/components/PdfRenderer/usePdfRenderer.ts","../src/lib/iconStyles.ts","../src/components/PdfRenderer/PdfRenderer.tsx","../src/components/PdfMultiViewer/PdfMultiViewerView.tsx","../src/components/PdfMultiViewer/usePdfMultiViewer.ts","../src/components/PdfMultiViewer/PdfMultiViewer.tsx"],"sourcesContent":["(() => {\n const throttle = (type: string, name: string) => {\n let running = false;\n const func = () => {\n if (running) {\n return;\n }\n running = true;\n requestAnimationFrame(() => {\n window.dispatchEvent(new Event(name));\n running = false;\n });\n };\n window.addEventListener(type, func);\n };\n\n throttle('resize', 'resizeAutoZoom');\n})();\n","import React from 'react';\n\nexport type I18nDataRenderer = {\n zoom?: string;\n originalSize?: string;\n scaleUp?: string;\n scaleDown?: string;\n rotateLeft?: string;\n rotateRight?: string;\n download?: string;\n};\n\nexport const defaultI18n: I18nDataRenderer = {\n zoom: 'Automatic zoom',\n originalSize: 'Original size',\n scaleUp: 'Scale up',\n scaleDown: 'Scale down',\n rotateLeft: 'Rotate left',\n rotateRight: 'Rotate right',\n download: 'Download',\n};\n\nexport const I18nContext = React.createContext(defaultI18n);\n","import { useContext } from 'react';\nimport '@/lib/resizeAutoZoomEvent';\nimport '@/components/PdfRenderer/ZoomSelectBox.css';\nimport { I18nContext, type I18nDataRenderer } from '@/contexts';\n\ntype Props = {\n autoZoom?: boolean;\n scale: number;\n setScale: (scale: number) => void;\n};\n\nconst createSelectOptions = ({ originalSize, zoom }: I18nDataRenderer) => [\n {\n id: 'automated',\n text: `${zoom}`,\n },\n {\n id: '50-percent',\n text: '50%',\n value: 50,\n },\n {\n id: '75-percent',\n text: '75%',\n value: 75,\n },\n {\n id: 'original',\n text: `${originalSize} (100%)`,\n value: 100,\n },\n {\n id: '125-percent',\n text: '125%',\n value: 125,\n },\n {\n id: '150-percent',\n text: '150%',\n value: 150,\n },\n {\n id: '200-percent',\n text: '200%',\n value: 200,\n },\n {\n id: '300-percent',\n text: '300%',\n value: 300,\n },\n {\n id: '400-percent',\n text: '400%',\n value: 400,\n },\n {\n id: 'calculated',\n },\n];\n\nconst showCalculatedScale = (scale: number, i18nData: I18nDataRenderer) => {\n return createSelectOptions(i18nData).filter(\n (option) => option.value === scale,\n ).length === 0 && scale % 10 === 0\n ? scale\n : 0;\n};\n\nconst ZoomSelectBox = ({ autoZoom, scale, setScale }: Props) => {\n const i18nData = useContext(I18nContext);\n\n return (\n <div className=\"dropdown-toolbar-container\">\n <span className=\"dropdown-toolbar\">\n <select\n value={scale}\n onChange={(e) => {\n setScale(parseInt(e.target.value, 10));\n }}\n >\n {createSelectOptions(i18nData).map(({ id, text, value }) => {\n switch (id) {\n case 'calculated':\n return (\n <option\n key={`${id}-${scale}`}\n value={showCalculatedScale(scale, i18nData)}\n hidden={true}\n disabled={true}\n >\n {`${scale}%`}\n </option>\n );\n case 'automated':\n return (\n autoZoom && (\n <option key={`${id}-${scale}`} value={-1}>\n {text}\n </option>\n )\n );\n default:\n return (\n <option key={id} value={value}>\n {text}\n </option>\n );\n }\n })}\n </select>\n </span>\n </div>\n );\n};\n\nexport default ZoomSelectBox;\n","import type { CSSProperties } from 'react';\nimport { Fragment } from 'react';\nimport ZoomSelectBox from '@/components/PdfRenderer/ZoomSelectBox';\nimport '@/components/PdfRenderer/PdfRendererControls.css';\nimport { I18nContext } from '@/contexts';\n\ntype Props = {\n autoZoom?: boolean;\n downloadBtn?: boolean;\n iconStyles?: CSSProperties;\n onDownload: () => void;\n onZoomIn: () => void;\n onZoomOut: () => void;\n onRotateRight: () => void;\n onRotateLeft: () => void;\n scale: number;\n setScale: (scale: number) => void;\n};\n\nconst PdfControls = ({\n autoZoom,\n downloadBtn,\n iconStyles,\n onDownload,\n onZoomIn,\n onZoomOut,\n onRotateRight,\n onRotateLeft,\n scale,\n setScale,\n}: Props) => (\n <div className=\"renderer-controls\" style={iconStyles}>\n <div>\n <I18nContext.Consumer>\n {({ scaleDown, scaleUp }) => (\n <div className=\"button-group\">\n <button\n className=\"renderer-controls-button\"\n type=\"button\"\n onClick={onZoomOut}\n aria-label={scaleDown}\n >\n <span className=\"zoom-out-label\" aria-hidden=\"true\" />\n </button>\n <div className=\"split-button-seperator\" />\n <button\n className=\"renderer-controls-button\"\n type=\"button\"\n onClick={onZoomIn}\n aria-label={scaleUp}\n >\n <span className=\"zoom-in-label\" aria-hidden=\"true\" />\n </button>\n </div>\n )}\n </I18nContext.Consumer>\n <ZoomSelectBox autoZoom={autoZoom} scale={scale} setScale={setScale} />\n <I18nContext.Consumer>\n {({ rotateLeft, rotateRight, download }) => (\n <Fragment>\n <div className=\"button-group\">\n <button\n className=\"renderer-controls-button\"\n type=\"button\"\n onClick={onRotateLeft}\n aria-label={rotateLeft}\n >\n <span className=\"rotate-left-label\" aria-hidden=\"true\" />\n </button>\n <div className=\"split-button-seperator\" />\n <button\n className=\"renderer-controls-button\"\n type=\"button\"\n onClick={onRotateRight}\n aria-label={rotateRight}\n >\n <span className=\"rotate-right-label\" aria-hidden=\"true\" />\n </button>\n </div>\n {downloadBtn && (\n <div className=\"button-group\">\n <button\n className=\"renderer-controls-button\"\n type=\"button\"\n onClick={onDownload}\n aria-label={download}\n >\n <span className=\"download-label\" aria-hidden=\"true\" />\n </button>\n </div>\n )}\n </Fragment>\n )}\n </I18nContext.Consumer>\n </div>\n </div>\n);\n\nexport default PdfControls;\n","import type { CSSProperties, RefObject } from 'react';\nimport { useMemo } from 'react';\nimport PdfRendererControls from '@/components/PdfRenderer/PdfRendererControls';\nimport { defaultI18n, I18nContext, type I18nDataRenderer } from '@/contexts';\n\ntype Props = {\n autoZoom: boolean;\n className?: string;\n containerRef: RefObject<HTMLDivElement>;\n controls: boolean;\n downloadBtn: boolean;\n iconStyles?: CSSProperties;\n i18nData?: I18nDataRenderer;\n isLoading: boolean;\n scale: number;\n setScale: (scale: number) => void;\n onDownload: () => void;\n onRotateLeft: () => void;\n onRotateRight: () => void;\n onZoomIn: () => void;\n onZoomOut: () => void;\n};\n\nconst PdfRendererView = ({\n autoZoom,\n className,\n containerRef,\n controls,\n downloadBtn,\n iconStyles,\n i18nData,\n isLoading,\n scale,\n setScale,\n onDownload,\n onRotateLeft,\n onRotateRight,\n onZoomIn,\n onZoomOut,\n}: Props) => {\n const i18nValue = useMemo(\n () => ({ ...defaultI18n, ...(i18nData ?? {}) }),\n [i18nData],\n );\n\n return (\n <div\n className={`pdfjs-multi renderer-container${className ? ` ${className}` : ''}`}\n style={iconStyles}\n >\n {controls && (\n <I18nContext.Provider value={i18nValue}>\n <PdfRendererControls\n autoZoom={autoZoom}\n downloadBtn={downloadBtn}\n iconStyles={iconStyles}\n scale={scale}\n setScale={setScale}\n onDownload={onDownload}\n onZoomIn={onZoomIn}\n onZoomOut={onZoomOut}\n onRotateRight={onRotateRight}\n onRotateLeft={onRotateLeft}\n />\n </I18nContext.Provider>\n )}\n <div className=\"renderer-stage\">\n <div\n ref={containerRef}\n className={`renderer-target-container ${!controls ? 'no-controls' : ''} `}\n >\n <div\n id=\"viewer\"\n className={`pdfViewer ${isLoading ? 'hidden' : ''}`}\n />\n </div>\n </div>\n </div>\n );\n};\n\nexport default PdfRendererView;\n","const isDataSchema = (url: string) => {\n let i = 0,\n ii = url.length;\n\n while (i < ii && url[i].trim() === '') {\n i++;\n }\n\n return url.substring(i, i + 5).toLowerCase() === 'data:';\n};\n\nexport const getPDFFileNameFromURL = (\n url: string,\n defaultFilename = 'document.pdf',\n) => {\n if (typeof url !== 'string') {\n return defaultFilename;\n }\n\n if (isDataSchema(url)) {\n console.warn(\n 'getPDFFileNameFromURL: ' +\n 'ignoring \"data:\" URL for performance reasons.',\n );\n return defaultFilename;\n }\n\n const reURI = /^(?:(?:[^:]+:)?\\/\\/[^/]+)?([^?#]*)(\\?[^#]*)?(#.*)?$/;\n const reFilename = /[^/?#=]+\\.pdf\\b(?!.*\\.pdf\\b)/i;\n const splitURI = reURI.exec(url);\n let suggestedFilename: RegExpExecArray | string | null = null;\n\n if (splitURI) {\n suggestedFilename =\n reFilename.exec(splitURI[1]) ||\n reFilename.exec(splitURI[2]) ||\n reFilename.exec(splitURI[3]);\n }\n\n if (suggestedFilename) {\n suggestedFilename = suggestedFilename[0];\n\n if (suggestedFilename.includes('%')) {\n try {\n const suggestedFilenameResult = reFilename.exec(\n decodeURIComponent(suggestedFilename),\n );\n\n if (suggestedFilenameResult) {\n suggestedFilename = suggestedFilenameResult[0];\n }\n } catch (_ex) {}\n }\n }\n\n return suggestedFilename || defaultFilename;\n};\n","import type { PDFDocumentProxy } from 'pdfjs-dist';\nimport type { DownloadManager, PDFViewer } from 'pdfjs-dist/web/pdf_viewer.mjs';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { getPDFFileNameFromURL } from '@/lib';\n\nconst SCALE = {\n percent: 100,\n min: 10,\n max: 1000,\n roundTo: 10,\n auto: -1,\n default: 100,\n};\n\nconst AUTO_FIT = {\n maxContainerWidth: 1020,\n padding: 56,\n fallbackWidth: 1019,\n};\n\nconst ZOOM = {\n largeStepMin: 110,\n largeStepMax: 990,\n specialSteps: new Set([75, 125]),\n roundingExceptions: new Set([125]),\n stepLarge: 20,\n stepDefault: 10,\n stepSmall: 5,\n};\n\nconst ROTATION_STEP = 90;\nconst SCROLL_DEFAULT = 0;\n\nconst roundToNearest = (numToRound: number, numToRoundTo: number) =>\n Math.round(numToRound / numToRoundTo) * numToRoundTo;\n\nexport type RendererDocumentPosition = {\n zoom: number;\n rotation: number;\n scrollTop: number | null;\n scrollLeft?: number | null;\n};\n\nexport type PdfChangeHook = (\n documentIndex: string,\n position: RendererDocumentPosition,\n) => void;\n\ntype UsePdfRendererArgs = {\n activeIndex: string;\n autoZoom: boolean;\n pdfChangeHook?: PdfChangeHook | null;\n pdfDoc: PDFDocumentProxy;\n rotation: number;\n scrollLeft?: number | null;\n scrollTop?: number | null;\n zoom?: number;\n};\n\nexport const usePdfRenderer = ({\n activeIndex,\n autoZoom,\n pdfChangeHook,\n pdfDoc,\n rotation,\n scrollLeft,\n scrollTop,\n zoom,\n}: UsePdfRendererArgs) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const pdfViewerRef = useRef<PDFViewer | null>(null);\n const downloadManagerRef = useRef<DownloadManager | null>(null);\n const initialAutoZoomRef = useRef(autoZoom);\n const latestPdfDocRef = useRef(pdfDoc);\n const [scale, setScaleState] = useState(SCALE.default);\n const [isLoading, setIsLoading] = useState(true);\n\n const scaleRef = useRef(scale);\n useEffect(() => {\n scaleRef.current = scale;\n }, [scale]);\n\n useEffect(() => {\n latestPdfDocRef.current = pdfDoc;\n }, [pdfDoc]);\n\n const applyScale = useCallback((nextScaleValue: number) => {\n const nextScale = nextScaleValue >= SCALE.min ? nextScaleValue : SCALE.min;\n setScaleState(nextScale);\n if (pdfViewerRef.current) {\n pdfViewerRef.current.currentScaleValue = String(\n nextScale / SCALE.percent,\n );\n }\n }, []);\n\n const autoFitScale = useCallback(() => {\n const firstPage = pdfViewerRef.current?._pages?.[0];\n if (!firstPage) return;\n\n const firstPageWidth = firstPage.viewport.width;\n const currentScale = firstPage.scale;\n const originalWidth = firstPageWidth / currentScale;\n const offsetWidth = containerRef.current?.offsetWidth;\n const containerWidth =\n offsetWidth && offsetWidth < AUTO_FIT.maxContainerWidth\n ? offsetWidth - AUTO_FIT.padding\n : AUTO_FIT.fallbackWidth;\n let nextScale = SCALE.auto;\n\n if (containerRef.current) {\n nextScale = Math.abs(containerWidth) / originalWidth;\n }\n applyScale(nextScale * SCALE.percent);\n }, [applyScale]);\n\n const setScale = useCallback(\n (nextScaleValue: number) => {\n if (autoZoom && nextScaleValue < 0) {\n autoFitScale();\n return;\n }\n\n applyScale(nextScaleValue);\n },\n [applyScale, autoFitScale, autoZoom],\n );\n\n const setScrollTop = useCallback((nextScrollTop: number | null) => {\n if (containerRef.current) {\n containerRef.current.scrollTop = nextScrollTop ?? SCROLL_DEFAULT;\n }\n }, []);\n\n const setScrollLeft = useCallback((nextScrollLeft: number | null) => {\n if (containerRef.current) {\n containerRef.current.scrollLeft = nextScrollLeft ?? SCROLL_DEFAULT;\n }\n }, []);\n\n const rePosition = useCallback(async () => {\n if (!pdfViewerRef.current) return;\n\n await pdfViewerRef.current.firstPagePromise;\n\n if (rotation) {\n pdfViewerRef.current.pagesRotation = rotation;\n }\n\n if (zoom) {\n setScale(zoom);\n } else if (!zoom && autoZoom) {\n autoFitScale();\n }\n\n if (typeof scrollTop !== 'undefined') {\n setScrollTop(scrollTop ?? null);\n }\n\n if (typeof scrollLeft !== 'undefined') {\n setScrollLeft(scrollLeft ?? null);\n }\n }, [\n autoFitScale,\n autoZoom,\n rotation,\n scrollLeft,\n scrollTop,\n setScale,\n setScrollLeft,\n setScrollTop,\n zoom,\n ]);\n\n const rePositionRef = useRef(rePosition);\n useEffect(() => {\n rePositionRef.current = rePosition;\n }, [rePosition]);\n\n useEffect(() => {\n let cancelled = false;\n\n const setupViewer = async () => {\n const { PdfjsLib } = await import('@/lib/pdfjsLib');\n if (cancelled) return;\n globalThis.pdfjsLib = PdfjsLib;\n\n const viewerModule =\n (\n globalThis as {\n __pdfjsViewer?: typeof import('pdfjs-dist/web/pdf_viewer.mjs');\n }\n ).__pdfjsViewer ?? (await import('pdfjs-dist/web/pdf_viewer.mjs'));\n const { PDFViewer, DownloadManager, EventBus } = viewerModule;\n\n downloadManagerRef.current = new DownloadManager();\n\n if (!containerRef.current) {\n return;\n }\n\n pdfViewerRef.current = new PDFViewer({\n container: containerRef.current,\n eventBus: new EventBus(),\n });\n\n pdfViewerRef.current.setDocument(latestPdfDocRef.current);\n\n if (initialAutoZoomRef.current) {\n window.addEventListener('resizeAutoZoom', autoFitScale);\n }\n\n await rePositionRef.current();\n if (!cancelled) {\n setIsLoading(false);\n }\n };\n\n setupViewer();\n\n return () => {\n cancelled = true;\n if (initialAutoZoomRef.current) {\n window.removeEventListener('resizeAutoZoom', autoFitScale);\n }\n pdfViewerRef.current = null;\n downloadManagerRef.current = null;\n };\n }, [autoFitScale]);\n\n const prevPdfDocRef = useRef(pdfDoc);\n const prevActiveIndexRef = useRef(activeIndex);\n\n useEffect(() => {\n if (!pdfViewerRef.current) {\n prevPdfDocRef.current = pdfDoc;\n prevActiveIndexRef.current = activeIndex;\n return;\n }\n\n if (prevPdfDocRef.current !== pdfDoc) {\n if (typeof pdfChangeHook === 'function') {\n pdfChangeHook(String(prevActiveIndexRef.current), {\n zoom: scaleRef.current,\n rotation: pdfViewerRef.current.pagesRotation,\n scrollTop: containerRef.current?.scrollTop ?? null,\n scrollLeft: containerRef.current?.scrollLeft ?? null,\n });\n }\n\n pdfViewerRef.current.setDocument(pdfDoc);\n rePosition();\n }\n\n prevPdfDocRef.current = pdfDoc;\n prevActiveIndexRef.current = activeIndex;\n }, [activeIndex, pdfChangeHook, pdfDoc, rePosition]);\n\n const zoomIn = useCallback(() => {\n const nextScale = roundToNearest(scaleRef.current, SCALE.roundTo);\n let newScale = nextScale;\n\n if (nextScale >= ZOOM.largeStepMin && nextScale < ZOOM.largeStepMax) {\n newScale = nextScale + ZOOM.stepLarge;\n } else if (ZOOM.specialSteps.has(nextScale)) {\n newScale = nextScale + ZOOM.stepSmall;\n } else {\n newScale = nextScale + ZOOM.stepDefault;\n }\n\n if (newScale > SCALE.max) return;\n\n setScale(newScale);\n }, [setScale]);\n\n const zoomOut = useCallback(() => {\n let nextScale = scaleRef.current;\n nextScale = ZOOM.roundingExceptions.has(nextScale)\n ? nextScale\n : roundToNearest(nextScale, SCALE.roundTo);\n let newScale = nextScale;\n\n if (nextScale > ZOOM.largeStepMin && !ZOOM.specialSteps.has(nextScale)) {\n newScale = nextScale - ZOOM.stepLarge;\n } else if (ZOOM.specialSteps.has(nextScale)) {\n newScale = nextScale - ZOOM.stepSmall;\n } else {\n newScale = nextScale - ZOOM.stepDefault;\n }\n\n if (newScale <= 0) return;\n\n setScale(newScale);\n }, [setScale]);\n\n const rotateRight = useCallback(() => {\n if (!pdfViewerRef.current) return;\n\n const currentRotation = pdfViewerRef.current.pagesRotation;\n pdfViewerRef.current.pagesRotation = currentRotation + ROTATION_STEP;\n }, []);\n\n const rotateLeft = useCallback(() => {\n if (!pdfViewerRef.current) return;\n\n const currentRotation = pdfViewerRef.current.pagesRotation;\n pdfViewerRef.current.pagesRotation = currentRotation - ROTATION_STEP;\n }, []);\n\n const download = useCallback(async () => {\n if (!downloadManagerRef.current) return;\n\n const pdfDocWithTransport = pdfDoc as PDFDocumentProxy & {\n _transport?: { _params?: { url?: string } };\n };\n const url = pdfDocWithTransport._transport?._params?.url;\n let filename = getPDFFileNameFromURL(url ?? '');\n\n if (typeof pdfDoc.getMetadata === 'function') {\n try {\n const metadata = await pdfDoc.getMetadata();\n const contentDispositionFilename = (\n metadata as { contentDispositionFilename?: string | null }\n ).contentDispositionFilename;\n\n if (\n typeof contentDispositionFilename === 'string' &&\n contentDispositionFilename.trim()\n ) {\n filename = contentDispositionFilename;\n }\n } catch (_error) {}\n }\n\n const downloadByUrl = () => {\n if (!url) return;\n (\n downloadManagerRef.current as DownloadManager & {\n downloadUrl: (downloadUrl: string, downloadFilename: string) => void;\n }\n ).downloadUrl(url, filename);\n };\n\n try {\n const data = await pdfDoc.getData();\n downloadManagerRef.current.download(data, url ?? '', filename);\n } catch (_e) {\n downloadByUrl();\n }\n }, [pdfDoc]);\n\n return {\n containerRef,\n download,\n isLoading,\n pdfViewerRef,\n rotateLeft,\n rotateRight,\n scale,\n setScale,\n zoomIn,\n zoomOut,\n };\n};\n","import type { CSSProperties } from 'react';\nimport type { IconConfig } from '@/types/iconConfig';\n\nconst iconVarMap = {\n zoomIn: '--pdfjs-multi-control-icon-zoom-in',\n zoomOut: '--pdfjs-multi-control-icon-zoom-out',\n rotateLeft: '--pdfjs-multi-control-icon-rotate-left',\n rotateRight: '--pdfjs-multi-control-icon-rotate-right',\n download: '--pdfjs-multi-control-icon-download',\n selectArrow: '--pdfjs-multi-select-icon',\n toggleList: '--pdfjs-multi-control-icon-toggle-list',\n texture: '--pdfjs-multi-texture',\n} as const;\n\nconst toCssValue = (value: string) => {\n const trimmed = value.trim();\n if (!trimmed) return undefined;\n if (trimmed === 'none') return 'none';\n if (/^[a-z-]+\\(/i.test(trimmed)) return trimmed;\n return `url(\"${trimmed.replaceAll('\"', '\\\\\"')}\")`;\n};\n\nexport const buildIconStyles = (\n icons?: IconConfig,\n): CSSProperties | undefined => {\n if (!icons) return undefined;\n\n const style: Record<string, string> = {};\n\n for (const [key, cssVar] of Object.entries(iconVarMap)) {\n const iconValue = icons[key as keyof IconConfig];\n if (!iconValue) continue;\n\n const cssValue = toCssValue(iconValue);\n if (!cssValue) continue;\n\n style[cssVar] = cssValue;\n }\n\n return Object.keys(style).length ? (style as CSSProperties) : undefined;\n};\n","import type { PDFDocumentProxy } from 'pdfjs-dist';\nimport type { PDFViewer } from 'pdfjs-dist/web/pdf_viewer.mjs';\nimport type { CSSProperties } from 'react';\nimport { forwardRef, useImperativeHandle, useMemo } from 'react';\nimport 'pdfjs-dist/web/pdf_viewer.css';\nimport '@/components/PdfRenderer/PdfRenderer.css';\nimport PdfRendererView from '@/components/PdfRenderer/PdfRendererView';\nimport {\n type PdfChangeHook,\n usePdfRenderer,\n} from '@/components/PdfRenderer/usePdfRenderer';\nimport { defaultI18n, type I18nDataRenderer } from '@/contexts';\nimport { buildIconStyles } from '@/lib/iconStyles';\nimport type { IconConfig } from '@/types/iconConfig';\n\nexport type { RendererDocumentPosition } from '@/components/PdfRenderer/usePdfRenderer';\n\ntype DefaultProps = {\n activeIndex?: string;\n autoZoom?: boolean;\n className?: string;\n controls?: boolean;\n downloadBtn: boolean;\n icons?: IconConfig;\n i18nData?: I18nDataRenderer;\n pdfChangeHook?: PdfChangeHook | null;\n style?: CSSProperties;\n zoom?: number;\n rotation?: number;\n scrollTop?: number | null;\n scrollLeft?: number | null;\n};\n\ntype Props = {\n pdfDoc: PDFDocumentProxy;\n} & Partial<DefaultProps>;\n\nexport type PdfRendererHandle = {\n pdfViewer: PDFViewer | null;\n};\n\nconst PdfRenderer = forwardRef<PdfRendererHandle, Props>(\n (\n {\n pdfDoc,\n activeIndex = '0',\n autoZoom = true,\n className,\n controls = true,\n downloadBtn = true,\n icons,\n i18nData = defaultI18n,\n pdfChangeHook = null,\n style,\n zoom,\n rotation = 0,\n scrollTop = 0,\n scrollLeft = 0,\n },\n ref,\n ) => {\n const {\n containerRef,\n download,\n isLoading,\n pdfViewerRef,\n rotateLeft,\n rotateRight,\n scale,\n setScale,\n zoomIn,\n zoomOut,\n } = usePdfRenderer({\n activeIndex,\n autoZoom,\n pdfChangeHook,\n pdfDoc,\n rotation,\n scrollLeft,\n scrollTop,\n zoom,\n });\n\n useImperativeHandle(ref, () => ({\n get pdfViewer() {\n return pdfViewerRef.current;\n },\n }));\n\n const iconStyles = useMemo(() => buildIconStyles(icons), [icons]);\n const mergedStyles = useMemo(() => {\n if (!iconStyles && !style) return undefined;\n return { ...(iconStyles ?? {}), ...(style ?? {}) };\n }, [iconStyles, style]);\n\n return (\n <PdfRendererView\n autoZoom={autoZoom}\n className={className}\n containerRef={containerRef}\n controls={controls}\n downloadBtn={downloadBtn}\n iconStyles={mergedStyles}\n i18nData={i18nData}\n isLoading={isLoading}\n scale={scale}\n setScale={setScale}\n onDownload={download}\n onRotateLeft={rotateLeft}\n onRotateRight={rotateRight}\n onZoomIn={zoomIn}\n onZoomOut={zoomOut}\n />\n );\n },\n);\n\nPdfRenderer.displayName = 'PdfRenderer';\n\nexport default PdfRenderer;\n","import type { PDFDocumentProxy } from 'pdfjs-dist';\nimport type { CSSProperties, RefObject } from 'react';\nimport { memo, useMemo } from 'react';\nimport type {\n I18nData,\n PdfFile,\n} from '@/components/PdfMultiViewer/usePdfMultiViewer';\nimport PdfRenderer from '@/components/PdfRenderer/PdfRenderer';\nimport type { RendererDocumentPosition } from '@/components/PdfRenderer/usePdfRenderer';\nimport type { IconConfig } from '@/types/iconConfig';\n\ntype Props = {\n activeIndex: string;\n autoZoom: boolean;\n className?: string;\n controls: boolean;\n files: PdfFile[];\n iconStyles?: CSSProperties;\n i18nData: I18nData;\n listVisible: boolean;\n overlayMode: boolean;\n pdfToShow?: PdfFile;\n rendererIcons?: IconConfig;\n rendererClassName?: string;\n rendererStyle?: CSSProperties;\n viewerContainerRef: RefObject<HTMLDivElement>;\n onRememberPosition: (\n index: string,\n position: RendererDocumentPosition,\n ) => void;\n onSelectPdf: (nextIndex: string, file: PdfFile) => () => void;\n onToggleList: () => void;\n};\n\ntype ListProps = {\n activeIndex: string;\n files: PdfFile[];\n i18nData: I18nData;\n listVisible: boolean;\n overlayMode: boolean;\n onSelectPdf: (nextIndex: string, file: PdfFile) => () => void;\n};\n\ntype ListItemProps = {\n file: PdfFile;\n i18nData: I18nData;\n index: number;\n isActive: boolean;\n onSelectPdf: (nextIndex: string, file: PdfFile) => () => void;\n};\n\nconst PdfMultiViewerListItem = memo(\n ({ file, i18nData, index, isActive, onSelectPdf }: ListItemProps) => {\n const handleSelect = useMemo(\n () => onSelectPdf(String(index), file),\n [file, index, onSelectPdf],\n );\n const isLoading = Boolean(file.isLoading && !file.pdfProxy);\n\n return (\n <li\n className={`pdf-viewer-list-item${file.pdfProxy ? ' loaded' : ''}${\n isLoading ? ' loading' : ''\n }${isActive ? ' active' : ''}`}\n >\n <button\n className=\"pdf-viewer-list-item-button\"\n onClick={handleSelect}\n type=\"button\"\n >\n {file.title || file.source}\n {file.pdfProxy && (\n <div className=\"pdf-viewer-list-item-meta\">\n {i18nData?.pages ?? 'Pages'}: {file.pdfProxy.numPages}\n </div>\n )}\n {isLoading && !file.pdfProxy && (\n <div className=\"pdf-viewer-list-item-meta\">\n {i18nData?.loading ?? 'Loading...'}\n </div>\n )}\n </button>\n </li>\n );\n },\n);\n\nPdfMultiViewerListItem.displayName = 'PdfMultiViewerListItem';\n\nconst PdfMultiViewerList = memo(\n ({\n activeIndex,\n files,\n i18nData,\n listVisible,\n overlayMode,\n onSelectPdf,\n }: ListProps) => (\n <ul\n className={`pdf-viewer-list${!listVisible ? ' hidden' : ''}${\n overlayMode ? ' overlay' : ''\n }`}\n >\n {files.map((file, index) => (\n <PdfMultiViewerListItem\n file={file}\n i18nData={i18nData}\n index={index}\n isActive={String(index) === String(activeIndex)}\n key={file.source}\n onSelectPdf={onSelectPdf}\n />\n ))}\n </ul>\n ),\n);\n\nPdfMultiViewerList.displayName = 'PdfMultiViewerList';\n\nconst PdfMultiViewerView = ({\n activeIndex,\n autoZoom,\n className,\n controls,\n files,\n iconStyles,\n i18nData,\n listVisible,\n overlayMode,\n pdfToShow,\n rendererIcons,\n rendererClassName,\n rendererStyle,\n viewerContainerRef,\n onRememberPosition,\n onSelectPdf,\n onToggleList,\n}: Props) => (\n <div\n className={`pdfjs-multi pdf-multi-viewer${className ? ` ${className}` : ''}`}\n ref={viewerContainerRef}\n style={iconStyles}\n >\n <div className=\"pdf-multi-viewer-option-bar\">\n <button\n className={`viewer-controls-button${listVisible ? ' toggled' : ''}`}\n onClick={onToggleList}\n type=\"button\"\n aria-label=\"Toggle list\"\n >\n <span className=\"toggle-list-label\" aria-hidden=\"true\" />\n </button>\n </div>\n <PdfMultiViewerList\n activeIndex={activeIndex}\n files={files}\n i18nData={i18nData}\n listVisible={listVisible}\n overlayMode={overlayMode}\n onSelectPdf={onSelectPdf}\n />\n <div className=\"pdf-viewer-multi-renderer\">\n {pdfToShow?.pdfProxy ? (\n <PdfRenderer\n activeIndex={activeIndex}\n autoZoom={autoZoom}\n className={rendererClassName}\n controls={controls}\n icons={rendererIcons}\n style={rendererStyle}\n pdfDoc={pdfToShow.pdfProxy as PDFDocumentProxy}\n i18nData={i18nData}\n pdfChangeHook={onRememberPosition}\n zoom={pdfToShow.zoom}\n rotation={pdfToShow.rotation}\n scrollTop={pdfToShow.scrollTop}\n scrollLeft={pdfToShow.scrollLeft}\n />\n ) : pdfToShow ? (\n <output className=\"pdf-viewer-loading\" aria-live=\"polite\">\n <span className=\"pdf-viewer-loading-spinner\" aria-hidden=\"true\" />\n <span className=\"pdf-viewer-loading-text\">\n {i18nData?.loading ?? 'Loading...'}\n </span>\n </output>\n ) : null}\n </div>\n </div>\n);\n\nexport default PdfMultiViewerView;\n","import type { PDFDocumentProxy, PDFWorker } from 'pdfjs-dist';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type { RendererDocumentPosition } from '@/components/PdfRenderer/usePdfRenderer';\nimport type { I18nDataRenderer } from '@/contexts';\nimport { PdfjsLib } from '@/lib';\n\nexport type PdfDefinition = {\n title?: string;\n source: string;\n};\n\nexport type PdfSource = string | PdfDefinition;\n\nexport type PdfFile = {\n index?: number;\n title?: string;\n zoom?: number;\n rotation?: number;\n scrollTop?: number | null;\n scrollLeft?: number | null;\n isLoading?: boolean;\n source: string;\n pdfProxy: PDFDocumentProxy | null;\n};\n\nexport type I18nData = {\n loading?: string;\n pages?: string;\n} & I18nDataRenderer;\n\ntype UsePdfMultiViewerArgs = {\n pdfs: PdfSource[];\n startIndex: string;\n i18nData: I18nData;\n lazyLoad: boolean;\n initialLoadIndex?: string | number;\n workerSrc?: string;\n};\n\nconst createPdfFile = (pdf: PdfSource): PdfFile => {\n return typeof pdf === 'object'\n ? { ...pdf, isLoading: false, pdfProxy: null }\n : {\n isLoading: false,\n source: pdf,\n pdfProxy: null,\n };\n};\n\nexport const usePdfMultiViewer = ({\n pdfs,\n startIndex,\n i18nData,\n lazyLoad,\n initialLoadIndex,\n workerSrc,\n}: UsePdfMultiViewerArgs) => {\n const viewerContainerRef = useRef<HTMLDivElement>(null);\n const initialFilesRef = useRef<PdfFile[] | null>(null);\n const workerRef = useRef<PDFWorker | null>(null);\n const loadingIndicesRef = useRef<Set<number>>(new Set());\n const initialLoadDoneRef = useRef(false);\n const positionsRef = useRef<Map<number, RendererDocumentPosition>>(new Map());\n\n const [files, setFiles] = useState<PdfFile[]>(() => {\n const mapped = pdfs.map(createPdfFile);\n initialFilesRef.current = mapped;\n return mapped;\n });\n const [activeIndex, setActiveIndex] = useState<string>(() => `${startIndex}`);\n const [_pendingIndex, setPendingIndex] = useState<string | null>(null);\n const [listVisible, setListVisible] = useState(true);\n const [overlayMode, setOverlayMode] = useState(false);\n\n const resolveIndex = useCallback((index?: string | number) => {\n const resolved = Number(index);\n return Number.isNaN(resolved) ? 0 : resolved;\n }, []);\n\n useEffect(() => {\n if (workerSrc) {\n PdfjsLib.GlobalWorkerOptions.workerSrc = workerSrc;\n const worker = PdfjsLib.PDFWorker.create({});\n workerRef.current = worker;\n return () => {\n worker.destroy();\n if (workerRef.current === worker) {\n workerRef.current = null;\n }\n };\n }\n return undefined;\n }, [workerSrc]);\n\n const toggleList = useCallback(() => {\n setListVisible((state) => !state);\n }, []);\n\n const setFileLoading = useCallback((index: number, isLoading: boolean) => {\n setFiles((state) =>\n state.map((pdfFile, pdfIndex) => {\n if (pdfIndex !== index) return pdfFile;\n return {\n ...pdfFile,\n isLoading,\n };\n }),\n );\n }, []);\n\n const loadPdfDocument = useCallback(\n async (file: PdfFile, index: number) => {\n if (file.pdfProxy) return;\n if (loadingIndicesRef.current.has(index)) return;\n\n loadingIndicesRef.current.add(index);\n setFileLoading(index, true);\n\n try {\n const worker = workerRef.current;\n const pdfDoc = await PdfjsLib.getDocument({\n url: file.source,\n ...(worker ? { worker } : {}),\n }).promise;\n\n setFiles((state) =>\n state.map((pdfFile, pdfIndex) => {\n if (pdfIndex !== index) return pdfFile;\n return {\n ...pdfFile,\n isLoading: false,\n pdfProxy: pdfDoc,\n };\n }),\n );\n\n setPendingIndex((current) => {\n if (current === String(index)) {\n setActiveIndex(current);\n return null;\n }\n return current;\n });\n } catch (_error) {\n setFileLoading(index, false);\n } finally {\n loadingIndicesRef.current.delete(index);\n }\n },\n [setFileLoading],\n );\n\n const selectPdf = useCallback(\n (nextIndex: string, file: PdfFile) => () => {\n if (lazyLoad && !file.pdfProxy) {\n setPendingIndex(nextIndex);\n void loadPdfDocument(file, Number(nextIndex));\n } else {\n setPendingIndex(null);\n setActiveIndex(nextIndex);\n }\n if (overlayMode && listVisible) toggleList();\n },\n [lazyLoad, listVisible, loadPdfDocument, overlayMode, toggleList],\n );\n\n const updateOverlayMode = useCallback((currentContainerWidth?: number) => {\n const containerWidth =\n currentContainerWidth || viewerContainerRef.current?.offsetWidth;\n\n setOverlayMode((current) => {\n if (\n containerWidth &&\n containerWidth >= 330 &&\n containerWidth <= 667 &&\n !current\n ) {\n return true;\n }\n\n if (current && containerWidth && containerWidth > 667) {\n return false;\n }\n\n return current;\n });\n }, []);\n\n const onResizeEvent = useCallback(() => {\n updateOverlayMode(viewerContainerRef.current?.offsetWidth);\n }, [updateOverlayMode]);\n\n const loadPdfDocuments = useCallback(() => {\n const currentFiles = initialFilesRef.current ?? [];\n currentFiles.forEach(async (file, index) => {\n await loadPdfDocument(file, index);\n });\n }, [loadPdfDocument]);\n\n const rememberPosition = useCallback(\n (index: string, position: RendererDocumentPosition) => {\n positionsRef.current.set(Number(index), position);\n },\n [],\n );\n\n useEffect(() => {\n window.addEventListener('resizeAutoZoom', onResizeEvent);\n updateOverlayMode(viewerContainerRef.current?.offsetWidth);\n if (!lazyLoad) {\n loadPdfDocuments();\n }\n\n return () => {\n window.removeEventListener('resizeAutoZoom', onResizeEvent);\n };\n }, [lazyLoad, loadPdfDocuments, onResizeEvent, updateOverlayMode]);\n\n useEffect(() => {\n if (!lazyLoad) return;\n const initialIndex = resolveIndex(initialLoadIndex ?? startIndex);\n const nextFile = files[initialIndex];\n if (!nextFile) return;\n if (initialLoadDoneRef.current) return;\n initialLoadDoneRef.current = true;\n void loadPdfDocument(nextFile, initialIndex);\n }, [\n files,\n initialLoadIndex,\n lazyLoad,\n loadPdfDocument,\n resolveIndex,\n startIndex,\n ]);\n\n useEffect(() => {\n if (!lazyLoad) return;\n const nextIndex = resolveIndex(activeIndex);\n const nextFile = files[nextIndex];\n if (!nextFile) return;\n void loadPdfDocument(nextFile, nextIndex);\n }, [activeIndex, files, lazyLoad, loadPdfDocument, resolveIndex]);\n\n const pdfToShow = useMemo(() => {\n const resolvedIndex = Number(activeIndex);\n const file = files[resolvedIndex];\n if (!file) return undefined;\n const position = positionsRef.current.get(resolvedIndex);\n return position ? { ...file, ...position } : file;\n }, [activeIndex, files]);\n\n return {\n activeIndex,\n files,\n i18nData,\n listVisible,\n overlayMode,\n pdfToShow,\n rememberPosition,\n selectPdf,\n toggleList,\n viewerContainerRef,\n };\n};\n","import type { CSSProperties } from 'react';\nimport { useMemo } from 'react';\nimport '@/components/PdfMultiViewer/PdfMultiViewer.css';\nimport PdfMultiViewerView from '@/components/PdfMultiViewer/PdfMultiViewerView';\nimport {\n type I18nData,\n type PdfSource,\n usePdfMultiViewer,\n} from '@/components/PdfMultiViewer/usePdfMultiViewer';\nimport { buildIconStyles } from '@/lib/iconStyles';\nimport type { IconConfig } from '@/types/iconConfig';\n\ntype DefaultProps = {\n autoZoom?: boolean;\n className?: string;\n controls?: boolean;\n icons?: IconConfig;\n lazyLoad?: boolean;\n initialLoadIndex?: string | number;\n rendererIcons?: IconConfig;\n rendererClassName?: string;\n rendererStyle?: CSSProperties;\n style?: CSSProperties;\n startIndex?: string;\n i18nData?: I18nData;\n workerSrc?: string;\n};\n\ntype Props = {\n pdfs: PdfSource[];\n} & Partial<DefaultProps>;\n\nconst DEFAULT_I18N_DATA: I18nData = { loading: 'Loading...', pages: 'Pages' };\n\nconst PdfMultiViewer = ({\n pdfs,\n autoZoom = true,\n className,\n controls = true,\n icons,\n lazyLoad = true,\n initialLoadIndex,\n rendererIcons,\n rendererClassName,\n rendererStyle,\n style,\n startIndex = '0',\n i18nData = DEFAULT_I18N_DATA,\n workerSrc,\n}: Props) => {\n const {\n activeIndex,\n files,\n listVisible,\n overlayMode,\n pdfToShow,\n rememberPosition,\n selectPdf,\n toggleList,\n viewerContainerRef,\n } = usePdfMultiViewer({\n i18nData,\n pdfs,\n startIndex,\n lazyLoad,\n initialLoadIndex,\n workerSrc,\n });\n\n const iconStyles = useMemo(() => buildIconStyles(icons), [icons]);\n const mergedStyles = useMemo(() => {\n if (!iconStyles && !style) return undefined;\n return { ...(iconStyles ?? {}), ...(style ?? {}) };\n }, [iconStyles, style]);\n\n return (\n <PdfMultiViewerView\n activeIndex={activeIndex}\n autoZoom={autoZoom}\n className={className}\n controls={controls}\n files={files}\n iconStyles={mergedStyles}\n i18nData={i18nData}\n listVisible={listVisible}\n onRememberPosition={rememberPosition}\n onSelectPdf={selectPdf}\n onToggleList={toggleList}\n overlayMode={overlayMode}\n pdfToShow={pdfToShow}\n rendererIcons={rendererIcons}\n rendererClassName={rendererClassName}\n rendererStyle={rendererStyle}\n viewerContainerRef={viewerContainerRef}\n />\n );\n};\n\nexport default PdfMultiViewer;\n\nexport type { I18nData };\n"],"mappings":"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"}
|