@cannyminds/dms-file-viewers 0.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.
Files changed (65) hide show
  1. package/dist/chunk-3STHCDAC.js +1402 -0
  2. package/dist/chunk-3STHCDAC.js.map +1 -0
  3. package/dist/chunk-4RL77HKO.js +196 -0
  4. package/dist/chunk-4RL77HKO.js.map +1 -0
  5. package/dist/chunk-73ZIFR3P.mjs +1402 -0
  6. package/dist/chunk-73ZIFR3P.mjs.map +1 -0
  7. package/dist/chunk-7JTIG6OU.js +177 -0
  8. package/dist/chunk-7JTIG6OU.js.map +1 -0
  9. package/dist/chunk-BNHQYEZ7.js +448 -0
  10. package/dist/chunk-BNHQYEZ7.js.map +1 -0
  11. package/dist/chunk-EMP7RZM2.js +159 -0
  12. package/dist/chunk-EMP7RZM2.js.map +1 -0
  13. package/dist/chunk-FZYMVHF6.mjs +159 -0
  14. package/dist/chunk-FZYMVHF6.mjs.map +1 -0
  15. package/dist/chunk-GNWU6XHH.js +288 -0
  16. package/dist/chunk-GNWU6XHH.js.map +1 -0
  17. package/dist/chunk-LKBM4O47.mjs +177 -0
  18. package/dist/chunk-LKBM4O47.mjs.map +1 -0
  19. package/dist/chunk-NOLXOOIP.mjs +448 -0
  20. package/dist/chunk-NOLXOOIP.mjs.map +1 -0
  21. package/dist/chunk-QLJKOQTP.mjs +78 -0
  22. package/dist/chunk-QLJKOQTP.mjs.map +1 -0
  23. package/dist/chunk-QQDQJ7TS.mjs +263 -0
  24. package/dist/chunk-QQDQJ7TS.mjs.map +1 -0
  25. package/dist/chunk-QRYIHDRT.mjs +196 -0
  26. package/dist/chunk-QRYIHDRT.mjs.map +1 -0
  27. package/dist/chunk-RE4XRGSV.js +263 -0
  28. package/dist/chunk-RE4XRGSV.js.map +1 -0
  29. package/dist/chunk-XQBXRMB7.mjs +288 -0
  30. package/dist/chunk-XQBXRMB7.mjs.map +1 -0
  31. package/dist/chunk-Z7FUO5RX.js +78 -0
  32. package/dist/chunk-Z7FUO5RX.js.map +1 -0
  33. package/dist/components/viewers/AudioViewer.js +9 -0
  34. package/dist/components/viewers/AudioViewer.js.map +1 -0
  35. package/dist/components/viewers/AudioViewer.mjs +9 -0
  36. package/dist/components/viewers/AudioViewer.mjs.map +1 -0
  37. package/dist/components/viewers/DefaultViewer.js +8 -0
  38. package/dist/components/viewers/DefaultViewer.js.map +1 -0
  39. package/dist/components/viewers/DefaultViewer.mjs +8 -0
  40. package/dist/components/viewers/DefaultViewer.mjs.map +1 -0
  41. package/dist/components/viewers/ImageViewer.js +10 -0
  42. package/dist/components/viewers/ImageViewer.js.map +1 -0
  43. package/dist/components/viewers/ImageViewer.mjs +10 -0
  44. package/dist/components/viewers/ImageViewer.mjs.map +1 -0
  45. package/dist/components/viewers/PDFViewer.js +9 -0
  46. package/dist/components/viewers/PDFViewer.js.map +1 -0
  47. package/dist/components/viewers/PDFViewer.mjs +9 -0
  48. package/dist/components/viewers/PDFViewer.mjs.map +1 -0
  49. package/dist/components/viewers/TIFFViewer.js +9 -0
  50. package/dist/components/viewers/TIFFViewer.js.map +1 -0
  51. package/dist/components/viewers/TIFFViewer.mjs +9 -0
  52. package/dist/components/viewers/TIFFViewer.mjs.map +1 -0
  53. package/dist/components/viewers/TextViewer.js +9 -0
  54. package/dist/components/viewers/TextViewer.js.map +1 -0
  55. package/dist/components/viewers/TextViewer.mjs +9 -0
  56. package/dist/components/viewers/TextViewer.mjs.map +1 -0
  57. package/dist/components/viewers/VideoViewer.js +9 -0
  58. package/dist/components/viewers/VideoViewer.js.map +1 -0
  59. package/dist/components/viewers/VideoViewer.mjs +9 -0
  60. package/dist/components/viewers/VideoViewer.mjs.map +1 -0
  61. package/dist/index.js +284 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/index.mjs +284 -0
  64. package/dist/index.mjs.map +1 -0
  65. package/package.json +46 -0
@@ -0,0 +1,1402 @@
1
+ "use client";
2
+ import {
3
+ FileIcon_default,
4
+ getFileExtension
5
+ } from "./chunk-QQDQJ7TS.mjs";
6
+
7
+ // src/components/viewers/PDFViewer.tsx
8
+ import React2, { useCallback, useEffect, useMemo, useRef as useRef2, useState as useState2, forwardRef, useImperativeHandle } from "react";
9
+ import { PDFViewer as HeadlessPDFViewer } from "@cannyminds/pdf-viewer";
10
+ import FirstPageIcon from "@mui/icons-material/FirstPage";
11
+ import LastPageIcon from "@mui/icons-material/LastPage";
12
+ import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
13
+ import ChevronRightIcon from "@mui/icons-material/ChevronRight";
14
+ import ZoomInIcon from "@mui/icons-material/ZoomIn";
15
+ import ZoomOutIcon from "@mui/icons-material/ZoomOut";
16
+ import FitScreenIcon from "@mui/icons-material/FitScreen";
17
+ import AspectRatioIcon from "@mui/icons-material/AspectRatio";
18
+ import SearchIcon2 from "@mui/icons-material/Search";
19
+ import DownloadIcon from "@mui/icons-material/Download";
20
+ import PrintIcon from "@mui/icons-material/Print";
21
+ import InfoIcon from "@mui/icons-material/Info";
22
+ import DescriptionIcon from "@mui/icons-material/Description";
23
+
24
+ // src/components/viewers/pdf/SearchSidebar.tsx
25
+ import { useState, useLayoutEffect, useRef } from "react";
26
+ import {
27
+ Box,
28
+ Typography,
29
+ TextField,
30
+ IconButton,
31
+ InputAdornment,
32
+ Divider
33
+ } from "@mui/material";
34
+ import SearchIcon from "@mui/icons-material/Search";
35
+ import CloseIcon from "@mui/icons-material/Close";
36
+ import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp";
37
+ import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
38
+ import ClearIcon from "@mui/icons-material/Clear";
39
+ import FindInPageIcon from "@mui/icons-material/FindInPage";
40
+ import { jsx, jsxs } from "react/jsx-runtime";
41
+ var SearchSidebar = ({
42
+ isOpen,
43
+ onClose,
44
+ onSearch,
45
+ onSearchResultClick,
46
+ onNextResult,
47
+ onPreviousResult,
48
+ currentResultIndex,
49
+ totalResults,
50
+ searchKeyword,
51
+ searchResults = [],
52
+ isSearching = false
53
+ }) => {
54
+ const [searchTerm, setSearchTerm] = useState(searchKeyword || "");
55
+ const [hasSearched, setHasSearched] = useState(false);
56
+ const contentRef = useRef(null);
57
+ useLayoutEffect(() => {
58
+ const element = contentRef.current;
59
+ if (!element) return;
60
+ const handleMouseMove = (e) => {
61
+ const rect = element.getBoundingClientRect();
62
+ const distanceFromRight = rect.right - e.clientX;
63
+ const distanceFromBottom = rect.bottom - e.clientY;
64
+ if (distanceFromRight <= 15 || distanceFromBottom <= 15) {
65
+ element.classList.add("scrollbar-hover");
66
+ } else {
67
+ element.classList.remove("scrollbar-hover");
68
+ }
69
+ };
70
+ const handleMouseLeave = () => element.classList.remove("scrollbar-hover");
71
+ element.addEventListener("mousemove", handleMouseMove);
72
+ element.addEventListener("mouseleave", handleMouseLeave);
73
+ return () => {
74
+ element.removeEventListener("mousemove", handleMouseMove);
75
+ element.removeEventListener("mouseleave", handleMouseLeave);
76
+ };
77
+ }, []);
78
+ useLayoutEffect(() => {
79
+ const style = document.createElement("style");
80
+ style.id = "search-sidebar-scrollbar";
81
+ style.textContent = `
82
+ @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+Tamil:wght@400;600&family=Noto+Sans+Devanagari:wght@400;600&display=swap');
83
+
84
+ .search-sidebar-content::-webkit-scrollbar {
85
+ width: 12px;
86
+ height: 12px;
87
+ }
88
+ .search-sidebar-content::-webkit-scrollbar-track {
89
+ background-color: transparent;
90
+ }
91
+ .search-sidebar-content::-webkit-scrollbar-thumb {
92
+ background-color: rgba(0, 0, 0, 0.25);
93
+ border-radius: 8px;
94
+ border: 4px solid transparent;
95
+ background-clip: padding-box;
96
+ transition: all 0.15s ease;
97
+ }
98
+ .search-sidebar-content.scrollbar-hover::-webkit-scrollbar-thumb {
99
+ background-color: rgba(0, 0, 0, 0.4);
100
+ border: 2px solid transparent;
101
+ }
102
+ .search-sidebar-content::-webkit-scrollbar-thumb:active {
103
+ background-color: rgba(25, 118, 210, 0.85);
104
+ border: 1px solid transparent;
105
+ }
106
+
107
+ /* Tamil font support for search results */
108
+ .search-result-text {
109
+ font-family: 'Noto Sans Tamil', 'Noto Sans Devanagari', Arial, sans-serif !important;
110
+ }
111
+ `;
112
+ document.head.appendChild(style);
113
+ return () => {
114
+ const el = document.getElementById("search-sidebar-scrollbar");
115
+ if (el) el.remove();
116
+ };
117
+ }, []);
118
+ useLayoutEffect(() => {
119
+ setSearchTerm(searchKeyword || "");
120
+ if (searchKeyword) {
121
+ setHasSearched(true);
122
+ }
123
+ }, [searchKeyword]);
124
+ const handleSearchSubmit = (e) => {
125
+ if (e) e.preventDefault();
126
+ if (searchTerm.trim()) {
127
+ setHasSearched(true);
128
+ onSearch(searchTerm.trim());
129
+ }
130
+ };
131
+ const handleSearchChange = (e) => {
132
+ const value = e.target.value;
133
+ setSearchTerm(value);
134
+ if (!value.trim()) {
135
+ setHasSearched(false);
136
+ onSearch("");
137
+ }
138
+ };
139
+ const handleClearSearch = () => {
140
+ setSearchTerm("");
141
+ setHasSearched(false);
142
+ onSearch("");
143
+ };
144
+ const resultsByPage = searchResults.reduce((acc, result) => {
145
+ if (!acc[result.pageNumber]) {
146
+ acc[result.pageNumber] = [];
147
+ }
148
+ acc[result.pageNumber].push(result);
149
+ return acc;
150
+ }, {});
151
+ const highlightText = (text, keyword) => {
152
+ if (!keyword) return text;
153
+ const textString = typeof text === "string" ? text : String(text || "");
154
+ if (!textString) return text;
155
+ try {
156
+ const escapedKeyword = keyword.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
157
+ const regex = new RegExp(`(${escapedKeyword})`, "gi");
158
+ const parts = textString.split(regex);
159
+ return parts.map(
160
+ (part, index) => regex.test(part) ? /* @__PURE__ */ jsx(
161
+ Box,
162
+ {
163
+ component: "span",
164
+ sx: {
165
+ color: "primary.main",
166
+ fontWeight: 600,
167
+ fontSize: "inherit"
168
+ },
169
+ children: part
170
+ },
171
+ index
172
+ ) : part
173
+ );
174
+ } catch (error) {
175
+ return textString;
176
+ }
177
+ };
178
+ if (!isOpen) return null;
179
+ return /* @__PURE__ */ jsxs(
180
+ Box,
181
+ {
182
+ sx: {
183
+ display: "flex",
184
+ flexDirection: "column",
185
+ height: "100%",
186
+ width: "320px",
187
+ backgroundColor: "background.paper",
188
+ borderLeft: "1px solid",
189
+ borderColor: "divider",
190
+ overflow: "hidden"
191
+ },
192
+ children: [
193
+ /* @__PURE__ */ jsxs(Box, { sx: { px: 3, py: 2.5, backgroundColor: "background.default" }, children: [
194
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", justifyContent: "space-between", mb: 2 }, children: [
195
+ /* @__PURE__ */ jsx(Typography, { variant: "h6", sx: { fontSize: "1.125rem", fontWeight: 600, color: "text.primary" }, children: "Search" }),
196
+ /* @__PURE__ */ jsx(
197
+ IconButton,
198
+ {
199
+ size: "small",
200
+ onClick: onClose,
201
+ sx: {
202
+ color: "text.secondary",
203
+ padding: "6px"
204
+ },
205
+ children: /* @__PURE__ */ jsx(CloseIcon, { fontSize: "small" })
206
+ }
207
+ )
208
+ ] }),
209
+ /* @__PURE__ */ jsx("form", { onSubmit: handleSearchSubmit, children: /* @__PURE__ */ jsx(
210
+ TextField,
211
+ {
212
+ fullWidth: true,
213
+ size: "medium",
214
+ placeholder: "Search in document...",
215
+ value: searchTerm,
216
+ onChange: handleSearchChange,
217
+ autoComplete: "off",
218
+ InputProps: {
219
+ startAdornment: /* @__PURE__ */ jsx(InputAdornment, { position: "start", children: /* @__PURE__ */ jsx(SearchIcon, { sx: { color: "text.disabled", fontSize: 20 } }) }),
220
+ endAdornment: searchTerm && /* @__PURE__ */ jsx(InputAdornment, { position: "end", children: /* @__PURE__ */ jsx(
221
+ IconButton,
222
+ {
223
+ size: "small",
224
+ onClick: handleClearSearch,
225
+ sx: {
226
+ color: "text.secondary",
227
+ padding: "4px",
228
+ "&:hover": {
229
+ backgroundColor: "action.hover"
230
+ }
231
+ },
232
+ children: /* @__PURE__ */ jsx(ClearIcon, { sx: { fontSize: 18 } })
233
+ }
234
+ ) })
235
+ },
236
+ sx: {
237
+ "& .MuiOutlinedInput-root": {
238
+ fontSize: "0.9375rem",
239
+ backgroundColor: "background.paper",
240
+ borderRadius: "8px",
241
+ "& fieldset": {
242
+ borderColor: "divider"
243
+ },
244
+ "&.Mui-focused fieldset": {
245
+ borderColor: "primary.main",
246
+ borderWidth: "2px"
247
+ }
248
+ },
249
+ "& .MuiInputBase-input": {
250
+ padding: "10px 14px"
251
+ }
252
+ }
253
+ }
254
+ ) }),
255
+ totalResults > 0 && /* @__PURE__ */ jsxs(
256
+ Box,
257
+ {
258
+ sx: {
259
+ display: "flex",
260
+ alignItems: "center",
261
+ justifyContent: "space-between",
262
+ mt: 2,
263
+ pt: 2,
264
+ borderTop: "1px solid",
265
+ borderColor: "divider"
266
+ },
267
+ children: [
268
+ /* @__PURE__ */ jsxs(Typography, { variant: "body2", sx: { color: "text.secondary", fontSize: "0.875rem", fontWeight: 500 }, children: [
269
+ currentResultIndex + 1,
270
+ " of ",
271
+ totalResults,
272
+ " results"
273
+ ] }),
274
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 0.5 }, children: [
275
+ /* @__PURE__ */ jsx(
276
+ IconButton,
277
+ {
278
+ size: "small",
279
+ onClick: onPreviousResult,
280
+ disabled: currentResultIndex <= 0,
281
+ sx: {
282
+ color: currentResultIndex <= 0 ? "text.disabled" : "primary.main",
283
+ padding: "6px",
284
+ borderRadius: "6px",
285
+ border: "1px solid",
286
+ borderColor: currentResultIndex <= 0 ? "divider" : "primary.main"
287
+ },
288
+ children: /* @__PURE__ */ jsx(KeyboardArrowUpIcon, { sx: { fontSize: 20 } })
289
+ }
290
+ ),
291
+ /* @__PURE__ */ jsx(
292
+ IconButton,
293
+ {
294
+ size: "small",
295
+ onClick: onNextResult,
296
+ disabled: currentResultIndex >= totalResults - 1,
297
+ sx: {
298
+ color: currentResultIndex >= totalResults - 1 ? "text.disabled" : "primary.main",
299
+ padding: "6px",
300
+ borderRadius: "6px",
301
+ border: "1px solid",
302
+ borderColor: currentResultIndex >= totalResults - 1 ? "divider" : "primary.main"
303
+ },
304
+ children: /* @__PURE__ */ jsx(KeyboardArrowDownIcon, { sx: { fontSize: 20 } })
305
+ }
306
+ )
307
+ ] })
308
+ ]
309
+ }
310
+ )
311
+ ] }),
312
+ /* @__PURE__ */ jsx(Divider, {}),
313
+ /* @__PURE__ */ jsxs(Box, { ref: contentRef, className: "search-sidebar-content", sx: {
314
+ flex: 1,
315
+ overflow: "auto",
316
+ backgroundColor: "background.default"
317
+ }, children: [
318
+ !searchTerm && !hasSearched && /* @__PURE__ */ jsxs(Box, { sx: { p: 4, textAlign: "center", mt: 6 }, children: [
319
+ /* @__PURE__ */ jsx(
320
+ Box,
321
+ {
322
+ sx: {
323
+ width: 80,
324
+ height: 80,
325
+ borderRadius: "50%",
326
+ backgroundColor: "action.hover",
327
+ display: "flex",
328
+ alignItems: "center",
329
+ justifyContent: "center",
330
+ margin: "0 auto",
331
+ mb: 3
332
+ },
333
+ children: /* @__PURE__ */ jsx(SearchIcon, { sx: { fontSize: 40, color: "text.disabled" } })
334
+ }
335
+ ),
336
+ /* @__PURE__ */ jsx(Typography, { variant: "body1", sx: { color: "text.primary", fontWeight: 500, mb: 1 }, children: "Search in Document" }),
337
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", sx: { color: "text.secondary", lineHeight: 1.6 }, children: "Enter keywords to find text within the PDF document" })
338
+ ] }),
339
+ searchTerm && !hasSearched && /* @__PURE__ */ jsxs(Box, { sx: { p: 4, textAlign: "center", mt: 6 }, children: [
340
+ /* @__PURE__ */ jsx(
341
+ Box,
342
+ {
343
+ sx: {
344
+ width: 80,
345
+ height: 80,
346
+ borderRadius: "50%",
347
+ backgroundColor: "#e3f2fd",
348
+ display: "flex",
349
+ alignItems: "center",
350
+ justifyContent: "center",
351
+ margin: "0 auto",
352
+ mb: 3
353
+ },
354
+ children: /* @__PURE__ */ jsx(FindInPageIcon, { sx: { fontSize: 40, color: "primary.main" } })
355
+ }
356
+ ),
357
+ /* @__PURE__ */ jsx(Typography, { variant: "body1", sx: { color: "text.primary", fontWeight: 500, mb: 1 }, children: "Ready to Search" }),
358
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", sx: { color: "text.secondary", mb: 2, lineHeight: 1.6 }, children: "Press Enter to find" }),
359
+ /* @__PURE__ */ jsxs(
360
+ Typography,
361
+ {
362
+ variant: "body2",
363
+ sx: {
364
+ color: "primary.main",
365
+ fontWeight: 600,
366
+ backgroundColor: "#e3f2fd",
367
+ padding: "6px 16px",
368
+ borderRadius: "16px",
369
+ display: "inline-block"
370
+ },
371
+ children: [
372
+ '"',
373
+ searchTerm,
374
+ '"'
375
+ ]
376
+ }
377
+ )
378
+ ] }),
379
+ hasSearched && totalResults === 0 && !isSearching && /* @__PURE__ */ jsxs(Box, { sx: { p: 4, textAlign: "center", mt: 6 }, children: [
380
+ /* @__PURE__ */ jsx(
381
+ Box,
382
+ {
383
+ sx: {
384
+ width: 80,
385
+ height: 80,
386
+ borderRadius: "50%",
387
+ backgroundColor: "#fff3e0",
388
+ display: "flex",
389
+ alignItems: "center",
390
+ justifyContent: "center",
391
+ margin: "0 auto",
392
+ mb: 3
393
+ },
394
+ children: /* @__PURE__ */ jsx(SearchIcon, { sx: { fontSize: 40, color: "#ff9800" } })
395
+ }
396
+ ),
397
+ /* @__PURE__ */ jsx(Typography, { variant: "body1", sx: { color: "text.primary", fontWeight: 500, mb: 1 }, children: "No Results Found" }),
398
+ /* @__PURE__ */ jsxs(Typography, { variant: "body2", sx: { color: "text.secondary", lineHeight: 1.6 }, children: [
399
+ "No matches found for ",
400
+ /* @__PURE__ */ jsxs("strong", { children: [
401
+ '"',
402
+ searchTerm,
403
+ '"'
404
+ ] })
405
+ ] })
406
+ ] }),
407
+ totalResults > 0 && /* @__PURE__ */ jsx(Box, { sx: { p: 2 }, children: Object.entries(resultsByPage).sort(([a, _], [b, __]) => parseInt(a) - parseInt(b)).map(([pageNum, pageResults]) => {
408
+ const pageNumber = parseInt(pageNum);
409
+ return /* @__PURE__ */ jsxs(Box, { sx: { mb: 3 }, children: [
410
+ /* @__PURE__ */ jsxs(
411
+ Typography,
412
+ {
413
+ variant: "subtitle2",
414
+ sx: {
415
+ color: "text.secondary",
416
+ mb: 1.5,
417
+ px: 1,
418
+ fontSize: "0.8125rem",
419
+ fontWeight: 600,
420
+ textTransform: "uppercase",
421
+ letterSpacing: "0.5px"
422
+ },
423
+ children: [
424
+ "Page ",
425
+ pageNumber
426
+ ]
427
+ }
428
+ ),
429
+ pageResults.map((result, index) => /* @__PURE__ */ jsx(
430
+ Box,
431
+ {
432
+ onClick: () => onSearchResultClick(result.pageNumber, result.index),
433
+ sx: {
434
+ p: 2,
435
+ mx: 1,
436
+ mb: 1.5,
437
+ borderRadius: "8px",
438
+ border: "1px solid",
439
+ borderColor: result.index === currentResultIndex ? "primary.main" : "divider",
440
+ backgroundColor: result.index === currentResultIndex ? "#e3f2fd" : "background.paper",
441
+ cursor: "pointer",
442
+ transition: "all 0.2s ease",
443
+ boxShadow: result.index === currentResultIndex ? "0 2px 8px rgba(25, 118, 210, 0.15)" : "0 1px 3px rgba(0, 0, 0, 0.05)",
444
+ "&:hover": {
445
+ borderColor: "primary.main",
446
+ boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
447
+ transform: "translateY(-1px)"
448
+ }
449
+ },
450
+ children: /* @__PURE__ */ jsx(
451
+ Typography,
452
+ {
453
+ variant: "body2",
454
+ className: "search-result-text",
455
+ sx: {
456
+ fontSize: "0.875rem",
457
+ lineHeight: 1.6,
458
+ color: result.index === currentResultIndex ? "text.primary" : "text.secondary"
459
+ },
460
+ children: highlightText(result.context, searchTerm)
461
+ }
462
+ )
463
+ },
464
+ index
465
+ ))
466
+ ] }, pageNumber);
467
+ }) })
468
+ ] })
469
+ ]
470
+ }
471
+ );
472
+ };
473
+
474
+ // src/components/viewers/PDFViewer.tsx
475
+ import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
476
+ var toolbarStyles = `
477
+ @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+Tamil:wght@400;500;600;700&family=Noto+Sans+Devanagari:wght@400;500;600;700&display=swap');
478
+
479
+ * {
480
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
481
+ 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
482
+ 'Noto Sans Tamil', 'Noto Sans Devanagari', 'Lohit Tamil', 'Tamil MN',
483
+ 'Arial Unicode MS', sans-serif !important;
484
+ }
485
+
486
+ /* Target PDF.js text layer */
487
+ .textLayer,
488
+ .textLayer span,
489
+ .textLayer div,
490
+ [class*="pdf"],
491
+ [class*="page"],
492
+ canvas + div,
493
+ .embedpdf-viewport *,
494
+ [data-pdf-viewer] *,
495
+ [role="document"] * {
496
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
497
+ 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
498
+ 'Noto Sans Tamil', 'Noto Sans Devanagari', 'Lohit Tamil', 'Tamil MN',
499
+ 'Arial Unicode MS', sans-serif !important;
500
+ }
501
+
502
+ .pdf-viewer-header {
503
+ display: flex;
504
+ align-items: center;
505
+ justify-content: center;
506
+ gap: 8px;
507
+ padding: 3px 16px 0 16px;
508
+ background: #fff;
509
+ min-height: 36px;
510
+ }
511
+ .header-file-name {
512
+ font-size: 12px;
513
+ font-weight: 500;
514
+ color: #424242;
515
+ white-space: nowrap;
516
+ overflow: hidden;
517
+ text-overflow: ellipsis;
518
+ max-width: 400px;
519
+ }
520
+ .pdf-viewer-toolbar {
521
+ display: flex;
522
+ align-items: center;
523
+ justify-content: center;
524
+ padding: 0 16px 6px 16px;
525
+ background: #fff;
526
+ gap: 12px;
527
+ flex-wrap: wrap;
528
+ min-height: 44px;
529
+ }
530
+ .toolbar-section {
531
+ display: flex;
532
+ align-items: center;
533
+ gap: 8px;
534
+ }
535
+ .toolbar-separator {
536
+ width: 1px;
537
+ height: 24px;
538
+ background: #e0e0e0;
539
+ margin: 0 4px;
540
+ }
541
+ .toolbar-button {
542
+ padding: 8px;
543
+ border: none;
544
+ background: transparent;
545
+ cursor: pointer;
546
+ border-radius: 4px;
547
+ display: flex;
548
+ align-items: center;
549
+ justify-content: center;
550
+ transition: background 0.2s;
551
+ }
552
+ .toolbar-button:hover:not(:disabled) {
553
+ background: #f5f5f5;
554
+ }
555
+ .toolbar-button:disabled {
556
+ opacity: 0.4;
557
+ cursor: not-allowed;
558
+ }
559
+ .toolbar-button svg {
560
+ width: 20px;
561
+ height: 20px;
562
+ display: block;
563
+ }
564
+ .page-input {
565
+ width: 60px;
566
+ padding: 4px 8px;
567
+ border: 1px solid #e0e0e0;
568
+ border-radius: 4px;
569
+ text-align: center;
570
+ font-size: 14px;
571
+ }
572
+ .page-info {
573
+ font-size: 14px;
574
+ color: #666;
575
+ white-space: nowrap;
576
+ }
577
+ .zoom-display {
578
+ min-width: 60px;
579
+ text-align: center;
580
+ font-size: 14px;
581
+ color: #666;
582
+ }
583
+ .search-input {
584
+ padding: 4px 8px;
585
+ border: 1px solid #e0e0e0;
586
+ border-radius: 4px;
587
+ font-size: 14px;
588
+ min-width: 200px;
589
+ }
590
+ .pdf-viewer-content {
591
+ flex: 1;
592
+ overflow: hidden;
593
+ position: relative;
594
+ user-select: text;
595
+ -webkit-user-select: text;
596
+ -moz-user-select: text;
597
+ -ms-user-select: text;
598
+ }
599
+ .pdf-viewer-container {
600
+ display: flex;
601
+ flex-direction: column;
602
+ height: 100%;
603
+ width: 100%;
604
+ }
605
+ .pdf-viewer-main {
606
+ display: flex;
607
+ flex: 1;
608
+ overflow: hidden;
609
+ position: relative;
610
+ }
611
+ .pdf-viewer-viewer-area {
612
+ flex: 1;
613
+ overflow: hidden;
614
+ position: relative;
615
+ user-select: text;
616
+ -webkit-user-select: text;
617
+ -moz-user-select: text;
618
+ -ms-user-select: text;
619
+ }
620
+ .pdf-viewer-viewer-area * {
621
+ user-select: text !important;
622
+ -webkit-user-select: text !important;
623
+ -moz-user-select: text !important;
624
+ -ms-user-select: text !important;
625
+ }
626
+ `;
627
+ var PDFViewerContent = forwardRef((props, ref) => {
628
+ const {
629
+ file,
630
+ onLoad,
631
+ onError,
632
+ fileName,
633
+ showPageCount = true,
634
+ showPageNavigation = true,
635
+ showZoomControls = true,
636
+ showDownload = true,
637
+ showPrint = true,
638
+ showSearch = true,
639
+ showMetadata = true,
640
+ showProperties = true,
641
+ onMetadataClick,
642
+ onPropertiesClick,
643
+ onDownloadClick,
644
+ onPrintClick
645
+ } = props;
646
+ const [pdfBuffer, setPdfBuffer] = useState2(null);
647
+ const [state, setState] = useState2("idle");
648
+ const [error, setError] = useState2(null);
649
+ const pdfViewerRef = useRef2(null);
650
+ const resolvedFileName = useMemo(() => {
651
+ if (fileName) return fileName;
652
+ if (file instanceof File) return file.name;
653
+ if (typeof file === "string") {
654
+ const urlParts = file.split("/");
655
+ return urlParts[urlParts.length - 1] || "document.pdf";
656
+ }
657
+ return "document.pdf";
658
+ }, [file, fileName]);
659
+ const fileExtension = useMemo(
660
+ () => getFileExtension(resolvedFileName),
661
+ [resolvedFileName]
662
+ );
663
+ const [currentPage, setCurrentPage] = useState2(1);
664
+ const [totalPages, setTotalPages] = useState2(0);
665
+ const [zoom, setZoom] = useState2(100);
666
+ const [searchQuery, setSearchQuery] = useState2("");
667
+ const [isSearching, setIsSearching] = useState2(false);
668
+ const [pdfContainer, setPdfContainer] = useState2(null);
669
+ const [isSidebarOpen, setIsSidebarOpen] = useState2(false);
670
+ const [searchResults, setSearchResults] = useState2([]);
671
+ const [currentSearchResultIndex, setCurrentSearchResultIndex] = useState2(0);
672
+ const [totalSearchResults, setTotalSearchResults] = useState2(0);
673
+ useEffect(() => {
674
+ setSearchQuery("");
675
+ setSearchResults([]);
676
+ setCurrentSearchResultIndex(0);
677
+ setTotalSearchResults(0);
678
+ setIsSearching(false);
679
+ setIsSidebarOpen(false);
680
+ setCurrentPage(1);
681
+ setTotalPages(0);
682
+ setZoom(100);
683
+ setState("idle");
684
+ setError(null);
685
+ setPdfBuffer(null);
686
+ }, [file]);
687
+ useEffect(() => {
688
+ if (state === "ready") {
689
+ setTimeout(() => {
690
+ const container = document.querySelector('[data-pdf-viewer], .embedpdf-viewport, [role="document"]');
691
+ if (container) {
692
+ setPdfContainer(container);
693
+ }
694
+ }, 500);
695
+ }
696
+ }, [state]);
697
+ useEffect(() => {
698
+ if (state === "ready" && totalPages === 0) {
699
+ const initializePageCount = async () => {
700
+ let viewer = pdfViewerRef.current;
701
+ let retries = 0;
702
+ while (!viewer && retries < 10) {
703
+ await new Promise((resolve) => setTimeout(resolve, 500));
704
+ viewer = pdfViewerRef.current;
705
+ retries++;
706
+ }
707
+ if (!viewer) return;
708
+ await new Promise((resolve) => setTimeout(resolve, 1500));
709
+ try {
710
+ let count = viewer.navigation?.getTotalPages?.();
711
+ if (count && count > 1) {
712
+ setTotalPages(count);
713
+ return;
714
+ }
715
+ } catch (e) {
716
+ }
717
+ try {
718
+ const results = await viewer.search?.searchText?.("e");
719
+ if (results?.results && results.results.length > 0) {
720
+ const pageIndices = results.results.map((m) => m.pageIndex).filter((idx) => typeof idx === "number");
721
+ const count = Math.max(...pageIndices) + 1;
722
+ viewer.search?.stopSearch?.();
723
+ setTotalPages(count);
724
+ return;
725
+ }
726
+ } catch (error2) {
727
+ }
728
+ try {
729
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
730
+ const selectors = [
731
+ "[data-page-index]",
732
+ "[data-page-number]",
733
+ ".embedpdf-page",
734
+ '[role="article"]',
735
+ "canvas[data-page]",
736
+ ".react-pdf__Page"
737
+ ];
738
+ let pages = null;
739
+ for (const selector of selectors) {
740
+ pages = document.querySelectorAll(selector);
741
+ if (pages.length > 0) break;
742
+ }
743
+ if (pages && pages.length > 0) {
744
+ setTotalPages(pages.length);
745
+ return;
746
+ }
747
+ } catch (error2) {
748
+ }
749
+ setTotalPages(1);
750
+ };
751
+ initializePageCount();
752
+ }
753
+ }, [state, totalPages]);
754
+ useEffect(() => {
755
+ if (state === "ready" && pdfViewerRef.current) {
756
+ const updateInfo = () => {
757
+ const current = pdfViewerRef.current?.navigation.getCurrentPage() || 1;
758
+ const total = pdfViewerRef.current?.navigation.getTotalPages() || 0;
759
+ const zoomValue = pdfViewerRef.current?.zoom.getZoom();
760
+ const currentSearchState = pdfViewerRef.current?.search.getSearchState();
761
+ setCurrentPage(current);
762
+ if (total > 0 && total !== totalPages) {
763
+ setTotalPages(total);
764
+ }
765
+ if (typeof zoomValue === "number") {
766
+ setZoom(Math.round(zoomValue * 100));
767
+ }
768
+ };
769
+ updateInfo();
770
+ const interval = setInterval(updateInfo, 300);
771
+ return () => clearInterval(interval);
772
+ }
773
+ }, [state, totalPages]);
774
+ useImperativeHandle(ref, () => ({
775
+ zoomIn: () => {
776
+ pdfViewerRef.current?.zoom.zoomIn();
777
+ updateZoomDisplay();
778
+ },
779
+ zoomOut: () => {
780
+ pdfViewerRef.current?.zoom.zoomOut();
781
+ updateZoomDisplay();
782
+ },
783
+ setZoom: (level) => {
784
+ pdfViewerRef.current?.zoom.setZoom(level);
785
+ updateZoomDisplay();
786
+ },
787
+ resetZoom: () => {
788
+ pdfViewerRef.current?.zoom.resetZoom();
789
+ updateZoomDisplay();
790
+ },
791
+ getZoom: () => {
792
+ const zoom2 = pdfViewerRef.current?.zoom.getZoom();
793
+ return typeof zoom2 === "number" ? zoom2 : 1;
794
+ },
795
+ goToPage: (page) => {
796
+ pdfViewerRef.current?.navigation.goToPage(page);
797
+ setCurrentPage(page);
798
+ },
799
+ getCurrentPage: () => pdfViewerRef.current?.navigation.getCurrentPage() || 1,
800
+ getTotalPages: () => pdfViewerRef.current?.navigation.getTotalPages() || 0,
801
+ nextPage: () => {
802
+ pdfViewerRef.current?.navigation.nextPage();
803
+ updatePageDisplay();
804
+ },
805
+ previousPage: () => {
806
+ pdfViewerRef.current?.navigation.previousPage();
807
+ updatePageDisplay();
808
+ },
809
+ goToFirstPage: () => {
810
+ pdfViewerRef.current?.navigation.goToFirstPage();
811
+ updatePageDisplay();
812
+ },
813
+ goToLastPage: () => {
814
+ pdfViewerRef.current?.navigation.goToLastPage();
815
+ updatePageDisplay();
816
+ },
817
+ searchText: async (keyword) => {
818
+ setIsSearching(true);
819
+ const results = await pdfViewerRef.current?.search.searchText(keyword);
820
+ setIsSearching(false);
821
+ setSearchQuery(keyword);
822
+ return results;
823
+ },
824
+ nextResult: () => {
825
+ const index = pdfViewerRef.current?.search.nextResult() || -1;
826
+ return index;
827
+ },
828
+ previousResult: () => {
829
+ const index = pdfViewerRef.current?.search.previousResult() || -1;
830
+ return index;
831
+ },
832
+ goToResult: (index) => pdfViewerRef.current?.search.goToResult(index) || -1,
833
+ stopSearch: () => {
834
+ pdfViewerRef.current?.search.stopSearch();
835
+ setSearchQuery("");
836
+ },
837
+ getSearchState: () => pdfViewerRef.current?.search.getSearchState() || null,
838
+ getSelectedText: () => pdfViewerRef.current?.selection.getSelectedText() || "",
839
+ clearSelection: () => pdfViewerRef.current?.selection.clearSelection()
840
+ }), []);
841
+ const updatePageDisplay = () => {
842
+ setTimeout(() => {
843
+ const current = pdfViewerRef.current?.navigation.getCurrentPage() || 1;
844
+ setCurrentPage(current);
845
+ }, 100);
846
+ };
847
+ const updateZoomDisplay = () => {
848
+ setTimeout(() => {
849
+ const zoomValue = pdfViewerRef.current?.zoom.getZoom();
850
+ if (typeof zoomValue === "number") {
851
+ setZoom(Math.round(zoomValue * 100));
852
+ }
853
+ }, 100);
854
+ };
855
+ const handleZoomIn = () => {
856
+ pdfViewerRef.current?.zoom.zoomIn();
857
+ updateZoomDisplay();
858
+ };
859
+ const handleZoomOut = () => {
860
+ pdfViewerRef.current?.zoom.zoomOut();
861
+ updateZoomDisplay();
862
+ };
863
+ const handleFitToWidth = () => {
864
+ pdfViewerRef.current?.zoom.fitToWidth();
865
+ updateZoomDisplay();
866
+ };
867
+ const handleFitToPage = () => {
868
+ pdfViewerRef.current?.zoom.fitToPage();
869
+ updateZoomDisplay();
870
+ };
871
+ const handlePreviousPage = () => {
872
+ pdfViewerRef.current?.navigation.previousPage();
873
+ updatePageDisplay();
874
+ };
875
+ const handleNextPage = () => {
876
+ pdfViewerRef.current?.navigation.nextPage();
877
+ updatePageDisplay();
878
+ };
879
+ const handleFirstPage = () => {
880
+ pdfViewerRef.current?.navigation.goToFirstPage();
881
+ updatePageDisplay();
882
+ };
883
+ const handleLastPage = () => {
884
+ pdfViewerRef.current?.navigation.goToLastPage();
885
+ updatePageDisplay();
886
+ };
887
+ const handlePageInput = (e) => {
888
+ const value = e.target.value;
889
+ const page = parseInt(value, 10);
890
+ if (/^\d*$/.test(value)) {
891
+ return;
892
+ }
893
+ if (!isNaN(page) && page >= 1 && (totalPages === 0 || page <= totalPages)) {
894
+ pdfViewerRef.current?.navigation.goToPage(page);
895
+ setCurrentPage(page);
896
+ }
897
+ };
898
+ const handlePageInputKeyPress = (e) => {
899
+ if (e.key === "Enter") {
900
+ const value = e.target.value;
901
+ const page = parseInt(value, 10);
902
+ if (!isNaN(page) && page >= 1 && (totalPages === 0 || page <= totalPages)) {
903
+ pdfViewerRef.current?.navigation.goToPage(page);
904
+ setCurrentPage(page);
905
+ }
906
+ }
907
+ };
908
+ const handleSearch = async () => {
909
+ if (searchQuery.trim()) {
910
+ setIsSearching(true);
911
+ const results = await pdfViewerRef.current?.search.searchText(searchQuery);
912
+ setIsSearching(false);
913
+ if (results && results.results) {
914
+ const formattedResults = results.results.map((result, index) => {
915
+ let textContent = "";
916
+ let contextContent = "";
917
+ if (typeof result === "string") {
918
+ textContent = result;
919
+ contextContent = result;
920
+ } else if (result.text) {
921
+ textContent = String(result.text);
922
+ contextContent = result.context ? String(result.context) : String(result.text);
923
+ } else if (result.str) {
924
+ textContent = String(result.str);
925
+ contextContent = String(result.str);
926
+ } else if (result.match) {
927
+ textContent = String(result.match);
928
+ contextContent = String(result.match);
929
+ } else {
930
+ textContent = JSON.stringify(result);
931
+ contextContent = textContent;
932
+ }
933
+ return {
934
+ pageNumber: (result.pageIndex ?? result.pageNumber ?? 0) + 1,
935
+ text: textContent,
936
+ context: contextContent,
937
+ index
938
+ };
939
+ });
940
+ setSearchResults(formattedResults);
941
+ setTotalSearchResults(formattedResults.length);
942
+ setCurrentSearchResultIndex(0);
943
+ } else {
944
+ setSearchResults([]);
945
+ setTotalSearchResults(0);
946
+ setCurrentSearchResultIndex(0);
947
+ }
948
+ }
949
+ };
950
+ const handleSearchKeyPress = (e) => {
951
+ if (e.key === "Enter") {
952
+ handleSearch();
953
+ }
954
+ };
955
+ const handleSidebarSearch = async (keyword) => {
956
+ setSearchQuery(keyword);
957
+ if (keyword.trim()) {
958
+ setIsSearching(true);
959
+ const results = await pdfViewerRef.current?.search.searchText(keyword);
960
+ setIsSearching(false);
961
+ if (results && results.results) {
962
+ const formattedResults = results.results.map((result, index) => {
963
+ let textContent = "";
964
+ let contextContent = "";
965
+ if (result.context && typeof result.context === "object") {
966
+ const before = result.context.before || "";
967
+ const match = result.context.match || "";
968
+ const after = result.context.after || "";
969
+ textContent = match;
970
+ contextContent = `${before}${match}${after}`;
971
+ } else if (typeof result === "string") {
972
+ textContent = result;
973
+ contextContent = result;
974
+ } else {
975
+ textContent = String(result.match || result.text || "");
976
+ contextContent = textContent;
977
+ }
978
+ return {
979
+ pageNumber: (result.pageIndex ?? result.pageNumber ?? 0) + 1,
980
+ text: textContent,
981
+ context: contextContent,
982
+ index
983
+ };
984
+ });
985
+ setSearchResults(formattedResults);
986
+ setTotalSearchResults(formattedResults.length);
987
+ setCurrentSearchResultIndex(0);
988
+ if (formattedResults.length > 0) {
989
+ const firstPageNumber = formattedResults[0].pageNumber;
990
+ pdfViewerRef.current?.navigation.goToPage(firstPageNumber);
991
+ setCurrentPage(firstPageNumber);
992
+ }
993
+ } else {
994
+ setSearchResults([]);
995
+ setTotalSearchResults(0);
996
+ setCurrentSearchResultIndex(0);
997
+ }
998
+ } else {
999
+ setSearchResults([]);
1000
+ pdfViewerRef.current?.search.stopSearch();
1001
+ setTotalSearchResults(0);
1002
+ setCurrentSearchResultIndex(0);
1003
+ }
1004
+ };
1005
+ const handleSearchResultClick = (pageNumber, resultIndex) => {
1006
+ pdfViewerRef.current?.navigation.goToPage(pageNumber);
1007
+ setCurrentSearchResultIndex(resultIndex);
1008
+ setCurrentPage(pageNumber);
1009
+ pdfViewerRef.current?.search.goToResult(resultIndex);
1010
+ };
1011
+ const toggleSidebar = () => {
1012
+ setIsSidebarOpen(!isSidebarOpen);
1013
+ };
1014
+ const handleNextSearchResult = () => {
1015
+ if (currentSearchResultIndex < totalSearchResults - 1) {
1016
+ const nextIndex = currentSearchResultIndex + 1;
1017
+ setCurrentSearchResultIndex(nextIndex);
1018
+ pdfViewerRef.current?.search.nextResult();
1019
+ if (searchResults[nextIndex]) {
1020
+ const pageNumber = searchResults[nextIndex].pageNumber;
1021
+ pdfViewerRef.current?.navigation.goToPage(pageNumber);
1022
+ setCurrentPage(pageNumber);
1023
+ }
1024
+ }
1025
+ };
1026
+ const handlePreviousSearchResult = () => {
1027
+ if (currentSearchResultIndex > 0) {
1028
+ const prevIndex = currentSearchResultIndex - 1;
1029
+ setCurrentSearchResultIndex(prevIndex);
1030
+ pdfViewerRef.current?.search.previousResult();
1031
+ if (searchResults[prevIndex]) {
1032
+ const pageNumber = searchResults[prevIndex].pageNumber;
1033
+ pdfViewerRef.current?.navigation.goToPage(pageNumber);
1034
+ setCurrentPage(pageNumber);
1035
+ }
1036
+ }
1037
+ };
1038
+ const handleDownload = () => {
1039
+ if (onDownloadClick) {
1040
+ onDownloadClick();
1041
+ return;
1042
+ }
1043
+ if (!pdfBuffer) return;
1044
+ const blob = new Blob([pdfBuffer], { type: "application/pdf" });
1045
+ const url = URL.createObjectURL(blob);
1046
+ const link = document.createElement("a");
1047
+ link.href = url;
1048
+ link.download = resolvedFileName;
1049
+ document.body.appendChild(link);
1050
+ link.click();
1051
+ document.body.removeChild(link);
1052
+ URL.revokeObjectURL(url);
1053
+ };
1054
+ const handlePrint = () => {
1055
+ if (onPrintClick) {
1056
+ onPrintClick();
1057
+ return;
1058
+ }
1059
+ if (!pdfBuffer) return;
1060
+ const blob = new Blob([pdfBuffer], { type: "application/pdf" });
1061
+ const blobUrl = URL.createObjectURL(blob);
1062
+ const iframe = document.createElement("iframe");
1063
+ iframe.style.position = "fixed";
1064
+ iframe.style.right = "0";
1065
+ iframe.style.bottom = "0";
1066
+ iframe.style.width = "0";
1067
+ iframe.style.height = "0";
1068
+ iframe.style.border = "0";
1069
+ document.body.appendChild(iframe);
1070
+ iframe.onload = () => {
1071
+ try {
1072
+ setTimeout(() => {
1073
+ const iframeWindow = iframe.contentWindow;
1074
+ if (!iframeWindow) return;
1075
+ iframeWindow.focus();
1076
+ iframeWindow.print();
1077
+ const checkPrintComplete = () => {
1078
+ setTimeout(() => {
1079
+ try {
1080
+ document.body.removeChild(iframe);
1081
+ URL.revokeObjectURL(blobUrl);
1082
+ } catch (e) {
1083
+ }
1084
+ }, 500);
1085
+ };
1086
+ if ("onafterprint" in iframeWindow) {
1087
+ iframeWindow.onafterprint = checkPrintComplete;
1088
+ } else {
1089
+ setTimeout(checkPrintComplete, 3e3);
1090
+ }
1091
+ }, 500);
1092
+ } catch (error2) {
1093
+ document.body.removeChild(iframe);
1094
+ URL.revokeObjectURL(blobUrl);
1095
+ }
1096
+ };
1097
+ iframe.onerror = () => {
1098
+ document.body.removeChild(iframe);
1099
+ URL.revokeObjectURL(blobUrl);
1100
+ };
1101
+ iframe.src = blobUrl;
1102
+ };
1103
+ useEffect(() => {
1104
+ if (!file) {
1105
+ setState("error");
1106
+ setError("No file provided");
1107
+ return;
1108
+ }
1109
+ const loadPDF = async () => {
1110
+ try {
1111
+ setState("loading");
1112
+ setError(null);
1113
+ let arrayBuffer;
1114
+ if (file instanceof File) {
1115
+ arrayBuffer = await file.arrayBuffer();
1116
+ } else if (typeof file === "string") {
1117
+ const response = await fetch(file);
1118
+ if (!response.ok) {
1119
+ throw new Error(`Failed to load PDF: ${response.statusText}`);
1120
+ }
1121
+ arrayBuffer = await response.arrayBuffer();
1122
+ } else if (file instanceof ArrayBuffer) {
1123
+ arrayBuffer = file;
1124
+ } else {
1125
+ throw new Error("Unsupported file type");
1126
+ }
1127
+ setPdfBuffer(arrayBuffer);
1128
+ setState("ready");
1129
+ onLoad?.();
1130
+ } catch (err) {
1131
+ const errorMessage = err.message || "Failed to load PDF";
1132
+ setState("error");
1133
+ setError(errorMessage);
1134
+ onError?.(err);
1135
+ }
1136
+ };
1137
+ loadPDF();
1138
+ }, [file, onLoad, onError]);
1139
+ const handlePasswordRequest = useCallback(async (fileName2) => {
1140
+ const password = prompt(`This PDF is password protected.
1141
+ Enter password for ${fileName2 || "document"}:`);
1142
+ return password;
1143
+ }, []);
1144
+ if (state === "loading") {
1145
+ return /* @__PURE__ */ jsxs2("div", { style: {
1146
+ display: "flex",
1147
+ flexDirection: "column",
1148
+ alignItems: "center",
1149
+ justifyContent: "center",
1150
+ height: "100%",
1151
+ gap: "16px"
1152
+ }, children: [
1153
+ /* @__PURE__ */ jsx2("div", { className: "spinner", style: {
1154
+ width: "48px",
1155
+ height: "48px",
1156
+ border: "4px solid #f3f3f3",
1157
+ borderTop: "4px solid #3498db",
1158
+ borderRadius: "50%",
1159
+ animation: "spin 1s linear infinite"
1160
+ } }),
1161
+ /* @__PURE__ */ jsx2("p", { children: "Loading PDF..." }),
1162
+ /* @__PURE__ */ jsx2("style", { children: `
1163
+ @keyframes spin {
1164
+ 0% { transform: rotate(0deg); }
1165
+ 100% { transform: rotate(360deg); }
1166
+ }
1167
+ ` })
1168
+ ] });
1169
+ }
1170
+ if (state === "error" || error) {
1171
+ return /* @__PURE__ */ jsx2("div", { style: {
1172
+ display: "flex",
1173
+ flexDirection: "column",
1174
+ alignItems: "center",
1175
+ justifyContent: "center",
1176
+ height: "100%",
1177
+ padding: "24px"
1178
+ }, children: /* @__PURE__ */ jsxs2("div", { style: {
1179
+ maxWidth: "400px",
1180
+ padding: "16px",
1181
+ backgroundColor: "#fee",
1182
+ border: "1px solid #fcc",
1183
+ borderRadius: "4px"
1184
+ }, children: [
1185
+ /* @__PURE__ */ jsx2("h3", { style: { marginTop: 0 }, children: "Failed to Load PDF" }),
1186
+ /* @__PURE__ */ jsx2("p", { children: error || "Unknown error occurred" })
1187
+ ] }) });
1188
+ }
1189
+ if (!pdfBuffer || state !== "ready") {
1190
+ return /* @__PURE__ */ jsx2("div", { style: {
1191
+ display: "flex",
1192
+ alignItems: "center",
1193
+ justifyContent: "center",
1194
+ height: "100%"
1195
+ }, children: /* @__PURE__ */ jsx2("p", { children: "Preparing PDF..." }) });
1196
+ }
1197
+ return /* @__PURE__ */ jsxs2("div", { className: "pdf-viewer-container", children: [
1198
+ /* @__PURE__ */ jsx2("style", { children: toolbarStyles }),
1199
+ /* @__PURE__ */ jsxs2("div", { className: "pdf-viewer-header", children: [
1200
+ /* @__PURE__ */ jsx2(FileIcon_default, { ext: fileExtension, size: 26 }),
1201
+ /* @__PURE__ */ jsx2("div", { className: "header-file-name", title: resolvedFileName, children: resolvedFileName })
1202
+ ] }),
1203
+ /* @__PURE__ */ jsxs2("div", { className: "pdf-viewer-toolbar", children: [
1204
+ showPageNavigation && /* @__PURE__ */ jsxs2(Fragment, { children: [
1205
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-separator" }),
1206
+ /* @__PURE__ */ jsxs2("div", { className: "toolbar-section", children: [
1207
+ /* @__PURE__ */ jsx2(
1208
+ "button",
1209
+ {
1210
+ className: "toolbar-button",
1211
+ onClick: handleFirstPage,
1212
+ disabled: currentPage <= 1,
1213
+ title: "First Page",
1214
+ children: /* @__PURE__ */ jsx2(FirstPageIcon, { fontSize: "small" })
1215
+ }
1216
+ ),
1217
+ /* @__PURE__ */ jsx2(
1218
+ "button",
1219
+ {
1220
+ className: "toolbar-button",
1221
+ onClick: handlePreviousPage,
1222
+ disabled: currentPage <= 1,
1223
+ title: "Previous Page",
1224
+ children: /* @__PURE__ */ jsx2(ChevronLeftIcon, { fontSize: "small" })
1225
+ }
1226
+ ),
1227
+ /* @__PURE__ */ jsx2(
1228
+ "input",
1229
+ {
1230
+ type: "number",
1231
+ className: "page-input",
1232
+ value: currentPage,
1233
+ onChange: handlePageInput,
1234
+ onKeyPress: handlePageInputKeyPress,
1235
+ min: 1,
1236
+ max: totalPages || void 0
1237
+ }
1238
+ ),
1239
+ showPageCount && /* @__PURE__ */ jsxs2("span", { className: "page-info", children: [
1240
+ "of ",
1241
+ totalPages || "..."
1242
+ ] }),
1243
+ /* @__PURE__ */ jsx2(
1244
+ "button",
1245
+ {
1246
+ className: "toolbar-button",
1247
+ onClick: handleNextPage,
1248
+ disabled: currentPage >= totalPages,
1249
+ title: "Next Page",
1250
+ children: /* @__PURE__ */ jsx2(ChevronRightIcon, { fontSize: "small" })
1251
+ }
1252
+ ),
1253
+ /* @__PURE__ */ jsx2(
1254
+ "button",
1255
+ {
1256
+ className: "toolbar-button",
1257
+ onClick: handleLastPage,
1258
+ disabled: currentPage >= totalPages,
1259
+ title: "Last Page",
1260
+ children: /* @__PURE__ */ jsx2(LastPageIcon, { fontSize: "small" })
1261
+ }
1262
+ )
1263
+ ] })
1264
+ ] }),
1265
+ showZoomControls && /* @__PURE__ */ jsxs2(Fragment, { children: [
1266
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-separator" }),
1267
+ /* @__PURE__ */ jsxs2("div", { className: "toolbar-section", children: [
1268
+ /* @__PURE__ */ jsx2(
1269
+ "button",
1270
+ {
1271
+ className: "toolbar-button",
1272
+ onClick: handleZoomOut,
1273
+ title: "Zoom Out",
1274
+ children: /* @__PURE__ */ jsx2(ZoomOutIcon, { fontSize: "small" })
1275
+ }
1276
+ ),
1277
+ /* @__PURE__ */ jsxs2("span", { className: "zoom-display", children: [
1278
+ zoom,
1279
+ "%"
1280
+ ] }),
1281
+ /* @__PURE__ */ jsx2(
1282
+ "button",
1283
+ {
1284
+ className: "toolbar-button",
1285
+ onClick: handleZoomIn,
1286
+ title: "Zoom In",
1287
+ children: /* @__PURE__ */ jsx2(ZoomInIcon, { fontSize: "small" })
1288
+ }
1289
+ ),
1290
+ /* @__PURE__ */ jsx2(
1291
+ "button",
1292
+ {
1293
+ className: "toolbar-button",
1294
+ onClick: handleFitToWidth,
1295
+ title: "Fit to Width",
1296
+ children: /* @__PURE__ */ jsx2(AspectRatioIcon, { fontSize: "small" })
1297
+ }
1298
+ ),
1299
+ /* @__PURE__ */ jsx2(
1300
+ "button",
1301
+ {
1302
+ className: "toolbar-button",
1303
+ onClick: handleFitToPage,
1304
+ title: "Fit to Page",
1305
+ children: /* @__PURE__ */ jsx2(FitScreenIcon, { fontSize: "small" })
1306
+ }
1307
+ )
1308
+ ] })
1309
+ ] }),
1310
+ showSearch && /* @__PURE__ */ jsxs2(Fragment, { children: [
1311
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-separator" }),
1312
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-section", children: /* @__PURE__ */ jsx2(
1313
+ "button",
1314
+ {
1315
+ className: "toolbar-button",
1316
+ onClick: toggleSidebar,
1317
+ title: "Search in PDF",
1318
+ style: {
1319
+ backgroundColor: isSidebarOpen ? "#e3f2fd" : "transparent",
1320
+ color: isSidebarOpen ? "#1976d2" : "inherit"
1321
+ },
1322
+ children: /* @__PURE__ */ jsx2(SearchIcon2, { fontSize: "small" })
1323
+ }
1324
+ ) })
1325
+ ] }),
1326
+ (showMetadata || showProperties || showDownload || showPrint) && /* @__PURE__ */ jsxs2(Fragment, { children: [
1327
+ /* @__PURE__ */ jsx2("div", { className: "toolbar-separator" }),
1328
+ /* @__PURE__ */ jsxs2("div", { className: "toolbar-section", children: [
1329
+ showDownload && /* @__PURE__ */ jsx2(
1330
+ "button",
1331
+ {
1332
+ className: "toolbar-button",
1333
+ onClick: onDownloadClick,
1334
+ title: "Download PDF",
1335
+ children: /* @__PURE__ */ jsx2(DownloadIcon, { fontSize: "small" })
1336
+ }
1337
+ ),
1338
+ showPrint && /* @__PURE__ */ jsx2(
1339
+ "button",
1340
+ {
1341
+ className: "toolbar-button",
1342
+ onClick: onPrintClick,
1343
+ title: "Print PDF",
1344
+ children: /* @__PURE__ */ jsx2(PrintIcon, { fontSize: "small" })
1345
+ }
1346
+ ),
1347
+ showMetadata && /* @__PURE__ */ jsx2(
1348
+ "button",
1349
+ {
1350
+ className: "toolbar-button",
1351
+ onClick: onMetadataClick,
1352
+ title: "Document Metadata",
1353
+ children: /* @__PURE__ */ jsx2(InfoIcon, { fontSize: "small" })
1354
+ }
1355
+ ),
1356
+ showProperties && /* @__PURE__ */ jsx2(
1357
+ "button",
1358
+ {
1359
+ className: "toolbar-button",
1360
+ onClick: onPropertiesClick,
1361
+ title: "Document Properties",
1362
+ children: /* @__PURE__ */ jsx2(DescriptionIcon, { fontSize: "small" })
1363
+ }
1364
+ )
1365
+ ] })
1366
+ ] })
1367
+ ] }),
1368
+ /* @__PURE__ */ jsxs2("div", { className: "pdf-viewer-main", children: [
1369
+ /* @__PURE__ */ jsx2("div", { className: "pdf-viewer-viewer-area", children: React2.createElement(HeadlessPDFViewer, {
1370
+ ref: pdfViewerRef,
1371
+ pdfBuffer,
1372
+ onPasswordRequest: handlePasswordRequest
1373
+ }) }),
1374
+ /* @__PURE__ */ jsx2(
1375
+ SearchSidebar,
1376
+ {
1377
+ isOpen: isSidebarOpen,
1378
+ onClose: () => setIsSidebarOpen(false),
1379
+ onSearch: handleSidebarSearch,
1380
+ onSearchResultClick: handleSearchResultClick,
1381
+ onNextResult: handleNextSearchResult,
1382
+ onPreviousResult: handlePreviousSearchResult,
1383
+ currentResultIndex: currentSearchResultIndex,
1384
+ totalResults: totalSearchResults,
1385
+ searchKeyword: searchQuery,
1386
+ searchResults,
1387
+ isSearching
1388
+ }
1389
+ )
1390
+ ] })
1391
+ ] });
1392
+ });
1393
+ PDFViewerContent.displayName = "PDFViewerContent";
1394
+ var PDFViewer = forwardRef((props, ref) => {
1395
+ return /* @__PURE__ */ jsx2(PDFViewerContent, { ...props, sourceDescription: "doc.pdf", ref });
1396
+ });
1397
+ PDFViewer.displayName = "PDFViewer";
1398
+
1399
+ export {
1400
+ PDFViewer
1401
+ };
1402
+ //# sourceMappingURL=chunk-73ZIFR3P.mjs.map