@cannyminds/dms-file-viewers 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-XBIKN46C.js → chunk-7QRYWFCO.js} +96 -57
- package/dist/chunk-7QRYWFCO.js.map +1 -0
- package/dist/{chunk-KBST5Z5H.mjs → chunk-7R2KG3PE.mjs} +2 -2
- package/dist/{chunk-7AUCINV2.mjs → chunk-CFYOPDCG.mjs} +2 -2
- package/dist/{chunk-57BAESSV.mjs → chunk-D74R4IKW.mjs} +2 -2
- package/dist/{chunk-VJFXCN5Z.mjs → chunk-DFBVN4MO.mjs} +5 -2
- package/dist/chunk-DFBVN4MO.mjs.map +1 -0
- package/dist/{chunk-ETHSDRF5.js → chunk-EXZCEYLI.js} +4 -4
- package/dist/{chunk-ETHSDRF5.js.map → chunk-EXZCEYLI.js.map} +1 -1
- package/dist/{chunk-FA5L62Y5.js → chunk-J3JKVSAM.js} +5 -2
- package/dist/chunk-J3JKVSAM.js.map +1 -0
- package/dist/{chunk-WNZHGFNC.mjs → chunk-NXVIRFGL.mjs} +2 -2
- package/dist/{chunk-THFHTTQX.mjs → chunk-P2VNW6OE.mjs} +2 -2
- package/dist/{chunk-QNDIZUU5.mjs → chunk-P5FH7LK7.mjs} +94 -55
- package/dist/chunk-P5FH7LK7.mjs.map +1 -0
- package/dist/{chunk-ORL5FTAW.mjs → chunk-PZJSY6OF.mjs} +51 -3
- package/dist/chunk-PZJSY6OF.mjs.map +1 -0
- package/dist/{chunk-LQVHD4FS.js → chunk-RVHIXSUP.js} +4 -4
- package/dist/{chunk-LQVHD4FS.js.map → chunk-RVHIXSUP.js.map} +1 -1
- package/dist/{chunk-QGM5J3SP.js → chunk-TGVFAAIP.js} +4 -4
- package/dist/{chunk-QGM5J3SP.js.map → chunk-TGVFAAIP.js.map} +1 -1
- package/dist/{chunk-RSCUIGVW.js → chunk-VOLQW3NF.js} +99 -51
- package/dist/chunk-VOLQW3NF.js.map +1 -0
- package/dist/{chunk-UUM656JE.js → chunk-VSGX22FQ.js} +4 -4
- package/dist/{chunk-UUM656JE.js.map → chunk-VSGX22FQ.js.map} +1 -1
- package/dist/{chunk-56PP5GHZ.js → chunk-WCAXWJE7.js} +4 -4
- package/dist/{chunk-56PP5GHZ.js.map → chunk-WCAXWJE7.js.map} +1 -1
- package/dist/components/viewers/AudioViewer.d.mts +1 -1
- package/dist/components/viewers/AudioViewer.d.ts +1 -1
- package/dist/components/viewers/AudioViewer.js +3 -3
- package/dist/components/viewers/AudioViewer.mjs +2 -2
- package/dist/components/viewers/DefaultViewer.d.mts +1 -1
- package/dist/components/viewers/DefaultViewer.d.ts +1 -1
- package/dist/components/viewers/DefaultViewer.js +3 -3
- package/dist/components/viewers/DefaultViewer.mjs +2 -2
- package/dist/components/viewers/ImageViewer.d.mts +1 -1
- package/dist/components/viewers/ImageViewer.d.ts +1 -1
- package/dist/components/viewers/ImageViewer.js +3 -3
- package/dist/components/viewers/ImageViewer.mjs +2 -2
- package/dist/components/viewers/PDFViewer.d.mts +4 -1
- package/dist/components/viewers/PDFViewer.d.ts +4 -1
- package/dist/components/viewers/PDFViewer.js +3 -3
- package/dist/components/viewers/PDFViewer.mjs +2 -2
- package/dist/components/viewers/TIFFViewer.d.mts +1 -1
- package/dist/components/viewers/TIFFViewer.d.ts +1 -1
- package/dist/components/viewers/TIFFViewer.js +3 -3
- package/dist/components/viewers/TIFFViewer.mjs +2 -2
- package/dist/components/viewers/TextViewer.d.mts +1 -1
- package/dist/components/viewers/TextViewer.d.ts +1 -1
- package/dist/components/viewers/TextViewer.js +3 -3
- package/dist/components/viewers/TextViewer.mjs +2 -2
- package/dist/components/viewers/VideoViewer.d.mts +1 -1
- package/dist/components/viewers/VideoViewer.d.ts +1 -1
- package/dist/components/viewers/VideoViewer.js +3 -3
- package/dist/components/viewers/VideoViewer.mjs +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +9 -9
- package/dist/index.mjs +8 -8
- package/dist/{types-CQIoF7E1.d.mts → types-DNrkDJdK.d.mts} +1 -0
- package/dist/{types-CQIoF7E1.d.ts → types-DNrkDJdK.d.ts} +1 -0
- package/package.json +2 -2
- package/dist/chunk-FA5L62Y5.js.map +0 -1
- package/dist/chunk-ORL5FTAW.mjs.map +0 -1
- package/dist/chunk-QNDIZUU5.mjs.map +0 -1
- package/dist/chunk-RSCUIGVW.js.map +0 -1
- package/dist/chunk-VJFXCN5Z.mjs.map +0 -1
- package/dist/chunk-XBIKN46C.js.map +0 -1
- /package/dist/{chunk-KBST5Z5H.mjs.map → chunk-7R2KG3PE.mjs.map} +0 -0
- /package/dist/{chunk-7AUCINV2.mjs.map → chunk-CFYOPDCG.mjs.map} +0 -0
- /package/dist/{chunk-57BAESSV.mjs.map → chunk-D74R4IKW.mjs.map} +0 -0
- /package/dist/{chunk-WNZHGFNC.mjs.map → chunk-NXVIRFGL.mjs.map} +0 -0
- /package/dist/{chunk-THFHTTQX.mjs.map → chunk-P2VNW6OE.mjs.map} +0 -0
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
FileIcon_default,
|
|
7
7
|
mergeToolbarConfig
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-DFBVN4MO.mjs";
|
|
9
9
|
|
|
10
10
|
// src/components/viewers/TIFFViewer.tsx
|
|
11
11
|
import {
|
|
@@ -101,8 +101,10 @@ var TIFFViewerContent = ({
|
|
|
101
101
|
const [imageUrl, setImageUrl] = useState(null);
|
|
102
102
|
const [pageImages, setPageImages] = useState(/* @__PURE__ */ new Map());
|
|
103
103
|
const [internalLoading, setInternalLoading] = useState(false);
|
|
104
|
+
const [imageSize, setImageSize] = useState(null);
|
|
104
105
|
const viewportRef = useRef(null);
|
|
105
106
|
const containerRef = useRef(null);
|
|
107
|
+
const imgRef = useRef(null);
|
|
106
108
|
const pageLoaderRef = useRef(pageLoader);
|
|
107
109
|
useEffect(() => {
|
|
108
110
|
pageLoaderRef.current = pageLoader;
|
|
@@ -241,12 +243,33 @@ var TIFFViewerContent = ({
|
|
|
241
243
|
}, []);
|
|
242
244
|
const hasImage = !!imageUrl;
|
|
243
245
|
const hasMultiplePages = totalPages > 1;
|
|
246
|
+
const MARGIN = 40;
|
|
247
|
+
const MIN_ZOOM = 25;
|
|
248
|
+
const MAX_ZOOM = 400;
|
|
249
|
+
const ZOOM_LEVELS = [25, 50, 75, 100, 125, 150, 200, 300, 400];
|
|
250
|
+
const calculateFitZoom = useCallback((mode) => {
|
|
251
|
+
if (!imageSize || viewportWidth <= 0) return null;
|
|
252
|
+
const availableWidth = viewportWidth - MARGIN;
|
|
253
|
+
if (mode === "fit-width") {
|
|
254
|
+
const calculatedZoom = Math.round(availableWidth / imageSize.width * 100);
|
|
255
|
+
return Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, calculatedZoom));
|
|
256
|
+
}
|
|
257
|
+
if (mode === "fit-page" && viewportHeight > 0) {
|
|
258
|
+
const availableHeight = viewportHeight - MARGIN;
|
|
259
|
+
const scaleW = availableWidth / imageSize.width;
|
|
260
|
+
const scaleH = availableHeight / imageSize.height;
|
|
261
|
+
const calculatedZoom = Math.round(Math.min(scaleW, scaleH) * 100);
|
|
262
|
+
return Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, calculatedZoom));
|
|
263
|
+
}
|
|
264
|
+
return null;
|
|
265
|
+
}, [imageSize, viewportWidth, viewportHeight]);
|
|
244
266
|
useEffect(() => {
|
|
245
|
-
if (hasImage)
|
|
246
|
-
|
|
247
|
-
|
|
267
|
+
if (!hasImage || !imageSize) return;
|
|
268
|
+
const newZoom = calculateFitZoom(fitMode);
|
|
269
|
+
if (newZoom !== null) {
|
|
270
|
+
setZoom(newZoom);
|
|
248
271
|
}
|
|
249
|
-
}, [currentPage, hasImage]);
|
|
272
|
+
}, [currentPage, hasImage, imageSize, fitMode, calculateFitZoom]);
|
|
250
273
|
useEffect(() => {
|
|
251
274
|
if (typeof window === "undefined" || typeof ResizeObserver === "undefined") {
|
|
252
275
|
return void 0;
|
|
@@ -271,27 +294,31 @@ var TIFFViewerContent = ({
|
|
|
271
294
|
const handleZoomIn = useCallback(() => {
|
|
272
295
|
setFitMode("zoom");
|
|
273
296
|
setZoom((value) => {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
return Math.min(value + 100, 500);
|
|
297
|
+
const nextLevel = ZOOM_LEVELS.find((level) => level > value);
|
|
298
|
+
return nextLevel || MAX_ZOOM;
|
|
277
299
|
});
|
|
278
300
|
}, []);
|
|
279
301
|
const handleZoomOut = useCallback(() => {
|
|
280
302
|
setFitMode("zoom");
|
|
281
303
|
setZoom((value) => {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
return Math.max(value - 100, 200);
|
|
304
|
+
const prevLevel = [...ZOOM_LEVELS].reverse().find((level) => level < value);
|
|
305
|
+
return prevLevel || MIN_ZOOM;
|
|
285
306
|
});
|
|
286
307
|
}, []);
|
|
287
308
|
const handleFitWidth = useCallback(() => {
|
|
288
309
|
setFitMode("fit-width");
|
|
289
|
-
|
|
290
|
-
|
|
310
|
+
const newZoom = calculateFitZoom("fit-width");
|
|
311
|
+
if (newZoom !== null) {
|
|
312
|
+
setZoom(newZoom);
|
|
313
|
+
}
|
|
314
|
+
}, [calculateFitZoom]);
|
|
291
315
|
const handleFitPage = useCallback(() => {
|
|
292
316
|
setFitMode("fit-page");
|
|
293
|
-
|
|
294
|
-
|
|
317
|
+
const newZoom = calculateFitZoom("fit-page");
|
|
318
|
+
if (newZoom !== null) {
|
|
319
|
+
setZoom(newZoom);
|
|
320
|
+
}
|
|
321
|
+
}, [calculateFitZoom]);
|
|
295
322
|
const handleFirstPage = useCallback(() => {
|
|
296
323
|
handlePageChange(1);
|
|
297
324
|
}, [handlePageChange]);
|
|
@@ -321,47 +348,51 @@ var TIFFViewerContent = ({
|
|
|
321
348
|
}, [isFullScreen]);
|
|
322
349
|
const toolbar = mergeToolbarConfig({ showDownload, showPrint, showMetadata, showProperties, onDownloadClick, onPrintClick, onMetadataClick, onPropertiesClick, toolbarActions });
|
|
323
350
|
const displayScale = zoom;
|
|
351
|
+
const handleImageLoad = useCallback((e) => {
|
|
352
|
+
const img = e.currentTarget;
|
|
353
|
+
setImageSize({ width: img.naturalWidth, height: img.naturalHeight });
|
|
354
|
+
if (!hasImage) {
|
|
355
|
+
onLoad?.();
|
|
356
|
+
}
|
|
357
|
+
}, [hasImage, onLoad]);
|
|
324
358
|
const renderImage = () => {
|
|
325
359
|
if (!imageUrl) {
|
|
326
360
|
return /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", children: "No image available." });
|
|
327
361
|
}
|
|
362
|
+
let imgStyle = {
|
|
363
|
+
display: "block",
|
|
364
|
+
borderRadius: "4px"
|
|
365
|
+
};
|
|
366
|
+
if (imageSize) {
|
|
367
|
+
const zoomFactor = zoom / 100;
|
|
368
|
+
const scaledWidth = imageSize.width * zoomFactor;
|
|
369
|
+
const scaledHeight = imageSize.height * zoomFactor;
|
|
370
|
+
imgStyle = {
|
|
371
|
+
...imgStyle,
|
|
372
|
+
width: `${scaledWidth}px`,
|
|
373
|
+
height: `${scaledHeight}px`,
|
|
374
|
+
maxWidth: "none",
|
|
375
|
+
maxHeight: "none"
|
|
376
|
+
};
|
|
377
|
+
}
|
|
328
378
|
return /* @__PURE__ */ jsx(
|
|
329
379
|
Box,
|
|
330
380
|
{
|
|
381
|
+
component: "img",
|
|
382
|
+
ref: imgRef,
|
|
383
|
+
src: imageUrl,
|
|
384
|
+
alt: `${resolvedFileName} page ${currentPage}`,
|
|
385
|
+
onLoad: handleImageLoad,
|
|
386
|
+
onError: () => {
|
|
387
|
+
setError("Failed to load image");
|
|
388
|
+
onError?.(new Error("Failed to load image"));
|
|
389
|
+
},
|
|
331
390
|
sx: {
|
|
332
|
-
|
|
333
|
-
borderRadius: 1,
|
|
391
|
+
...imgStyle,
|
|
334
392
|
boxShadow: 1,
|
|
335
393
|
backgroundColor: "#fff",
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
alignItems: "center"
|
|
339
|
-
},
|
|
340
|
-
children: /* @__PURE__ */ jsx(
|
|
341
|
-
Box,
|
|
342
|
-
{
|
|
343
|
-
component: "img",
|
|
344
|
-
src: imageUrl,
|
|
345
|
-
alt: `${resolvedFileName} page ${currentPage}`,
|
|
346
|
-
sx: {
|
|
347
|
-
maxWidth: fitMode === "fit-width" ? "100%" : "none",
|
|
348
|
-
maxHeight: fitMode === "fit-page" ? "100%" : "none",
|
|
349
|
-
width: fitMode === "zoom" ? `${zoom}%` : "auto",
|
|
350
|
-
height: "auto",
|
|
351
|
-
display: "block",
|
|
352
|
-
borderRadius: 1
|
|
353
|
-
},
|
|
354
|
-
onLoad: () => {
|
|
355
|
-
if (!hasImage) {
|
|
356
|
-
onLoad?.();
|
|
357
|
-
}
|
|
358
|
-
},
|
|
359
|
-
onError: () => {
|
|
360
|
-
setError("Failed to load image");
|
|
361
|
-
onError?.(new Error("Failed to load image"));
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
)
|
|
394
|
+
margin: "20px"
|
|
395
|
+
}
|
|
365
396
|
}
|
|
366
397
|
);
|
|
367
398
|
};
|
|
@@ -447,7 +478,7 @@ var TIFFViewerContent = ({
|
|
|
447
478
|
{
|
|
448
479
|
size: "small",
|
|
449
480
|
onClick: handleZoomOut,
|
|
450
|
-
disabled: !hasImage || zoom <=
|
|
481
|
+
disabled: !hasImage || zoom <= 25,
|
|
451
482
|
title: "Zoom Out",
|
|
452
483
|
"aria-label": "Zoom out",
|
|
453
484
|
children: /* @__PURE__ */ jsx(ZoomOutIcon, { fontSize: "small" })
|
|
@@ -459,7 +490,7 @@ var TIFFViewerContent = ({
|
|
|
459
490
|
{
|
|
460
491
|
size: "small",
|
|
461
492
|
onClick: handleZoomIn,
|
|
462
|
-
disabled: !hasImage || zoom >=
|
|
493
|
+
disabled: !hasImage || zoom >= 400,
|
|
463
494
|
title: "Zoom In",
|
|
464
495
|
"aria-label": "Zoom in",
|
|
465
496
|
children: /* @__PURE__ */ jsx(ZoomInIcon, { fontSize: "small" })
|
|
@@ -557,7 +588,7 @@ var TIFFViewerContent = ({
|
|
|
557
588
|
flexShrink: 1,
|
|
558
589
|
minHeight: 0,
|
|
559
590
|
p: 0,
|
|
560
|
-
overflow: "
|
|
591
|
+
overflow: "hidden",
|
|
561
592
|
backgroundColor: "#f6f8fa",
|
|
562
593
|
position: "relative"
|
|
563
594
|
},
|
|
@@ -571,13 +602,21 @@ var TIFFViewerContent = ({
|
|
|
571
602
|
left: 0,
|
|
572
603
|
right: 0,
|
|
573
604
|
bottom: 0,
|
|
574
|
-
display: "flex",
|
|
575
|
-
alignItems: "center",
|
|
576
|
-
justifyContent: "center",
|
|
577
|
-
p: 3,
|
|
578
605
|
overflow: "auto"
|
|
579
606
|
},
|
|
580
|
-
children:
|
|
607
|
+
children: /* @__PURE__ */ jsx(
|
|
608
|
+
Box,
|
|
609
|
+
{
|
|
610
|
+
sx: {
|
|
611
|
+
minWidth: "100%",
|
|
612
|
+
minHeight: "100%",
|
|
613
|
+
display: "flex",
|
|
614
|
+
alignItems: "center",
|
|
615
|
+
justifyContent: "center"
|
|
616
|
+
},
|
|
617
|
+
children: renderImage()
|
|
618
|
+
}
|
|
619
|
+
)
|
|
581
620
|
}
|
|
582
621
|
)
|
|
583
622
|
}
|
|
@@ -597,4 +636,4 @@ var TIFFViewer = (props) => {
|
|
|
597
636
|
export {
|
|
598
637
|
TIFFViewer
|
|
599
638
|
};
|
|
600
|
-
//# sourceMappingURL=chunk-
|
|
639
|
+
//# sourceMappingURL=chunk-P5FH7LK7.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/viewers/TIFFViewer.tsx"],"sourcesContent":["import React, {\r\n useCallback,\r\n useEffect,\r\n useMemo,\r\n useRef,\r\n useState\r\n} from 'react';\r\nimport {\r\n Box,\r\n Button,\r\n ButtonGroup,\r\n Card,\r\n CardContent,\r\n CardHeader,\r\n Divider,\r\n LinearProgress,\r\n Stack,\r\n Typography,\r\n IconButton,\r\n Tooltip\r\n} from '@mui/material';\r\nimport DownloadIcon from '@mui/icons-material/Download';\r\nimport PrintIcon from '@mui/icons-material/Print';\r\nimport FullscreenIcon from '@mui/icons-material/Fullscreen';\r\nimport FirstPageIcon from '@mui/icons-material/FirstPage';\r\nimport LastPageIcon from '@mui/icons-material/LastPage';\r\nimport ChevronLeftIcon from '@mui/icons-material/ChevronLeft';\r\nimport ChevronRightIcon from '@mui/icons-material/ChevronRight';\r\nimport ZoomInIcon from '@mui/icons-material/ZoomIn';\r\nimport ZoomOutIcon from '@mui/icons-material/ZoomOut';\r\nimport FitScreenIcon from '@mui/icons-material/FitScreen';\r\nimport AspectRatioIcon from '@mui/icons-material/AspectRatio';\r\nimport InfoIcon from '@mui/icons-material/Info';\r\nimport DescriptionIcon from '@mui/icons-material/Description';\r\nimport { FileViewerProps } from '../../types';\r\nimport { getFileExtension } from '../../utils/fileUtils';\r\nimport { mergeToolbarConfig } from '../../utils/toolbarUtils';\r\nimport FileIcon from '../FileIcon';\r\n\r\nconst resolveDocumentName = (file?: File, fileName?: string, url?: string) => {\r\n if (file?.name) {\r\n return file.name;\r\n }\r\n if (fileName) {\r\n return fileName;\r\n }\r\n if (url) {\r\n const parts = url.split('?')[0]?.split('#')[0]?.split('/') ?? [];\r\n return parts[parts.length - 1] || 'document.tiff';\r\n }\r\n return 'document.tiff';\r\n};\r\n\r\ninterface TIFFViewerContentProps extends FileViewerProps {\r\n sourceDescription: string;\r\n}\r\n\r\nconst TIFFViewerContent: React.FC<TIFFViewerContentProps> = ({\r\n sourceDescription,\r\n file,\r\n url,\r\n fileName,\r\n totalPages = 1,\r\n className = '',\r\n style = {},\r\n width = '100%',\r\n height = '100%',\r\n onLoad,\r\n onError,\r\n onDownloadClick,\r\n onPrintClick,\r\n onMetadataClick,\r\n onPropertiesClick,\r\n pageLoader,\r\n showDownload = true,\r\n showPrint = true,\r\n showMetadata = false,\r\n showProperties = false,\r\n // Extract props that shouldn't be passed to DOM elements\r\n mimeType,\r\n fileSize,\r\n showPageCount,\r\n showPageNavigation,\r\n showZoomControls,\r\n showSearch,\r\n customRegistry,\r\n initialSearchText,\r\n initialSearchPages,\r\n autoOpenSearch,\r\n autoExecuteSearch,\r\n onSearchComplete,\r\n toolbarActions,\r\n ...props\r\n}) => {\r\n const [currentPage, setCurrentPage] = useState(1);\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [fitMode, setFitMode] = useState<'fit-width' | 'fit-page' | 'zoom'>('fit-page');\r\n const [zoom, setZoom] = useState(100);\r\n const [viewportWidth, setViewportWidth] = useState<number>(0);\r\n const [viewportHeight, setViewportHeight] = useState<number>(0);\r\n const [isFullScreen, setIsFullScreen] = useState(false);\r\n const [imageUrl, setImageUrl] = useState<string | null>(null);\r\n const [pageImages, setPageImages] = useState<Map<number, string>>(new Map());\r\n const [internalLoading, setInternalLoading] = useState(false);\r\n const [imageSize, setImageSize] = useState<{ width: number; height: number } | null>(null);\r\n\r\n const viewportRef = useRef<HTMLDivElement | null>(null);\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const imgRef = useRef<HTMLImageElement | null>(null);\r\n \r\n // Store pageLoader in ref to prevent re-renders\r\n const pageLoaderRef = useRef(pageLoader);\r\n useEffect(() => {\r\n pageLoaderRef.current = pageLoader;\r\n }, [pageLoader]);\r\n\r\n // Update page image from ArrayBuffer data\r\n const updatePageImage = useCallback((pageData: ArrayBuffer, pageNumber: number) => {\r\n const blob = new Blob([pageData]);\r\n const imageUrl = URL.createObjectURL(blob);\r\n \r\n setPageImages(prev => {\r\n // Only clean up old URL if we're replacing with a different one\r\n const oldUrl = prev.get(pageNumber);\r\n if (oldUrl && oldUrl !== imageUrl) {\r\n URL.revokeObjectURL(oldUrl);\r\n }\r\n return new Map(prev).set(pageNumber, imageUrl);\r\n });\r\n setCurrentPage(pageNumber);\r\n setImageUrl(imageUrl);\r\n }, []);\r\n\r\n // Load initial page when pageLoader is available\r\n useEffect(() => {\r\n const loadInitialPage = async () => {\r\n if (pageLoaderRef.current && !pageImages.has(1) && currentPage === 1) {\r\n setInternalLoading(true);\r\n setError(null);\r\n \r\n try {\r\n const pageData = await pageLoaderRef.current(1);\r\n if (pageData) {\r\n updatePageImage(pageData, 1);\r\n } else {\r\n setError('Failed to load page 1');\r\n }\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : 'Unable to load page 1';\r\n setError(message);\r\n onError?.(new Error(message));\r\n } finally {\r\n setInternalLoading(false);\r\n }\r\n }\r\n };\r\n\r\n loadInitialPage();\r\n }, [pageImages, currentPage, updatePageImage, onError]);\r\n\r\n // Handle internal page navigation\r\n const handlePageChange = useCallback(async (newPageNumber: number) => {\r\n if (!pageLoaderRef.current) {\r\n console.warn('pageLoader not provided - page navigation disabled');\r\n return;\r\n }\r\n\r\n // Check if page is already cached\r\n const cachedUrl = pageImages.get(newPageNumber);\r\n if (cachedUrl) {\r\n setCurrentPage(newPageNumber);\r\n setImageUrl(cachedUrl);\r\n return;\r\n }\r\n\r\n setInternalLoading(true);\r\n setError(null);\r\n \r\n try {\r\n const pageData = await pageLoaderRef.current(newPageNumber);\r\n if (pageData) {\r\n updatePageImage(pageData, newPageNumber);\r\n } else {\r\n setError(`Failed to load page ${newPageNumber}`);\r\n }\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : `Unable to load page ${newPageNumber}`;\r\n setError(message);\r\n onError?.(new Error(message));\r\n } finally {\r\n setInternalLoading(false);\r\n }\r\n }, [pageImages, onError, updatePageImage]);\r\n\r\n const resolvedFileName = useMemo(\r\n () => fileName || sourceDescription,\r\n [fileName, sourceDescription]\r\n );\r\n\r\n const fileExtension = useMemo(\r\n () => getFileExtension(resolvedFileName || ''),\r\n [resolvedFileName]\r\n );\r\n\r\n const loadImage = useCallback(async (resetPage = false) => {\r\n if (!file && !url) {\r\n setImageUrl(null);\r\n if (resetPage) setCurrentPage(1);\r\n setError(null);\r\n return;\r\n }\r\n\r\n setIsLoading(true);\r\n setError(null);\r\n\r\n try {\r\n let imageDataUrl: string;\r\n if (file) {\r\n imageDataUrl = URL.createObjectURL(file);\r\n } else if (url) {\r\n imageDataUrl = url;\r\n } else {\r\n throw new Error('No file or URL provided');\r\n }\r\n\r\n setImageUrl(imageDataUrl);\r\n if (resetPage) {\r\n setCurrentPage(1);\r\n setFitMode('fit-page');\r\n setZoom(100);\r\n }\r\n onLoad?.();\r\n } catch (err) {\r\n const message = err instanceof Error ? err.message : 'Unable to load image file';\r\n setError(message);\r\n setImageUrl(null);\r\n if (resetPage) {\r\n setCurrentPage(1);\r\n setFitMode('fit-width');\r\n setZoom(100);\r\n }\r\n onError?.(new Error(message));\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n }, [file, url, onLoad, onError]);\r\n\r\n const [previousFileSource, setPreviousFileSource] = useState<{ file?: File; url?: string }>({});\r\n\r\n useEffect(() => {\r\n const currentFileSource = { file, url };\r\n const isNewFile = previousFileSource.file !== file || previousFileSource.url !== url;\r\n \r\n if (isNewFile) {\r\n setPreviousFileSource(currentFileSource);\r\n void loadImage(true); // Reset page on new file\r\n } else {\r\n void loadImage(false); // Don't reset page for same file\r\n }\r\n }, [file, url, loadImage, previousFileSource.file, previousFileSource.url]);\r\n\r\n useEffect(() => {\r\n return () => {\r\n // Clean up all cached page URLs only on unmount\r\n pageImages.forEach((url) => {\r\n URL.revokeObjectURL(url);\r\n });\r\n // Clean up current image URL if it's from a file (not from pageLoader)\r\n if (imageUrl && file && !pageImages.has(currentPage)) {\r\n URL.revokeObjectURL(imageUrl);\r\n }\r\n };\r\n }, []); // Empty dependency array - only cleanup on unmount\r\n\r\n const hasImage = !!imageUrl;\r\n const hasMultiplePages = totalPages > 1;\r\n\r\n // Constants for zoom calculation\r\n const MARGIN = 40;\r\n const MIN_ZOOM = 25;\r\n const MAX_ZOOM = 400;\r\n const ZOOM_LEVELS = [25, 50, 75, 100, 125, 150, 200, 300, 400];\r\n\r\n // Helper function to calculate zoom based on fit mode\r\n const calculateFitZoom = useCallback((mode: 'fit-width' | 'fit-page'): number | null => {\r\n if (!imageSize || viewportWidth <= 0) return null;\r\n\r\n const availableWidth = viewportWidth - MARGIN;\r\n\r\n if (mode === 'fit-width') {\r\n const calculatedZoom = Math.round((availableWidth / imageSize.width) * 100);\r\n return Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, calculatedZoom));\r\n }\r\n\r\n if (mode === 'fit-page' && viewportHeight > 0) {\r\n const availableHeight = viewportHeight - MARGIN;\r\n const scaleW = availableWidth / imageSize.width;\r\n const scaleH = availableHeight / imageSize.height;\r\n const calculatedZoom = Math.round(Math.min(scaleW, scaleH) * 100);\r\n return Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, calculatedZoom));\r\n }\r\n\r\n return null;\r\n }, [imageSize, viewportWidth, viewportHeight]);\r\n\r\n // Recalculate zoom when changing pages in fit modes\r\n useEffect(() => {\r\n if (!hasImage || !imageSize) return;\r\n\r\n const newZoom = calculateFitZoom(fitMode as 'fit-width' | 'fit-page');\r\n if (newZoom !== null) {\r\n setZoom(newZoom);\r\n }\r\n }, [currentPage, hasImage, imageSize, fitMode, calculateFitZoom]);\r\n\r\n useEffect(() => {\r\n if (typeof window === 'undefined' || typeof ResizeObserver === 'undefined') {\r\n return undefined;\r\n }\r\n\r\n if (!viewportRef.current) {\r\n return undefined;\r\n }\r\n\r\n const updateSize = () => {\r\n const bounds = viewportRef.current?.getBoundingClientRect();\r\n if (bounds) {\r\n setViewportWidth(bounds.width);\r\n setViewportHeight(bounds.height);\r\n }\r\n };\r\n\r\n updateSize();\r\n const observer = new ResizeObserver(updateSize);\r\n observer.observe(viewportRef.current);\r\n\r\n return () => {\r\n observer.disconnect();\r\n };\r\n }, []);\r\n\r\n const handleZoomIn = useCallback(() => {\r\n setFitMode('zoom');\r\n setZoom((value) => {\r\n const nextLevel = ZOOM_LEVELS.find(level => level > value);\r\n return nextLevel || MAX_ZOOM;\r\n });\r\n }, []);\r\n\r\n const handleZoomOut = useCallback(() => {\r\n setFitMode('zoom');\r\n setZoom((value) => {\r\n const prevLevel = [...ZOOM_LEVELS].reverse().find(level => level < value);\r\n return prevLevel || MIN_ZOOM;\r\n });\r\n }, []);\r\n\r\n const handleFitWidth = useCallback(() => {\r\n setFitMode('fit-width');\r\n const newZoom = calculateFitZoom('fit-width');\r\n if (newZoom !== null) {\r\n setZoom(newZoom);\r\n }\r\n }, [calculateFitZoom]);\r\n\r\n const handleFitPage = useCallback(() => {\r\n setFitMode('fit-page');\r\n const newZoom = calculateFitZoom('fit-page');\r\n if (newZoom !== null) {\r\n setZoom(newZoom);\r\n }\r\n }, [calculateFitZoom]);\r\n\r\n const handleFirstPage = useCallback(() => {\r\n handlePageChange(1);\r\n }, [handlePageChange]);\r\n\r\n const handleLastPage = useCallback(() => {\r\n handlePageChange(totalPages);\r\n }, [handlePageChange, totalPages]);\r\n\r\n const handlePreviousPage = useCallback(() => {\r\n const newPage = Math.max(currentPage - 1, 1);\r\n if (newPage !== currentPage) {\r\n handlePageChange(newPage);\r\n }\r\n }, [currentPage, handlePageChange]);\r\n\r\n const handleNextPage = useCallback(() => {\r\n const newPage = Math.min(currentPage + 1, totalPages);\r\n if (newPage !== currentPage) {\r\n handlePageChange(newPage);\r\n }\r\n }, [currentPage, totalPages, handlePageChange]);\r\n\r\n const handleToggleFullScreen = useCallback(() => {\r\n if (!isFullScreen && containerRef.current?.requestFullscreen) {\r\n containerRef.current.requestFullscreen();\r\n setIsFullScreen(true);\r\n } else if (isFullScreen && document.exitFullscreen) {\r\n document.exitFullscreen();\r\n setIsFullScreen(false);\r\n }\r\n }, [isFullScreen]);\r\n\r\n const toolbar = mergeToolbarConfig({ showDownload, showPrint, showMetadata, showProperties, onDownloadClick, onPrintClick, onMetadataClick, onPropertiesClick, toolbarActions });\r\n\r\n const displayScale = zoom;\r\n\r\n const handleImageLoad = useCallback((e: React.SyntheticEvent<HTMLImageElement>) => {\r\n const img = e.currentTarget;\r\n setImageSize({ width: img.naturalWidth, height: img.naturalHeight });\r\n if (!hasImage) {\r\n onLoad?.();\r\n }\r\n }, [hasImage, onLoad]);\r\n\r\n const renderImage = () => {\r\n if (!imageUrl) {\r\n return (\r\n <Typography variant=\"body2\" color=\"text.secondary\">\r\n No image available.\r\n </Typography>\r\n );\r\n }\r\n\r\n // Calculate scaled dimensions based on zoom\r\n let imgStyle: React.CSSProperties = {\r\n display: 'block',\r\n borderRadius: '4px',\r\n };\r\n\r\n if (imageSize) {\r\n // Always use zoom-based calculation for consistent behavior\r\n const zoomFactor = zoom / 100;\r\n const scaledWidth = imageSize.width * zoomFactor;\r\n const scaledHeight = imageSize.height * zoomFactor;\r\n imgStyle = {\r\n ...imgStyle,\r\n width: `${scaledWidth}px`,\r\n height: `${scaledHeight}px`,\r\n maxWidth: 'none',\r\n maxHeight: 'none',\r\n };\r\n }\r\n\r\n return (\r\n <Box\r\n component=\"img\"\r\n ref={imgRef}\r\n src={imageUrl}\r\n alt={`${resolvedFileName} page ${currentPage}`}\r\n onLoad={handleImageLoad}\r\n onError={() => {\r\n setError('Failed to load image');\r\n onError?.(new Error('Failed to load image'));\r\n }}\r\n sx={{\r\n ...imgStyle,\r\n boxShadow: 1,\r\n backgroundColor: '#fff',\r\n margin: '20px',\r\n }}\r\n />\r\n );\r\n };\r\n\r\n return (\r\n <Box\r\n ref={containerRef}\r\n className={`tiff-viewer ${className}`}\r\n sx={{\r\n width,\r\n height,\r\n display: 'flex',\r\n flexDirection: 'column',\r\n overflow: 'hidden',\r\n ...style\r\n }}\r\n {...props}\r\n >\r\n <Card sx={{ height: '100%', width: '100%', display: 'flex', flexDirection: 'column', overflow: 'hidden' }} elevation={1}>\r\n <CardHeader\r\n avatar={<FileIcon ext={fileExtension} size={32} />}\r\n title={\r\n <Typography variant=\"subtitle1\" fontWeight={500}>\r\n {resolvedFileName}\r\n </Typography>\r\n }\r\n sx={{ pb: 1 }}\r\n />\r\n\r\n {/* Toolbar - All Controls at Top (Centered) */}\r\n <Box sx={{ px: 2, pb: 1, display: 'flex', justifyContent: 'center' }}>\r\n <Stack direction=\"row\" spacing={1} alignItems=\"center\" flexWrap=\"wrap\" gap={1}>\r\n {/* Page Navigation */}\r\n {hasMultiplePages && (\r\n <>\r\n <IconButton\r\n size=\"small\"\r\n onClick={handleFirstPage}\r\n disabled={currentPage === 1}\r\n title=\"First Page\"\r\n aria-label=\"Go to first page\"\r\n >\r\n <FirstPageIcon fontSize=\"small\" />\r\n </IconButton>\r\n <IconButton\r\n size=\"small\"\r\n onClick={handlePreviousPage}\r\n disabled={currentPage === 1}\r\n title=\"Previous Page\"\r\n aria-label=\"Go to previous page\"\r\n >\r\n <ChevronLeftIcon fontSize=\"small\" />\r\n </IconButton>\r\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ minWidth: 100, textAlign: 'center' }}>\r\n Page {currentPage} of {totalPages}\r\n </Typography>\r\n <IconButton\r\n size=\"small\"\r\n onClick={handleNextPage}\r\n disabled={currentPage === totalPages}\r\n title=\"Next Page\"\r\n aria-label=\"Go to next page\"\r\n >\r\n <ChevronRightIcon fontSize=\"small\" />\r\n </IconButton>\r\n <IconButton\r\n size=\"small\"\r\n onClick={handleLastPage}\r\n disabled={currentPage === totalPages}\r\n title=\"Last Page\"\r\n aria-label=\"Go to last page\"\r\n >\r\n <LastPageIcon fontSize=\"small\" />\r\n </IconButton>\r\n <Divider orientation=\"vertical\" flexItem sx={{ mx: 1 }} />\r\n </>\r\n )}\r\n\r\n {/* Zoom Controls */}\r\n <IconButton\r\n size=\"small\"\r\n onClick={handleZoomOut}\r\n disabled={!hasImage || zoom <= 25}\r\n title=\"Zoom Out\"\r\n aria-label=\"Zoom out\"\r\n >\r\n <ZoomOutIcon fontSize=\"small\" />\r\n </IconButton>\r\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ minWidth: 64, textAlign: 'center' }}>\r\n {hasImage ? `${displayScale}%` : '—'}\r\n </Typography>\r\n <IconButton\r\n size=\"small\"\r\n onClick={handleZoomIn}\r\n disabled={!hasImage || zoom >= 400}\r\n title=\"Zoom In\"\r\n aria-label=\"Zoom in\"\r\n >\r\n <ZoomInIcon fontSize=\"small\" />\r\n </IconButton>\r\n\r\n <IconButton\r\n size=\"small\"\r\n onClick={handleFitWidth}\r\n disabled={!hasImage}\r\n title=\"Fit to Width\"\r\n aria-label=\"Fit to width\"\r\n color={fitMode === 'fit-width' ? 'primary' : 'default'}\r\n >\r\n <AspectRatioIcon fontSize=\"small\" />\r\n </IconButton>\r\n\r\n <IconButton\r\n size=\"small\"\r\n onClick={handleFitPage}\r\n disabled={!hasImage}\r\n title=\"Fit to Page\"\r\n aria-label=\"Fit to page\"\r\n color={fitMode === 'fit-page' ? 'primary' : 'default'}\r\n >\r\n <FitScreenIcon fontSize=\"small\" />\r\n </IconButton>\r\n\r\n <Divider orientation=\"vertical\" flexItem sx={{ mx: 1 }} />\r\n\r\n {/* Actions */}\r\n {!toolbar.isHidden('download') && (\r\n <IconButton\r\n size=\"small\"\r\n onClick={toolbar.getHandler('download', onDownloadClick)}\r\n disabled={toolbar.isDisabled('download')}\r\n title={toolbar.getLabel('download') || \"Download\"}\r\n aria-label=\"Download TIFF\"\r\n >\r\n {toolbar.getIcon('download') || <DownloadIcon fontSize=\"small\" />}\r\n </IconButton>\r\n )}\r\n\r\n {!toolbar.isHidden('print') && (\r\n <IconButton\r\n size=\"small\"\r\n onClick={toolbar.getHandler('print', onPrintClick)}\r\n disabled={toolbar.isDisabled('print')}\r\n title={toolbar.getLabel('print') || \"Print\"}\r\n aria-label=\"Print TIFF\"\r\n >\r\n {toolbar.getIcon('print') || <PrintIcon fontSize=\"small\" />}\r\n </IconButton>\r\n )}\r\n\r\n {!toolbar.isHidden('fullscreen') && (\r\n <IconButton\r\n size=\"small\"\r\n onClick={toolbar.getHandler('fullscreen', handleToggleFullScreen)}\r\n disabled={toolbar.isDisabled('fullscreen')}\r\n title={toolbar.getLabel('fullscreen') || \"Fullscreen\"}\r\n aria-label=\"Toggle fullscreen\"\r\n >\r\n {toolbar.getIcon('fullscreen') || <FullscreenIcon fontSize=\"small\" />}\r\n </IconButton>\r\n )}\r\n\r\n {!toolbar.isHidden('metadata') && (\r\n <IconButton\r\n size=\"small\"\r\n onClick={toolbar.getHandler('metadata', onMetadataClick)}\r\n disabled={toolbar.isDisabled('metadata')}\r\n title={toolbar.getLabel('metadata') || \"Document Metadata\"}\r\n aria-label=\"View document metadata\"\r\n >\r\n {toolbar.getIcon('metadata') || <DescriptionIcon fontSize=\"small\" />}\r\n </IconButton>\r\n )}\r\n\r\n {!toolbar.isHidden('properties') && (\r\n <IconButton\r\n size=\"small\"\r\n onClick={toolbar.getHandler('properties', onPropertiesClick)}\r\n disabled={toolbar.isDisabled('properties')}\r\n title={toolbar.getLabel('properties') || \"Document Properties\"}\r\n aria-label=\"View document properties\"\r\n >\r\n {toolbar.getIcon('properties') || <InfoIcon fontSize=\"small\" />}\r\n </IconButton>\r\n )}\r\n </Stack>\r\n </Box>\r\n\r\n {(isLoading || internalLoading) && <LinearProgress sx={{ mx: 3, mb: 1 }} />}\r\n {error && (\r\n <Typography color=\"error\" variant=\"body2\" sx={{ px: 3, pb: 1 }}>\r\n {error}\r\n </Typography>\r\n )}\r\n <Divider />\r\n <CardContent\r\n sx={{\r\n flexGrow: 1,\r\n flexShrink: 1,\r\n minHeight: 0,\r\n p: 0,\r\n overflow: 'hidden',\r\n backgroundColor: '#f6f8fa',\r\n position: 'relative'\r\n }}\r\n >\r\n <Box\r\n ref={viewportRef}\r\n sx={{\r\n position: 'absolute',\r\n top: 0,\r\n left: 0,\r\n right: 0,\r\n bottom: 0,\r\n overflow: 'auto',\r\n }}\r\n >\r\n <Box\r\n sx={{\r\n minWidth: '100%',\r\n minHeight: '100%',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n }}\r\n >\r\n {renderImage()}\r\n </Box>\r\n </Box>\r\n </CardContent>\r\n </Card>\r\n </Box>\r\n );\r\n};\r\n\r\nexport const TIFFViewer: React.FC<FileViewerProps> = (props) => {\r\n const sourceDescription = useMemo(\r\n () => resolveDocumentName(props.file, props.fileName, props.url),\r\n [props.file, props.fileName, props.url]\r\n );\r\n\r\n return <TIFFViewerContent {...props} sourceDescription={sourceDescription} />;\r\n};\r\n"],"mappings":"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","names":["imageUrl","url"]}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
import {
|
|
9
9
|
FileIcon_default,
|
|
10
10
|
mergeToolbarConfig
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-DFBVN4MO.mjs";
|
|
12
12
|
|
|
13
13
|
// src/components/viewers/PDFViewer.tsx
|
|
14
14
|
import { useCallback, useEffect as useEffect3, useMemo, useRef as useRef2, useState as useState3, forwardRef, useImperativeHandle } from "react";
|
|
@@ -50,6 +50,8 @@ import DownloadIcon from "@mui/icons-material/Download";
|
|
|
50
50
|
import PrintIcon from "@mui/icons-material/Print";
|
|
51
51
|
import InfoIcon from "@mui/icons-material/Info";
|
|
52
52
|
import DescriptionIcon from "@mui/icons-material/Description";
|
|
53
|
+
import RotateLeftIcon from "@mui/icons-material/RotateLeft";
|
|
54
|
+
import RotateRightIcon from "@mui/icons-material/RotateRight";
|
|
53
55
|
import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
54
56
|
var PDFToolbar = React2.memo(({
|
|
55
57
|
currentPage,
|
|
@@ -64,6 +66,9 @@ var PDFToolbar = React2.memo(({
|
|
|
64
66
|
showProperties,
|
|
65
67
|
showDownload,
|
|
66
68
|
showPrint,
|
|
69
|
+
showRotation,
|
|
70
|
+
disabledRotateLeft,
|
|
71
|
+
disabledRotateRight,
|
|
67
72
|
disabledMetadata,
|
|
68
73
|
disabledProperties,
|
|
69
74
|
disabledDownload,
|
|
@@ -80,6 +85,8 @@ var PDFToolbar = React2.memo(({
|
|
|
80
85
|
onFitToPage,
|
|
81
86
|
onToggleSidebar,
|
|
82
87
|
onToggleFullScreen,
|
|
88
|
+
onRotateLeft,
|
|
89
|
+
onRotateRight,
|
|
83
90
|
onDownloadClick,
|
|
84
91
|
onPrintClick,
|
|
85
92
|
onMetadataClick,
|
|
@@ -192,6 +199,31 @@ var PDFToolbar = React2.memo(({
|
|
|
192
199
|
)
|
|
193
200
|
] })
|
|
194
201
|
] }),
|
|
202
|
+
showRotation && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
203
|
+
/* @__PURE__ */ jsx2("div", { className: "toolbar-separator" }),
|
|
204
|
+
/* @__PURE__ */ jsxs("div", { className: "toolbar-section", children: [
|
|
205
|
+
/* @__PURE__ */ jsx2(
|
|
206
|
+
"button",
|
|
207
|
+
{
|
|
208
|
+
className: "toolbar-button",
|
|
209
|
+
onClick: onRotateLeft,
|
|
210
|
+
disabled: disabledRotateLeft,
|
|
211
|
+
title: "Rotate Counterclockwise",
|
|
212
|
+
children: /* @__PURE__ */ jsx2(RotateLeftIcon, { fontSize: "small" })
|
|
213
|
+
}
|
|
214
|
+
),
|
|
215
|
+
/* @__PURE__ */ jsx2(
|
|
216
|
+
"button",
|
|
217
|
+
{
|
|
218
|
+
className: "toolbar-button",
|
|
219
|
+
onClick: onRotateRight,
|
|
220
|
+
disabled: disabledRotateRight,
|
|
221
|
+
title: "Rotate Clockwise",
|
|
222
|
+
children: /* @__PURE__ */ jsx2(RotateRightIcon, { fontSize: "small" })
|
|
223
|
+
}
|
|
224
|
+
)
|
|
225
|
+
] })
|
|
226
|
+
] }),
|
|
195
227
|
showSearch && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
196
228
|
/* @__PURE__ */ jsx2("div", { className: "toolbar-separator" }),
|
|
197
229
|
/* @__PURE__ */ jsx2("div", { className: "toolbar-section", children: /* @__PURE__ */ jsx2(
|
|
@@ -951,6 +983,7 @@ var PDFViewerContent = forwardRef((props, ref) => {
|
|
|
951
983
|
showPageCount = true,
|
|
952
984
|
showPageNavigation = true,
|
|
953
985
|
showZoomControls = true,
|
|
986
|
+
showRotation = true,
|
|
954
987
|
showDownload = true,
|
|
955
988
|
showPrint = true,
|
|
956
989
|
showSearch = true,
|
|
@@ -1019,6 +1052,7 @@ var PDFViewerContent = forwardRef((props, ref) => {
|
|
|
1019
1052
|
showPrint,
|
|
1020
1053
|
showMetadata,
|
|
1021
1054
|
showProperties,
|
|
1055
|
+
showRotation,
|
|
1022
1056
|
onDownloadClick,
|
|
1023
1057
|
onPrintClick,
|
|
1024
1058
|
onMetadataClick,
|
|
@@ -1118,6 +1152,12 @@ var PDFViewerContent = forwardRef((props, ref) => {
|
|
|
1118
1152
|
}
|
|
1119
1153
|
}
|
|
1120
1154
|
},
|
|
1155
|
+
handleRotateLeft: () => {
|
|
1156
|
+
pdfViewerRef.current?.rotate?.rotateBackward();
|
|
1157
|
+
},
|
|
1158
|
+
handleRotateRight: () => {
|
|
1159
|
+
pdfViewerRef.current?.rotate?.rotateForward();
|
|
1160
|
+
},
|
|
1121
1161
|
handleToggleFullScreen
|
|
1122
1162
|
}), [isSidebarOpen, totalPages, handleToggleFullScreen]);
|
|
1123
1163
|
useEffect3(() => {
|
|
@@ -1329,7 +1369,10 @@ var PDFViewerContent = forwardRef((props, ref) => {
|
|
|
1329
1369
|
},
|
|
1330
1370
|
getSearchState: () => pdfViewerRef.current?.search.getSearchState() || null,
|
|
1331
1371
|
getSelectedText: () => pdfViewerRef.current?.selection.getSelectedText() || "",
|
|
1332
|
-
clearSelection: () => pdfViewerRef.current?.selection.clearSelection()
|
|
1372
|
+
clearSelection: () => pdfViewerRef.current?.selection.clearSelection(),
|
|
1373
|
+
rotateForward: () => pdfViewerRef.current?.rotate?.rotateForward(),
|
|
1374
|
+
rotateBackward: () => pdfViewerRef.current?.rotate?.rotateBackward(),
|
|
1375
|
+
getRotation: () => pdfViewerRef.current?.rotate?.getRotation() || 0
|
|
1333
1376
|
}), []);
|
|
1334
1377
|
const updatePageDisplay = () => {
|
|
1335
1378
|
requestAnimationFrame(() => {
|
|
@@ -1612,10 +1655,13 @@ var PDFViewerContent = forwardRef((props, ref) => {
|
|
|
1612
1655
|
showPageCount,
|
|
1613
1656
|
showZoomControls,
|
|
1614
1657
|
showSearch,
|
|
1658
|
+
showRotation: !toolbar.isHidden("rotation"),
|
|
1615
1659
|
showMetadata: !toolbar.isHidden("metadata"),
|
|
1616
1660
|
showProperties: !toolbar.isHidden("properties"),
|
|
1617
1661
|
showDownload: !toolbar.isHidden("download"),
|
|
1618
1662
|
showPrint: !toolbar.isHidden("print"),
|
|
1663
|
+
disabledRotateLeft: toolbar.isDisabled("rotateLeft"),
|
|
1664
|
+
disabledRotateRight: toolbar.isDisabled("rotateRight"),
|
|
1619
1665
|
disabledMetadata: toolbar.isDisabled("metadata"),
|
|
1620
1666
|
disabledProperties: toolbar.isDisabled("properties"),
|
|
1621
1667
|
disabledDownload: toolbar.isDisabled("download"),
|
|
@@ -1632,6 +1678,8 @@ var PDFViewerContent = forwardRef((props, ref) => {
|
|
|
1632
1678
|
onFitToPage: toolbarHandlers.handleFitToPage,
|
|
1633
1679
|
onToggleSidebar: toolbarHandlers.toggleSidebar,
|
|
1634
1680
|
onToggleFullScreen: toolbarHandlers.handleToggleFullScreen,
|
|
1681
|
+
onRotateLeft: toolbarHandlers.handleRotateLeft,
|
|
1682
|
+
onRotateRight: toolbarHandlers.handleRotateRight,
|
|
1635
1683
|
onDownloadClick: toolbar.getHandler("download", onDownloadClick),
|
|
1636
1684
|
onPrintClick: toolbar.getHandler("print", onPrintClick),
|
|
1637
1685
|
onMetadataClick: toolbar.getHandler("metadata", onMetadataClick),
|
|
@@ -1685,4 +1733,4 @@ PDFViewer.displayName = "PDFViewer";
|
|
|
1685
1733
|
export {
|
|
1686
1734
|
PDFViewer
|
|
1687
1735
|
};
|
|
1688
|
-
//# sourceMappingURL=chunk-
|
|
1736
|
+
//# sourceMappingURL=chunk-PZJSY6OF.mjs.map
|