import React, { useEffect, useMemo, useState } from 'react'; import { createPluginRegistration } from '@embedpdf/core'; import { EmbedPDF } from '@embedpdf/core/react'; import { usePdfiumEngine } from '@embedpdf/engines/react'; // Import the essential plugins import { Viewport, ViewportPluginPackage } from '@embedpdf/plugin-viewport/react'; import { Scroller, ScrollPluginPackage, ScrollStrategy } from '@embedpdf/plugin-scroll/react'; import { LoaderPluginPackage } from '@embedpdf/plugin-loader/react'; import { RenderPluginPackage } from '@embedpdf/plugin-render/react'; import { ZoomPluginPackage } from '@embedpdf/plugin-zoom/react'; import { InteractionManagerPluginPackage, PagePointerProvider, GlobalPointerProvider } from '@embedpdf/plugin-interaction-manager/react'; import { SelectionLayer, SelectionPluginPackage } from '@embedpdf/plugin-selection/react'; import { TilingLayer, TilingPluginPackage } from '@embedpdf/plugin-tiling/react'; import { PanPluginPackage } from '@embedpdf/plugin-pan/react'; import { SpreadPluginPackage, SpreadMode } from '@embedpdf/plugin-spread/react'; import { SearchPluginPackage } from '@embedpdf/plugin-search/react'; import { ThumbnailPluginPackage } from '@embedpdf/plugin-thumbnail/react'; import { RotatePluginPackage, Rotate } from '@embedpdf/plugin-rotate/react'; import { Rotation } from '@embedpdf/models'; import { CustomSearchLayer } from './CustomSearchLayer'; import { ZoomAPIBridge } from './ZoomAPIBridge'; import ToolLoadingFallback from '../tools/ToolLoadingFallback'; import { Center, Stack, Text } from '@mantine/core'; import { ScrollAPIBridge } from './ScrollAPIBridge'; import { SelectionAPIBridge } from './SelectionAPIBridge'; import { PanAPIBridge } from './PanAPIBridge'; import { SpreadAPIBridge } from './SpreadAPIBridge'; import { SearchAPIBridge } from './SearchAPIBridge'; import { ThumbnailAPIBridge } from './ThumbnailAPIBridge'; import { RotateAPIBridge } from './RotateAPIBridge'; interface LocalEmbedPDFProps { file?: File | Blob; url?: string | null; } export function LocalEmbedPDF({ file, url }: LocalEmbedPDFProps) { const [pdfUrl, setPdfUrl] = useState(null); // Convert File to URL if needed useEffect(() => { if (file) { const objectUrl = URL.createObjectURL(file); setPdfUrl(objectUrl); return () => URL.revokeObjectURL(objectUrl); } else if (url) { setPdfUrl(url); } }, [file, url]); // Create plugins configuration const plugins = useMemo(() => { if (!pdfUrl) return []; return [ createPluginRegistration(LoaderPluginPackage, { loadingOptions: { type: 'url', pdfFile: { id: 'stirling-pdf-viewer', url: pdfUrl, }, }, }), createPluginRegistration(ViewportPluginPackage, { viewportGap: 10, }), createPluginRegistration(ScrollPluginPackage, { strategy: ScrollStrategy.Vertical, initialPage: 0, }), createPluginRegistration(RenderPluginPackage), // Register interaction manager (required for zoom and selection features) createPluginRegistration(InteractionManagerPluginPackage), // Register selection plugin (depends on InteractionManager) createPluginRegistration(SelectionPluginPackage), // Register pan plugin (depends on Viewport, InteractionManager) createPluginRegistration(PanPluginPackage, { defaultMode: 'mobile', // Try mobile mode which might be more permissive }), // Register zoom plugin with configuration createPluginRegistration(ZoomPluginPackage, { defaultZoomLevel: 1.4, // Start at 140% zoom for better readability minZoom: 0.2, maxZoom: 3.0, }), // Register tiling plugin (depends on Render, Scroll, Viewport) createPluginRegistration(TilingPluginPackage, { tileSize: 768, overlapPx: 5, extraRings: 1, }), // Register spread plugin for dual page layout createPluginRegistration(SpreadPluginPackage, { defaultSpreadMode: SpreadMode.None, // Start with single page view }), // Register search plugin for text search createPluginRegistration(SearchPluginPackage), // Register thumbnail plugin for page thumbnails createPluginRegistration(ThumbnailPluginPackage), // Register rotate plugin createPluginRegistration(RotatePluginPackage, { defaultRotation: Rotation.Degree0, // Start with no rotation }), ]; }, [pdfUrl]); // Initialize the engine with the React hook const { engine, isLoading, error } = usePdfiumEngine(); // Early return if no file or URL provided if (!file && !url) { return (
📄
No PDF provided
); } if (isLoading || !engine || !pdfUrl) { return ; } if (error) { return (
Error loading PDF engine: {error.message}
); } // Wrap your UI with the provider return (
(
e.preventDefault()} onDrop={(e) => e.preventDefault()} onDragOver={(e) => e.preventDefault()} > {/* High-resolution tile layer */} {/* Search highlight layer */} {/* Selection layer for text interaction */}
)} />
); }