pdfjs-annotation-extension-for-react 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,18 +1,27 @@
1
- # pdfjs-annotation-extension-for-react
1
+ <div>
2
+ <h1 align="center"><code>pdfjs-annotation-extension-for-react</code> ⚡️ </h1>
3
+ <p align="center">
4
+ <strong>A lightweight, extensible React PDF annotator and viewer built on top of PDF.js</strong><br/> Supporting the editing of existing PDF file annotations, posting comments, replying, submitting annotation data, and loading for further editing.
5
+ </p>
6
+ </div>
2
7
 
3
- A lightweight, extensible React PDF viewer and annotator built on top of PDF.js, designed for enterprise-grade document reading and annotation scenarios.
8
+ ---
4
9
 
5
10
  [![NPM](https://img.shields.io/npm/v/pdfjs-annotation-extension-for-react.svg)](https://www.npmjs.com/package/pdfjs-annotation-extension-for-react)
6
11
  [![License](https://img.shields.io/npm/l/pdfjs-annotation-extension-for-react)](./LICENSE)
7
12
 
13
+ ## Online Demo
14
+
15
+ [![Demo](https://img.shields.io/badge/🔥_Live_Demo-React_PDF_Viewer_Plus-FF6F61?style=for-the-badge&logo=github&logoColor=white)](https://laomai-codefee.github.io/pdfjs-annotation-extension-for-react-demo/)
16
+
8
17
  ## ✨ Features
9
18
 
10
- - 📄 High-fidelity PDF rendering based on PDF.js
11
19
  - ✍️ Rich annotation system
12
20
  - Highlight, drawing, shapes, text notes
13
21
  - Signatures (draw / enter / upload)
14
22
  - Stamps with editor support
15
23
  - Edit native PDF annotations directly
24
+ - 📄 High-fidelity PDF rendering based on PDF.js
16
25
  - 🎨 Theme system based on Radix UI Themes
17
26
  - 🌍 Internationalization (zh-CN, en-US)
18
27
  - 🧩 Highly customizable UI
@@ -25,9 +34,35 @@ A lightweight, extensible React PDF viewer and annotator built on top of PDF.js,
25
34
  - 🧠 Designed for extensibility
26
35
  - Clean context & extension architecture
27
36
 
28
- ## Online Demo
29
-
30
- [![Demo](https://img.shields.io/badge/🔥_Live_Demo-React_PDF_Viewer_Plus-FF6F61?style=for-the-badge&logo=github&logoColor=white)](https://laomai-codefee.github.io/pdfjs-annotation-extension-for-react-demo/)
37
+ ## ✍️ Annotation Tools
38
+
39
+ 1. Rectangle
40
+ 2. Circle
41
+ 3. Free Hand (grouped if drawn within a short time)
42
+ 4. Free Highlight (with auto-correction)
43
+ 5. Arrow
44
+ 6. Cloud
45
+ 7. FreeText
46
+ 8. Signature
47
+ 9. Stamp (upload custom images)
48
+ 10. Text Highlight
49
+ 11. Text Strikeout
50
+ 12. Text Underline
51
+ 13. Text
52
+
53
+ ## ✍️ Editing existing annotations in PDF files
54
+
55
+ 1. Square
56
+ 2. Circle
57
+ 3. Ink
58
+ 4. FreeText
59
+ 5. Line
60
+ 6. Polygon
61
+ 7. PolyLine
62
+ 8. Text
63
+ 9. Highlight
64
+ 10. Underline
65
+ 11. StrikeOut
31
66
 
32
67
  ## 📦 Installation
33
68
 
@@ -39,38 +74,38 @@ yarn add pdfjs-annotation-extension-for-react
39
74
 
40
75
  # 🚀 Quick Start
41
76
 
42
- ## Basic PDF Viewer
77
+ ## 1. PDF Annotator
43
78
 
44
79
  ```jsx
45
- import { PdfViewer } from 'pdfjs-annotation-extension-for-react'
80
+ import { PdfAnnotator } from 'pdfjs-annotation-extension-for-react'
46
81
  import 'pdfjs-annotation-extension-for-react/style'
47
82
 
48
83
  export default function App() {
49
84
  return (
50
- <PdfViewer
51
- title="PDF Viewer"
85
+ <PdfAnnotator
86
+ title="PDF Annotator"
52
87
  url="https://example.com/sample.pdf"
53
- layoutStyle={{ width: '100vw', height: '100vh' }}
88
+ user={{ id: 'u1', name: 'Alice' }}
89
+ onSave={(annotations) => {
90
+ console.log('Saved annotations:', annotations)
91
+ }}
54
92
  />
55
93
  )
56
94
  }
57
95
  ```
58
96
 
59
- ## PDF Annotator
97
+ ## 2. Basic PDF Viewer
60
98
 
61
99
  ```jsx
62
- import { PdfAnnotator } from 'pdfjs-annotation-extension-for-react'
100
+ import { PdfViewer } from 'pdfjs-annotation-extension-for-react'
63
101
  import 'pdfjs-annotation-extension-for-react/style'
64
102
 
65
103
  export default function App() {
66
104
  return (
67
- <PdfAnnotator
68
- title="PDF Annotator"
105
+ <PdfViewer
106
+ title="PDF Viewer"
69
107
  url="https://example.com/sample.pdf"
70
- user={{ id: 'u1', name: 'Alice' }}
71
- onSave={(annotations) => {
72
- console.log('Saved annotations:', annotations)
73
- }}
108
+ layoutStyle={{ width: '100vw', height: '100vh' }}
74
109
  />
75
110
  )
76
111
  }
@@ -78,117 +113,18 @@ export default function App() {
78
113
 
79
114
  # 🧩 Components
80
115
 
81
- ## 📄 PdfViewer
82
-
83
- A lightweight PDF viewer with toolbar, sidebar, actions and extensible UI slots.
84
-
85
- ### Props
86
-
87
-
88
- | Prop | Type | Default | Description |
89
- | -------------------- | -------------------------------- | ------------------------------------- | ----------------------- |
90
- | `theme` | Radix Theme Color | `'violet'` | Viewer theme color |
91
- | `title` | `ReactNode` | - | Page title |
92
- | `url` | `string | URL` | **required** | PDF file URL |
93
- | `locale` | `'zh-CN' | 'en-US'` | `'zh-CN'` | UI language |
94
- | `initialScale` | `PdfScale` | `'auto'` | Initial zoom |
95
- | `layoutStyle` | `CSSProperties` | `{ width: '100vw', height: '100vh' }` | Container style |
96
- | `isSidebarCollapsed` | `boolean` | `true` | Sidebar collapsed state |
97
- | `showSidebarTrigger` | `boolean` | `false` | Show sidebar toggle |
98
- | `showTextLayer` | `boolean` | `true` | Enable text selection |
99
- | `actions` | `ReactNode | (ctx) => ReactNode` | - | Custom action area |
100
- | `sidebar` | `ReactNode | (ctx) => ReactNode` | - | Custom sidebar |
101
- | `toolbar` | `ReactNode | (ctx) => ReactNode` | ZoomTool | Custom toolbar |
102
- | `onDocumentLoaded` | `(pdfViewer) => void` | - | PDF loaded callback |
103
- | `onEventBusReady` | `(eventBus) => void` | - | PDF.js EventBus ready |
104
-
105
- ### 🎨 Custom UI
106
-
107
- #### Custom Toolbar
108
-
109
- ```jsx
110
- <PdfViewer
111
- url={pdfUrl}
112
- toolbar={(context) => (
113
- <>
114
- <button onClick={() => console.log(context.pdfViewer)}>
115
- PDF Viewer
116
- </button>
117
- <button onClick={context.toggleSidebar}>
118
- Toggle Sidebar
119
- </button>
120
- <button onClick={() => context.setSidebarCollapsed(false)}>
121
- Open Sidebar
122
- </button>
123
- <button onClick={() => context.setSidebarCollapsed(true)}>
124
- Close Sidebar
125
- </button>
126
- </>
127
- )}
128
- />
129
- ```
130
-
131
- ### Custom Sidebar
132
-
133
- ```jsx
134
- <PdfViewer
135
- url={pdfUrl}
136
- sidebar={(context) => (
137
- <>
138
- <button onClick={() => console.log(context.pdfViewer)}>
139
- PDF Viewer
140
- </button>
141
- <button onClick={() => {
142
- context.pdfViewer?.scrollPageIntoView({
143
- pageNumber: 1
144
- })
145
- }}>
146
- page1
147
- </button>
148
- <button onClick={() => {
149
- context.pdfViewer?.scrollPageIntoView({
150
- pageNumber: 10
151
- })
152
- }}>
153
- page 10
154
- </button>
155
- <button onClick={() => {
156
- context.pdfViewer?.scrollPageIntoView({
157
- pageNumber: 100
158
- })
159
- }}>
160
- page 100
161
- </button>
162
- </>
163
- )}
164
- />
165
- ```
116
+ ### Base Props
166
117
 
167
- ### Custom Actions
168
-
169
- ```jsx
170
- <PdfViewer
171
- url={pdfUrl}
172
- actions={(context) => (
173
- <>
174
- <button onClick={() => console.log(context.pdfViewer)}>
175
- PDF Viewer
176
- </button>
177
- <button onClick={context.toggleSidebar}>
178
- Toggle Sidebar
179
- </button>
180
- <button onClick={() => context.setSidebarCollapsed(false)}>
181
- Open Sidebar
182
- </button>
183
- <button onClick={() => context.setSidebarCollapsed(true)}>
184
- Close Sidebar
185
- </button>
186
- </>
187
- )}
188
- />
189
- ```
190
-
191
- ---
118
+ | Name | Type | Default | Description |
119
+ | ---------------------- | ----------------------- | --------------------------------------- | ------------------------------------------------------ |
120
+ | `theme` | Radix Theme Color | `violet` | Theme color of the viewer UI |
121
+ | `title` | `React.ReactNode` | — | Page title content; accepts text or custom React nodes |
122
+ | `url *` | `string \| URL` | — | PDF file URL; supports string URLs or `URL` objects |
123
+ | `locale` | `'zh-CN' \| 'en-US'` | `zh-CN` | Locale used for internationalization |
124
+ | `initialScale` | `PdfScale` | `auto` | Initial zoom level of the PDF viewer |
125
+ | `layoutStyle` | `React.CSSProperties` | `{ width: '100vw', height: '100vh' }` | Styles applied to the PDF viewer container |
126
+ | `isSidebarCollapsed` | `boolean` | `false` | Whether the sidebar is collapsed by default |
127
+ | `enableRange` | `boolean \| 'auto'` | `auto` | Enables HTTP Range (streaming) loading for PDFs |
192
128
 
193
129
  ## ✍️ PdfAnnotator
194
130
 
@@ -196,20 +132,19 @@ An advanced PDF viewer with annotation capabilities.
196
132
 
197
133
  ### Props
198
134
 
199
-
200
- | Prop | Type | Default | Description |
201
- | ------------------------- | ------------------------------- | --------------------------------- | --------------------------- |
202
- | `user` | `{ id: string; name: string }` | `{ id: 'null', name: 'unknown' }` | Annotation author |
203
- | `enableNativeAnnotations` | `boolean` | `false` | Load native PDF annotations |
204
- | `initialAnnotations` | `IAnnotationStore[]` | `[]` | Existing annotations |
205
- | `defaultOptions` | `DeepPartial` | - | Default annotator options |
206
- | `onSave` | `(annotations) => void` | - | Save callback |
207
- | `onLoad` | `() => void` | - | Load complete |
208
- | `onAnnotationAdded` | `(annotation) => void` | - | Add callback |
209
- | `onAnnotationDeleted` | `(id) => void` | - | Delete callback |
210
- | `onAnnotationUpdated` | `(annotation) => void` | - | Update callback |
211
- | `onAnnotationSelected` | `(annotation, isClick) => void` | - | Select callback |
212
- | `actions` | `ReactNode | Component` | - | Custom action buttons |
135
+ | Name | Type | Default | Description |
136
+ | --------------------------- | ------------------------------------------------------------------- | ----------------------------------- | -------------------------------------------------------------------- |
137
+ | `user` | `User` | `{ id: 'null', name: 'unknown' }` | Current user information<br />used to identify the annotation author |
138
+ | `enableNativeAnnotations` | `boolean` | `false` | Native annotations embedded in the PDF file |
139
+ | `defaultOptions` | `DeepPartial` | | Default configuration for the annotator; |
140
+ | `initialAnnotations` | `IAnnotationStore[]` | | Existing annotations to be rendered during initialization |
141
+ | `actions` | `React.ReactNode \| React.ComponentType` | | Custom actions area  |
142
+ | `onSave` | `(annotations: IAnnotationStore[]) => void` | | Callback triggered when annotations are saved |
143
+ | `onLoad` | `() => void` | | Callback triggered when the PDF and annotator are fully loaded |
144
+ | `onAnnotationAdded` | `(annotation: IAnnotationStore) => void` | | Fired when a new annotation is created |
145
+ | `onAnnotationDeleted` | `(id: string) => void` | | Fired when an annotation is deleted |
146
+ | `onAnnotationSelected` | `(annotation: IAnnotationStore \| null, isClick: boolean) => void` | | Fired when an annotation is selected or deselected |
147
+ | `onAnnotationUpdated` | `(annotation: IAnnotationStore) => void` | | Fired when an existing annotation is modified |
213
148
 
214
149
  ### ⚙️ defaultOptions (Enterprise Design)
215
150
 
@@ -227,6 +162,7 @@ This ensures:
227
162
  - Safe for long-term enterprise use
228
163
 
229
164
  #### Example
165
+
230
166
  ```tsx
231
167
  import qiantubifengshouxietiFont from './fonts/qiantubifengshouxieti.ttf';
232
168
 
@@ -326,6 +262,110 @@ import qiantubifengshouxietiFont from './fonts/qiantubifengshouxieti.ttf';
326
262
  />
327
263
  ```
328
264
 
265
+ ## 📄 PdfViewer
266
+
267
+ A lightweight PDF viewer with toolbar, sidebar, actions and extensible UI slots.
268
+
269
+ ### Props
270
+
271
+ | Name | Type | Default | Description |
272
+ | ---------------------- | ------------------------------------------------------------------------- | --------- | ------------------------------------------------------------------------------------------ |
273
+ | `actions` | `React.ReactNode \| (context: PdfViewerContextValue) => React.ReactNode` | — | Custom actions area in the toolbar |
274
+ | `sidebar` | `React.ReactNode \| (context: PdfViewerContextValue) => React.ReactNode` | — | Custom sidebar component |
275
+ | `toolbar` | `React.ReactNode \| (context: PdfViewerContextValue) => React.ReactNode` | — | Custom toolbar component |
276
+ | `showSidebarTrigger` | `boolean` | `false` | Whether to display a button to toggle the sidebar visibility |
277
+ | `showTextLayer` | `boolean` | `true` | Whether to render the text layer |
278
+ | `onDocumentLoaded` | `(pdfViewer: PDFViewer \| null) => void` | — | Callback invoked when the PDF <br />document is fully loaded and the viewer is initialized |
279
+ | `onEventBusReady` | `(eventBus: EventBus \| null) => void` | — | Callback invoked when the pdf.js EventBus is ready |
280
+
281
+ ### 🎨 Custom UI
282
+
283
+ #### Custom Toolbar
284
+
285
+ ```jsx
286
+ <PdfViewer
287
+ url={pdfUrl}
288
+ toolbar={(context) => (
289
+ <>
290
+ <button onClick={() => console.log(context.pdfViewer)}>
291
+ PDF Viewer
292
+ </button>
293
+ <button onClick={context.toggleSidebar}>
294
+ Toggle Sidebar
295
+ </button>
296
+ <button onClick={() => context.setSidebarCollapsed(false)}>
297
+ Open Sidebar
298
+ </button>
299
+ <button onClick={() => context.setSidebarCollapsed(true)}>
300
+ Close Sidebar
301
+ </button>
302
+ </>
303
+ )}
304
+ />
305
+ ```
306
+
307
+ ### Custom Sidebar
308
+
309
+ ```jsx
310
+ <PdfViewer
311
+ url={pdfUrl}
312
+ sidebar={(context) => (
313
+ <>
314
+ <button onClick={() => console.log(context.pdfViewer)}>
315
+ PDF Viewer
316
+ </button>
317
+ <button onClick={() => {
318
+ context.pdfViewer?.scrollPageIntoView({
319
+ pageNumber: 1
320
+ })
321
+ }}>
322
+ page1
323
+ </button>
324
+ <button onClick={() => {
325
+ context.pdfViewer?.scrollPageIntoView({
326
+ pageNumber: 10
327
+ })
328
+ }}>
329
+ page 10
330
+ </button>
331
+ <button onClick={() => {
332
+ context.pdfViewer?.scrollPageIntoView({
333
+ pageNumber: 100
334
+ })
335
+ }}>
336
+ page 100
337
+ </button>
338
+ </>
339
+ )}
340
+ />
341
+ ```
342
+
343
+ ### Custom Actions
344
+
345
+ ```jsx
346
+ <PdfViewer
347
+ url={pdfUrl}
348
+ actions={(context) => (
349
+ <>
350
+ <button onClick={() => console.log(context.pdfViewer)}>
351
+ PDF Viewer
352
+ </button>
353
+ <button onClick={context.toggleSidebar}>
354
+ Toggle Sidebar
355
+ </button>
356
+ <button onClick={() => context.setSidebarCollapsed(false)}>
357
+ Open Sidebar
358
+ </button>
359
+ <button onClick={() => context.setSidebarCollapsed(true)}>
360
+ Close Sidebar
361
+ </button>
362
+ </>
363
+ )}
364
+ />
365
+ ```
366
+
367
+ ---
368
+
329
369
  # 🌍 Browser Support
330
370
 
331
371
  - Chrome (latest)