@aeli3/react-pdf-viewer
v1.0.0
Published
A lightweight, customizable React PDF viewer component with TypeScript support
Maintainers
Readme
PdfViewer
A lightweight, customizable React PDF viewer component built with TypeScript, powered by PDF.js.
Features
- 📄 Full PDF rendering with pdf.js
- 🎨 Light and dark mode support
- 🔍 Zoom in/out controls
- 📱 Responsive design with mobile support
- ✨ Smooth animations and transitions
- 🎯 Bounding box overlays for annotations
- 📥 Download PDF capability
- ⌨️ Page navigation with input
- 🎪 Intelligent page visibility detection
- 🎨 Fully customizable with CSS tokens
- ♿ Accessible components
Installation
npm install @your-org/pdf-viewer
# or
pnpm add @your-org/pdf-viewer
# or
yarn add @your-org/pdf-viewerQuick Start
import { PdfViewer } from '@your-org/pdf-viewer';
import '@your-org/pdf-viewer/style.css';
import { useState } from 'react';
export default function App() {
const [isOpen, setIsOpen] = useState(false);
return (
<div>
<button onClick={() => setIsOpen(true)}>Open PDF</button>
<PdfViewer isOpen={isOpen} onClose={() => setIsOpen(false)} file="/path/to/document.pdf" />
</div>
);
}Props
| Prop | Type | Default | Description |
| ------------------ | -------------------------------- | --------------- | ---------------------------------------- |
| isOpen | boolean | - | Controls visibility of the PDF viewer |
| onClose | () => void | - | Callback triggered when viewer is closed |
| file | string \| Uint8Array | - | Path to PDF file or PDF data |
| theme | 'light' \| 'dark' | 'light' | Color theme |
| scale | number | 1.2 | Initial zoom scale |
| minScale | number | 0.5 | Minimum zoom scale |
| maxScale | number | 2 | Maximum zoom scale |
| showToolbar | boolean | true | Show zoom controls in toolbar |
| portal | Element \| DocumentFragment | document.body | DOM element to render into |
| boundingBoxesMap | Map<number, BoundingBoxType[]> | - | Overlay bounding boxes on pages |
Customization
CSS Tokens
Customize the appearance by overriding CSS custom properties (tokens). All tokens are defined in the :root selector and support light/dark mode variants.
Colors
| Token | Default (Light) | Default (Dark) | Purpose |
| -------------------- | --------------- | -------------- | ------------------------ |
| --color-primary | #2f3033 | #e5eefb | Primary text and accents |
| --color-secondary | #5d5e61 | #94a3b8 | Secondary text |
| --color-tertiary | #747591 | #a5a8c8 | Tertiary text |
| --color-neutral | #f8f9fa | #1f2937 | Neutral backgrounds |
| --color-bg | #eef0f3 | #0b1220 | Main background |
| --color-surface | #ffffff | #111827 | Card/surface backgrounds |
| --color-surface-2 | #f1f4f6 | #1f2937 | Secondary surface |
| --color-text | #2f3033 | #e5eefb | Primary text color |
| --color-text-muted | #5d5e61 | #94a3b8 | Muted text color |
| --color-border | #e2e5e9 | #334155 | Border color |
Spacing
| Token | Value |
| ----------- | ------ |
| --space-1 | 4px |
| --space-2 | 8px |
| --space-3 | 12px |
| --space-4 | 16px |
| --space-5 | 20px |
| --space-6 | 24px |
Typography
| Token | Default |
| ---------------- | ----------------------- |
| --font-heading | 'Manrope', sans-serif |
| --font-body | 'Inter', sans-serif |
| --font-label | 'Inter', sans-serif |
Shadows & Radius
| Token | Value |
| ------------- | ------------------------------------- |
| --shadow-sm | 0 1px 2px rgba(187, 187, 187, 0.06) |
| --shadow-md | 0 8px 24px rgba(15, 23, 42, 0.12) |
| --radius-sm | 8px |
| --radius-md | 12px |
| --radius-lg | 16px |
CSS Classes
Customize specific viewer components by targeting their CSS classes:
| Class | Purpose |
| ----------------------- | -------------------------------- |
| .pdfv | Main viewer container |
| .pdfv__viewport | Scrollable page container |
| .pdfv__topbar | Header with title and navigation |
| .pdfv__toolbar | Bottom zoom controls |
| .pdfv__page | Individual page wrapper |
| .pdfv__canvas-wrapper | PDF canvas wrapper |
| .pdfv__boundingbox | Annotation overlay |
| .textLayer | Text selection layer |
| .loader-container | Loading indicator |
Example: Custom Styling
import { PdfViewer } from '@your-org/pdf-viewer';
import '@your-org/pdf-viewer/style.css';
import './custom-pdf-theme.css';
// In custom-pdf-theme.css:
:root {
--color-primary: #1e40af;
--color-bg: #f0f9ff;
--color-surface: #ffffff;
--font-heading: 'Sora', sans-serif;
}
[data-theme='dark'] {
--color-primary: #60a5fa;
--color-bg: #0c1222;
--color-surface: #1e293b;
}
export default function App() {
return (
<PdfViewer
isOpen={true}
onClose={() => {}}
file="/document.pdf"
theme="dark"
/>
);
}Bounding Boxes (Annotations)
Add overlay annotations to specific areas of pages:
<PdfViewer
file="/document.pdf"
isOpen={isOpen}
onClose={() => setIsOpen(false)}
boundingBoxesMap={
new Map([
[
1,
[
{
top: 100,
left: 50,
bottom: 200,
right: 300,
style: { backgroundColor: 'rgba(255, 0, 0, 0.3)' },
},
],
],
])
}
/>Theme Support
Set theme using the theme prop:
<PdfViewer theme="dark" {...props} />Or the viewer respects system theme preference when no data-theme attribute is set on the root element.
License
MIT
