|
|
"use client"; |
|
|
|
|
|
import { useCallback, useState } from "react"; |
|
|
import { pdfjs, Document, Page } from "react-pdf"; |
|
|
import "react-pdf/dist/esm/Page/AnnotationLayer.css"; |
|
|
import "react-pdf/dist/esm/Page/TextLayer.css"; |
|
|
import { useResizeObserver } from "@wojtekmaj/react-hooks"; |
|
|
|
|
|
import type { PDFDocumentProxy } from "pdfjs-dist"; |
|
|
import { |
|
|
Sheet, |
|
|
SheetContent, |
|
|
SheetHeader, |
|
|
SheetTitle, |
|
|
SheetTrigger, |
|
|
} from "./ui/sheet"; |
|
|
|
|
|
pdfjs.GlobalWorkerOptions.workerSrc = new URL( |
|
|
"pdfjs-dist/build/pdf.worker.min.mjs", |
|
|
import.meta.url |
|
|
).toString(); |
|
|
|
|
|
const options = { |
|
|
cMapUrl: "/cmaps/", |
|
|
standardFontDataUrl: "/standard_fonts/", |
|
|
}; |
|
|
|
|
|
export default function PdfViewer({ file }: { file: File }) { |
|
|
const [numPages, setNumPages] = useState<number>(); |
|
|
const [containerRef, setContainerRef] = useState<HTMLElement | null>(null); |
|
|
const [containerWidth, setContainerWidth] = useState<number>(); |
|
|
|
|
|
|
|
|
const onResize = useCallback<ResizeObserverCallback>((entries) => { |
|
|
const [entry] = entries; |
|
|
if (entry) { |
|
|
setContainerWidth(entry.contentRect.width); |
|
|
} |
|
|
}, []); |
|
|
|
|
|
useResizeObserver(containerRef, {}, onResize); |
|
|
|
|
|
async function onDocumentLoadSuccess(page: PDFDocumentProxy): Promise<void> { |
|
|
setNumPages(page._pdfInfo.numPages); |
|
|
} |
|
|
|
|
|
return ( |
|
|
<Sheet> |
|
|
<SheetTrigger className="h-10 rounded-lg px-4 py-2 border-input bg-background border-2 hover:bg-accent hover:text-accent-foreground"> |
|
|
Preview |
|
|
</SheetTrigger> |
|
|
<SheetContent side="bottom"> |
|
|
<SheetHeader> |
|
|
<SheetTitle>{file.name}</SheetTitle> |
|
|
</SheetHeader> |
|
|
<div |
|
|
ref={setContainerRef} |
|
|
className="max-w-2xl mx-auto mt-2 max-h-[calc(100vh-10rem)] overflow-y-auto" |
|
|
> |
|
|
<Document |
|
|
file={file} |
|
|
onLoadSuccess={onDocumentLoadSuccess} |
|
|
options={options} |
|
|
> |
|
|
{Array.from(new Array(numPages), (_el, index) => ( |
|
|
<Page |
|
|
key={`page_${index + 1}`} |
|
|
pageNumber={index + 1} |
|
|
width={containerWidth} |
|
|
/> |
|
|
))} |
|
|
</Document> |
|
|
</div> |
|
|
</SheetContent> |
|
|
</Sheet> |
|
|
); |
|
|
} |
|
|
|