@cannyminds/dms-file-viewers 0.6.0 → 0.7.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.
@@ -233,8 +233,15 @@ var ImageViewer = ({
233
233
  setIsFullScreen(false);
234
234
  }
235
235
  };
236
+ const handleFullscreenChange = () => {
237
+ setIsFullScreen(!!document.fullscreenElement);
238
+ };
236
239
  window.addEventListener("keydown", handleKeyDown);
237
- return () => window.removeEventListener("keydown", handleKeyDown);
240
+ document.addEventListener("fullscreenchange", handleFullscreenChange);
241
+ return () => {
242
+ window.removeEventListener("keydown", handleKeyDown);
243
+ document.removeEventListener("fullscreenchange", handleFullscreenChange);
244
+ };
238
245
  }, [isFullScreen]);
239
246
  if (!src) {
240
247
  return /* @__PURE__ */ jsxs3("div", { className: "pdf-viewer-container", style: { width, height, ...style }, children: [
@@ -250,7 +257,7 @@ var ImageViewer = ({
250
257
  const displayHeight = rotated ? imageSize.width : imageSize.height;
251
258
  const scaledWidth = displayWidth * (zoom / 100);
252
259
  const scaledHeight = displayHeight * (zoom / 100);
253
- return /* @__PURE__ */ jsxs3("div", { className: "pdf-viewer-container", style: { width, height, ...style }, children: [
260
+ return /* @__PURE__ */ jsxs3("div", { ref: containerRef, className: "pdf-viewer-container", style: { width, height, ...style }, children: [
254
261
  /* @__PURE__ */ jsx3("style", { children: toolbarStyles }),
255
262
  /* @__PURE__ */ jsx3(ImageHeader, { fileName: displayName, fileExtension: ext }),
256
263
  /* @__PURE__ */ jsx3(
@@ -331,4 +338,4 @@ var ImageViewer = ({
331
338
  export {
332
339
  ImageViewer
333
340
  };
334
- //# sourceMappingURL=chunk-U4W524VZ.mjs.map
341
+ //# sourceMappingURL=chunk-57BAESSV.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/viewers/ImageViewer.tsx","../src/components/viewers/image/ImageToolbar.tsx","../src/components/viewers/image/ImageHeader.tsx"],"sourcesContent":["import React, { useRef, useState, useMemo, useEffect } from 'react';\r\nimport { ImageToolbar } from './image/ImageToolbar';\r\nimport { ImageHeader } from './image/ImageHeader';\r\nimport { toolbarStyles } from './pdf/PDFStyles';\r\nimport { FileViewerProps } from '../../types';\r\nimport { mergeToolbarConfig } from '../../utils/toolbarUtils';\r\n\r\nexport const ImageViewer: React.FC<FileViewerProps> = ({\r\n file,\r\n url,\r\n fileName,\r\n width = '100%',\r\n height = '100%',\r\n className = '',\r\n style = {},\r\n showDownload = true,\r\n showPrint = true,\r\n showMetadata = false,\r\n showProperties = false,\r\n onDownloadClick,\r\n onPrintClick,\r\n onMetadataClick,\r\n onPropertiesClick,\r\n // Extract props that shouldn't be passed to DOM elements\r\n mimeType,\r\n fileSize,\r\n showPageCount,\r\n showPageNavigation,\r\n showZoomControls,\r\n showSearch,\r\n customRegistry,\r\n initialSearchText,\r\n initialSearchPages,\r\n autoOpenSearch,\r\n autoExecuteSearch,\r\n onSearchComplete,\r\n toolbarActions,\r\n ...props\r\n}) => {\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const imageAreaRef = useRef<HTMLDivElement>(null);\r\n const [imageSize, setImageSize] = useState({ width: 0, height: 0 });\r\n const [zoom, setZoom] = useState(100);\r\n const [rotation, setRotation] = useState(0);\r\n const [pendingFit, setPendingFit] = useState<'width' | 'page' | null>(null);\r\n const didAutoFit = useRef(false);\r\n const [isDragging, setIsDragging] = useState(false);\r\n const [dragStart, setDragStart] = useState({ x: 0, y: 0 });\r\n const [scrollStart, setScrollStart] = useState({ left: 0, top: 0 });\r\n const [isFullScreen, setIsFullScreen] = useState(false);\r\n\r\n const src = useMemo(() => {\r\n if (file) {\r\n const objectUrl = URL.createObjectURL(file);\r\n return objectUrl;\r\n }\r\n return url || '';\r\n }, [file, url]);\r\n\r\n useEffect(() => {\r\n return () => {\r\n if (file && src) {\r\n URL.revokeObjectURL(src);\r\n }\r\n };\r\n }, [file, src]);\r\n\r\n const handleImageLoad = (e: React.SyntheticEvent<HTMLImageElement>) => {\r\n const img = e.currentTarget;\r\n setImageSize({ width: img.naturalWidth, height: img.naturalHeight });\r\n if (!didAutoFit.current) {\r\n setPendingFit('page');\r\n didAutoFit.current = true;\r\n }\r\n };\r\n\r\n useEffect(() => {\r\n if (!imageAreaRef.current || !imageSize.width || !imageSize.height || !pendingFit) return;\r\n \r\n const containerWidth = imageAreaRef.current.offsetWidth;\r\n const containerHeight = imageAreaRef.current.offsetHeight;\r\n const rot = rotation % 360;\r\n const rotated = rot === 90 || rot === 270;\r\n const imgW = rotated ? imageSize.height : imageSize.width;\r\n const imgH = rotated ? imageSize.width : imageSize.height;\r\n\r\n if (pendingFit === 'width') {\r\n setZoom(Math.round((containerWidth / imgW) * 100));\r\n } else if (pendingFit === 'page') {\r\n const scaleW = containerWidth / imgW;\r\n const scaleH = containerHeight / imgH;\r\n setZoom(Math.round(Math.min(scaleW, scaleH) * 100));\r\n }\r\n setPendingFit(null);\r\n }, [pendingFit, imageSize, rotation]);\r\n\r\n const handleZoomIn = () => setZoom(z => Math.min(z + 10, 400));\r\n const handleZoomOut = () => setZoom(z => Math.max(z - 10, 10));\r\n const handleFitToWidth = () => setPendingFit('width');\r\n const handleFitToPage = () => setPendingFit('page');\r\n const handleRotateLeft = () => setRotation(r => (r - 90 + 360) % 360);\r\n const handleRotateRight = () => setRotation(r => (r + 90) % 360);\r\n \r\n const handleToggleFullScreen = () => {\r\n if (!isFullScreen && containerRef.current?.requestFullscreen) {\r\n containerRef.current.requestFullscreen();\r\n setIsFullScreen(true);\r\n } else if (isFullScreen && document.exitFullscreen) {\r\n document.exitFullscreen();\r\n setIsFullScreen(false);\r\n }\r\n };\r\n\r\n const handleMouseDown = (e: React.MouseEvent) => {\r\n if (imageAreaRef.current) {\r\n setIsDragging(true);\r\n setDragStart({ x: e.clientX, y: e.clientY });\r\n setScrollStart({\r\n left: imageAreaRef.current.scrollLeft,\r\n top: imageAreaRef.current.scrollTop,\r\n });\r\n }\r\n };\r\n\r\n const handleMouseMove = (e: React.MouseEvent) => {\r\n if (!isDragging || !imageAreaRef.current) return;\r\n const dx = e.clientX - dragStart.x;\r\n const dy = e.clientY - dragStart.y;\r\n imageAreaRef.current.scrollLeft = scrollStart.left - dx;\r\n imageAreaRef.current.scrollTop = scrollStart.top - dy;\r\n };\r\n\r\n const handleMouseUp = () => setIsDragging(false);\r\n const handleMouseLeave = () => setIsDragging(false);\r\n\r\n const toolbar = mergeToolbarConfig({ \r\n showDownload, \r\n showPrint, \r\n showMetadata, \r\n showProperties, \r\n onDownloadClick, \r\n onPrintClick, \r\n onMetadataClick, \r\n onPropertiesClick, \r\n toolbarActions \r\n });\r\n\r\n useEffect(() => {\r\n const handleKeyDown = (e: KeyboardEvent) => {\r\n if (e.key === '+') setZoom(z => Math.min(z + 10, 400));\r\n if (e.key === '-') setZoom(z => Math.max(z - 10, 10));\r\n if (e.key === 'r') setRotation(r => (r + 90) % 360);\r\n if (e.key === 'R') setRotation(r => (r - 90 + 360) % 360);\r\n if (e.key === 'Escape' && isFullScreen && document.exitFullscreen) {\r\n document.exitFullscreen();\r\n setIsFullScreen(false);\r\n }\r\n };\r\n\r\n const handleFullscreenChange = () => {\r\n setIsFullScreen(!!document.fullscreenElement);\r\n };\r\n\r\n window.addEventListener('keydown', handleKeyDown);\r\n document.addEventListener('fullscreenchange', handleFullscreenChange);\r\n\r\n return () => {\r\n window.removeEventListener('keydown', handleKeyDown);\r\n document.removeEventListener('fullscreenchange', handleFullscreenChange);\r\n };\r\n }, [isFullScreen]);\r\n\r\n if (!src) {\r\n return (\r\n <div className=\"pdf-viewer-container\" style={{ width, height, ...style }}>\r\n <style>{toolbarStyles}</style>\r\n <div style={{ height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#666' }}>\r\n <strong>No image source provided</strong>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n const displayName = fileName || file?.name || 'image';\r\n const ext = displayName.split('.').pop() || '';\r\n\r\n const rot = rotation % 360;\r\n const rotated = rot === 90 || rot === 270;\r\n const displayWidth = rotated ? imageSize.height : imageSize.width;\r\n const displayHeight = rotated ? imageSize.width : imageSize.height;\r\n const scaledWidth = displayWidth * (zoom / 100);\r\n const scaledHeight = displayHeight * (zoom / 100);\r\n\r\n return (\r\n <div ref={containerRef} className=\"pdf-viewer-container\" style={{ width, height, ...style }}>\r\n <style>{toolbarStyles}</style>\r\n <ImageHeader fileName={displayName} fileExtension={ext} />\r\n <ImageToolbar\r\n zoom={zoom}\r\n rotation={rotation}\r\n onZoomIn={handleZoomIn}\r\n onZoomOut={handleZoomOut}\r\n onFitToWidth={handleFitToWidth}\r\n onFitToPage={handleFitToPage}\r\n onRotateLeft={handleRotateLeft}\r\n onRotateRight={handleRotateRight}\r\n onToggleFullScreen={handleToggleFullScreen}\r\n showDownload={!toolbar.isHidden('download')}\r\n showPrint={!toolbar.isHidden('print')}\r\n showMetadata={!toolbar.isHidden('metadata')}\r\n showProperties={!toolbar.isHidden('properties')}\r\n disabledDownload={toolbar.isDisabled('download')}\r\n disabledPrint={toolbar.isDisabled('print')}\r\n disabledMetadata={toolbar.isDisabled('metadata')}\r\n disabledProperties={toolbar.isDisabled('properties')}\r\n onDownloadClick={toolbar.getHandler('download', onDownloadClick)}\r\n onPrintClick={toolbar.getHandler('print', onPrintClick)}\r\n onMetadataClick={toolbar.getHandler('metadata', onMetadataClick)}\r\n onPropertiesClick={toolbar.getHandler('properties', onPropertiesClick)}\r\n />\r\n <div \r\n ref={imageAreaRef}\r\n className=\"pdf-viewer-content\"\r\n style={{\r\n cursor: isDragging ? 'grabbing' : 'grab',\r\n overflow: 'auto',\r\n background: '#f5f5f5'\r\n }}\r\n onMouseDown={handleMouseDown}\r\n onMouseMove={handleMouseMove}\r\n onMouseUp={handleMouseUp}\r\n onMouseLeave={handleMouseLeave}\r\n >\r\n <div style={{\r\n minWidth: `${scaledWidth}px`,\r\n minHeight: `${scaledHeight}px`,\r\n width: `${scaledWidth}px`,\r\n height: `${scaledHeight}px`,\r\n margin: 'auto',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n position: 'relative',\r\n }}>\r\n <img\r\n src={src}\r\n alt={displayName}\r\n onLoad={handleImageLoad}\r\n crossOrigin=\"anonymous\"\r\n style={{\r\n transform: `rotate(${rotation}deg)`,\r\n transformOrigin: 'center center',\r\n maxWidth: '100%',\r\n maxHeight: '100%',\r\n width: '100%',\r\n height: '100%',\r\n objectFit: 'contain',\r\n pointerEvents: 'none',\r\n userSelect: 'none',\r\n }}\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\nimport ZoomInIcon from '@mui/icons-material/ZoomIn';\r\nimport ZoomOutIcon from '@mui/icons-material/ZoomOut';\r\nimport RotateLeftIcon from '@mui/icons-material/RotateLeft';\r\nimport RotateRightIcon from '@mui/icons-material/RotateRight';\r\nimport FitScreenIcon from '@mui/icons-material/FitScreen';\r\nimport AspectRatioIcon from '@mui/icons-material/AspectRatio';\r\nimport FullscreenIcon from '@mui/icons-material/Fullscreen';\r\nimport DownloadIcon from '@mui/icons-material/Download';\r\nimport PrintIcon from '@mui/icons-material/Print';\r\nimport InfoIcon from '@mui/icons-material/Info';\r\nimport DescriptionIcon from '@mui/icons-material/Description';\r\n\r\ninterface ImageToolbarProps {\r\n zoom: number;\r\n rotation: number;\r\n onZoomIn: () => void;\r\n onZoomOut: () => void;\r\n onFitToWidth: () => void;\r\n onFitToPage: () => void;\r\n onRotateLeft: () => void;\r\n onRotateRight: () => void;\r\n onToggleFullScreen: () => void;\r\n showDownload: boolean;\r\n showPrint: boolean;\r\n showMetadata: boolean;\r\n showProperties: boolean;\r\n disabledDownload?: boolean;\r\n disabledPrint?: boolean;\r\n disabledMetadata?: boolean;\r\n disabledProperties?: boolean;\r\n onDownloadClick?: () => void;\r\n onPrintClick?: () => void;\r\n onMetadataClick?: () => void;\r\n onPropertiesClick?: () => void;\r\n}\r\n\r\nexport const ImageToolbar = React.memo<ImageToolbarProps>(({ \r\n zoom,\r\n rotation,\r\n onZoomIn,\r\n onZoomOut,\r\n onFitToWidth,\r\n onFitToPage,\r\n onRotateLeft,\r\n onRotateRight,\r\n onToggleFullScreen,\r\n showDownload,\r\n showPrint,\r\n showMetadata,\r\n showProperties,\r\n disabledDownload,\r\n disabledPrint,\r\n disabledMetadata,\r\n disabledProperties,\r\n onDownloadClick,\r\n onPrintClick,\r\n onMetadataClick,\r\n onPropertiesClick,\r\n}) => (\r\n <div className=\"pdf-viewer-toolbar\">\r\n <div className=\"toolbar-separator\"></div>\r\n <div className=\"toolbar-section\">\r\n <button className=\"toolbar-button\" onClick={onZoomOut} title=\"Zoom Out\">\r\n <ZoomOutIcon fontSize=\"small\" />\r\n </button>\r\n <span className=\"zoom-display\">{zoom}%</span>\r\n <button className=\"toolbar-button\" onClick={onZoomIn} title=\"Zoom In\">\r\n <ZoomInIcon fontSize=\"small\" />\r\n </button>\r\n <button className=\"toolbar-button\" onClick={onFitToWidth} title=\"Fit to Width\">\r\n <AspectRatioIcon fontSize=\"small\" />\r\n </button>\r\n <button className=\"toolbar-button\" onClick={onFitToPage} title=\"Fit to Page\">\r\n <FitScreenIcon fontSize=\"small\" />\r\n </button>\r\n </div>\r\n <div className=\"toolbar-separator\"></div>\r\n <div className=\"toolbar-section\">\r\n <button className=\"toolbar-button\" onClick={onRotateLeft} title=\"Rotate Left\">\r\n <RotateLeftIcon fontSize=\"small\" />\r\n </button>\r\n <button className=\"toolbar-button\" onClick={onRotateRight} title=\"Rotate Right\">\r\n <RotateRightIcon fontSize=\"small\" />\r\n </button>\r\n <span className=\"page-info\">Rotation: {rotation}°</span>\r\n </div>\r\n <div className=\"toolbar-separator\"></div>\r\n <div className=\"toolbar-section\">\r\n <button className=\"toolbar-button\" onClick={onToggleFullScreen} title=\"Fullscreen\">\r\n <FullscreenIcon fontSize=\"small\" />\r\n </button>\r\n </div>\r\n {(showDownload || showPrint || showMetadata || showProperties) && (\r\n <>\r\n <div className=\"toolbar-separator\"></div>\r\n <div className=\"toolbar-section\">\r\n {showDownload && (\r\n <button className=\"toolbar-button\" onClick={onDownloadClick} disabled={disabledDownload} title=\"Download Image\">\r\n <DownloadIcon fontSize=\"small\" />\r\n </button>\r\n )}\r\n {showPrint && (\r\n <button className=\"toolbar-button\" onClick={onPrintClick} disabled={disabledPrint} title=\"Print Image\">\r\n <PrintIcon fontSize=\"small\" />\r\n </button>\r\n )}\r\n {showMetadata && (\r\n <button className=\"toolbar-button\" onClick={onMetadataClick} disabled={disabledMetadata} title=\"Image Metadata\">\r\n <DescriptionIcon fontSize=\"small\" />\r\n </button>\r\n )}\r\n {showProperties && (\r\n <button className=\"toolbar-button\" onClick={onPropertiesClick} disabled={disabledProperties} title=\"Image Properties\">\r\n <InfoIcon fontSize=\"small\" />\r\n </button>\r\n )}\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n));\r\n\r\nImageToolbar.displayName = 'ImageToolbar';\r\n","import React from 'react';\r\nimport FileIcon from '../../FileIcon';\r\n\r\ninterface ImageHeaderProps {\r\n fileName: string;\r\n fileExtension: string;\r\n}\r\n\r\nexport const ImageHeader = React.memo<ImageHeaderProps>(({ fileName, fileExtension }) => {\r\n return (\r\n <div className=\"pdf-viewer-header\">\r\n <FileIcon ext={fileExtension} size={26} />\r\n <div className=\"header-file-name\" title={fileName}>\r\n {fileName}\r\n </div>\r\n </div>\r\n );\r\n});\r\n\r\nImageHeader.displayName = 'ImageHeader';\r\n"],"mappings":"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","names":["React","jsx","jsxs","React","jsx","jsxs","rot","rotated"]}
@@ -286,7 +286,8 @@ import {
286
286
  TextField,
287
287
  IconButton,
288
288
  InputAdornment,
289
- Divider
289
+ Divider,
290
+ CircularProgress
290
291
  } from "@mui/material";
291
292
  import SearchIcon2 from "@mui/icons-material/Search";
292
293
  import CloseIcon from "@mui/icons-material/Close";
@@ -389,10 +390,10 @@ var SearchSidebar = ({
389
390
  }, []);
390
391
  useLayoutEffect(() => {
391
392
  setSearchTerm(searchKeyword || "");
392
- if (searchKeyword) {
393
+ if (searchKeyword || searchResults.length > 0) {
393
394
  setHasSearched(true);
394
395
  }
395
- }, [searchKeyword]);
396
+ }, [searchKeyword, searchResults]);
396
397
  const handleSearchSubmit = (e) => {
397
398
  if (e) e.preventDefault();
398
399
  if (searchTerm.trim()) {
@@ -608,7 +609,7 @@ var SearchSidebar = ({
608
609
  /* @__PURE__ */ jsx4(Typography, { variant: "body1", sx: { color: "text.primary", fontWeight: 500, mb: 1 }, children: "Search in Document" }),
609
610
  /* @__PURE__ */ jsx4(Typography, { variant: "body2", sx: { color: "text.secondary", lineHeight: 1.6 }, children: "Enter keywords to find text within the PDF document" })
610
611
  ] }),
611
- searchTerm && !hasSearched && /* @__PURE__ */ jsxs3(Box, { sx: { p: 4, textAlign: "center", mt: 6 }, children: [
612
+ searchTerm && !hasSearched && !isSearching && /* @__PURE__ */ jsxs3(Box, { sx: { p: 4, textAlign: "center", mt: 6 }, children: [
612
613
  /* @__PURE__ */ jsx4(
613
614
  Box,
614
615
  {
@@ -650,6 +651,27 @@ var SearchSidebar = ({
650
651
  }
651
652
  )
652
653
  ] }),
654
+ isSearching && /* @__PURE__ */ jsxs3(Box, { sx: { p: 4, textAlign: "center", mt: 6 }, children: [
655
+ /* @__PURE__ */ jsx4(
656
+ Box,
657
+ {
658
+ sx: {
659
+ display: "flex",
660
+ alignItems: "center",
661
+ justifyContent: "center",
662
+ margin: "0 auto",
663
+ mb: 3
664
+ },
665
+ children: /* @__PURE__ */ jsx4(CircularProgress, { size: 60, thickness: 4 })
666
+ }
667
+ ),
668
+ /* @__PURE__ */ jsx4(Typography, { variant: "body1", sx: { color: "text.primary", fontWeight: 500, mb: 1 }, children: "Searching..." }),
669
+ /* @__PURE__ */ jsxs3(Typography, { variant: "body2", sx: { color: "text.secondary", lineHeight: 1.6 }, children: [
670
+ 'Finding matches for "',
671
+ searchTerm,
672
+ '"'
673
+ ] })
674
+ ] }),
653
675
  hasSearched && totalResults === 0 && !isSearching && /* @__PURE__ */ jsxs3(Box, { sx: { p: 4, textAlign: "center", mt: 6 }, children: [
654
676
  /* @__PURE__ */ jsx4(
655
677
  Box,
@@ -984,6 +1006,14 @@ var PDFViewerContent = forwardRef((props, ref) => {
984
1006
  setIsFullScreen(false);
985
1007
  }
986
1008
  }, [isFullScreen]);
1009
+ const handleSidebarClose = useCallback(() => {
1010
+ setIsSidebarOpen(false);
1011
+ setSearchQuery("");
1012
+ setSearchResults([]);
1013
+ setTotalSearchResults(0);
1014
+ setCurrentSearchResultIndex(0);
1015
+ pdfViewerRef.current?.search.stopSearch();
1016
+ }, []);
987
1017
  const toolbar = mergeToolbarConfig({
988
1018
  showDownload,
989
1019
  showPrint,
@@ -1060,7 +1090,13 @@ var PDFViewerContent = forwardRef((props, ref) => {
1060
1090
  setCurrentPage(current);
1061
1091
  });
1062
1092
  },
1063
- toggleSidebar: () => setIsSidebarOpen(!isSidebarOpen),
1093
+ toggleSidebar: () => {
1094
+ if (isSidebarOpen) {
1095
+ handleSidebarClose();
1096
+ } else {
1097
+ setIsSidebarOpen(true);
1098
+ }
1099
+ },
1064
1100
  handlePageInput: (e) => {
1065
1101
  const value = e.target.value;
1066
1102
  if (/^\d*$/.test(value)) {
@@ -1085,21 +1121,31 @@ var PDFViewerContent = forwardRef((props, ref) => {
1085
1121
  handleToggleFullScreen
1086
1122
  }), [isSidebarOpen, totalPages, handleToggleFullScreen]);
1087
1123
  useEffect3(() => {
1088
- console.log("came", initialSearchText, pdfViewerRef.current, hasExecutedInitialSearch.current);
1089
- if (pdfViewerRef.current && !hasExecutedInitialSearch.current && initialSearchText) {
1090
- hasExecutedInitialSearch.current = true;
1091
- setIsSidebarOpen(true);
1092
- setSearchQuery(initialSearchText);
1093
- handleSidebarSearch(initialSearchText, initialSearchPages);
1094
- setAutoExecuteSearch(false);
1095
- pdfViewerRef.current.search.searchText(initialSearchText).then((results) => {
1096
- console.log("results", results);
1097
- if (results?.results?.length > 0) {
1098
- pdfViewerRef.current?.navigation.goToPage(results.results[0].pageIndex + 1);
1099
- }
1124
+ console.log("came", initialSearchText, pdfViewerRef.current, hasExecutedInitialSearch.current, "state:", state, "totalPages:", totalPages);
1125
+ if (!initialSearchText || hasExecutedInitialSearch.current) return;
1126
+ const isPDFReady = state === "ready";
1127
+ const isPagesInitialized = totalPages > 0;
1128
+ const isViewerAvailable = !!pdfViewerRef.current;
1129
+ const isSearchAPIReady = !!pdfViewerRef.current?.search?.searchText;
1130
+ const canExecuteSearch = isPDFReady && isPagesInitialized && isViewerAvailable && isSearchAPIReady;
1131
+ if (!canExecuteSearch) return;
1132
+ hasExecutedInitialSearch.current = true;
1133
+ const SEARCH_INITIALIZATION_DELAY = 10;
1134
+ setTimeout(() => {
1135
+ if (!pdfViewerRef.current?.search?.searchText) {
1136
+ console.warn("Search API became unavailable, skipping initial search");
1137
+ hasExecutedInitialSearch.current = false;
1138
+ return;
1139
+ }
1140
+ requestAnimationFrame(() => {
1141
+ requestAnimationFrame(() => {
1142
+ setIsSidebarOpen(true);
1143
+ handleSidebarSearch(initialSearchText, initialSearchPages);
1144
+ setAutoExecuteSearch(false);
1145
+ });
1100
1146
  });
1101
- }
1102
- }, [pdfViewerRef.current, initialSearchText]);
1147
+ }, SEARCH_INITIALIZATION_DELAY);
1148
+ }, [state, totalPages, pdfViewerRef.current, initialSearchText, initialSearchPages]);
1103
1149
  useEffect3(() => {
1104
1150
  setSearchQuery("");
1105
1151
  setSearchResults([]);
@@ -1107,6 +1153,7 @@ var PDFViewerContent = forwardRef((props, ref) => {
1107
1153
  setTotalSearchResults(0);
1108
1154
  setIsSearching(false);
1109
1155
  setIsSidebarOpen(false);
1156
+ hasExecutedInitialSearch.current = false;
1110
1157
  setCurrentPage(1);
1111
1158
  setTotalPages(0);
1112
1159
  setZoom(100);
@@ -1289,45 +1336,15 @@ var PDFViewerContent = forwardRef((props, ref) => {
1289
1336
  });
1290
1337
  };
1291
1338
  const handleSearch = async () => {
1292
- if (searchQuery.trim()) {
1293
- setIsSearching(true);
1294
- const results = await pdfViewerRef.current?.search.searchText(searchQuery);
1295
- setIsSearching(false);
1296
- if (results && results.results) {
1297
- const formattedResults = results.results.map((result, index) => {
1298
- let textContent = "";
1299
- let contextContent = "";
1300
- if (typeof result === "string") {
1301
- textContent = result;
1302
- contextContent = result;
1303
- } else if (result.text) {
1304
- textContent = String(result.text);
1305
- contextContent = result.context ? String(result.context) : String(result.text);
1306
- } else if (result.str) {
1307
- textContent = String(result.str);
1308
- contextContent = String(result.str);
1309
- } else if (result.match) {
1310
- textContent = String(result.match);
1311
- contextContent = String(result.match);
1312
- } else {
1313
- textContent = JSON.stringify(result);
1314
- contextContent = textContent;
1315
- }
1316
- return {
1317
- pageNumber: (result.pageIndex ?? result.pageNumber ?? 0) + 1,
1318
- text: textContent,
1319
- context: contextContent,
1320
- index
1321
- };
1322
- });
1323
- setSearchResults(formattedResults);
1324
- setTotalSearchResults(formattedResults.length);
1325
- setCurrentSearchResultIndex(0);
1326
- } else {
1327
- setSearchResults([]);
1328
- setTotalSearchResults(0);
1329
- setCurrentSearchResultIndex(0);
1330
- }
1339
+ if (!searchQuery.trim()) return;
1340
+ setIsSearching(true);
1341
+ const results = await pdfViewerRef.current?.search.searchText(searchQuery);
1342
+ setIsSearching(false);
1343
+ if (results?.results && Array.isArray(results.results) && results.results.length > 0) {
1344
+ const formattedResults = formatSearchResults(results.results);
1345
+ updateSearchState(formattedResults);
1346
+ } else {
1347
+ clearSearchResults();
1331
1348
  }
1332
1349
  };
1333
1350
  const handleSearchKeyPress = (e) => {
@@ -1337,66 +1354,92 @@ var PDFViewerContent = forwardRef((props, ref) => {
1337
1354
  };
1338
1355
  const handleSidebarSearch = async (keyword, pageNumbers) => {
1339
1356
  setSearchQuery(keyword);
1340
- if (keyword.trim()) {
1341
- setIsSearching(true);
1342
- const results = await pdfViewerRef.current?.search.searchText(keyword);
1357
+ if (!keyword.trim()) {
1358
+ setSearchResults([]);
1359
+ setTotalSearchResults(0);
1360
+ setCurrentSearchResultIndex(0);
1361
+ pdfViewerRef.current?.search.stopSearch();
1362
+ return;
1363
+ }
1364
+ if (!pdfViewerRef.current?.search?.searchText) {
1365
+ console.warn("Search functionality not yet available");
1366
+ return;
1367
+ }
1368
+ setIsSearching(true);
1369
+ try {
1370
+ const results = await pdfViewerRef.current.search.searchText(keyword);
1371
+ console.log("Search completed:", results);
1343
1372
  setIsSearching(false);
1344
- if (results && results.results && results.results.length > 0) {
1345
- const formattedResults = results.results.map((result, index) => {
1346
- let textContent = "";
1347
- let contextContent = "";
1348
- if (result.context && typeof result.context === "object") {
1349
- const before = result.context.before || "";
1350
- const match = result.context.match || "";
1351
- const after = result.context.after || "";
1352
- textContent = match;
1353
- contextContent = `${before}${match}${after}`;
1354
- } else if (typeof result === "string") {
1355
- textContent = result;
1356
- contextContent = result;
1357
- } else {
1358
- textContent = String(result.match || result.text || "");
1359
- contextContent = textContent;
1360
- }
1361
- return {
1362
- pageNumber: (result.pageIndex ?? result.pageNumber ?? 0) + 1,
1363
- text: textContent,
1364
- context: contextContent,
1365
- index
1366
- };
1367
- });
1368
- setSearchResults(formattedResults);
1369
- setTotalSearchResults(formattedResults.length);
1370
- setCurrentSearchResultIndex(0);
1371
- if (formattedResults.length > 0) {
1372
- const firstPageNumber = formattedResults[0].pageNumber;
1373
- pdfViewerRef.current?.navigation.goToPage(firstPageNumber);
1374
- setCurrentPage(firstPageNumber);
1375
- }
1373
+ const hasValidResults = results?.results && Array.isArray(results.results) && results.results.length > 0;
1374
+ if (hasValidResults) {
1375
+ const formattedResults = formatSearchResults(results.results);
1376
+ updateSearchState(formattedResults);
1377
+ navigateToFirstResult(formattedResults);
1376
1378
  } else if (pageNumbers && pageNumbers.length > 0) {
1377
- const fallbackResults = pageNumbers.map((pageNum, index) => ({
1378
- pageNumber: pageNum,
1379
- text: keyword,
1380
- context: `"${keyword}" found on this page ${pageNum}`,
1381
- index
1382
- }));
1383
- setSearchResults(fallbackResults);
1384
- setTotalSearchResults(fallbackResults.length);
1385
- setCurrentSearchResultIndex(0);
1386
- pdfViewerRef.current?.navigation.goToPage(pageNumbers[0]);
1387
- setCurrentPage(pageNumbers[0]);
1379
+ const fallbackResults = createFallbackResults(pageNumbers, keyword);
1380
+ updateSearchState(fallbackResults);
1381
+ navigateToPage(pageNumbers[0]);
1388
1382
  } else {
1389
- setSearchResults([]);
1390
- setTotalSearchResults(0);
1391
- setCurrentSearchResultIndex(0);
1383
+ clearSearchResults();
1392
1384
  }
1393
- } else {
1394
- setSearchResults([]);
1395
- pdfViewerRef.current?.search.stopSearch();
1396
- setTotalSearchResults(0);
1397
- setCurrentSearchResultIndex(0);
1385
+ } catch (error2) {
1386
+ console.error("Search failed:", error2);
1387
+ setIsSearching(false);
1388
+ clearSearchResults();
1398
1389
  }
1399
1390
  };
1391
+ const formatSearchResults = (results) => {
1392
+ return results.map((result, index) => {
1393
+ let textContent = "";
1394
+ let contextContent = "";
1395
+ if (result.context && typeof result.context === "object") {
1396
+ const { before = "", match = "", after = "" } = result.context;
1397
+ textContent = match;
1398
+ contextContent = `${before}${match}${after}`;
1399
+ } else if (typeof result === "string") {
1400
+ textContent = result;
1401
+ contextContent = result;
1402
+ } else {
1403
+ textContent = String(result.match || result.text || "");
1404
+ contextContent = textContent;
1405
+ }
1406
+ return {
1407
+ pageNumber: (result.pageIndex ?? result.pageNumber ?? 0) + 1,
1408
+ text: textContent,
1409
+ context: contextContent,
1410
+ index
1411
+ };
1412
+ });
1413
+ };
1414
+ const createFallbackResults = (pageNumbers, keyword) => {
1415
+ return pageNumbers.map((pageNum, index) => ({
1416
+ pageNumber: pageNum,
1417
+ text: keyword,
1418
+ context: `"${keyword}" found on this page ${pageNum}`,
1419
+ index
1420
+ }));
1421
+ };
1422
+ const updateSearchState = (results) => {
1423
+ setSearchResults(results);
1424
+ setTotalSearchResults(results.length);
1425
+ setCurrentSearchResultIndex(0);
1426
+ };
1427
+ const clearSearchResults = () => {
1428
+ setSearchResults([]);
1429
+ setTotalSearchResults(0);
1430
+ setCurrentSearchResultIndex(0);
1431
+ };
1432
+ const navigateToFirstResult = (results) => {
1433
+ if (results.length > 0) {
1434
+ navigateToPage(results[0].pageNumber);
1435
+ }
1436
+ };
1437
+ const navigateToPage = (pageNumber) => {
1438
+ requestAnimationFrame(() => {
1439
+ pdfViewerRef.current?.navigation.goToPage(pageNumber);
1440
+ setCurrentPage(pageNumber);
1441
+ });
1442
+ };
1400
1443
  const handleSearchResultClick = (pageNumber, resultIndex) => {
1401
1444
  pdfViewerRef.current?.navigation.goToPage(pageNumber);
1402
1445
  setCurrentSearchResultIndex(resultIndex);
@@ -1598,7 +1641,7 @@ var PDFViewerContent = forwardRef((props, ref) => {
1598
1641
  SearchSidebar,
1599
1642
  {
1600
1643
  isOpen: isSidebarOpen,
1601
- onClose: () => setIsSidebarOpen(false),
1644
+ onClose: handleSidebarClose,
1602
1645
  onSearch: handleSidebarSearch,
1603
1646
  onSearchResultClick: handleSearchResultClick,
1604
1647
  onNextResult: handleNextSearchResult,
@@ -1632,4 +1675,4 @@ PDFViewer.displayName = "PDFViewer";
1632
1675
  export {
1633
1676
  PDFViewer
1634
1677
  };
1635
- //# sourceMappingURL=chunk-ZKGWS327.mjs.map
1678
+ //# sourceMappingURL=chunk-HLDLNHNY.mjs.map