JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 18
  • Score
    100M100P100Q58175F
  • License MIT

A feature-rich PDF viewer and annotator component for React applications with drawing, text, shapes, and signature support

Package Exports

  • @sandeepmvn/react-pdf-annotator-v2
  • @sandeepmvn/react-pdf-annotator-v2/dist/style.css

Readme

React PDF Annotator v2

A feature-rich, fully customizable PDF viewer and annotator component for React applications. Built with TypeScript, this package provides comprehensive annotation tools including drawing, highlighting, text, shapes, stamps, and digital signatures.

✨ Features

  • 📄 PDF Viewing: Smooth PDF rendering with zoom controls and page navigation
  • 🎨 Drawing Tools: Pen and highlighter with customizable colors and stroke widths
  • âœī¸ Text Annotation: Add text boxes with custom colors and font sizes
  • 📐 Shapes: Rectangle and circle annotations
  • đŸ–ī¸ Text Markup: Underline, strikethrough, and squiggly line tools
  • 🔖 Stamps: Pre-defined stamps (Approved, Confidential, etc.)
  • âœī¸ Digital Signatures: Draw and add signatures and initials
  • â†Šī¸ Undo/Redo: Full history management for all annotations
  • 💾 Export: Download annotated PDFs with all annotations embedded
  • đŸŽ¯ TypeScript: Fully typed for better development experience

đŸ“Ļ Installation

npm install react-pdf-annotator-v2

or

yarn add react-pdf-annotator-v2

or

pnpm add react-pdf-annotator-v2

🚀 Quick Start

import React from 'react';
import { PdfViewer } from 'react-pdf-annotator-v2';
import 'react-pdf-annotator-v2/dist/style.css';

function App() {
  return (
    <div style={{ height: '100vh' }}>
      <PdfViewer 
        fileUrl="https://example.com/sample.pdf" 
        fileName="sample.pdf" 
      />
    </div>
  );
}

export default App;

Read-only Mode

To display a PDF without annotation tools (view-only mode):

<PdfViewer 
  fileUrl="https://example.com/sample.pdf" 
  fileName="sample.pdf" 
  readonly={true}
/>

Tracking Annotation Changes

To receive real-time updates when annotations are added, modified, or deleted:

import { Annotations } from 'react-pdf-annotator-v2';

function App() {
  const handleAnnotationsChange = (annotations: Annotations) => {
    console.log('Annotations updated:', annotations);
    // Save to database, update state, etc.
  };

  return (
    <PdfViewer 
      fileUrl="https://example.com/sample.pdf" 
      fileName="sample.pdf" 
      onAnnotationsChange={handleAnnotationsChange}
    />
  );
}

The annotations parameter is an object where keys are page numbers and values are arrays of annotations:

{
  1: [{ id: '...', type: 'PEN', points: [...], color: '#000000', ... }],
  2: [{ id: '...', type: 'TEXT', content: 'Hello', x: 100, y: 200, ... }],
  // ...
}

Getting Annotated Document

Use refs to programmatically get the current annotated PDF as a Blob or URL:

import { useRef } from 'react';
import { PdfViewer, PdfViewerRef } from 'react-pdf-annotator-v2';

function App() {
  const pdfViewerRef = useRef<PdfViewerRef>(null);

  const handleSave = async () => {
    if (!pdfViewerRef.current) return;
    
    // Get as Blob
    const blob = await pdfViewerRef.current.getAnnotatedDocument();
    if (blob) {
      // Upload to server
      const formData = new FormData();
      formData.append('file', blob, 'annotated.pdf');
      await fetch('/api/upload', { method: 'POST', body: formData });
    }
  };

  const handlePreview = async () => {
    if (!pdfViewerRef.current) return;
    
    // Get as URL for preview
    const url = await pdfViewerRef.current.getAnnotatedDocumentUrl();
    if (url) {
      window.open(url, '_blank');
      // Remember to revoke URL when done: URL.revokeObjectURL(url)
    }
  };

  return (
    <>
      <button onClick={handleSave}>Save to Server</button>
      <button onClick={handlePreview}>Preview</button>
      <PdfViewer 
        ref={pdfViewerRef}
        fileUrl="https://example.com/sample.pdf" 
        fileName="sample.pdf" 
      />
    </>
  );
}

📖 API Reference

PdfViewer Props

Prop Type Required Default Description
fileUrl string Yes - URL of the PDF file to display
fileName string Yes - Name of the PDF file (used for downloads)
readonly boolean No false Hide annotation tools and prevent editing
onAnnotationsChange (annotations: Annotations) => void No - Callback fired when annotations change (add/update/delete/undo/redo)
ref React.Ref<PdfViewerRef> No - Ref to access component methods

PdfViewerRef Methods

When using a ref, the following methods are available:

Method Return Type Description
getAnnotatedDocument() Promise<Blob | null> Returns the current PDF with annotations as a Blob
getAnnotatedDocumentUrl() Promise<string | null> Returns an object URL of the annotated PDF (remember to revoke when done)

Available Exports

// Main Component and Types
import { PdfViewer } from 'react-pdf-annotator-v2';
import type { PdfViewerRef } from 'react-pdf-annotator-v2';

// Sub-components (for custom layouts)
import { 
  PdfPage, 
  Toolbar, 
  AnnotationLayer,
  SignatureModal 
} from 'react-pdf-annotator-v2';

// Hooks
import { useAnnotationHistory } from 'react-pdf-annotator-v2';

// Types
import type { 
  AnnotationTool,
  Annotation,
  PenAnnotation,
  TextAnnotation,
  // ... other types
} from 'react-pdf-annotator-v2';

// Constants
import { 
  DEFAULT_COLOR,
  DEFAULT_STROKE_WIDTH,
  COLORS 
} from 'react-pdf-annotator-v2';

🎨 Customization

The package includes pre-built styles that use Tailwind CSS. The CSS is already bundled, so you don't need Tailwind CSS in your project.

Simply import the CSS file:

import 'react-pdf-annotator-v2/dist/style.css';

The styles will work out of the box without any additional configuration.

đŸ› ī¸ Advanced Usage

Using the Annotation Hook

import { useAnnotationHistory } from 'react-pdf-annotator-v2';

function CustomAnnotator() {
  const { 
    annotations, 
    addAnnotation, 
    undo, 
    redo, 
    canUndo, 
    canRedo 
  } = useAnnotationHistory();

  // Your custom implementation
}

TypeScript Support

The package is fully typed. Import types as needed:

import type { 
  AnnotationTool, 
  Annotation, 
  PenAnnotation 
} from 'react-pdf-annotator-v2';

const tool: AnnotationTool = 'PEN';
const annotation: Annotation = {
  // ...
};

📋 Requirements

  • React 18.0.0 or higher
  • React DOM 18.0.0 or higher

🔧 Peer Dependencies

This package requires the following peer dependencies:

{
  "react": "^18.0.0",
  "react-dom": "^18.0.0"
}

Make sure these are installed in your project.

📝 License

MIT

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

📮 Issues

If you encounter any issues or have suggestions, please file an issue on the GitHub repository.

🙏 Acknowledgments

Built with:

  • pdf-lib - PDF manipulation
  • PDF.js - PDF rendering
  • React & TypeScript
  • Tailwind CSS

📚 Documentation

For more detailed documentation and examples, visit the documentation site.


Made with â¤ī¸ for the React community