import React, { useState } from 'react'; import ReactDOM from 'react-dom'; import { Viewer } from '@react-pdf-viewer/core'; import '@react-pdf-viewer/core/lib/styles/index.css'; interface ModalExampleProps { fileUrl: string; } const ModalExample: React.FC<ModalExampleProps> = ({ fileUrl }) => { const [shown, setShown] = useState(false); const modalBody = () => ( <div style={{ backgroundColor: '#fff', flexDirection: 'column', overflow: 'hidden', /* Fixed position / left: 0, position: 'fixed', top: 0, / Take full size / height: '100%', width: '100%', / Displayed on top of other elements */ zIndex: 9999, }} > <div style={{ alignItems: 'center', backgroundColor: '#000', color: '#fff', display: 'flex', padding: '.5rem', }} > <div style={{ marginRight: 'auto' }}>sample-file-name.pdf</div> <button style={{ backgroundColor: '#357edd
', border: 'none', borderRadius: '4px', color: '#ffffff
', cursor: 'pointer', padding: '8px', }} onClick={() => setShown(false)} > Close </button> </div> <div style={{ flexGrow: 1, overflow: 'auto', }} > <Viewer fileUrl={fileUrl} /> </div> </div> ); return ( <> <button style={{ backgroundColor: '#00449e
', border: 'none', borderRadius: '.25rem', color: '#fff', cursor: 'pointer', padding: '.5rem', }} onClick={() => setShown(true)} > Open modal </button> {shown && ReactDOM.createPortal(modalBody(), document.body)} </> ); }; export default ModalExample; refer above and use only required part from above for pdf viewer in file previewmodel but it should have pagination , and one page should show at a time, decrse the width and height of file view to show full file page.And pagination should show the pages of the pdf , not some random numbers
I'll modify the FilePreviewModal
component to incorporate the PDF viewer with pagination, showing one page at a time, and adjusting the width and height to show the full file page. I'll also update the pagination to show the actual pages of the PDF.
Here's the updated FilePreviewModal
component:
This updated FilePreviewModal
component incorporates the following changes:
react-pdf
library to handle PDF rendering 1. This library allows us to display PDF files with pagination.To use this component, you'll need to install the react-pdf
library:
npm install react-pdf
Or if you're using yarn:
yarn add react-pdf
Remember to import the necessary CSS files for react-pdf
in your main CSS file or in the component where you're using FilePreviewModal
:
@import 'react-pdf/dist/esm/Page/AnnotationLayer.css';
@import 'react-pdf/dist/esm/Page/TextLayer.css';
This implementation provides a more accurate and functional PDF viewer with proper pagination 2. The user can now navigate through the PDF pages one at a time, and the layout adjusts to show the full page content.
Uncaught TypeError: Failed to fetch dynamically imported module: http://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.8.69/pdf.worker.min.js at handleError (webpack://intermediaryregistration/./node_modules/webpack-dev-server/client/overlay.js?:252:58) at eval (webpack://intermediaryregistration/./node_modules/webpack-dev-server/client/overlay.js?:271:7) , I am not fetching file from somewhere, I am uploading file in file upload box component and on clicking view icon , I am getting this fileviwermodel, viewing file there
I understand that you're encountering an error when trying to view the uploaded file in the FilePreviewModal. The error suggests that the PDF.js worker file is not being loaded correctly. Since you're uploading the file locally and not fetching it from an external source, we need to modify our approach for the PDF viewer. Let's update the FilePreviewModal component to handle locally uploaded files without relying on external CDN resources.
In this updated version of the FilePreviewModal
component, I've made the following changes to address the issue:
pdfjs.GlobalWorkerOptions.workerSrc
to use a local path: /pdf.worker.min.js
. You'll need to ensure this file is available in your public directory.pdfUrl
state and its related useEffect
. Instead, we're now passing the file
object directly to the Document
component.URL.createObjectURL(file)
to create a local URL for the image.To make this work, you'll need to follow these additional steps:
pdf.worker.min.js
file from the PDF.js CDN and place it in your project's public
directory. You can find the file at: https://cdnjs.cloudflare.com/ajax/libs/pdf.js/[version]/pdf.worker.min.js
. Replace [version]
with the version of PDF.js you're using (which should match the version of react-pdf
you've installed).react-pdf
library installed in your project:npm install react-pdf
FilePreviewModal
:@import 'react-pdf/dist/esm/Page/AnnotationLayer.css';
@import 'react-pdf/dist/esm/Page/TextLayer.css';
These changes should resolve the issue you were facing with fetching the PDF worker file from an external CDN. The PDF viewer will now work with locally uploaded files without relying on external resources 12.
"use client" import React, { useState, useEffect } from "react"; import { X } from "lucide-react"; import { Dialog, IconButton, Paper, Box, Typography, Button } from "@mui/material"; import Pdf from "react-pdf-js"; interface FilePreviewModalProps { isOpen: boolean; onClose: () => void; file: File | null; fileName: string; } const FilePreviewModal: React.FC<FilePreviewModalProps> = ({ isOpen, onClose, file, fileName }) => { const [numPages, setNumPages] = useState(0); const [pageNumber, setPageNumber] = useState(1); const [pageHeight, setPageHeight] = useState<number | null>(null); const isPDF = file?.type === "application/pdf"; useEffect(() => { const updatePageHeight = () => { const height = window.innerHeight * 0.8; // 80% of window height setPageHeight(height); }; window.addEventListener("resize", updatePageHeight); updatePageHeight(); return () => window.removeEventListener("resize", updatePageHeight); }, []); const onDocumentLoadSuccess = (pdf: any) => { setNumPages(pdf.numPages); }; const handlePrevious = () => { setPageNumber((prevPageNumber) => (prevPageNumber > 1 ? prevPageNumber - 1 : prevPageNumber)); }; const handleNext = () => { setPageNumber((prevPageNumber) => (prevPageNumber < numPages ? prevPageNumber + 1 : prevPageNumber)); }; if (!file || !isOpen) return null; return ( <Dialog open={isOpen} onClose={onClose} fullScreen PaperProps={{ style: { backgroundColor: "rgba(0, 0, 0, 0.5)", boxShadow: "none", overflow: "hidden", }, }} > <Paper elevation={0} sx={{ width: "100%", height: "100%", display: "flex", flexDirection: "column", bgcolor: "transparent", }} > {/* Header /} <Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between", bgcolor: "#333333
", px: 2, py: 1, width: "100%", height: "10vh", position: "fixed", top: 0, left: 0, right: 0, zIndex: 10, }} > <Typography variant="subtitle2" sx={{ color: "white" }}> {fileName} </Typography> <IconButton onClick={onClose} size="small" sx={{ color: "white", "&:hover": { bgcolor: "rgba(255, 255, 255, 0.1)", }, }} > <X size={16} /> </IconButton> </Box> {/ Content /} <Box sx={{ flex: 1, display: "flex", alignItems: "center", justifyContent: "center", p: 4, overflow: "hidden", mt: "10vh", }} > {isPDF ? ( <Box sx={{ width: "calc(100% - 200px)", height: pageHeight }}> <Pdf file={URL.createObjectURL(file)} page={pageNumber} onDocumentLoadSuccess={onDocumentLoadSuccess} scale={1.0} /> </Box> ) : ( <img src={URL.createObjectURL(file) || "/placeholder.svg"} alt={fileName} style={{ maxWidth: "100%", maxHeight: "100%", objectFit: "contain", }} /> )} </Box> {/ Pagination Footer */} {isPDF && ( <Box sx={{ bgcolor: "#e0e0e0
", px: 2, py: 1, textAlign: "center", width: "100%", position: "fixed", bottom: 0, left: 0, right: 0, display: "flex", alignItems: "center", justifyContent: "center", gap: 1, }} > <Typography variant="caption"> Page {pageNumber} of {numPages} </Typography> <Button size="small" onClick={handlePrevious} disabled={pageNumber === 1}> Previous </Button> <Button size="small" onClick={handleNext} disabled={pageNumber === numPages}> Next </Button> </Box> )} </Paper> </Dialog> ); }; export default FilePreviewModal; I am unable view the pdf properly here, it is just showing 1st page that also half stuck to viewport unable to view.and in pagination it is not showing actual pages of pdf