react-pdf-highlighter-plus 1.0.7 → 1.1.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/README.md +50 -0
- package/dist/esm/index.d.ts +558 -9
- package/dist/esm/index.js +1280 -8
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/style/PdfHighlighter.css +15 -1
- package/package.json +3 -3
package/dist/esm/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import debounce from "lodash.debounce";
|
|
3
3
|
import React6, {
|
|
4
4
|
useLayoutEffect as useLayoutEffect2,
|
|
5
|
+
useMemo,
|
|
5
6
|
useRef as useRef5,
|
|
6
7
|
useState as useState5
|
|
7
8
|
} from "react";
|
|
@@ -1120,6 +1121,21 @@ var PDFViewer;
|
|
|
1120
1121
|
var SCROLL_MARGIN = 10;
|
|
1121
1122
|
var DEFAULT_SCALE_VALUE = "auto";
|
|
1122
1123
|
var DEFAULT_TEXT_SELECTION_COLOR = "rgba(153,193,218,255)";
|
|
1124
|
+
var defaultLightTheme = {
|
|
1125
|
+
mode: "light",
|
|
1126
|
+
containerBackgroundColor: "#e5e5e5",
|
|
1127
|
+
scrollbarThumbColor: "#9f9f9f",
|
|
1128
|
+
scrollbarTrackColor: "#d1d1d1",
|
|
1129
|
+
darkModeInvertIntensity: 0.9
|
|
1130
|
+
};
|
|
1131
|
+
var defaultDarkTheme = {
|
|
1132
|
+
mode: "dark",
|
|
1133
|
+
containerBackgroundColor: "#3a3a3a",
|
|
1134
|
+
// Lighter than PDF page (~#1a1a1a) for contrast
|
|
1135
|
+
scrollbarThumbColor: "#6b6b6b",
|
|
1136
|
+
scrollbarTrackColor: "#2c2c2c",
|
|
1137
|
+
darkModeInvertIntensity: 0.9
|
|
1138
|
+
};
|
|
1123
1139
|
var findOrCreateHighlightLayer = (textLayer) => {
|
|
1124
1140
|
return findOrCreateContainerLayer(
|
|
1125
1141
|
textLayer,
|
|
@@ -1158,8 +1174,14 @@ var PdfHighlighter = ({
|
|
|
1158
1174
|
onShapeComplete,
|
|
1159
1175
|
onShapeCancel,
|
|
1160
1176
|
shapeStrokeColor = "#000000",
|
|
1161
|
-
shapeStrokeWidth = 2
|
|
1177
|
+
shapeStrokeWidth = 2,
|
|
1178
|
+
theme: userTheme
|
|
1162
1179
|
}) => {
|
|
1180
|
+
const resolvedTheme = useMemo(() => {
|
|
1181
|
+
const mode = userTheme?.mode ?? "light";
|
|
1182
|
+
const defaults = mode === "light" ? defaultLightTheme : defaultDarkTheme;
|
|
1183
|
+
return { ...defaults, ...userTheme, mode };
|
|
1184
|
+
}, [userTheme]);
|
|
1163
1185
|
const [tip, setTip] = useState5(null);
|
|
1164
1186
|
const [isViewerReady, setIsViewerReady] = useState5(false);
|
|
1165
1187
|
const containerNodeRef = useRef5(null);
|
|
@@ -1457,17 +1479,27 @@ var PdfHighlighter = ({
|
|
|
1457
1479
|
getViewer: () => viewerRef.current,
|
|
1458
1480
|
getTip: () => tip,
|
|
1459
1481
|
setTip,
|
|
1460
|
-
updateTipPosition: updateTipPositionRef.current
|
|
1482
|
+
updateTipPosition: updateTipPositionRef.current,
|
|
1483
|
+
getLinkService: () => linkServiceRef.current,
|
|
1484
|
+
getEventBus: () => eventBusRef.current,
|
|
1485
|
+
goToPage: (pageNumber) => {
|
|
1486
|
+
viewerRef.current?.scrollPageIntoView({ pageNumber });
|
|
1487
|
+
}
|
|
1461
1488
|
};
|
|
1462
1489
|
utilsRef(pdfHighlighterUtils);
|
|
1463
1490
|
const isFreetextMode = enableFreetextCreation?.({}) ?? false;
|
|
1464
1491
|
const isImageMode = enableImageCreation?.({}) ?? false;
|
|
1465
1492
|
let containerClassName = "PdfHighlighter";
|
|
1493
|
+
if (resolvedTheme.mode === "dark") containerClassName += " PdfHighlighter--dark";
|
|
1466
1494
|
if (isFreetextMode) containerClassName += " PdfHighlighter--freetext-mode";
|
|
1467
1495
|
if (isImageMode) containerClassName += " PdfHighlighter--image-mode";
|
|
1468
1496
|
if (enableDrawingMode) containerClassName += " PdfHighlighter--drawing-mode";
|
|
1469
1497
|
if (enableShapeMode) containerClassName += " PdfHighlighter--shape-mode";
|
|
1470
1498
|
if (areaSelectionMode) containerClassName += " PdfHighlighter--area-mode";
|
|
1499
|
+
const containerStyle = {
|
|
1500
|
+
...style,
|
|
1501
|
+
backgroundColor: resolvedTheme.containerBackgroundColor
|
|
1502
|
+
};
|
|
1471
1503
|
return /* @__PURE__ */ React6.createElement(PdfHighlighterContext.Provider, { value: pdfHighlighterUtils }, /* @__PURE__ */ React6.createElement(
|
|
1472
1504
|
"div",
|
|
1473
1505
|
{
|
|
@@ -1475,13 +1507,28 @@ var PdfHighlighter = ({
|
|
|
1475
1507
|
className: containerClassName,
|
|
1476
1508
|
onPointerDown: handleMouseDown,
|
|
1477
1509
|
onPointerUp: handleMouseUp,
|
|
1478
|
-
style
|
|
1510
|
+
style: containerStyle
|
|
1479
1511
|
},
|
|
1480
1512
|
/* @__PURE__ */ React6.createElement("div", { className: "pdfViewer" }),
|
|
1481
1513
|
/* @__PURE__ */ React6.createElement("style", null, `
|
|
1482
1514
|
.textLayer ::selection {
|
|
1483
1515
|
background: ${textSelectionColor};
|
|
1484
1516
|
}
|
|
1517
|
+
.PdfHighlighter::-webkit-scrollbar-thumb {
|
|
1518
|
+
background-color: ${resolvedTheme.scrollbarThumbColor};
|
|
1519
|
+
}
|
|
1520
|
+
.PdfHighlighter::-webkit-scrollbar-track,
|
|
1521
|
+
.PdfHighlighter::-webkit-scrollbar-track-piece {
|
|
1522
|
+
background-color: ${resolvedTheme.scrollbarTrackColor};
|
|
1523
|
+
}
|
|
1524
|
+
${resolvedTheme.mode === "dark" ? `
|
|
1525
|
+
.PdfHighlighter--dark .page {
|
|
1526
|
+
filter: invert(${resolvedTheme.darkModeInvertIntensity}) hue-rotate(180deg) brightness(1.05);
|
|
1527
|
+
}
|
|
1528
|
+
.PdfHighlighter--dark .PdfHighlighter__highlight-layer {
|
|
1529
|
+
filter: invert(${resolvedTheme.darkModeInvertIntensity}) hue-rotate(180deg) brightness(0.95);
|
|
1530
|
+
}
|
|
1531
|
+
` : ""}
|
|
1485
1532
|
`),
|
|
1486
1533
|
isViewerReady && /* @__PURE__ */ React6.createElement(
|
|
1487
1534
|
TipContainer,
|
|
@@ -2445,8 +2492,7 @@ var SignaturePad = ({
|
|
|
2445
2492
|
ctx.lineWidth = 2;
|
|
2446
2493
|
ctx.lineCap = "round";
|
|
2447
2494
|
ctx.lineJoin = "round";
|
|
2448
|
-
ctx.
|
|
2449
|
-
ctx.fillRect(0, 0, width, height);
|
|
2495
|
+
ctx.clearRect(0, 0, width, height);
|
|
2450
2496
|
}, [isOpen, width, height]);
|
|
2451
2497
|
const getPosition = useCallback3(
|
|
2452
2498
|
(e) => {
|
|
@@ -2528,8 +2574,7 @@ var SignaturePad = ({
|
|
|
2528
2574
|
const canvas = canvasRef.current;
|
|
2529
2575
|
const ctx = canvas?.getContext("2d");
|
|
2530
2576
|
if (!ctx || !canvas) return;
|
|
2531
|
-
ctx.
|
|
2532
|
-
ctx.fillRect(0, 0, width, height);
|
|
2577
|
+
ctx.clearRect(0, 0, width, height);
|
|
2533
2578
|
};
|
|
2534
2579
|
const handleDone = () => {
|
|
2535
2580
|
const canvas = canvasRef.current;
|
|
@@ -3096,7 +3141,7 @@ var DEFAULT_ERROR_MESSAGE = (error) => /* @__PURE__ */ React16.createElement("di
|
|
|
3096
3141
|
var DEFAULT_ON_ERROR = (error) => {
|
|
3097
3142
|
throw new Error(`Error loading PDF document: ${error.message}!`);
|
|
3098
3143
|
};
|
|
3099
|
-
var DEFAULT_WORKER_SRC = "https://unpkg.com/pdfjs-dist@4/build/pdf.worker.min.mjs";
|
|
3144
|
+
var DEFAULT_WORKER_SRC = "https://unpkg.com/pdfjs-dist@4.4.168/build/pdf.worker.min.mjs";
|
|
3100
3145
|
var PdfLoader = ({
|
|
3101
3146
|
document: document2,
|
|
3102
3147
|
beforeLoad = DEFAULT_BEFORE_LOAD,
|
|
@@ -3536,23 +3581,1250 @@ async function exportPdf(pdfSource, highlights, options = {}) {
|
|
|
3536
3581
|
}
|
|
3537
3582
|
return pdfDoc.save();
|
|
3538
3583
|
}
|
|
3584
|
+
|
|
3585
|
+
// src/components/leftpanel/LeftPanel.tsx
|
|
3586
|
+
import React21, { useState as useState17, useMemo as useMemo4, useCallback as useCallback8 } from "react";
|
|
3587
|
+
import { List, FileText, ChevronLeft, ChevronRight as ChevronRight2 } from "lucide-react";
|
|
3588
|
+
|
|
3589
|
+
// src/contexts/LeftPanelContext.ts
|
|
3590
|
+
import { createContext as createContext3, useContext as useContext3 } from "react";
|
|
3591
|
+
var LeftPanelContext = createContext3(
|
|
3592
|
+
void 0
|
|
3593
|
+
);
|
|
3594
|
+
var useLeftPanelContext = () => {
|
|
3595
|
+
const context = useContext3(LeftPanelContext);
|
|
3596
|
+
if (context === void 0) {
|
|
3597
|
+
throw new Error("useLeftPanelContext must be used within LeftPanel");
|
|
3598
|
+
}
|
|
3599
|
+
return context;
|
|
3600
|
+
};
|
|
3601
|
+
|
|
3602
|
+
// src/hooks/useDocumentOutline.ts
|
|
3603
|
+
import { useState as useState12, useEffect as useEffect12, useCallback as useCallback5, useMemo as useMemo2 } from "react";
|
|
3604
|
+
async function processOutlineItems(pdfDocument, items, level) {
|
|
3605
|
+
const processed = [];
|
|
3606
|
+
for (let i = 0; i < items.length; i++) {
|
|
3607
|
+
const item = items[i];
|
|
3608
|
+
let pageNumber = 1;
|
|
3609
|
+
if (item.dest) {
|
|
3610
|
+
try {
|
|
3611
|
+
const dest = typeof item.dest === "string" ? await pdfDocument.getDestination(item.dest) : item.dest;
|
|
3612
|
+
if (dest && Array.isArray(dest) && dest[0]) {
|
|
3613
|
+
const pageIndex = await pdfDocument.getPageIndex(dest[0]);
|
|
3614
|
+
pageNumber = pageIndex + 1;
|
|
3615
|
+
}
|
|
3616
|
+
} catch {
|
|
3617
|
+
console.log(`Failed to resolve destination for outline item: ${item.title}`);
|
|
3618
|
+
}
|
|
3619
|
+
}
|
|
3620
|
+
const children = item.items?.length ? await processOutlineItems(pdfDocument, item.items, level + 1) : [];
|
|
3621
|
+
processed.push({
|
|
3622
|
+
id: `outline-${level}-${i}`,
|
|
3623
|
+
title: item.title,
|
|
3624
|
+
pageNumber,
|
|
3625
|
+
dest: item.dest,
|
|
3626
|
+
level,
|
|
3627
|
+
bold: item.bold,
|
|
3628
|
+
italic: item.italic,
|
|
3629
|
+
children
|
|
3630
|
+
});
|
|
3631
|
+
}
|
|
3632
|
+
return processed;
|
|
3633
|
+
}
|
|
3634
|
+
function flattenOutline(items) {
|
|
3635
|
+
const result = [];
|
|
3636
|
+
for (const item of items) {
|
|
3637
|
+
result.push(item);
|
|
3638
|
+
if (item.children.length) {
|
|
3639
|
+
result.push(...flattenOutline(item.children));
|
|
3640
|
+
}
|
|
3641
|
+
}
|
|
3642
|
+
return result;
|
|
3643
|
+
}
|
|
3644
|
+
function useDocumentOutline(options) {
|
|
3645
|
+
const { pdfDocument, linkService } = options;
|
|
3646
|
+
const [outline, setOutline] = useState12(null);
|
|
3647
|
+
const [isLoading, setIsLoading] = useState12(true);
|
|
3648
|
+
const [error, setError] = useState12(null);
|
|
3649
|
+
useEffect12(() => {
|
|
3650
|
+
let cancelled = false;
|
|
3651
|
+
async function fetchOutline() {
|
|
3652
|
+
try {
|
|
3653
|
+
setIsLoading(true);
|
|
3654
|
+
setError(null);
|
|
3655
|
+
const rawOutline = await pdfDocument.getOutline();
|
|
3656
|
+
console.log("Raw outline from PDF:", rawOutline);
|
|
3657
|
+
if (cancelled) return;
|
|
3658
|
+
if (!rawOutline || rawOutline.length === 0) {
|
|
3659
|
+
setOutline([]);
|
|
3660
|
+
return;
|
|
3661
|
+
}
|
|
3662
|
+
const processedOutline = await processOutlineItems(
|
|
3663
|
+
pdfDocument,
|
|
3664
|
+
rawOutline,
|
|
3665
|
+
0
|
|
3666
|
+
);
|
|
3667
|
+
if (cancelled) return;
|
|
3668
|
+
console.log("Processed outline:", processedOutline);
|
|
3669
|
+
setOutline(processedOutline);
|
|
3670
|
+
} catch (err) {
|
|
3671
|
+
if (cancelled) return;
|
|
3672
|
+
console.error("Failed to load outline:", err);
|
|
3673
|
+
setError(err instanceof Error ? err : new Error("Failed to load outline"));
|
|
3674
|
+
} finally {
|
|
3675
|
+
if (!cancelled) {
|
|
3676
|
+
setIsLoading(false);
|
|
3677
|
+
}
|
|
3678
|
+
}
|
|
3679
|
+
}
|
|
3680
|
+
fetchOutline();
|
|
3681
|
+
return () => {
|
|
3682
|
+
cancelled = true;
|
|
3683
|
+
};
|
|
3684
|
+
}, [pdfDocument]);
|
|
3685
|
+
const navigateToItem = useCallback5(
|
|
3686
|
+
(item) => {
|
|
3687
|
+
console.log("Navigating to outline item:", item);
|
|
3688
|
+
if (linkService && item.dest && typeof linkService === "object" && "goToDestination" in linkService) {
|
|
3689
|
+
linkService.goToDestination(item.dest);
|
|
3690
|
+
}
|
|
3691
|
+
},
|
|
3692
|
+
[linkService]
|
|
3693
|
+
);
|
|
3694
|
+
const flatOutline = useMemo2(() => {
|
|
3695
|
+
if (!outline) return [];
|
|
3696
|
+
return flattenOutline(outline);
|
|
3697
|
+
}, [outline]);
|
|
3698
|
+
const hasOutline = useMemo2(() => {
|
|
3699
|
+
return outline !== null && outline.length > 0;
|
|
3700
|
+
}, [outline]);
|
|
3701
|
+
return { outline, isLoading, error, navigateToItem, flatOutline, hasOutline };
|
|
3702
|
+
}
|
|
3703
|
+
|
|
3704
|
+
// src/hooks/useThumbnails.ts
|
|
3705
|
+
import { useState as useState13, useCallback as useCallback6, useRef as useRef15, useEffect as useEffect13 } from "react";
|
|
3706
|
+
function useThumbnails(options) {
|
|
3707
|
+
const { pdfDocument, thumbnailWidth = 200, cacheSize = 50, preloadAll = true } = options;
|
|
3708
|
+
const [thumbnails, setThumbnails] = useState13(
|
|
3709
|
+
/* @__PURE__ */ new Map()
|
|
3710
|
+
);
|
|
3711
|
+
const loadingRef = useRef15(/* @__PURE__ */ new Set());
|
|
3712
|
+
const loadedRef = useRef15(/* @__PURE__ */ new Set());
|
|
3713
|
+
const cacheOrderRef = useRef15([]);
|
|
3714
|
+
const totalPages = pdfDocument.numPages;
|
|
3715
|
+
const loadThumbnail = useCallback6(
|
|
3716
|
+
async (pageNumber) => {
|
|
3717
|
+
if (loadingRef.current.has(pageNumber) || loadedRef.current.has(pageNumber)) {
|
|
3718
|
+
return;
|
|
3719
|
+
}
|
|
3720
|
+
loadingRef.current.add(pageNumber);
|
|
3721
|
+
setThumbnails((prev) => {
|
|
3722
|
+
const next = new Map(prev);
|
|
3723
|
+
next.set(pageNumber, {
|
|
3724
|
+
pageNumber,
|
|
3725
|
+
dataUrl: null,
|
|
3726
|
+
isLoading: true
|
|
3727
|
+
});
|
|
3728
|
+
return next;
|
|
3729
|
+
});
|
|
3730
|
+
try {
|
|
3731
|
+
const page = await pdfDocument.getPage(pageNumber);
|
|
3732
|
+
const viewport = page.getViewport({ scale: 1 });
|
|
3733
|
+
const scale = thumbnailWidth / viewport.width;
|
|
3734
|
+
const scaledViewport = page.getViewport({ scale });
|
|
3735
|
+
const canvas = document.createElement("canvas");
|
|
3736
|
+
canvas.width = scaledViewport.width;
|
|
3737
|
+
canvas.height = scaledViewport.height;
|
|
3738
|
+
const context = canvas.getContext("2d");
|
|
3739
|
+
await page.render({
|
|
3740
|
+
canvasContext: context,
|
|
3741
|
+
viewport: scaledViewport
|
|
3742
|
+
}).promise;
|
|
3743
|
+
const dataUrl = canvas.toDataURL("image/png");
|
|
3744
|
+
cacheOrderRef.current = cacheOrderRef.current.filter(
|
|
3745
|
+
(p) => p !== pageNumber
|
|
3746
|
+
);
|
|
3747
|
+
cacheOrderRef.current.push(pageNumber);
|
|
3748
|
+
if (cacheOrderRef.current.length > cacheSize) {
|
|
3749
|
+
const toEvict = cacheOrderRef.current.shift();
|
|
3750
|
+
setThumbnails((prev) => {
|
|
3751
|
+
const next = new Map(prev);
|
|
3752
|
+
next.delete(toEvict);
|
|
3753
|
+
return next;
|
|
3754
|
+
});
|
|
3755
|
+
}
|
|
3756
|
+
loadedRef.current.add(pageNumber);
|
|
3757
|
+
setThumbnails((prev) => {
|
|
3758
|
+
const next = new Map(prev);
|
|
3759
|
+
next.set(pageNumber, {
|
|
3760
|
+
pageNumber,
|
|
3761
|
+
dataUrl,
|
|
3762
|
+
isLoading: false
|
|
3763
|
+
});
|
|
3764
|
+
return next;
|
|
3765
|
+
});
|
|
3766
|
+
} catch (error) {
|
|
3767
|
+
console.error(`Failed to load thumbnail for page ${pageNumber}:`, error);
|
|
3768
|
+
setThumbnails((prev) => {
|
|
3769
|
+
const next = new Map(prev);
|
|
3770
|
+
next.set(pageNumber, {
|
|
3771
|
+
pageNumber,
|
|
3772
|
+
dataUrl: null,
|
|
3773
|
+
isLoading: false,
|
|
3774
|
+
error: error instanceof Error ? error.message : "Failed to load"
|
|
3775
|
+
});
|
|
3776
|
+
return next;
|
|
3777
|
+
});
|
|
3778
|
+
} finally {
|
|
3779
|
+
loadingRef.current.delete(pageNumber);
|
|
3780
|
+
}
|
|
3781
|
+
},
|
|
3782
|
+
[pdfDocument, thumbnailWidth, cacheSize]
|
|
3783
|
+
);
|
|
3784
|
+
const getThumbnail = useCallback6(
|
|
3785
|
+
(pageNumber) => {
|
|
3786
|
+
return thumbnails.get(pageNumber) || {
|
|
3787
|
+
pageNumber,
|
|
3788
|
+
dataUrl: null,
|
|
3789
|
+
isLoading: false
|
|
3790
|
+
};
|
|
3791
|
+
},
|
|
3792
|
+
[thumbnails]
|
|
3793
|
+
);
|
|
3794
|
+
const preloadThumbnails = useCallback6(
|
|
3795
|
+
(pageNumbers) => {
|
|
3796
|
+
pageNumbers.forEach((pageNumber) => {
|
|
3797
|
+
loadThumbnail(pageNumber);
|
|
3798
|
+
});
|
|
3799
|
+
},
|
|
3800
|
+
[loadThumbnail]
|
|
3801
|
+
);
|
|
3802
|
+
const clearCache = useCallback6(() => {
|
|
3803
|
+
setThumbnails(/* @__PURE__ */ new Map());
|
|
3804
|
+
cacheOrderRef.current = [];
|
|
3805
|
+
loadingRef.current.clear();
|
|
3806
|
+
loadedRef.current.clear();
|
|
3807
|
+
}, []);
|
|
3808
|
+
useEffect13(() => {
|
|
3809
|
+
if (preloadAll && totalPages > 0) {
|
|
3810
|
+
const pageNumbers = Array.from({ length: totalPages }, (_, i) => i + 1);
|
|
3811
|
+
pageNumbers.forEach((pageNumber) => {
|
|
3812
|
+
loadThumbnail(pageNumber);
|
|
3813
|
+
});
|
|
3814
|
+
}
|
|
3815
|
+
}, [preloadAll, totalPages, loadThumbnail]);
|
|
3816
|
+
useEffect13(() => {
|
|
3817
|
+
return () => {
|
|
3818
|
+
loadingRef.current.clear();
|
|
3819
|
+
};
|
|
3820
|
+
}, []);
|
|
3821
|
+
return {
|
|
3822
|
+
getThumbnail,
|
|
3823
|
+
loadThumbnail,
|
|
3824
|
+
preloadThumbnails,
|
|
3825
|
+
clearCache,
|
|
3826
|
+
totalPages,
|
|
3827
|
+
thumbnails
|
|
3828
|
+
};
|
|
3829
|
+
}
|
|
3830
|
+
|
|
3831
|
+
// src/hooks/usePageNavigation.ts
|
|
3832
|
+
import { useState as useState14, useEffect as useEffect14, useCallback as useCallback7 } from "react";
|
|
3833
|
+
function usePageNavigation(options) {
|
|
3834
|
+
const { viewer, eventBus } = options;
|
|
3835
|
+
const [currentPage, setCurrentPage] = useState14(1);
|
|
3836
|
+
const isEventBus = (obj) => {
|
|
3837
|
+
return obj !== null && typeof obj === "object" && "on" in obj && "off" in obj;
|
|
3838
|
+
};
|
|
3839
|
+
const isViewer = (obj) => {
|
|
3840
|
+
return obj !== null && typeof obj === "object" && "scrollPageIntoView" in obj;
|
|
3841
|
+
};
|
|
3842
|
+
useEffect14(() => {
|
|
3843
|
+
if (!eventBus || !isEventBus(eventBus)) return;
|
|
3844
|
+
const handlePageChange = (evt) => {
|
|
3845
|
+
setCurrentPage(evt.pageNumber);
|
|
3846
|
+
};
|
|
3847
|
+
eventBus.on("pagechanging", handlePageChange);
|
|
3848
|
+
return () => {
|
|
3849
|
+
eventBus.off("pagechanging", handlePageChange);
|
|
3850
|
+
};
|
|
3851
|
+
}, [eventBus]);
|
|
3852
|
+
useEffect14(() => {
|
|
3853
|
+
if (viewer && isViewer(viewer) && viewer.currentPageNumber) {
|
|
3854
|
+
setCurrentPage(viewer.currentPageNumber);
|
|
3855
|
+
}
|
|
3856
|
+
}, [viewer]);
|
|
3857
|
+
const goToPage = useCallback7(
|
|
3858
|
+
(pageNumber) => {
|
|
3859
|
+
if (viewer && isViewer(viewer)) {
|
|
3860
|
+
const totalPages2 = viewer.pagesCount || 0;
|
|
3861
|
+
if (pageNumber >= 1 && pageNumber <= totalPages2) {
|
|
3862
|
+
viewer.scrollPageIntoView({ pageNumber });
|
|
3863
|
+
return;
|
|
3864
|
+
}
|
|
3865
|
+
}
|
|
3866
|
+
const pageElement = document.querySelector(
|
|
3867
|
+
`.page[data-page-number="${pageNumber}"]`
|
|
3868
|
+
);
|
|
3869
|
+
if (pageElement) {
|
|
3870
|
+
pageElement.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
3871
|
+
setCurrentPage(pageNumber);
|
|
3872
|
+
}
|
|
3873
|
+
},
|
|
3874
|
+
[viewer]
|
|
3875
|
+
);
|
|
3876
|
+
const totalPages = viewer && isViewer(viewer) ? viewer.pagesCount || 0 : 0;
|
|
3877
|
+
return {
|
|
3878
|
+
currentPage,
|
|
3879
|
+
totalPages,
|
|
3880
|
+
goToPage
|
|
3881
|
+
};
|
|
3882
|
+
}
|
|
3883
|
+
|
|
3884
|
+
// src/components/leftpanel/DocumentOutline.tsx
|
|
3885
|
+
import React18 from "react";
|
|
3886
|
+
import { Loader2, FileQuestion } from "lucide-react";
|
|
3887
|
+
|
|
3888
|
+
// src/components/leftpanel/OutlineItem.tsx
|
|
3889
|
+
import React17, { useState as useState15 } from "react";
|
|
3890
|
+
import { ChevronRight, ChevronDown } from "lucide-react";
|
|
3891
|
+
var OutlineItem = ({
|
|
3892
|
+
item,
|
|
3893
|
+
currentPage,
|
|
3894
|
+
onNavigate,
|
|
3895
|
+
defaultExpanded = true,
|
|
3896
|
+
showExpandIcons = true,
|
|
3897
|
+
maxDepth = 10,
|
|
3898
|
+
styles,
|
|
3899
|
+
classNames,
|
|
3900
|
+
renderItem
|
|
3901
|
+
}) => {
|
|
3902
|
+
const [isExpanded, setIsExpanded] = useState15(defaultExpanded);
|
|
3903
|
+
const [isHovered, setIsHovered] = useState15(false);
|
|
3904
|
+
const hasChildren = item.children && item.children.length > 0;
|
|
3905
|
+
const isActive = currentPage === item.pageNumber;
|
|
3906
|
+
const canShowChildren = item.level < maxDepth;
|
|
3907
|
+
const handleToggle = () => {
|
|
3908
|
+
if (hasChildren) {
|
|
3909
|
+
setIsExpanded(!isExpanded);
|
|
3910
|
+
}
|
|
3911
|
+
};
|
|
3912
|
+
const handleNavigate = () => {
|
|
3913
|
+
onNavigate(item);
|
|
3914
|
+
};
|
|
3915
|
+
const renderProps = {
|
|
3916
|
+
isExpanded,
|
|
3917
|
+
isActive,
|
|
3918
|
+
level: item.level,
|
|
3919
|
+
hasChildren,
|
|
3920
|
+
onToggle: handleToggle,
|
|
3921
|
+
onNavigate: handleNavigate
|
|
3922
|
+
};
|
|
3923
|
+
if (renderItem) {
|
|
3924
|
+
return /* @__PURE__ */ React17.createElement(React17.Fragment, null, renderItem(item, renderProps));
|
|
3925
|
+
}
|
|
3926
|
+
const indent = 12 + item.level * 16;
|
|
3927
|
+
const defaultContainerStyle = {
|
|
3928
|
+
display: "flex",
|
|
3929
|
+
alignItems: "center",
|
|
3930
|
+
gap: "6px",
|
|
3931
|
+
padding: "6px 12px",
|
|
3932
|
+
paddingLeft: `${indent}px`,
|
|
3933
|
+
cursor: "pointer",
|
|
3934
|
+
position: "relative",
|
|
3935
|
+
transition: "background-color 0.15s ease",
|
|
3936
|
+
backgroundColor: "transparent",
|
|
3937
|
+
borderRadius: "4px",
|
|
3938
|
+
margin: "1px 4px"
|
|
3939
|
+
};
|
|
3940
|
+
const defaultExpandButtonStyle = {
|
|
3941
|
+
padding: "2px",
|
|
3942
|
+
border: "none",
|
|
3943
|
+
background: "transparent",
|
|
3944
|
+
cursor: "pointer",
|
|
3945
|
+
display: "flex",
|
|
3946
|
+
alignItems: "center",
|
|
3947
|
+
justifyContent: "center",
|
|
3948
|
+
borderRadius: "3px",
|
|
3949
|
+
flexShrink: 0,
|
|
3950
|
+
transition: "background-color 0.15s ease"
|
|
3951
|
+
};
|
|
3952
|
+
const defaultExpandIconStyle = {
|
|
3953
|
+
width: 12,
|
|
3954
|
+
height: 12,
|
|
3955
|
+
color: "#64748b"
|
|
3956
|
+
};
|
|
3957
|
+
const defaultActiveIndicatorStyle = {
|
|
3958
|
+
width: 6,
|
|
3959
|
+
height: 6,
|
|
3960
|
+
borderRadius: "50%",
|
|
3961
|
+
backgroundColor: "#3b82f6",
|
|
3962
|
+
flexShrink: 0
|
|
3963
|
+
};
|
|
3964
|
+
const defaultTitleStyle = {
|
|
3965
|
+
flex: 1,
|
|
3966
|
+
overflow: "hidden",
|
|
3967
|
+
textOverflow: "ellipsis",
|
|
3968
|
+
whiteSpace: "nowrap",
|
|
3969
|
+
fontSize: "13px",
|
|
3970
|
+
fontWeight: 400,
|
|
3971
|
+
fontStyle: item.italic ? "italic" : "normal",
|
|
3972
|
+
color: "#475569",
|
|
3973
|
+
lineHeight: 1.4
|
|
3974
|
+
};
|
|
3975
|
+
const defaultTitleActiveStyle = {
|
|
3976
|
+
fontWeight: 500,
|
|
3977
|
+
color: "#1e40af"
|
|
3978
|
+
};
|
|
3979
|
+
const defaultPageNumberStyle = {
|
|
3980
|
+
fontSize: "11px",
|
|
3981
|
+
color: "#94a3b8",
|
|
3982
|
+
flexShrink: 0,
|
|
3983
|
+
fontVariantNumeric: "tabular-nums",
|
|
3984
|
+
minWidth: "20px",
|
|
3985
|
+
textAlign: "right"
|
|
3986
|
+
};
|
|
3987
|
+
const defaultPageNumberActiveStyle = {
|
|
3988
|
+
color: "#3b82f6"
|
|
3989
|
+
};
|
|
3990
|
+
const defaultChildrenContainerStyle = {
|
|
3991
|
+
position: "relative"
|
|
3992
|
+
};
|
|
3993
|
+
const containerStyle = {
|
|
3994
|
+
...defaultContainerStyle,
|
|
3995
|
+
...styles?.container,
|
|
3996
|
+
...isHovered && !isActive ? { backgroundColor: "#f8fafc", ...styles?.containerHover } : {},
|
|
3997
|
+
...isActive ? styles?.containerActive : {}
|
|
3998
|
+
};
|
|
3999
|
+
const expandButtonStyle = {
|
|
4000
|
+
...defaultExpandButtonStyle,
|
|
4001
|
+
...styles?.expandButton
|
|
4002
|
+
};
|
|
4003
|
+
const expandIconStyle = {
|
|
4004
|
+
...defaultExpandIconStyle,
|
|
4005
|
+
...styles?.expandIcon
|
|
4006
|
+
};
|
|
4007
|
+
const activeIndicatorStyle = {
|
|
4008
|
+
...defaultActiveIndicatorStyle,
|
|
4009
|
+
...styles?.activeIndicator
|
|
4010
|
+
};
|
|
4011
|
+
const titleStyle = {
|
|
4012
|
+
...defaultTitleStyle,
|
|
4013
|
+
...styles?.title,
|
|
4014
|
+
...isActive ? { ...defaultTitleActiveStyle, ...styles?.titleActive } : {}
|
|
4015
|
+
};
|
|
4016
|
+
const pageNumberStyle = {
|
|
4017
|
+
...defaultPageNumberStyle,
|
|
4018
|
+
...styles?.pageNumber,
|
|
4019
|
+
...isActive ? { ...defaultPageNumberActiveStyle, ...styles?.pageNumberActive } : {}
|
|
4020
|
+
};
|
|
4021
|
+
const childrenContainerStyle = {
|
|
4022
|
+
...defaultChildrenContainerStyle,
|
|
4023
|
+
...styles?.childrenContainer
|
|
4024
|
+
};
|
|
4025
|
+
const containerClassName = [
|
|
4026
|
+
classNames?.container,
|
|
4027
|
+
isHovered && !isActive ? classNames?.containerHover : "",
|
|
4028
|
+
isActive ? classNames?.containerActive : ""
|
|
4029
|
+
].filter(Boolean).join(" ");
|
|
4030
|
+
const titleClassName = [
|
|
4031
|
+
classNames?.title,
|
|
4032
|
+
isActive ? classNames?.titleActive : ""
|
|
4033
|
+
].filter(Boolean).join(" ");
|
|
4034
|
+
const pageNumberClassName = [
|
|
4035
|
+
classNames?.pageNumber,
|
|
4036
|
+
isActive ? classNames?.pageNumberActive : ""
|
|
4037
|
+
].filter(Boolean).join(" ");
|
|
4038
|
+
return /* @__PURE__ */ React17.createElement("div", { className: "outline-item" }, /* @__PURE__ */ React17.createElement(
|
|
4039
|
+
"div",
|
|
4040
|
+
{
|
|
4041
|
+
className: containerClassName || void 0,
|
|
4042
|
+
style: containerStyle,
|
|
4043
|
+
onClick: handleNavigate,
|
|
4044
|
+
onMouseEnter: () => setIsHovered(true),
|
|
4045
|
+
onMouseLeave: () => setIsHovered(false),
|
|
4046
|
+
role: "button",
|
|
4047
|
+
tabIndex: 0,
|
|
4048
|
+
onKeyDown: (e) => {
|
|
4049
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
4050
|
+
e.preventDefault();
|
|
4051
|
+
handleNavigate();
|
|
4052
|
+
}
|
|
4053
|
+
}
|
|
4054
|
+
},
|
|
4055
|
+
showExpandIcons && hasChildren && canShowChildren ? /* @__PURE__ */ React17.createElement(
|
|
4056
|
+
"button",
|
|
4057
|
+
{
|
|
4058
|
+
className: classNames?.expandButton,
|
|
4059
|
+
onClick: (e) => {
|
|
4060
|
+
e.stopPropagation();
|
|
4061
|
+
handleToggle();
|
|
4062
|
+
},
|
|
4063
|
+
style: expandButtonStyle,
|
|
4064
|
+
onMouseEnter: (e) => {
|
|
4065
|
+
e.currentTarget.style.backgroundColor = "#e5e7eb";
|
|
4066
|
+
},
|
|
4067
|
+
onMouseLeave: (e) => {
|
|
4068
|
+
e.currentTarget.style.backgroundColor = "transparent";
|
|
4069
|
+
},
|
|
4070
|
+
"aria-label": isExpanded ? "Collapse" : "Expand"
|
|
4071
|
+
},
|
|
4072
|
+
isExpanded ? /* @__PURE__ */ React17.createElement(ChevronDown, { className: classNames?.expandIcon, style: expandIconStyle }) : /* @__PURE__ */ React17.createElement(ChevronRight, { className: classNames?.expandIcon, style: expandIconStyle })
|
|
4073
|
+
) : /* @__PURE__ */ React17.createElement("div", { style: { width: 16, flexShrink: 0 } }),
|
|
4074
|
+
isActive && /* @__PURE__ */ React17.createElement("div", { className: classNames?.activeIndicator, style: activeIndicatorStyle }),
|
|
4075
|
+
/* @__PURE__ */ React17.createElement("span", { className: titleClassName || void 0, style: titleStyle, title: item.title }, item.title),
|
|
4076
|
+
/* @__PURE__ */ React17.createElement("span", { className: pageNumberClassName || void 0, style: pageNumberStyle }, item.pageNumber)
|
|
4077
|
+
), hasChildren && isExpanded && canShowChildren && /* @__PURE__ */ React17.createElement("div", { className: classNames?.childrenContainer, style: childrenContainerStyle }, item.children.map((child) => /* @__PURE__ */ React17.createElement(
|
|
4078
|
+
OutlineItem,
|
|
4079
|
+
{
|
|
4080
|
+
key: child.id,
|
|
4081
|
+
item: child,
|
|
4082
|
+
currentPage,
|
|
4083
|
+
onNavigate,
|
|
4084
|
+
defaultExpanded,
|
|
4085
|
+
showExpandIcons,
|
|
4086
|
+
maxDepth,
|
|
4087
|
+
styles,
|
|
4088
|
+
classNames,
|
|
4089
|
+
renderItem
|
|
4090
|
+
}
|
|
4091
|
+
))));
|
|
4092
|
+
};
|
|
4093
|
+
|
|
4094
|
+
// src/components/leftpanel/DocumentOutline.tsx
|
|
4095
|
+
var DocumentOutline = ({
|
|
4096
|
+
outline,
|
|
4097
|
+
isLoading = false,
|
|
4098
|
+
currentPage = 1,
|
|
4099
|
+
onNavigate,
|
|
4100
|
+
showExpandIcons = true,
|
|
4101
|
+
defaultExpanded = true,
|
|
4102
|
+
maxDepth = 10,
|
|
4103
|
+
className = "",
|
|
4104
|
+
styles,
|
|
4105
|
+
classNames,
|
|
4106
|
+
itemStyles,
|
|
4107
|
+
itemClassNames,
|
|
4108
|
+
renderItem,
|
|
4109
|
+
emptyContent,
|
|
4110
|
+
loadingContent
|
|
4111
|
+
}) => {
|
|
4112
|
+
const defaultLoadingContainerStyle = {
|
|
4113
|
+
display: "flex",
|
|
4114
|
+
flexDirection: "column",
|
|
4115
|
+
alignItems: "center",
|
|
4116
|
+
justifyContent: "center",
|
|
4117
|
+
padding: "48px 16px"
|
|
4118
|
+
};
|
|
4119
|
+
const defaultLoadingSpinnerStyle = {
|
|
4120
|
+
width: 28,
|
|
4121
|
+
height: 28,
|
|
4122
|
+
color: "#94a3b8",
|
|
4123
|
+
marginBottom: 12,
|
|
4124
|
+
animation: "spin 1s linear infinite"
|
|
4125
|
+
};
|
|
4126
|
+
const defaultLoadingTextStyle = {
|
|
4127
|
+
fontSize: 13,
|
|
4128
|
+
color: "#64748b"
|
|
4129
|
+
};
|
|
4130
|
+
const defaultEmptyContainerStyle = {
|
|
4131
|
+
display: "flex",
|
|
4132
|
+
flexDirection: "column",
|
|
4133
|
+
alignItems: "center",
|
|
4134
|
+
justifyContent: "center",
|
|
4135
|
+
padding: "48px 20px"
|
|
4136
|
+
};
|
|
4137
|
+
const defaultEmptyIconContainerStyle = {
|
|
4138
|
+
width: 56,
|
|
4139
|
+
height: 56,
|
|
4140
|
+
borderRadius: "50%",
|
|
4141
|
+
backgroundColor: "#f1f5f9",
|
|
4142
|
+
display: "flex",
|
|
4143
|
+
alignItems: "center",
|
|
4144
|
+
justifyContent: "center",
|
|
4145
|
+
marginBottom: 16
|
|
4146
|
+
};
|
|
4147
|
+
const defaultEmptyIconStyle = {
|
|
4148
|
+
width: 28,
|
|
4149
|
+
height: 28,
|
|
4150
|
+
color: "#94a3b8"
|
|
4151
|
+
};
|
|
4152
|
+
const defaultEmptyTitleStyle = {
|
|
4153
|
+
fontSize: 14,
|
|
4154
|
+
fontWeight: 500,
|
|
4155
|
+
color: "#475569",
|
|
4156
|
+
marginBottom: 4
|
|
4157
|
+
};
|
|
4158
|
+
const defaultEmptyDescriptionStyle = {
|
|
4159
|
+
fontSize: 13,
|
|
4160
|
+
color: "#94a3b8",
|
|
4161
|
+
textAlign: "center"
|
|
4162
|
+
};
|
|
4163
|
+
const defaultContainerStyle = {
|
|
4164
|
+
paddingTop: "8px",
|
|
4165
|
+
paddingBottom: "8px"
|
|
4166
|
+
};
|
|
4167
|
+
if (isLoading) {
|
|
4168
|
+
return /* @__PURE__ */ React18.createElement(
|
|
4169
|
+
"div",
|
|
4170
|
+
{
|
|
4171
|
+
className: [className, classNames?.loadingContainer].filter(Boolean).join(" ") || void 0,
|
|
4172
|
+
style: { ...defaultLoadingContainerStyle, ...styles?.loadingContainer }
|
|
4173
|
+
},
|
|
4174
|
+
loadingContent || /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(Loader2, { className: classNames?.loadingSpinner, style: { ...defaultLoadingSpinnerStyle, ...styles?.loadingSpinner } }), /* @__PURE__ */ React18.createElement("p", { className: classNames?.loadingText, style: { ...defaultLoadingTextStyle, ...styles?.loadingText } }, "Loading outline..."))
|
|
4175
|
+
);
|
|
4176
|
+
}
|
|
4177
|
+
if (!outline || outline.length === 0) {
|
|
4178
|
+
return /* @__PURE__ */ React18.createElement(
|
|
4179
|
+
"div",
|
|
4180
|
+
{
|
|
4181
|
+
className: [className, classNames?.emptyContainer].filter(Boolean).join(" ") || void 0,
|
|
4182
|
+
style: { ...defaultEmptyContainerStyle, ...styles?.emptyContainer }
|
|
4183
|
+
},
|
|
4184
|
+
emptyContent || /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement("div", { className: classNames?.emptyIconContainer, style: { ...defaultEmptyIconContainerStyle, ...styles?.emptyIconContainer } }, /* @__PURE__ */ React18.createElement(FileQuestion, { className: classNames?.emptyIcon, style: { ...defaultEmptyIconStyle, ...styles?.emptyIcon } })), /* @__PURE__ */ React18.createElement("p", { className: classNames?.emptyTitle, style: { ...defaultEmptyTitleStyle, ...styles?.emptyTitle } }, "No outline available"), /* @__PURE__ */ React18.createElement("p", { className: classNames?.emptyDescription, style: { ...defaultEmptyDescriptionStyle, ...styles?.emptyDescription } }, "This document doesn't have a table of contents"))
|
|
4185
|
+
);
|
|
4186
|
+
}
|
|
4187
|
+
return /* @__PURE__ */ React18.createElement(
|
|
4188
|
+
"div",
|
|
4189
|
+
{
|
|
4190
|
+
className: ["document-outline", className, classNames?.container].filter(Boolean).join(" "),
|
|
4191
|
+
style: { ...defaultContainerStyle, ...styles?.container }
|
|
4192
|
+
},
|
|
4193
|
+
outline.map((item) => /* @__PURE__ */ React18.createElement(
|
|
4194
|
+
OutlineItem,
|
|
4195
|
+
{
|
|
4196
|
+
key: item.id,
|
|
4197
|
+
item,
|
|
4198
|
+
currentPage,
|
|
4199
|
+
onNavigate,
|
|
4200
|
+
defaultExpanded,
|
|
4201
|
+
showExpandIcons,
|
|
4202
|
+
maxDepth,
|
|
4203
|
+
styles: itemStyles,
|
|
4204
|
+
classNames: itemClassNames,
|
|
4205
|
+
renderItem
|
|
4206
|
+
}
|
|
4207
|
+
))
|
|
4208
|
+
);
|
|
4209
|
+
};
|
|
4210
|
+
|
|
4211
|
+
// src/components/leftpanel/ThumbnailPanel.tsx
|
|
4212
|
+
import React20, { useMemo as useMemo3 } from "react";
|
|
4213
|
+
|
|
4214
|
+
// src/components/leftpanel/ThumbnailItem.tsx
|
|
4215
|
+
import React19, { useEffect as useEffect15, useRef as useRef16, useState as useState16 } from "react";
|
|
4216
|
+
import { Loader2 as Loader22, AlertCircle } from "lucide-react";
|
|
4217
|
+
var ThumbnailItem = ({
|
|
4218
|
+
pageNumber,
|
|
4219
|
+
thumbnail,
|
|
4220
|
+
isActive,
|
|
4221
|
+
onLoad,
|
|
4222
|
+
onClick,
|
|
4223
|
+
showPageNumber = true,
|
|
4224
|
+
className = ""
|
|
4225
|
+
}) => {
|
|
4226
|
+
const containerRef = useRef16(null);
|
|
4227
|
+
const hasLoadedRef = useRef16(false);
|
|
4228
|
+
const [isHovered, setIsHovered] = useState16(false);
|
|
4229
|
+
useEffect15(() => {
|
|
4230
|
+
const element = containerRef.current;
|
|
4231
|
+
if (!element || hasLoadedRef.current) return;
|
|
4232
|
+
const observer = new IntersectionObserver(
|
|
4233
|
+
(entries) => {
|
|
4234
|
+
entries.forEach((entry) => {
|
|
4235
|
+
if (entry.isIntersecting && !hasLoadedRef.current) {
|
|
4236
|
+
hasLoadedRef.current = true;
|
|
4237
|
+
onLoad(pageNumber);
|
|
4238
|
+
observer.disconnect();
|
|
4239
|
+
}
|
|
4240
|
+
});
|
|
4241
|
+
},
|
|
4242
|
+
{
|
|
4243
|
+
rootMargin: "200px",
|
|
4244
|
+
threshold: 0.1
|
|
4245
|
+
}
|
|
4246
|
+
);
|
|
4247
|
+
observer.observe(element);
|
|
4248
|
+
return () => {
|
|
4249
|
+
observer.disconnect();
|
|
4250
|
+
};
|
|
4251
|
+
}, [pageNumber, onLoad]);
|
|
4252
|
+
const handleClick = () => {
|
|
4253
|
+
onClick(pageNumber);
|
|
4254
|
+
};
|
|
4255
|
+
const containerStyle = {
|
|
4256
|
+
display: "flex",
|
|
4257
|
+
flexDirection: "column",
|
|
4258
|
+
alignItems: "center",
|
|
4259
|
+
padding: "8px",
|
|
4260
|
+
cursor: "pointer",
|
|
4261
|
+
borderRadius: "8px",
|
|
4262
|
+
transition: "all 0.15s ease",
|
|
4263
|
+
backgroundColor: isActive ? "rgba(59, 130, 246, 0.08)" : isHovered ? "rgba(0, 0, 0, 0.03)" : "transparent",
|
|
4264
|
+
border: isActive ? "2px solid #3b82f6" : "2px solid transparent"
|
|
4265
|
+
};
|
|
4266
|
+
const imageContainerStyle = {
|
|
4267
|
+
position: "relative",
|
|
4268
|
+
width: "100%",
|
|
4269
|
+
backgroundColor: "#ffffff",
|
|
4270
|
+
borderRadius: "4px",
|
|
4271
|
+
overflow: "hidden",
|
|
4272
|
+
boxShadow: isActive ? "0 4px 12px rgba(59, 130, 246, 0.25)" : isHovered ? "0 4px 12px rgba(0, 0, 0, 0.12)" : "0 1px 3px rgba(0, 0, 0, 0.08)",
|
|
4273
|
+
aspectRatio: "8.5 / 11",
|
|
4274
|
+
transition: "box-shadow 0.15s ease"
|
|
4275
|
+
};
|
|
4276
|
+
const pageNumberStyle = {
|
|
4277
|
+
marginTop: "8px",
|
|
4278
|
+
fontSize: "12px",
|
|
4279
|
+
fontWeight: 500,
|
|
4280
|
+
color: isActive ? "#3b82f6" : "#6b7280",
|
|
4281
|
+
transition: "color 0.15s ease"
|
|
4282
|
+
};
|
|
4283
|
+
return /* @__PURE__ */ React19.createElement(
|
|
4284
|
+
"div",
|
|
4285
|
+
{
|
|
4286
|
+
ref: containerRef,
|
|
4287
|
+
className: `thumbnail-item ${className}`,
|
|
4288
|
+
style: containerStyle,
|
|
4289
|
+
onClick: handleClick,
|
|
4290
|
+
onMouseEnter: () => setIsHovered(true),
|
|
4291
|
+
onMouseLeave: () => setIsHovered(false),
|
|
4292
|
+
role: "button",
|
|
4293
|
+
tabIndex: 0,
|
|
4294
|
+
onKeyDown: (e) => {
|
|
4295
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
4296
|
+
e.preventDefault();
|
|
4297
|
+
handleClick();
|
|
4298
|
+
}
|
|
4299
|
+
},
|
|
4300
|
+
"aria-label": `Page ${pageNumber}${isActive ? " (current)" : ""}`,
|
|
4301
|
+
"aria-current": isActive ? "page" : void 0
|
|
4302
|
+
},
|
|
4303
|
+
/* @__PURE__ */ React19.createElement("div", { style: imageContainerStyle }, thumbnail.isLoading && /* @__PURE__ */ React19.createElement(
|
|
4304
|
+
"div",
|
|
4305
|
+
{
|
|
4306
|
+
style: {
|
|
4307
|
+
position: "absolute",
|
|
4308
|
+
inset: 0,
|
|
4309
|
+
display: "flex",
|
|
4310
|
+
alignItems: "center",
|
|
4311
|
+
justifyContent: "center",
|
|
4312
|
+
backgroundColor: "#f9fafb"
|
|
4313
|
+
}
|
|
4314
|
+
},
|
|
4315
|
+
/* @__PURE__ */ React19.createElement(
|
|
4316
|
+
Loader22,
|
|
4317
|
+
{
|
|
4318
|
+
style: {
|
|
4319
|
+
width: 24,
|
|
4320
|
+
height: 24,
|
|
4321
|
+
color: "#9ca3af",
|
|
4322
|
+
animation: "spin 1s linear infinite"
|
|
4323
|
+
}
|
|
4324
|
+
}
|
|
4325
|
+
)
|
|
4326
|
+
), thumbnail.error && !thumbnail.isLoading && /* @__PURE__ */ React19.createElement(
|
|
4327
|
+
"div",
|
|
4328
|
+
{
|
|
4329
|
+
style: {
|
|
4330
|
+
position: "absolute",
|
|
4331
|
+
inset: 0,
|
|
4332
|
+
display: "flex",
|
|
4333
|
+
flexDirection: "column",
|
|
4334
|
+
alignItems: "center",
|
|
4335
|
+
justifyContent: "center",
|
|
4336
|
+
backgroundColor: "#fef2f2"
|
|
4337
|
+
}
|
|
4338
|
+
},
|
|
4339
|
+
/* @__PURE__ */ React19.createElement(AlertCircle, { style: { width: 20, height: 20, color: "#f87171", marginBottom: 4 } }),
|
|
4340
|
+
/* @__PURE__ */ React19.createElement("span", { style: { fontSize: 10, color: "#9ca3af" } }, "Failed")
|
|
4341
|
+
), thumbnail.dataUrl && !thumbnail.isLoading && /* @__PURE__ */ React19.createElement(
|
|
4342
|
+
"img",
|
|
4343
|
+
{
|
|
4344
|
+
src: thumbnail.dataUrl,
|
|
4345
|
+
alt: `Page ${pageNumber}`,
|
|
4346
|
+
style: {
|
|
4347
|
+
width: "100%",
|
|
4348
|
+
height: "100%",
|
|
4349
|
+
objectFit: "contain"
|
|
4350
|
+
},
|
|
4351
|
+
draggable: false
|
|
4352
|
+
}
|
|
4353
|
+
), !thumbnail.dataUrl && !thumbnail.isLoading && !thumbnail.error && /* @__PURE__ */ React19.createElement(
|
|
4354
|
+
"div",
|
|
4355
|
+
{
|
|
4356
|
+
style: {
|
|
4357
|
+
position: "absolute",
|
|
4358
|
+
inset: 0,
|
|
4359
|
+
display: "flex",
|
|
4360
|
+
alignItems: "center",
|
|
4361
|
+
justifyContent: "center",
|
|
4362
|
+
backgroundColor: "#f9fafb"
|
|
4363
|
+
}
|
|
4364
|
+
},
|
|
4365
|
+
/* @__PURE__ */ React19.createElement(
|
|
4366
|
+
"span",
|
|
4367
|
+
{
|
|
4368
|
+
style: {
|
|
4369
|
+
fontSize: 24,
|
|
4370
|
+
fontWeight: 300,
|
|
4371
|
+
color: "#d1d5db"
|
|
4372
|
+
}
|
|
4373
|
+
},
|
|
4374
|
+
pageNumber
|
|
4375
|
+
)
|
|
4376
|
+
)),
|
|
4377
|
+
showPageNumber && /* @__PURE__ */ React19.createElement("div", { style: pageNumberStyle }, pageNumber)
|
|
4378
|
+
);
|
|
4379
|
+
};
|
|
4380
|
+
|
|
4381
|
+
// src/components/leftpanel/ThumbnailPanel.tsx
|
|
4382
|
+
var ThumbnailPanel = ({
|
|
4383
|
+
totalPages,
|
|
4384
|
+
currentPage,
|
|
4385
|
+
getThumbnail,
|
|
4386
|
+
loadThumbnail,
|
|
4387
|
+
onPageSelect,
|
|
4388
|
+
showPageNumbers = true,
|
|
4389
|
+
className = "",
|
|
4390
|
+
renderThumbnail
|
|
4391
|
+
}) => {
|
|
4392
|
+
const pageNumbers = useMemo3(() => {
|
|
4393
|
+
return Array.from({ length: totalPages }, (_, i) => i + 1);
|
|
4394
|
+
}, [totalPages]);
|
|
4395
|
+
if (totalPages === 0) {
|
|
4396
|
+
return /* @__PURE__ */ React20.createElement(
|
|
4397
|
+
"div",
|
|
4398
|
+
{
|
|
4399
|
+
className,
|
|
4400
|
+
style: {
|
|
4401
|
+
display: "flex",
|
|
4402
|
+
alignItems: "center",
|
|
4403
|
+
justifyContent: "center",
|
|
4404
|
+
padding: "48px 16px"
|
|
4405
|
+
}
|
|
4406
|
+
},
|
|
4407
|
+
/* @__PURE__ */ React20.createElement("p", { style: { fontSize: 13, color: "#9ca3af" } }, "No pages to display")
|
|
4408
|
+
);
|
|
4409
|
+
}
|
|
4410
|
+
return /* @__PURE__ */ React20.createElement(
|
|
4411
|
+
"div",
|
|
4412
|
+
{
|
|
4413
|
+
className: `thumbnail-panel ${className}`,
|
|
4414
|
+
style: {
|
|
4415
|
+
padding: "12px"
|
|
4416
|
+
}
|
|
4417
|
+
},
|
|
4418
|
+
/* @__PURE__ */ React20.createElement(
|
|
4419
|
+
"div",
|
|
4420
|
+
{
|
|
4421
|
+
style: {
|
|
4422
|
+
display: "flex",
|
|
4423
|
+
flexDirection: "column",
|
|
4424
|
+
gap: "8px"
|
|
4425
|
+
}
|
|
4426
|
+
},
|
|
4427
|
+
pageNumbers.map((pageNumber) => {
|
|
4428
|
+
const thumbnail = getThumbnail(pageNumber);
|
|
4429
|
+
const isActive = currentPage === pageNumber;
|
|
4430
|
+
if (renderThumbnail) {
|
|
4431
|
+
return /* @__PURE__ */ React20.createElement(
|
|
4432
|
+
"div",
|
|
4433
|
+
{
|
|
4434
|
+
key: pageNumber,
|
|
4435
|
+
onClick: () => onPageSelect(pageNumber),
|
|
4436
|
+
style: { cursor: "pointer" }
|
|
4437
|
+
},
|
|
4438
|
+
renderThumbnail(pageNumber, thumbnail, isActive)
|
|
4439
|
+
);
|
|
4440
|
+
}
|
|
4441
|
+
return /* @__PURE__ */ React20.createElement(
|
|
4442
|
+
ThumbnailItem,
|
|
4443
|
+
{
|
|
4444
|
+
key: pageNumber,
|
|
4445
|
+
pageNumber,
|
|
4446
|
+
thumbnail,
|
|
4447
|
+
isActive,
|
|
4448
|
+
onLoad: loadThumbnail,
|
|
4449
|
+
onClick: onPageSelect,
|
|
4450
|
+
showPageNumber: showPageNumbers
|
|
4451
|
+
}
|
|
4452
|
+
);
|
|
4453
|
+
})
|
|
4454
|
+
)
|
|
4455
|
+
);
|
|
4456
|
+
};
|
|
4457
|
+
|
|
4458
|
+
// src/components/leftpanel/LeftPanel.tsx
|
|
4459
|
+
var defaultTheme = {
|
|
4460
|
+
backgroundColor: "#ffffff",
|
|
4461
|
+
borderColor: "#e5e7eb",
|
|
4462
|
+
accentColor: "#3b82f6",
|
|
4463
|
+
textColor: "#374151",
|
|
4464
|
+
mutedTextColor: "#6b7280",
|
|
4465
|
+
hoverBackgroundColor: "#f9fafb"
|
|
4466
|
+
};
|
|
4467
|
+
var LeftPanel = ({
|
|
4468
|
+
pdfDocument,
|
|
4469
|
+
viewer = null,
|
|
4470
|
+
linkService = null,
|
|
4471
|
+
eventBus = null,
|
|
4472
|
+
isOpen: controlledIsOpen,
|
|
4473
|
+
onOpenChange,
|
|
4474
|
+
defaultTab = "thumbnails",
|
|
4475
|
+
tabs = ["outline", "thumbnails"],
|
|
4476
|
+
width = 260,
|
|
4477
|
+
className = "",
|
|
4478
|
+
style,
|
|
4479
|
+
renderOutlineItem,
|
|
4480
|
+
renderThumbnail,
|
|
4481
|
+
onPageSelect,
|
|
4482
|
+
thumbnailWidth = 180,
|
|
4483
|
+
children,
|
|
4484
|
+
theme: userTheme,
|
|
4485
|
+
showFooter = true,
|
|
4486
|
+
showToggleButton = true,
|
|
4487
|
+
tabStyles,
|
|
4488
|
+
tabClassNames,
|
|
4489
|
+
footerStyles,
|
|
4490
|
+
footerClassNames,
|
|
4491
|
+
toggleButtonStyles,
|
|
4492
|
+
toggleButtonClassNames,
|
|
4493
|
+
outlineStyles,
|
|
4494
|
+
outlineClassNames,
|
|
4495
|
+
outlineItemStyles,
|
|
4496
|
+
outlineItemClassNames
|
|
4497
|
+
}) => {
|
|
4498
|
+
const theme = useMemo4(() => ({ ...defaultTheme, ...userTheme }), [userTheme]);
|
|
4499
|
+
const [internalIsOpen, setInternalIsOpen] = useState17(true);
|
|
4500
|
+
const [activeTab, setActiveTab] = useState17(defaultTab);
|
|
4501
|
+
const isOpen = controlledIsOpen !== void 0 ? controlledIsOpen : internalIsOpen;
|
|
4502
|
+
const setIsOpen = useCallback8(
|
|
4503
|
+
(open) => {
|
|
4504
|
+
if (onOpenChange) {
|
|
4505
|
+
onOpenChange(open);
|
|
4506
|
+
} else {
|
|
4507
|
+
setInternalIsOpen(open);
|
|
4508
|
+
}
|
|
4509
|
+
},
|
|
4510
|
+
[onOpenChange]
|
|
4511
|
+
);
|
|
4512
|
+
const {
|
|
4513
|
+
outline,
|
|
4514
|
+
isLoading: isOutlineLoading,
|
|
4515
|
+
hasOutline,
|
|
4516
|
+
navigateToItem
|
|
4517
|
+
} = useDocumentOutline({
|
|
4518
|
+
pdfDocument,
|
|
4519
|
+
linkService
|
|
4520
|
+
});
|
|
4521
|
+
const { getThumbnail, loadThumbnail, totalPages } = useThumbnails({
|
|
4522
|
+
pdfDocument,
|
|
4523
|
+
thumbnailWidth
|
|
4524
|
+
});
|
|
4525
|
+
const { currentPage, goToPage } = usePageNavigation({
|
|
4526
|
+
viewer,
|
|
4527
|
+
eventBus
|
|
4528
|
+
});
|
|
4529
|
+
const handlePageSelect = useCallback8(
|
|
4530
|
+
(pageNumber) => {
|
|
4531
|
+
goToPage(pageNumber);
|
|
4532
|
+
onPageSelect?.(pageNumber);
|
|
4533
|
+
},
|
|
4534
|
+
[goToPage, onPageSelect]
|
|
4535
|
+
);
|
|
4536
|
+
const handleOutlineNavigate = useCallback8(
|
|
4537
|
+
(item) => {
|
|
4538
|
+
navigateToItem(item);
|
|
4539
|
+
onPageSelect?.(item.pageNumber);
|
|
4540
|
+
},
|
|
4541
|
+
[navigateToItem, onPageSelect]
|
|
4542
|
+
);
|
|
4543
|
+
const contextValue = useMemo4(
|
|
4544
|
+
() => ({
|
|
4545
|
+
currentPage,
|
|
4546
|
+
totalPages,
|
|
4547
|
+
goToPage: handlePageSelect,
|
|
4548
|
+
goToOutlineItem: handleOutlineNavigate,
|
|
4549
|
+
pdfDocument,
|
|
4550
|
+
outline,
|
|
4551
|
+
hasOutline,
|
|
4552
|
+
isOutlineLoading,
|
|
4553
|
+
getThumbnail,
|
|
4554
|
+
loadThumbnail,
|
|
4555
|
+
activeTab,
|
|
4556
|
+
setActiveTab,
|
|
4557
|
+
isOpen,
|
|
4558
|
+
setIsOpen
|
|
4559
|
+
}),
|
|
4560
|
+
[
|
|
4561
|
+
currentPage,
|
|
4562
|
+
totalPages,
|
|
4563
|
+
handlePageSelect,
|
|
4564
|
+
handleOutlineNavigate,
|
|
4565
|
+
pdfDocument,
|
|
4566
|
+
outline,
|
|
4567
|
+
hasOutline,
|
|
4568
|
+
isOutlineLoading,
|
|
4569
|
+
getThumbnail,
|
|
4570
|
+
loadThumbnail,
|
|
4571
|
+
activeTab,
|
|
4572
|
+
isOpen,
|
|
4573
|
+
setIsOpen
|
|
4574
|
+
]
|
|
4575
|
+
);
|
|
4576
|
+
const panelWidth = typeof width === "number" ? `${width}px` : width;
|
|
4577
|
+
const cssVars = {
|
|
4578
|
+
"--lp-bg": theme.backgroundColor,
|
|
4579
|
+
"--lp-border": theme.borderColor,
|
|
4580
|
+
"--lp-accent": theme.accentColor,
|
|
4581
|
+
"--lp-text": theme.textColor,
|
|
4582
|
+
"--lp-muted": theme.mutedTextColor,
|
|
4583
|
+
"--lp-hover": theme.hoverBackgroundColor
|
|
4584
|
+
};
|
|
4585
|
+
return /* @__PURE__ */ React21.createElement(LeftPanelContext.Provider, { value: contextValue }, showToggleButton && /* @__PURE__ */ React21.createElement(
|
|
4586
|
+
"button",
|
|
4587
|
+
{
|
|
4588
|
+
className: toggleButtonClassNames?.button,
|
|
4589
|
+
onClick: () => setIsOpen(!isOpen),
|
|
4590
|
+
style: {
|
|
4591
|
+
position: "absolute",
|
|
4592
|
+
top: "50%",
|
|
4593
|
+
transform: "translateY(-50%)",
|
|
4594
|
+
left: isOpen ? `calc(${panelWidth} - 1px)` : "0",
|
|
4595
|
+
zIndex: 20,
|
|
4596
|
+
width: "24px",
|
|
4597
|
+
height: "48px",
|
|
4598
|
+
backgroundColor: theme.backgroundColor,
|
|
4599
|
+
border: `1px solid ${theme.borderColor}`,
|
|
4600
|
+
borderLeft: "none",
|
|
4601
|
+
borderRadius: "0 6px 6px 0",
|
|
4602
|
+
display: "flex",
|
|
4603
|
+
alignItems: "center",
|
|
4604
|
+
justifyContent: "center",
|
|
4605
|
+
cursor: "pointer",
|
|
4606
|
+
boxShadow: "2px 0 8px rgba(0,0,0,0.08)",
|
|
4607
|
+
transition: "left 0.2s ease-in-out, background-color 0.15s ease",
|
|
4608
|
+
...toggleButtonStyles?.button
|
|
4609
|
+
},
|
|
4610
|
+
onMouseEnter: (e) => {
|
|
4611
|
+
e.currentTarget.style.backgroundColor = theme.hoverBackgroundColor || "#f9fafb";
|
|
4612
|
+
},
|
|
4613
|
+
onMouseLeave: (e) => {
|
|
4614
|
+
e.currentTarget.style.backgroundColor = theme.backgroundColor || "#ffffff";
|
|
4615
|
+
},
|
|
4616
|
+
"aria-label": isOpen ? "Close panel" : "Open panel"
|
|
4617
|
+
},
|
|
4618
|
+
isOpen ? /* @__PURE__ */ React21.createElement(ChevronLeft, { className: toggleButtonClassNames?.icon, style: { width: 14, height: 14, color: theme.mutedTextColor, ...toggleButtonStyles?.icon } }) : /* @__PURE__ */ React21.createElement(ChevronRight2, { className: toggleButtonClassNames?.icon, style: { width: 14, height: 14, color: theme.mutedTextColor, ...toggleButtonStyles?.icon } })
|
|
4619
|
+
), /* @__PURE__ */ React21.createElement(
|
|
4620
|
+
"div",
|
|
4621
|
+
{
|
|
4622
|
+
className: `left-panel ${className}`,
|
|
4623
|
+
style: {
|
|
4624
|
+
display: "flex",
|
|
4625
|
+
flexDirection: "column",
|
|
4626
|
+
height: "100%",
|
|
4627
|
+
backgroundColor: theme.backgroundColor,
|
|
4628
|
+
borderRight: `1px solid ${theme.borderColor}`,
|
|
4629
|
+
transition: "width 0.2s ease-in-out, min-width 0.2s ease-in-out",
|
|
4630
|
+
position: "relative",
|
|
4631
|
+
width: isOpen ? panelWidth : "0px",
|
|
4632
|
+
minWidth: isOpen ? panelWidth : "0px",
|
|
4633
|
+
overflow: "hidden",
|
|
4634
|
+
...cssVars,
|
|
4635
|
+
...style
|
|
4636
|
+
}
|
|
4637
|
+
},
|
|
4638
|
+
/* @__PURE__ */ React21.createElement(
|
|
4639
|
+
"div",
|
|
4640
|
+
{
|
|
4641
|
+
style: {
|
|
4642
|
+
display: "flex",
|
|
4643
|
+
flexDirection: "column",
|
|
4644
|
+
height: "100%",
|
|
4645
|
+
overflow: "hidden",
|
|
4646
|
+
width: panelWidth,
|
|
4647
|
+
minWidth: panelWidth
|
|
4648
|
+
}
|
|
4649
|
+
},
|
|
4650
|
+
tabs.length > 1 && /* @__PURE__ */ React21.createElement(
|
|
4651
|
+
"div",
|
|
4652
|
+
{
|
|
4653
|
+
className: tabClassNames?.container,
|
|
4654
|
+
style: {
|
|
4655
|
+
display: "flex",
|
|
4656
|
+
borderBottom: `1px solid ${theme.borderColor}`,
|
|
4657
|
+
flexShrink: 0,
|
|
4658
|
+
...tabStyles?.container
|
|
4659
|
+
}
|
|
4660
|
+
},
|
|
4661
|
+
tabs.includes("outline") && /* @__PURE__ */ React21.createElement(
|
|
4662
|
+
"button",
|
|
4663
|
+
{
|
|
4664
|
+
className: [tabClassNames?.tab, activeTab === "outline" ? tabClassNames?.tabActive : ""].filter(Boolean).join(" ") || void 0,
|
|
4665
|
+
onClick: () => setActiveTab("outline"),
|
|
4666
|
+
style: {
|
|
4667
|
+
flex: 1,
|
|
4668
|
+
display: "flex",
|
|
4669
|
+
alignItems: "center",
|
|
4670
|
+
justifyContent: "center",
|
|
4671
|
+
gap: "6px",
|
|
4672
|
+
padding: "12px 16px",
|
|
4673
|
+
fontSize: "13px",
|
|
4674
|
+
fontWeight: 500,
|
|
4675
|
+
color: activeTab === "outline" ? theme.accentColor : theme.mutedTextColor,
|
|
4676
|
+
backgroundColor: activeTab === "outline" ? `${theme.accentColor}08` : "transparent",
|
|
4677
|
+
borderBottom: activeTab === "outline" ? `2px solid ${theme.accentColor}` : "2px solid transparent",
|
|
4678
|
+
border: "none",
|
|
4679
|
+
cursor: "pointer",
|
|
4680
|
+
transition: "all 0.15s ease",
|
|
4681
|
+
...tabStyles?.tab,
|
|
4682
|
+
...activeTab === "outline" ? tabStyles?.tabActive : {}
|
|
4683
|
+
}
|
|
4684
|
+
},
|
|
4685
|
+
/* @__PURE__ */ React21.createElement(FileText, { className: tabClassNames?.tabIcon, style: { width: 15, height: 15, ...tabStyles?.tabIcon } }),
|
|
4686
|
+
/* @__PURE__ */ React21.createElement("span", { className: tabClassNames?.tabText, style: tabStyles?.tabText }, "Outline")
|
|
4687
|
+
),
|
|
4688
|
+
tabs.includes("thumbnails") && /* @__PURE__ */ React21.createElement(
|
|
4689
|
+
"button",
|
|
4690
|
+
{
|
|
4691
|
+
className: [tabClassNames?.tab, activeTab === "thumbnails" ? tabClassNames?.tabActive : ""].filter(Boolean).join(" ") || void 0,
|
|
4692
|
+
onClick: () => setActiveTab("thumbnails"),
|
|
4693
|
+
style: {
|
|
4694
|
+
flex: 1,
|
|
4695
|
+
display: "flex",
|
|
4696
|
+
alignItems: "center",
|
|
4697
|
+
justifyContent: "center",
|
|
4698
|
+
gap: "6px",
|
|
4699
|
+
padding: "12px 16px",
|
|
4700
|
+
fontSize: "13px",
|
|
4701
|
+
fontWeight: 500,
|
|
4702
|
+
color: activeTab === "thumbnails" ? theme.accentColor : theme.mutedTextColor,
|
|
4703
|
+
backgroundColor: activeTab === "thumbnails" ? `${theme.accentColor}08` : "transparent",
|
|
4704
|
+
borderBottom: activeTab === "thumbnails" ? `2px solid ${theme.accentColor}` : "2px solid transparent",
|
|
4705
|
+
border: "none",
|
|
4706
|
+
cursor: "pointer",
|
|
4707
|
+
transition: "all 0.15s ease",
|
|
4708
|
+
...tabStyles?.tab,
|
|
4709
|
+
...activeTab === "thumbnails" ? tabStyles?.tabActive : {}
|
|
4710
|
+
}
|
|
4711
|
+
},
|
|
4712
|
+
/* @__PURE__ */ React21.createElement(List, { className: tabClassNames?.tabIcon, style: { width: 15, height: 15, ...tabStyles?.tabIcon } }),
|
|
4713
|
+
/* @__PURE__ */ React21.createElement("span", { className: tabClassNames?.tabText, style: tabStyles?.tabText }, "Pages")
|
|
4714
|
+
)
|
|
4715
|
+
),
|
|
4716
|
+
tabs.length === 1 && /* @__PURE__ */ React21.createElement(
|
|
4717
|
+
"div",
|
|
4718
|
+
{
|
|
4719
|
+
className: tabClassNames?.container,
|
|
4720
|
+
style: {
|
|
4721
|
+
display: "flex",
|
|
4722
|
+
alignItems: "center",
|
|
4723
|
+
gap: "8px",
|
|
4724
|
+
padding: "12px 16px",
|
|
4725
|
+
borderBottom: `1px solid ${theme.borderColor}`,
|
|
4726
|
+
flexShrink: 0,
|
|
4727
|
+
...tabStyles?.container
|
|
4728
|
+
}
|
|
4729
|
+
},
|
|
4730
|
+
tabs[0] === "outline" ? /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement(FileText, { className: tabClassNames?.tabIcon, style: { width: 15, height: 15, color: theme.mutedTextColor, ...tabStyles?.tabIcon } }), /* @__PURE__ */ React21.createElement("span", { className: tabClassNames?.tabText, style: { fontSize: "13px", fontWeight: 500, color: theme.textColor, ...tabStyles?.tabText } }, "Outline")) : /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement(List, { className: tabClassNames?.tabIcon, style: { width: 15, height: 15, color: theme.mutedTextColor, ...tabStyles?.tabIcon } }), /* @__PURE__ */ React21.createElement("span", { className: tabClassNames?.tabText, style: { fontSize: "13px", fontWeight: 500, color: theme.textColor, ...tabStyles?.tabText } }, "Pages"))
|
|
4731
|
+
),
|
|
4732
|
+
/* @__PURE__ */ React21.createElement(
|
|
4733
|
+
"div",
|
|
4734
|
+
{
|
|
4735
|
+
style: {
|
|
4736
|
+
flex: 1,
|
|
4737
|
+
minHeight: 0,
|
|
4738
|
+
overflowY: "auto",
|
|
4739
|
+
overflowX: "hidden"
|
|
4740
|
+
}
|
|
4741
|
+
},
|
|
4742
|
+
activeTab === "outline" && tabs.includes("outline") && /* @__PURE__ */ React21.createElement(
|
|
4743
|
+
DocumentOutline,
|
|
4744
|
+
{
|
|
4745
|
+
outline,
|
|
4746
|
+
isLoading: isOutlineLoading,
|
|
4747
|
+
currentPage,
|
|
4748
|
+
onNavigate: handleOutlineNavigate,
|
|
4749
|
+
renderItem: renderOutlineItem,
|
|
4750
|
+
styles: outlineStyles,
|
|
4751
|
+
classNames: outlineClassNames,
|
|
4752
|
+
itemStyles: outlineItemStyles,
|
|
4753
|
+
itemClassNames: outlineItemClassNames
|
|
4754
|
+
}
|
|
4755
|
+
),
|
|
4756
|
+
activeTab === "thumbnails" && tabs.includes("thumbnails") && /* @__PURE__ */ React21.createElement(
|
|
4757
|
+
ThumbnailPanel,
|
|
4758
|
+
{
|
|
4759
|
+
totalPages,
|
|
4760
|
+
currentPage,
|
|
4761
|
+
getThumbnail,
|
|
4762
|
+
loadThumbnail,
|
|
4763
|
+
onPageSelect: handlePageSelect,
|
|
4764
|
+
renderThumbnail
|
|
4765
|
+
}
|
|
4766
|
+
),
|
|
4767
|
+
children
|
|
4768
|
+
),
|
|
4769
|
+
showFooter && /* @__PURE__ */ React21.createElement(
|
|
4770
|
+
"div",
|
|
4771
|
+
{
|
|
4772
|
+
className: footerClassNames?.container,
|
|
4773
|
+
style: {
|
|
4774
|
+
flexShrink: 0,
|
|
4775
|
+
borderTop: `1px solid ${theme.borderColor}`,
|
|
4776
|
+
padding: "10px 16px",
|
|
4777
|
+
backgroundColor: theme.hoverBackgroundColor,
|
|
4778
|
+
...footerStyles?.container
|
|
4779
|
+
}
|
|
4780
|
+
},
|
|
4781
|
+
/* @__PURE__ */ React21.createElement(
|
|
4782
|
+
"div",
|
|
4783
|
+
{
|
|
4784
|
+
className: footerClassNames?.text,
|
|
4785
|
+
style: {
|
|
4786
|
+
fontSize: "12px",
|
|
4787
|
+
color: theme.mutedTextColor,
|
|
4788
|
+
textAlign: "center",
|
|
4789
|
+
fontWeight: 500,
|
|
4790
|
+
...footerStyles?.text
|
|
4791
|
+
}
|
|
4792
|
+
},
|
|
4793
|
+
"Page ",
|
|
4794
|
+
currentPage,
|
|
4795
|
+
" of ",
|
|
4796
|
+
totalPages
|
|
4797
|
+
)
|
|
4798
|
+
)
|
|
4799
|
+
)
|
|
4800
|
+
));
|
|
4801
|
+
};
|
|
3539
4802
|
export {
|
|
3540
4803
|
AreaHighlight,
|
|
4804
|
+
DocumentOutline,
|
|
3541
4805
|
DrawingCanvas,
|
|
3542
4806
|
DrawingHighlight,
|
|
3543
4807
|
FreetextHighlight,
|
|
3544
4808
|
ImageHighlight,
|
|
4809
|
+
LeftPanel,
|
|
3545
4810
|
MonitoredHighlightContainer,
|
|
4811
|
+
OutlineItem,
|
|
3546
4812
|
PdfHighlighter,
|
|
3547
4813
|
PdfLoader,
|
|
3548
4814
|
ShapeCanvas,
|
|
3549
4815
|
ShapeHighlight,
|
|
3550
4816
|
SignaturePad,
|
|
3551
4817
|
TextHighlight,
|
|
4818
|
+
ThumbnailItem,
|
|
4819
|
+
ThumbnailPanel,
|
|
3552
4820
|
exportPdf,
|
|
3553
4821
|
scaledPositionToViewport,
|
|
4822
|
+
useDocumentOutline,
|
|
3554
4823
|
useHighlightContainerContext,
|
|
4824
|
+
useLeftPanelContext,
|
|
4825
|
+
usePageNavigation,
|
|
3555
4826
|
usePdfHighlighterContext,
|
|
4827
|
+
useThumbnails,
|
|
3556
4828
|
viewportPositionToScaled
|
|
3557
4829
|
};
|
|
3558
4830
|
//# sourceMappingURL=index.js.map
|