react-pdfjs-multi 1.0.0-rc.3 → 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.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as PdfjsLib } from "./pdfjsLib-DgdIcD_k.mjs";
|
|
2
|
-
import React, { Fragment, forwardRef, useCallback, useContext, useEffect, useImperativeHandle, useRef, useState } from "react";
|
|
2
|
+
import React, { Fragment, forwardRef, memo, useCallback, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
3
3
|
import "pdfjs-dist/web/pdf_viewer.css";
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
|
|
@@ -122,8 +122,9 @@ var ZoomSelectBox_default = ZoomSelectBox;
|
|
|
122
122
|
|
|
123
123
|
//#endregion
|
|
124
124
|
//#region src/components/PdfRenderer/PdfRendererControls.tsx
|
|
125
|
-
const PdfControls = ({ autoZoom, downloadBtn, onDownload, onZoomIn, onZoomOut, onRotateRight, onRotateLeft, scale, setScale }) => /* @__PURE__ */ jsx("div", {
|
|
125
|
+
const PdfControls = ({ autoZoom, downloadBtn, iconStyles, onDownload, onZoomIn, onZoomOut, onRotateRight, onRotateLeft, scale, setScale }) => /* @__PURE__ */ jsx("div", {
|
|
126
126
|
className: "renderer-controls",
|
|
127
|
+
style: iconStyles,
|
|
127
128
|
children: /* @__PURE__ */ jsxs("div", { children: [
|
|
128
129
|
/* @__PURE__ */ jsx(I18nContext.Consumer, { children: ({ scaleDown, scaleUp }) => /* @__PURE__ */ jsxs("div", {
|
|
129
130
|
className: "button-group",
|
|
@@ -200,37 +201,41 @@ var PdfRendererControls_default = PdfControls;
|
|
|
200
201
|
|
|
201
202
|
//#endregion
|
|
202
203
|
//#region src/components/PdfRenderer/PdfRendererView.tsx
|
|
203
|
-
const PdfRendererView = ({ autoZoom, containerRef, controls, downloadBtn, iconStyles, i18nData, isLoading, scale, setScale, onDownload, onRotateLeft, onRotateRight, onZoomIn, onZoomOut }) =>
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
children: /* @__PURE__ */ jsx(
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
className:
|
|
204
|
+
const PdfRendererView = ({ autoZoom, className, containerRef, controls, downloadBtn, iconStyles, i18nData, isLoading, scale, setScale, onDownload, onRotateLeft, onRotateRight, onZoomIn, onZoomOut }) => {
|
|
205
|
+
const i18nValue = useMemo(() => ({
|
|
206
|
+
...defaultI18n,
|
|
207
|
+
...i18nData ?? {}
|
|
208
|
+
}), [i18nData]);
|
|
209
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
210
|
+
className: `pdfjs-multi renderer-container${className ? ` ${className}` : ""}`,
|
|
211
|
+
style: iconStyles,
|
|
212
|
+
children: [controls && /* @__PURE__ */ jsx(I18nContext.Provider, {
|
|
213
|
+
value: i18nValue,
|
|
214
|
+
children: /* @__PURE__ */ jsx(PdfRendererControls_default, {
|
|
215
|
+
autoZoom,
|
|
216
|
+
downloadBtn,
|
|
217
|
+
iconStyles,
|
|
218
|
+
scale,
|
|
219
|
+
setScale,
|
|
220
|
+
onDownload,
|
|
221
|
+
onZoomIn,
|
|
222
|
+
onZoomOut,
|
|
223
|
+
onRotateRight,
|
|
224
|
+
onRotateLeft
|
|
225
|
+
})
|
|
226
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
227
|
+
className: "renderer-stage",
|
|
227
228
|
children: /* @__PURE__ */ jsx("div", {
|
|
228
|
-
|
|
229
|
-
className: `
|
|
229
|
+
ref: containerRef,
|
|
230
|
+
className: `renderer-target-container ${!controls ? "no-controls" : ""} `,
|
|
231
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
232
|
+
id: "viewer",
|
|
233
|
+
className: `pdfViewer ${isLoading ? "hidden" : ""}`
|
|
234
|
+
})
|
|
230
235
|
})
|
|
231
|
-
})
|
|
232
|
-
})
|
|
233
|
-
}
|
|
236
|
+
})]
|
|
237
|
+
});
|
|
238
|
+
};
|
|
234
239
|
var PdfRendererView_default = PdfRendererView;
|
|
235
240
|
|
|
236
241
|
//#endregion
|
|
@@ -505,7 +510,7 @@ const buildIconStyles = (icons) => {
|
|
|
505
510
|
|
|
506
511
|
//#endregion
|
|
507
512
|
//#region src/components/PdfRenderer/PdfRenderer.tsx
|
|
508
|
-
const PdfRenderer = forwardRef(({ pdfDoc, activeIndex = "0", autoZoom = true, controls = true, downloadBtn = true, icons, i18nData = defaultI18n, pdfChangeHook = null, zoom, rotation = 0, scrollTop = 0, scrollLeft = 0 }, ref) => {
|
|
513
|
+
const PdfRenderer = 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) => {
|
|
509
514
|
const { containerRef, download, isLoading, pdfViewerRef, rotateLeft, rotateRight, scale, setScale, zoomIn, zoomOut } = usePdfRenderer({
|
|
510
515
|
activeIndex,
|
|
511
516
|
autoZoom,
|
|
@@ -519,12 +524,20 @@ const PdfRenderer = forwardRef(({ pdfDoc, activeIndex = "0", autoZoom = true, co
|
|
|
519
524
|
useImperativeHandle(ref, () => ({ get pdfViewer() {
|
|
520
525
|
return pdfViewerRef.current;
|
|
521
526
|
} }));
|
|
527
|
+
const iconStyles = useMemo(() => buildIconStyles(icons), [icons]);
|
|
522
528
|
return /* @__PURE__ */ jsx(PdfRendererView_default, {
|
|
523
529
|
autoZoom,
|
|
530
|
+
className,
|
|
524
531
|
containerRef,
|
|
525
532
|
controls,
|
|
526
533
|
downloadBtn,
|
|
527
|
-
iconStyles:
|
|
534
|
+
iconStyles: useMemo(() => {
|
|
535
|
+
if (!iconStyles && !style) return void 0;
|
|
536
|
+
return {
|
|
537
|
+
...iconStyles ?? {},
|
|
538
|
+
...style ?? {}
|
|
539
|
+
};
|
|
540
|
+
}, [iconStyles, style]),
|
|
528
541
|
i18nData,
|
|
529
542
|
isLoading,
|
|
530
543
|
scale,
|
|
@@ -541,8 +554,51 @@ var PdfRenderer_default = PdfRenderer;
|
|
|
541
554
|
|
|
542
555
|
//#endregion
|
|
543
556
|
//#region src/components/PdfMultiViewer/PdfMultiViewerView.tsx
|
|
544
|
-
const
|
|
545
|
-
|
|
557
|
+
const PdfMultiViewerListItem = memo(({ file, i18nData, index, isActive, onSelectPdf }) => {
|
|
558
|
+
const handleSelect = useMemo(() => onSelectPdf(String(index), file), [
|
|
559
|
+
file,
|
|
560
|
+
index,
|
|
561
|
+
onSelectPdf
|
|
562
|
+
]);
|
|
563
|
+
const isLoading = Boolean(file.isLoading && !file.pdfProxy);
|
|
564
|
+
return /* @__PURE__ */ jsx("li", {
|
|
565
|
+
className: `pdf-viewer-list-item${file.pdfProxy ? " loaded" : ""}${isLoading ? " loading" : ""}${isActive ? " active" : ""}`,
|
|
566
|
+
children: /* @__PURE__ */ jsxs("button", {
|
|
567
|
+
className: "pdf-viewer-list-item-button",
|
|
568
|
+
onClick: handleSelect,
|
|
569
|
+
type: "button",
|
|
570
|
+
children: [
|
|
571
|
+
file.title || file.source,
|
|
572
|
+
file.pdfProxy && /* @__PURE__ */ jsxs("div", {
|
|
573
|
+
className: "pdf-viewer-list-item-meta",
|
|
574
|
+
children: [
|
|
575
|
+
i18nData?.pages ?? "Pages",
|
|
576
|
+
": ",
|
|
577
|
+
file.pdfProxy.numPages
|
|
578
|
+
]
|
|
579
|
+
}),
|
|
580
|
+
isLoading && !file.pdfProxy && /* @__PURE__ */ jsx("div", {
|
|
581
|
+
className: "pdf-viewer-list-item-meta",
|
|
582
|
+
children: i18nData?.loading ?? "Loading..."
|
|
583
|
+
})
|
|
584
|
+
]
|
|
585
|
+
})
|
|
586
|
+
});
|
|
587
|
+
});
|
|
588
|
+
PdfMultiViewerListItem.displayName = "PdfMultiViewerListItem";
|
|
589
|
+
const PdfMultiViewerList = memo(({ activeIndex, files, i18nData, listVisible, overlayMode, onSelectPdf }) => /* @__PURE__ */ jsx("ul", {
|
|
590
|
+
className: `pdf-viewer-list${!listVisible ? " hidden" : ""}${overlayMode ? " overlay" : ""}`,
|
|
591
|
+
children: files.map((file, index) => /* @__PURE__ */ jsx(PdfMultiViewerListItem, {
|
|
592
|
+
file,
|
|
593
|
+
i18nData,
|
|
594
|
+
index,
|
|
595
|
+
isActive: String(index) === String(activeIndex),
|
|
596
|
+
onSelectPdf
|
|
597
|
+
}, file.source))
|
|
598
|
+
}));
|
|
599
|
+
PdfMultiViewerList.displayName = "PdfMultiViewerList";
|
|
600
|
+
const PdfMultiViewerView = ({ activeIndex, autoZoom, className, controls, files, iconStyles, i18nData, listVisible, overlayMode, pdfToShow, rendererIcons, rendererClassName, rendererStyle, viewerContainerRef, onRememberPosition, onSelectPdf, onToggleList }) => /* @__PURE__ */ jsxs("div", {
|
|
601
|
+
className: `pdfjs-multi pdf-multi-viewer${className ? ` ${className}` : ""}`,
|
|
546
602
|
ref: viewerContainerRef,
|
|
547
603
|
style: iconStyles,
|
|
548
604
|
children: [
|
|
@@ -559,42 +615,23 @@ const PdfMultiViewerView = ({ activeIndex, autoZoom, controls, files, iconStyles
|
|
|
559
615
|
})
|
|
560
616
|
})
|
|
561
617
|
}),
|
|
562
|
-
/* @__PURE__ */ jsx(
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
children: /* @__PURE__ */ jsxs("button", {
|
|
570
|
-
className: "pdf-viewer-list-item-button",
|
|
571
|
-
onClick: handleSelect,
|
|
572
|
-
type: "button",
|
|
573
|
-
children: [
|
|
574
|
-
file.title || file.source,
|
|
575
|
-
file.pdfProxy && /* @__PURE__ */ jsxs("div", {
|
|
576
|
-
className: "pdf-viewer-list-item-meta",
|
|
577
|
-
children: [
|
|
578
|
-
i18nData?.pages ?? "Pages",
|
|
579
|
-
": ",
|
|
580
|
-
file.pdfProxy.numPages
|
|
581
|
-
]
|
|
582
|
-
}),
|
|
583
|
-
isLoading && !file.pdfProxy && /* @__PURE__ */ jsx("div", {
|
|
584
|
-
className: "pdf-viewer-list-item-meta",
|
|
585
|
-
children: i18nData?.loading ?? "Loading..."
|
|
586
|
-
})
|
|
587
|
-
]
|
|
588
|
-
})
|
|
589
|
-
}, file.source);
|
|
590
|
-
})
|
|
618
|
+
/* @__PURE__ */ jsx(PdfMultiViewerList, {
|
|
619
|
+
activeIndex,
|
|
620
|
+
files,
|
|
621
|
+
i18nData,
|
|
622
|
+
listVisible,
|
|
623
|
+
overlayMode,
|
|
624
|
+
onSelectPdf
|
|
591
625
|
}),
|
|
592
626
|
/* @__PURE__ */ jsx("div", {
|
|
593
627
|
className: "pdf-viewer-multi-renderer",
|
|
594
628
|
children: pdfToShow?.pdfProxy ? /* @__PURE__ */ jsx(PdfRenderer_default, {
|
|
595
629
|
activeIndex,
|
|
596
630
|
autoZoom,
|
|
631
|
+
className: rendererClassName,
|
|
597
632
|
controls,
|
|
633
|
+
icons: rendererIcons,
|
|
634
|
+
style: rendererStyle,
|
|
598
635
|
pdfDoc: pdfToShow.pdfProxy,
|
|
599
636
|
i18nData,
|
|
600
637
|
pdfChangeHook: onRememberPosition,
|
|
@@ -637,12 +674,14 @@ const usePdfMultiViewer = ({ pdfs, startIndex, i18nData, lazyLoad, initialLoadIn
|
|
|
637
674
|
const workerRef = useRef(null);
|
|
638
675
|
const loadingIndicesRef = useRef(/* @__PURE__ */ new Set());
|
|
639
676
|
const initialLoadDoneRef = useRef(false);
|
|
677
|
+
const positionsRef = useRef(/* @__PURE__ */ new Map());
|
|
640
678
|
const [files, setFiles] = useState(() => {
|
|
641
679
|
const mapped = pdfs.map(createPdfFile);
|
|
642
680
|
initialFilesRef.current = mapped;
|
|
643
681
|
return mapped;
|
|
644
682
|
});
|
|
645
683
|
const [activeIndex, setActiveIndex] = useState(() => `${startIndex}`);
|
|
684
|
+
const [_pendingIndex, setPendingIndex] = useState(null);
|
|
646
685
|
const [listVisible, setListVisible] = useState(true);
|
|
647
686
|
const [overlayMode, setOverlayMode] = useState(false);
|
|
648
687
|
const resolveIndex = useCallback((index) => {
|
|
@@ -691,6 +730,13 @@ const usePdfMultiViewer = ({ pdfs, startIndex, i18nData, lazyLoad, initialLoadIn
|
|
|
691
730
|
pdfProxy: pdfDoc
|
|
692
731
|
};
|
|
693
732
|
}));
|
|
733
|
+
setPendingIndex((current) => {
|
|
734
|
+
if (current === String(index)) {
|
|
735
|
+
setActiveIndex(current);
|
|
736
|
+
return null;
|
|
737
|
+
}
|
|
738
|
+
return current;
|
|
739
|
+
});
|
|
694
740
|
} catch (_error) {
|
|
695
741
|
setFileLoading(index, false);
|
|
696
742
|
} finally {
|
|
@@ -698,8 +744,13 @@ const usePdfMultiViewer = ({ pdfs, startIndex, i18nData, lazyLoad, initialLoadIn
|
|
|
698
744
|
}
|
|
699
745
|
}, [setFileLoading]);
|
|
700
746
|
const selectPdf = useCallback((nextIndex, file) => () => {
|
|
701
|
-
|
|
702
|
-
|
|
747
|
+
if (lazyLoad && !file.pdfProxy) {
|
|
748
|
+
setPendingIndex(nextIndex);
|
|
749
|
+
loadPdfDocument(file, Number(nextIndex));
|
|
750
|
+
} else {
|
|
751
|
+
setPendingIndex(null);
|
|
752
|
+
setActiveIndex(nextIndex);
|
|
753
|
+
}
|
|
703
754
|
if (overlayMode && listVisible) toggleList();
|
|
704
755
|
}, [
|
|
705
756
|
lazyLoad,
|
|
@@ -725,13 +776,7 @@ const usePdfMultiViewer = ({ pdfs, startIndex, i18nData, lazyLoad, initialLoadIn
|
|
|
725
776
|
});
|
|
726
777
|
}, [loadPdfDocument]);
|
|
727
778
|
const rememberPosition = useCallback((index, position) => {
|
|
728
|
-
|
|
729
|
-
if (pdfIndex !== Number(index)) return pdfFile;
|
|
730
|
-
return {
|
|
731
|
-
...pdfFile,
|
|
732
|
-
...position
|
|
733
|
-
};
|
|
734
|
-
}));
|
|
779
|
+
positionsRef.current.set(Number(index), position);
|
|
735
780
|
}, []);
|
|
736
781
|
useEffect(() => {
|
|
737
782
|
window.addEventListener("resizeAutoZoom", onResizeEvent);
|
|
@@ -781,7 +826,16 @@ const usePdfMultiViewer = ({ pdfs, startIndex, i18nData, lazyLoad, initialLoadIn
|
|
|
781
826
|
i18nData,
|
|
782
827
|
listVisible,
|
|
783
828
|
overlayMode,
|
|
784
|
-
pdfToShow:
|
|
829
|
+
pdfToShow: useMemo(() => {
|
|
830
|
+
const resolvedIndex = Number(activeIndex);
|
|
831
|
+
const file = files[resolvedIndex];
|
|
832
|
+
if (!file) return void 0;
|
|
833
|
+
const position = positionsRef.current.get(resolvedIndex);
|
|
834
|
+
return position ? {
|
|
835
|
+
...file,
|
|
836
|
+
...position
|
|
837
|
+
} : file;
|
|
838
|
+
}, [activeIndex, files]),
|
|
785
839
|
rememberPosition,
|
|
786
840
|
selectPdf,
|
|
787
841
|
toggleList,
|
|
@@ -791,10 +845,11 @@ const usePdfMultiViewer = ({ pdfs, startIndex, i18nData, lazyLoad, initialLoadIn
|
|
|
791
845
|
|
|
792
846
|
//#endregion
|
|
793
847
|
//#region src/components/PdfMultiViewer/PdfMultiViewer.tsx
|
|
794
|
-
const
|
|
848
|
+
const DEFAULT_I18N_DATA = {
|
|
795
849
|
loading: "Loading...",
|
|
796
850
|
pages: "Pages"
|
|
797
|
-
}
|
|
851
|
+
};
|
|
852
|
+
const PdfMultiViewer = ({ pdfs, autoZoom = true, className, controls = true, icons, lazyLoad = true, initialLoadIndex, rendererIcons, rendererClassName, rendererStyle, style, startIndex = "0", i18nData = DEFAULT_I18N_DATA, workerSrc }) => {
|
|
798
853
|
const { activeIndex, files, listVisible, overlayMode, pdfToShow, rememberPosition, selectPdf, toggleList, viewerContainerRef } = usePdfMultiViewer({
|
|
799
854
|
i18nData,
|
|
800
855
|
pdfs,
|
|
@@ -803,12 +858,20 @@ const PdfMultiViewer = ({ pdfs, autoZoom = true, controls = true, icons, lazyLoa
|
|
|
803
858
|
initialLoadIndex,
|
|
804
859
|
workerSrc
|
|
805
860
|
});
|
|
861
|
+
const iconStyles = useMemo(() => buildIconStyles(icons), [icons]);
|
|
806
862
|
return /* @__PURE__ */ jsx(PdfMultiViewerView_default, {
|
|
807
863
|
activeIndex,
|
|
808
864
|
autoZoom,
|
|
865
|
+
className,
|
|
809
866
|
controls,
|
|
810
867
|
files,
|
|
811
|
-
iconStyles:
|
|
868
|
+
iconStyles: useMemo(() => {
|
|
869
|
+
if (!iconStyles && !style) return void 0;
|
|
870
|
+
return {
|
|
871
|
+
...iconStyles ?? {},
|
|
872
|
+
...style ?? {}
|
|
873
|
+
};
|
|
874
|
+
}, [iconStyles, style]),
|
|
812
875
|
i18nData,
|
|
813
876
|
listVisible,
|
|
814
877
|
onRememberPosition: rememberPosition,
|
|
@@ -816,6 +879,9 @@ const PdfMultiViewer = ({ pdfs, autoZoom = true, controls = true, icons, lazyLoa
|
|
|
816
879
|
onToggleList: toggleList,
|
|
817
880
|
overlayMode,
|
|
818
881
|
pdfToShow,
|
|
882
|
+
rendererIcons,
|
|
883
|
+
rendererClassName,
|
|
884
|
+
rendererStyle,
|
|
819
885
|
viewerContainerRef
|
|
820
886
|
});
|
|
821
887
|
};
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["ZoomSelectBox","PdfRendererControls","PdfRendererView","PdfRenderer","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.mjs","names":["ZoomSelectBox","PdfRendererControls","PdfRendererView","PdfRenderer","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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"}
|