preview.tsx
Overview
preview.tsx is a React functional component file that renders a PDF document viewer with highlight capabilities. It leverages the react-pdf-highlighter library to display PDF content and allows users to see and interact with text and area highlights on the document. The component fetches the PDF URL via a custom hook, handles document loading states, error handling, and dynamically adjusts the container size based on the first page dimensions.
This component is memoized for performance optimization and is designed to be integrated into a larger application where PDF document preview and annotation are needed, such as document review tools or collaborative editors.
Detailed Description
Interfaces
IProps
interface IProps {
highlights: IHighlight[];
setWidthAndHeight: (width: number, height: number) => void;
}
highlights: An array of
IHighlightobjects representing the highlights (text or area) to be rendered on the PDF.setWidthAndHeight: A callback function that receives the width and height of the PDF’s first page viewport to adjust the container size or layout externally.
Components and Functions
HighlightPopup
const HighlightPopup = ({
comment,
}: {
comment: { text: string; emoji: string };
}) => JSX.Element | null
Purpose: Renders a popup that displays the comment associated with a highlight, including an emoji and text.
Parameters:
comment: An object containing:text(string): The comment text.emoji(string): An emoji related to the comment.
Returns: A JSX element displaying the emoji and comment text if text exists; otherwise, returns
null.Usage: Used internally as the content for the popup shown when hovering over a highlight.
Preview
const Preview = ({ highlights: state, setWidthAndHeight }: IProps) => JSX.Element
Purpose: The main React component that loads and displays a PDF document with highlights. It manages loading states, error handling, and dynamic size adjustment.
Parameters:
highlights(renamed tostateinternally): An array of highlights to render.setWidthAndHeight: Callback to communicate the PDF page size back to the parent component.
Returns: JSX element representing the entire PDF preview with highlights.
Hooks Used:
useGetDocumentUrl(): Custom hook to retrieve the PDF URL.useCatchDocumentError(url): Custom hook that returns error messages related to loading the document.useRef: To hold a reference to the function that scrolls to a highlight.useEffect: Scrolls to the first highlight when the highlights array changes.
Key Implementation Details:
Uses
PdfLoaderfromreact-pdf-highlighterto load the PDF asynchronously.Displays Ant Design’s
Skeletoncomponent while loading.Displays a custom
FileErrorcomponent if an error occurs loading the PDF.Once the PDF is loaded, retrieves the dimensions of the first page and calls
setWidthAndHeight.Uses
PdfHighlighterto render highlights, with interaction features:Highlights can be text-based or area-based.
Area selection enabled when holding the Alt key.
Highlights show a popup on hover containing comments.
Uses an empty
resetHashfunction, likely a placeholder for scrolling or URL hash resetting on scroll.The scrolling function for highlights is stored in a
refand invoked on new highlights.
Usage Example:
import Preview from './preview';
const highlights = [
{
id: '1',
position: { boundingRect: {...}, rects: [...] },
content: { text: 'Example highlight' },
comment: { text: 'Important note', emoji: '📝' },
},
];
const MyComponent = () => {
const [width, setWidth] = useState(0);
const [height, setHeight] = useState(0);
return (
<Preview
highlights={highlights}
setWidthAndHeight={(w, h) => {
setWidth(w);
setHeight(h);
}}
/>
);
};
Important Implementation Details
Highlight Handling: The
highlightTransformcallback differentiates between text highlights and area highlights by checking if thehighlight.content.imageproperty exists.Text highlights use the
Highlightcomponent.Area highlights use the
AreaHighlightcomponent.
Popup Interaction: The
Popupcomponent wraps highlights, showing theHighlightPopupcontent on mouse hover.PDF Page Dimension Calculation: The first page dimensions are asynchronously fetched via
pdfDocument.getPage(1).then(...)and passed up usingsetWidthAndHeightfor responsive layout.Memoization: The component is wrapped with React’s
memoto avoid unnecessary re-renders when props don't change.Error Handling: Uses a custom hook
useCatchDocumentErrorand renders aFileErrorcomponent if loading fails.Loading State: Displays an Ant Design
Skeletonloader while the PDF is being fetched.
Interaction with Other Parts of the System
Custom Hooks:
useGetDocumentUrlpresumably fetches or computes the URL of the PDF to display.useCatchDocumentErrortracks and provides error messages related to document loading.
UI Components:
FileErroris a component that displays file loading errors.Ant Design’s
Skeletonis used for loading placeholders.
Styling: Uses CSS modules imported from
index.lessfor styling the container and popup.PDF Highlighting Library: Relies on
react-pdf-highlighterfor PDF rendering and highlight management.
This component likely fits into a document viewer or annotation system where users need to preview PDFs with annotations/highlights, handle errors gracefully, and respond to dynamic PDF sizes.
Visual Diagram
classDiagram
class Preview {
+highlights: IHighlight[]
+setWidthAndHeight(width: number, height: number): void
-url: string
-ref: React.Ref<(highlight: IHighlight) => void>
-error: string | null
+resetHash(): void
+useEffect()
+render()
}
class HighlightPopup {
+comment: { text: string; emoji: string }
+render(): JSX.Element | null
}
Preview --> PdfLoader
PdfLoader --> PdfHighlighter
PdfHighlighter --> Highlight
PdfHighlighter --> AreaHighlight
Highlight ..> HighlightPopup : uses for popup content
AreaHighlight ..> HighlightPopup : uses for popup content
Preview ..> useGetDocumentUrl : uses
Preview ..> useCatchDocumentError : uses
Preview ..> FileError : renders on error
Summary
The preview.tsx file provides a performant, error-resilient PDF preview component with rich highlight functionality. It cleanly separates concerns by using hooks for data and error management, leverages established libraries for PDF rendering/highlighting, and offers a user-friendly interface through popups and area selection. Its design facilitates integration into larger document viewing or collaboration platforms.