@tawqi3i/pdf-viewer 0.1.0

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 ADDED
@@ -0,0 +1,162 @@
1
+ # @tawqi3i/pdf-viewer
2
+
3
+ React PDF viewer and annotation SDK built on [GemBox PDF Viewer](https://www.gemboxsoftware.com/pdf-viewer). View PDFs, place text fields, stamps, and drawn signatures, then bake them into the document with pdf-lib or convert them to coordinate fields for a server-side signing API.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @tawqi3i/pdf-viewer react react-dom
9
+ ```
10
+
11
+ ## Setup (Vite)
12
+
13
+ Add the SDK's Vite plugin — it applies the GemBox build workarounds (pdfjs UMD fix, Vue 3 define flags, dep-optimizer exclusion) that the viewer needs:
14
+
15
+ ```js
16
+ // vite.config.js
17
+ import { defineConfig } from 'vite'
18
+ import react from '@vitejs/plugin-react'
19
+ import tawqi3iPdfViewer from '@tawqi3i/pdf-viewer/vite'
20
+
21
+ export default defineConfig({
22
+ plugins: [react(), tawqi3iPdfViewer()],
23
+ })
24
+ ```
25
+
26
+ Import the stylesheet once (e.g. in your entry file):
27
+
28
+ ```js
29
+ import '@tawqi3i/pdf-viewer/styles.css'
30
+ ```
31
+
32
+ ## Quick start — turn-key annotator
33
+
34
+ `PdfAnnotator` is a complete viewer + annotation workspace. Your app injects behavior through callbacks; the component owns the UI mechanics (toolbar, drag/resize, signature capture, snackbars).
35
+
36
+ ```jsx
37
+ import { PdfAnnotator, bakeAnnotationsToBase64 } from '@tawqi3i/pdf-viewer'
38
+
39
+ function App() {
40
+ return (
41
+ <PdfAnnotator
42
+ className="h-screen"
43
+ header={<img src="/logo.svg" alt="My app" className="h-8" />}
44
+ onSave={(file, annotations) => {/* download / persist */}}
45
+ onComplete={async (file, annotations) => {
46
+ // e.g. flatten annotations and send to your signing API.
47
+ // Throw to show an error snackbar; resolve to show success.
48
+ const data = await bakeAnnotationsToBase64(file, annotations)
49
+ await fetch('/api/envelopes/seal', {
50
+ method: 'POST',
51
+ headers: { 'Content-Type': 'application/json' },
52
+ body: JSON.stringify({ name: file.name, data }),
53
+ })
54
+ }}
55
+ />
56
+ )
57
+ }
58
+ ```
59
+
60
+ Give the component a sized container (`h-screen`, a flex cell, etc.) — it fills its parent.
61
+
62
+ Key props (see `index.d.ts` for the full list):
63
+
64
+ | Prop | Purpose |
65
+ | --- | --- |
66
+ | `fileBlob` / `fileUrl` | Document source. Local upload/drag-drop is built in (`allowFileUpload`). |
67
+ | `onFileChange(file)` | Fired when the user opens or closes a file. |
68
+ | `onSave(file, annotations)` | Save/download button behavior — entirely yours. |
69
+ | `onComplete(file, annotations)` | Async "Complete" action (seal/send). Button appears only when provided. |
70
+ | `header` | Branding slot at the left of the header bar. |
71
+ | `loading` / `errorMessage` | Remote-fetch spinner and error display driven by your app. |
72
+ | `isSigned`, `saveAlwaysEnabled` | Save-button state flags. |
73
+ | `stamps` | Custom stamp presets (defaults to APPROVED / REJECTED / REVIEWED / VOID). |
74
+ | `labels` | Override built-in UI strings (e.g. `completeSuccess`). |
75
+ | `readOnly` | Display-only mode; hides all annotation UI. |
76
+ | `licenseKey` | GemBox license key (defaults to the free limited key). |
77
+
78
+ ## Display-only viewer
79
+
80
+ ```jsx
81
+ import { PdfViewer } from '@tawqi3i/pdf-viewer'
82
+
83
+ <PdfViewer
84
+ fileBlob={blob} // or fileUrl="https://…/doc.pdf"
85
+ height="100%"
86
+ visibility={{ open: false, download: false, print: false }}
87
+ onError={(err) => console.error(err)}
88
+ />
89
+ ```
90
+
91
+ ## Building blocks
92
+
93
+ For custom layouts, compose the pieces yourself:
94
+
95
+ ```jsx
96
+ import {
97
+ PdfViewer, AnnotationLayer, AnnotationToolbar, SignatureModal,
98
+ useAnnotations, bakeAnnotationsToBase64,
99
+ } from '@tawqi3i/pdf-viewer'
100
+
101
+ function CustomWorkspace({ blob }) {
102
+ const ann = useAnnotations()
103
+ return (
104
+ <div className="relative h-full">
105
+ <PdfViewer fileBlob={blob} height="100%" />
106
+ <AnnotationLayer
107
+ annotations={ann.annotations}
108
+ activeTool={ann.activeTool}
109
+ pendingSignature={ann.pendingSignature}
110
+ onPlace={ann.handlePlace}
111
+ onDelete={ann.handleDelete}
112
+ onMove={ann.handleMove}
113
+ onResize={ann.handleResize}
114
+ onTextChange={ann.handleTextChange}
115
+ />
116
+ <AnnotationToolbar
117
+ activeTool={ann.activeTool}
118
+ onToolSelect={ann.handleToolSelect}
119
+ selectedStamp={ann.selectedStamp}
120
+ onStampSelect={ann.setSelectedStamp}
121
+ onUndo={ann.handleUndo}
122
+ onClearAll={ann.handleClearAll}
123
+ onSave={() => {/* … */}}
124
+ count={ann.annotations.length}
125
+ />
126
+ {ann.showSignatureModal && (
127
+ <SignatureModal
128
+ onConfirm={ann.handleSignatureConfirm}
129
+ onClose={() => ann.setShowSignatureModal(false)}
130
+ />
131
+ )}
132
+ </div>
133
+ )
134
+ }
135
+ ```
136
+
137
+ The annotation overlay positions itself by querying GemBox's rendered pages via their `data-page-number` attributes — keep the overlay inside the same `position: relative` container as the viewer.
138
+
139
+ ## Utilities
140
+
141
+ - `bakeAnnotationsToBase64(file, annotations)` — flatten annotations into the PDF (pdf-lib), returns base64.
142
+ - `annotationsToFields(file, annotations)` — convert annotations to coordinate field objects (PDF points) for server-side placement.
143
+ - `base64ToFile(base64, filename)` / `blobToBase64(blob)` — conversion helpers.
144
+
145
+ ## Theming
146
+
147
+ The stylesheet ships its design tokens as CSS variables — override them to re-brand:
148
+
149
+ ```css
150
+ :root {
151
+ --color-brand: #7c3aed;
152
+ --color-brand-dark: #5b21b6;
153
+ }
154
+ ```
155
+
156
+ The stylesheet contains no CSS reset/preflight, so it won't interfere with your app's base styles.
157
+
158
+ ## Development (this repo)
159
+
160
+ - `npm run dev` — local dev harness at `index.html`
161
+ - `npm run build` — build the library to `dist/`
162
+ - `npm run dev:lib` — rebuild on change (for workspace consumers)