@kopexa/pdf-viewer 1.0.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/LICENSE +201 -0
- package/README.md +149 -0
- package/dist/chunk-EIAXW4SI.mjs +167 -0
- package/dist/chunk-P4M32GKY.mjs +27 -0
- package/dist/chunk-UJB5LFCW.mjs +28 -0
- package/dist/index.d.mts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +263 -0
- package/dist/index.mjs +15 -0
- package/dist/messages.d.mts +24 -0
- package/dist/messages.d.ts +24 -0
- package/dist/messages.js +52 -0
- package/dist/messages.mjs +6 -0
- package/dist/pdf-viewer-lazy.d.mts +17 -0
- package/dist/pdf-viewer-lazy.d.ts +17 -0
- package/dist/pdf-viewer-lazy.js +255 -0
- package/dist/pdf-viewer-lazy.mjs +8 -0
- package/dist/pdf-viewer.d.mts +71 -0
- package/dist/pdf-viewer.d.ts +71 -0
- package/dist/pdf-viewer.js +217 -0
- package/dist/pdf-viewer.mjs +12 -0
- package/package.json +68 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __esm = (fn, res) => function __init() {
|
|
7
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
8
|
+
};
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
22
|
+
|
|
23
|
+
// src/messages.ts
|
|
24
|
+
var import_i18n, messages;
|
|
25
|
+
var init_messages = __esm({
|
|
26
|
+
"src/messages.ts"() {
|
|
27
|
+
"use strict";
|
|
28
|
+
import_i18n = require("@kopexa/i18n");
|
|
29
|
+
messages = (0, import_i18n.defineMessages)({
|
|
30
|
+
loading: {
|
|
31
|
+
id: "pdf_viewer.loading",
|
|
32
|
+
defaultMessage: "Loading document\u2026",
|
|
33
|
+
description: "Shown while the PDF document is loading"
|
|
34
|
+
},
|
|
35
|
+
error_title: {
|
|
36
|
+
id: "pdf_viewer.error_title",
|
|
37
|
+
defaultMessage: "Something went wrong while loading the document.",
|
|
38
|
+
description: "Primary error message when PDF fails to load"
|
|
39
|
+
},
|
|
40
|
+
error_hint: {
|
|
41
|
+
id: "pdf_viewer.error_hint",
|
|
42
|
+
defaultMessage: "Please try again.",
|
|
43
|
+
description: "Secondary error message hinting the user to retry"
|
|
44
|
+
},
|
|
45
|
+
page_label: {
|
|
46
|
+
id: "pdf_viewer.page_label",
|
|
47
|
+
defaultMessage: "Page {page} of {total}",
|
|
48
|
+
description: "Page indicator below each page of the PDF"
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// src/pdf-viewer.tsx
|
|
55
|
+
var pdf_viewer_exports = {};
|
|
56
|
+
__export(pdf_viewer_exports, {
|
|
57
|
+
PDFViewer: () => PDFViewer,
|
|
58
|
+
configurePDFWorker: () => configurePDFWorker,
|
|
59
|
+
pdfjs: () => import_react_pdf.pdfjs
|
|
60
|
+
});
|
|
61
|
+
function configurePDFWorker(workerSrc) {
|
|
62
|
+
if (typeof window === "undefined") return;
|
|
63
|
+
import_react_pdf.pdfjs.GlobalWorkerOptions.workerSrc = workerSrc != null ? workerSrc : `https://unpkg.com/pdfjs-dist@${import_react_pdf.pdfjs.version}/build/pdf.worker.min.mjs`;
|
|
64
|
+
}
|
|
65
|
+
function base64ToUint8Array(base64String) {
|
|
66
|
+
const binaryString = atob(base64String);
|
|
67
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
68
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
69
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
70
|
+
}
|
|
71
|
+
return bytes;
|
|
72
|
+
}
|
|
73
|
+
var import_i18n2, import_motion_utils, import_shared_utils, import_react, import_react2, import_react_pdf, import_AnnotationLayer, import_TextLayer, import_jsx_runtime, PAGE_SELECTOR, FADE_TRANSITION, PDFViewer;
|
|
74
|
+
var init_pdf_viewer = __esm({
|
|
75
|
+
"src/pdf-viewer.tsx"() {
|
|
76
|
+
"use strict";
|
|
77
|
+
"use client";
|
|
78
|
+
import_i18n2 = require("@kopexa/i18n");
|
|
79
|
+
import_motion_utils = require("@kopexa/motion-utils");
|
|
80
|
+
import_shared_utils = require("@kopexa/shared-utils");
|
|
81
|
+
import_react = require("motion/react");
|
|
82
|
+
import_react2 = require("react");
|
|
83
|
+
import_react_pdf = require("react-pdf");
|
|
84
|
+
import_AnnotationLayer = require("react-pdf/dist/Page/AnnotationLayer.css");
|
|
85
|
+
import_TextLayer = require("react-pdf/dist/Page/TextLayer.css");
|
|
86
|
+
init_messages();
|
|
87
|
+
import_jsx_runtime = require("react/jsx-runtime");
|
|
88
|
+
PAGE_SELECTOR = "[data-page-number]";
|
|
89
|
+
FADE_TRANSITION = {
|
|
90
|
+
duration: 0.4,
|
|
91
|
+
ease: import_motion_utils.TRANSITION_EASINGS.ease
|
|
92
|
+
};
|
|
93
|
+
PDFViewer = ({
|
|
94
|
+
className,
|
|
95
|
+
source,
|
|
96
|
+
onDocumentLoad,
|
|
97
|
+
onPageClick,
|
|
98
|
+
customPageRenderer,
|
|
99
|
+
options,
|
|
100
|
+
loadingContent,
|
|
101
|
+
errorContent,
|
|
102
|
+
pageLabel: pageLabelProp,
|
|
103
|
+
...props
|
|
104
|
+
}) => {
|
|
105
|
+
var _a;
|
|
106
|
+
const intl = (0, import_i18n2.useSafeIntl)();
|
|
107
|
+
const $el = (0, import_react2.useRef)(null);
|
|
108
|
+
const [width, setWidth] = (0, import_react2.useState)(0);
|
|
109
|
+
const [numPages, setNumPages] = (0, import_react2.useState)(0);
|
|
110
|
+
const [pdfError, setPdfError] = (0, import_react2.useState)(false);
|
|
111
|
+
const sourceUrl = source.type === "url" ? source.url : null;
|
|
112
|
+
const sourceData = source.type === "data" ? source.data : null;
|
|
113
|
+
const sourceBase64 = source.type === "base64" ? source.data : null;
|
|
114
|
+
const fileRef = (0, import_react2.useRef)(null);
|
|
115
|
+
const prevKeyRef = (0, import_react2.useRef)(null);
|
|
116
|
+
const currentKey = (_a = sourceUrl != null ? sourceUrl : sourceData) != null ? _a : sourceBase64;
|
|
117
|
+
if (currentKey !== prevKeyRef.current) {
|
|
118
|
+
prevKeyRef.current = currentKey;
|
|
119
|
+
if (sourceUrl) {
|
|
120
|
+
fileRef.current = sourceUrl;
|
|
121
|
+
} else if (sourceData) {
|
|
122
|
+
fileRef.current = { data: sourceData };
|
|
123
|
+
} else if (sourceBase64) {
|
|
124
|
+
fileRef.current = { data: base64ToUint8Array(sourceBase64) };
|
|
125
|
+
} else {
|
|
126
|
+
fileRef.current = null;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const file = fileRef.current;
|
|
130
|
+
const onDocumentLoaded = (doc) => {
|
|
131
|
+
setNumPages(doc.numPages);
|
|
132
|
+
onDocumentLoad == null ? void 0 : onDocumentLoad(doc);
|
|
133
|
+
};
|
|
134
|
+
const onDocumentPageClick = (event, pageNumber) => {
|
|
135
|
+
const target = event.target instanceof HTMLElement ? event.target : null;
|
|
136
|
+
if (!target) return;
|
|
137
|
+
const $page = target.closest(PAGE_SELECTOR);
|
|
138
|
+
if (!$page) return;
|
|
139
|
+
const { height, width: width2, top, left } = $page.getBoundingClientRect();
|
|
140
|
+
onPageClick == null ? void 0 : onPageClick({
|
|
141
|
+
pageNumber,
|
|
142
|
+
numPages,
|
|
143
|
+
originalEvent: event,
|
|
144
|
+
pageHeight: height,
|
|
145
|
+
pageWidth: width2,
|
|
146
|
+
pageX: event.clientX - left,
|
|
147
|
+
pageY: event.clientY - top
|
|
148
|
+
});
|
|
149
|
+
};
|
|
150
|
+
(0, import_react2.useEffect)(() => {
|
|
151
|
+
if (!$el.current) return;
|
|
152
|
+
const $current = $el.current;
|
|
153
|
+
const updateWidth = () => {
|
|
154
|
+
setWidth($current.getBoundingClientRect().width);
|
|
155
|
+
};
|
|
156
|
+
updateWidth();
|
|
157
|
+
window.addEventListener("resize", updateWidth);
|
|
158
|
+
return () => window.removeEventListener("resize", updateWidth);
|
|
159
|
+
}, []);
|
|
160
|
+
const loader = loadingContent != null ? loadingContent : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex h-[80vh] max-h-[60rem] flex-col items-center justify-center", children: [
|
|
161
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-12 w-12 animate-spin rounded-full border-4 border-muted border-t-primary" }),
|
|
162
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mt-4 text-muted-foreground", children: intl.formatMessage(messages.loading) })
|
|
163
|
+
] });
|
|
164
|
+
const error = errorContent != null ? errorContent : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex h-[80vh] max-h-[60rem] flex-col items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-center text-muted-foreground", children: [
|
|
165
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: intl.formatMessage(messages.error_title) }),
|
|
166
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mt-1 text-sm", children: intl.formatMessage(messages.error_hint) })
|
|
167
|
+
] }) });
|
|
168
|
+
if (!file) return error;
|
|
169
|
+
const isLoaded = numPages > 0;
|
|
170
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.LazyMotion, { features: import_react.domAnimation, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: $el, className: (0, import_shared_utils.cn)("overflow-hidden", className), ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
171
|
+
import_react_pdf.Document,
|
|
172
|
+
{
|
|
173
|
+
file,
|
|
174
|
+
className: (0, import_shared_utils.cn)("w-full overflow-hidden rounded", {
|
|
175
|
+
"h-[80vh] max-h-[60rem]": !isLoaded
|
|
176
|
+
}),
|
|
177
|
+
onLoadSuccess: onDocumentLoaded,
|
|
178
|
+
onSourceError: () => setPdfError(true),
|
|
179
|
+
externalLinkTarget: "_blank",
|
|
180
|
+
loading: pdfError ? error : loader,
|
|
181
|
+
error,
|
|
182
|
+
options,
|
|
183
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.AnimatePresence, { mode: "wait", children: !isLoaded ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
184
|
+
import_react.m.div,
|
|
185
|
+
{
|
|
186
|
+
initial: { opacity: 1 },
|
|
187
|
+
exit: { opacity: 0 },
|
|
188
|
+
transition: FADE_TRANSITION,
|
|
189
|
+
children: pdfError ? error : loader
|
|
190
|
+
},
|
|
191
|
+
"loader"
|
|
192
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
193
|
+
import_react.m.div,
|
|
194
|
+
{
|
|
195
|
+
initial: { opacity: 0 },
|
|
196
|
+
animate: { opacity: 1 },
|
|
197
|
+
transition: FADE_TRANSITION,
|
|
198
|
+
children: Array.from({ length: numPages }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "last:-mb-2", children: [
|
|
199
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "overflow-hidden rounded border border-border will-change-transform", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
200
|
+
import_react_pdf.Page,
|
|
201
|
+
{
|
|
202
|
+
pageNumber: i + 1,
|
|
203
|
+
width,
|
|
204
|
+
renderAnnotationLayer: true,
|
|
205
|
+
renderTextLayer: true,
|
|
206
|
+
loading: () => "",
|
|
207
|
+
renderMode: customPageRenderer ? "custom" : "canvas",
|
|
208
|
+
customRenderer: customPageRenderer,
|
|
209
|
+
onClick: (e) => onDocumentPageClick(e, i + 1)
|
|
210
|
+
}
|
|
211
|
+
) }),
|
|
212
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "my-2 text-center text-[11px] text-muted-foreground/80", children: pageLabelProp ? pageLabelProp(i + 1, numPages) : intl.formatMessage(messages.page_label, {
|
|
213
|
+
page: i + 1,
|
|
214
|
+
total: numPages
|
|
215
|
+
}) })
|
|
216
|
+
] }, `page-${i + 1}`))
|
|
217
|
+
},
|
|
218
|
+
"pages"
|
|
219
|
+
) })
|
|
220
|
+
}
|
|
221
|
+
) }) });
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// src/index.ts
|
|
227
|
+
var index_exports = {};
|
|
228
|
+
__export(index_exports, {
|
|
229
|
+
PDFViewer: () => PDFViewer,
|
|
230
|
+
PDFViewerLazy: () => PDFViewerLazy,
|
|
231
|
+
configurePDFWorker: () => configurePDFWorker,
|
|
232
|
+
pdfjs: () => import_react_pdf.pdfjs
|
|
233
|
+
});
|
|
234
|
+
module.exports = __toCommonJS(index_exports);
|
|
235
|
+
init_pdf_viewer();
|
|
236
|
+
|
|
237
|
+
// src/pdf-viewer-lazy.tsx
|
|
238
|
+
var import_i18n3 = require("@kopexa/i18n");
|
|
239
|
+
var import_react_utils = require("@kopexa/react-utils");
|
|
240
|
+
var import_react3 = require("react");
|
|
241
|
+
init_messages();
|
|
242
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
243
|
+
var LazyPDFViewer = (0, import_react3.lazy)(
|
|
244
|
+
() => Promise.resolve().then(() => (init_pdf_viewer(), pdf_viewer_exports)).then((mod) => ({ default: mod.PDFViewer }))
|
|
245
|
+
);
|
|
246
|
+
var DefaultFallback = () => {
|
|
247
|
+
const intl = (0, import_i18n3.useSafeIntl)();
|
|
248
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex h-[80vh] max-h-[60rem] flex-col items-center justify-center", children: [
|
|
249
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "h-12 w-12 animate-spin rounded-full border-4 border-muted border-t-primary" }),
|
|
250
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "mt-4 text-muted-foreground", children: intl.formatMessage(messages.loading) })
|
|
251
|
+
] });
|
|
252
|
+
};
|
|
253
|
+
var PDFViewerLazy = ({ fallback, ...props }) => {
|
|
254
|
+
const fb = fallback != null ? fallback : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DefaultFallback, {});
|
|
255
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_utils.ClientOnly, { fallback: fb, children: () => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react3.Suspense, { fallback: fb, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(LazyPDFViewer, { ...props }) }) });
|
|
256
|
+
};
|
|
257
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
258
|
+
0 && (module.exports = {
|
|
259
|
+
PDFViewer,
|
|
260
|
+
PDFViewerLazy,
|
|
261
|
+
configurePDFWorker,
|
|
262
|
+
pdfjs
|
|
263
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PDFViewerLazy
|
|
3
|
+
} from "./chunk-P4M32GKY.mjs";
|
|
4
|
+
import {
|
|
5
|
+
PDFViewer,
|
|
6
|
+
configurePDFWorker,
|
|
7
|
+
pdfjs
|
|
8
|
+
} from "./chunk-EIAXW4SI.mjs";
|
|
9
|
+
import "./chunk-UJB5LFCW.mjs";
|
|
10
|
+
export {
|
|
11
|
+
PDFViewer,
|
|
12
|
+
PDFViewerLazy,
|
|
13
|
+
configurePDFWorker,
|
|
14
|
+
pdfjs
|
|
15
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
declare const messages: {
|
|
2
|
+
loading: {
|
|
3
|
+
id: string;
|
|
4
|
+
defaultMessage: string;
|
|
5
|
+
description: string;
|
|
6
|
+
};
|
|
7
|
+
error_title: {
|
|
8
|
+
id: string;
|
|
9
|
+
defaultMessage: string;
|
|
10
|
+
description: string;
|
|
11
|
+
};
|
|
12
|
+
error_hint: {
|
|
13
|
+
id: string;
|
|
14
|
+
defaultMessage: string;
|
|
15
|
+
description: string;
|
|
16
|
+
};
|
|
17
|
+
page_label: {
|
|
18
|
+
id: string;
|
|
19
|
+
defaultMessage: string;
|
|
20
|
+
description: string;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export { messages };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
declare const messages: {
|
|
2
|
+
loading: {
|
|
3
|
+
id: string;
|
|
4
|
+
defaultMessage: string;
|
|
5
|
+
description: string;
|
|
6
|
+
};
|
|
7
|
+
error_title: {
|
|
8
|
+
id: string;
|
|
9
|
+
defaultMessage: string;
|
|
10
|
+
description: string;
|
|
11
|
+
};
|
|
12
|
+
error_hint: {
|
|
13
|
+
id: string;
|
|
14
|
+
defaultMessage: string;
|
|
15
|
+
description: string;
|
|
16
|
+
};
|
|
17
|
+
page_label: {
|
|
18
|
+
id: string;
|
|
19
|
+
defaultMessage: string;
|
|
20
|
+
description: string;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export { messages };
|
package/dist/messages.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/messages.ts
|
|
21
|
+
var messages_exports = {};
|
|
22
|
+
__export(messages_exports, {
|
|
23
|
+
messages: () => messages
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(messages_exports);
|
|
26
|
+
var import_i18n = require("@kopexa/i18n");
|
|
27
|
+
var messages = (0, import_i18n.defineMessages)({
|
|
28
|
+
loading: {
|
|
29
|
+
id: "pdf_viewer.loading",
|
|
30
|
+
defaultMessage: "Loading document\u2026",
|
|
31
|
+
description: "Shown while the PDF document is loading"
|
|
32
|
+
},
|
|
33
|
+
error_title: {
|
|
34
|
+
id: "pdf_viewer.error_title",
|
|
35
|
+
defaultMessage: "Something went wrong while loading the document.",
|
|
36
|
+
description: "Primary error message when PDF fails to load"
|
|
37
|
+
},
|
|
38
|
+
error_hint: {
|
|
39
|
+
id: "pdf_viewer.error_hint",
|
|
40
|
+
defaultMessage: "Please try again.",
|
|
41
|
+
description: "Secondary error message hinting the user to retry"
|
|
42
|
+
},
|
|
43
|
+
page_label: {
|
|
44
|
+
id: "pdf_viewer.page_label",
|
|
45
|
+
defaultMessage: "Page {page} of {total}",
|
|
46
|
+
description: "Page indicator below each page of the PDF"
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
50
|
+
0 && (module.exports = {
|
|
51
|
+
messages
|
|
52
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { PDFViewerProps } from './pdf-viewer.mjs';
|
|
2
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
|
+
import 'react-pdf';
|
|
4
|
+
import 'react';
|
|
5
|
+
|
|
6
|
+
type PDFViewerLazyProps = PDFViewerProps & {
|
|
7
|
+
/** Fallback content shown during SSR and before hydration. */
|
|
8
|
+
fallback?: React.ReactNode;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* A lazy-loaded PDF viewer that only renders on the client.
|
|
12
|
+
* Uses `ClientOnly` to prevent SSR and `React.lazy` to avoid
|
|
13
|
+
* importing pdfjs-dist on the server (which requires browser APIs like DOMMatrix).
|
|
14
|
+
*/
|
|
15
|
+
declare const PDFViewerLazy: ({ fallback, ...props }: PDFViewerLazyProps) => react_jsx_runtime.JSX.Element;
|
|
16
|
+
|
|
17
|
+
export { PDFViewerLazy, type PDFViewerLazyProps };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { PDFViewerProps } from './pdf-viewer.js';
|
|
2
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
|
+
import 'react-pdf';
|
|
4
|
+
import 'react';
|
|
5
|
+
|
|
6
|
+
type PDFViewerLazyProps = PDFViewerProps & {
|
|
7
|
+
/** Fallback content shown during SSR and before hydration. */
|
|
8
|
+
fallback?: React.ReactNode;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* A lazy-loaded PDF viewer that only renders on the client.
|
|
12
|
+
* Uses `ClientOnly` to prevent SSR and `React.lazy` to avoid
|
|
13
|
+
* importing pdfjs-dist on the server (which requires browser APIs like DOMMatrix).
|
|
14
|
+
*/
|
|
15
|
+
declare const PDFViewerLazy: ({ fallback, ...props }: PDFViewerLazyProps) => react_jsx_runtime.JSX.Element;
|
|
16
|
+
|
|
17
|
+
export { PDFViewerLazy, type PDFViewerLazyProps };
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __esm = (fn, res) => function __init() {
|
|
8
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
9
|
+
};
|
|
10
|
+
var __export = (target, all) => {
|
|
11
|
+
for (var name in all)
|
|
12
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
13
|
+
};
|
|
14
|
+
var __copyProps = (to, from, except, desc) => {
|
|
15
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
16
|
+
for (let key of __getOwnPropNames(from))
|
|
17
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
18
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
23
|
+
|
|
24
|
+
// src/messages.ts
|
|
25
|
+
var import_i18n, messages;
|
|
26
|
+
var init_messages = __esm({
|
|
27
|
+
"src/messages.ts"() {
|
|
28
|
+
"use strict";
|
|
29
|
+
import_i18n = require("@kopexa/i18n");
|
|
30
|
+
messages = (0, import_i18n.defineMessages)({
|
|
31
|
+
loading: {
|
|
32
|
+
id: "pdf_viewer.loading",
|
|
33
|
+
defaultMessage: "Loading document\u2026",
|
|
34
|
+
description: "Shown while the PDF document is loading"
|
|
35
|
+
},
|
|
36
|
+
error_title: {
|
|
37
|
+
id: "pdf_viewer.error_title",
|
|
38
|
+
defaultMessage: "Something went wrong while loading the document.",
|
|
39
|
+
description: "Primary error message when PDF fails to load"
|
|
40
|
+
},
|
|
41
|
+
error_hint: {
|
|
42
|
+
id: "pdf_viewer.error_hint",
|
|
43
|
+
defaultMessage: "Please try again.",
|
|
44
|
+
description: "Secondary error message hinting the user to retry"
|
|
45
|
+
},
|
|
46
|
+
page_label: {
|
|
47
|
+
id: "pdf_viewer.page_label",
|
|
48
|
+
defaultMessage: "Page {page} of {total}",
|
|
49
|
+
description: "Page indicator below each page of the PDF"
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// src/pdf-viewer.tsx
|
|
56
|
+
var pdf_viewer_exports = {};
|
|
57
|
+
__export(pdf_viewer_exports, {
|
|
58
|
+
PDFViewer: () => PDFViewer,
|
|
59
|
+
configurePDFWorker: () => configurePDFWorker,
|
|
60
|
+
pdfjs: () => import_react_pdf.pdfjs
|
|
61
|
+
});
|
|
62
|
+
function configurePDFWorker(workerSrc) {
|
|
63
|
+
if (typeof window === "undefined") return;
|
|
64
|
+
import_react_pdf.pdfjs.GlobalWorkerOptions.workerSrc = workerSrc != null ? workerSrc : `https://unpkg.com/pdfjs-dist@${import_react_pdf.pdfjs.version}/build/pdf.worker.min.mjs`;
|
|
65
|
+
}
|
|
66
|
+
function base64ToUint8Array(base64String) {
|
|
67
|
+
const binaryString = atob(base64String);
|
|
68
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
69
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
70
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
71
|
+
}
|
|
72
|
+
return bytes;
|
|
73
|
+
}
|
|
74
|
+
var import_i18n2, import_motion_utils, import_shared_utils, import_react, import_react2, import_react_pdf, import_AnnotationLayer, import_TextLayer, import_jsx_runtime, PAGE_SELECTOR, FADE_TRANSITION, PDFViewer;
|
|
75
|
+
var init_pdf_viewer = __esm({
|
|
76
|
+
"src/pdf-viewer.tsx"() {
|
|
77
|
+
"use strict";
|
|
78
|
+
"use client";
|
|
79
|
+
import_i18n2 = require("@kopexa/i18n");
|
|
80
|
+
import_motion_utils = require("@kopexa/motion-utils");
|
|
81
|
+
import_shared_utils = require("@kopexa/shared-utils");
|
|
82
|
+
import_react = require("motion/react");
|
|
83
|
+
import_react2 = require("react");
|
|
84
|
+
import_react_pdf = require("react-pdf");
|
|
85
|
+
import_AnnotationLayer = require("react-pdf/dist/Page/AnnotationLayer.css");
|
|
86
|
+
import_TextLayer = require("react-pdf/dist/Page/TextLayer.css");
|
|
87
|
+
init_messages();
|
|
88
|
+
import_jsx_runtime = require("react/jsx-runtime");
|
|
89
|
+
PAGE_SELECTOR = "[data-page-number]";
|
|
90
|
+
FADE_TRANSITION = {
|
|
91
|
+
duration: 0.4,
|
|
92
|
+
ease: import_motion_utils.TRANSITION_EASINGS.ease
|
|
93
|
+
};
|
|
94
|
+
PDFViewer = ({
|
|
95
|
+
className,
|
|
96
|
+
source,
|
|
97
|
+
onDocumentLoad,
|
|
98
|
+
onPageClick,
|
|
99
|
+
customPageRenderer,
|
|
100
|
+
options,
|
|
101
|
+
loadingContent,
|
|
102
|
+
errorContent,
|
|
103
|
+
pageLabel: pageLabelProp,
|
|
104
|
+
...props
|
|
105
|
+
}) => {
|
|
106
|
+
var _a;
|
|
107
|
+
const intl = (0, import_i18n2.useSafeIntl)();
|
|
108
|
+
const $el = (0, import_react2.useRef)(null);
|
|
109
|
+
const [width, setWidth] = (0, import_react2.useState)(0);
|
|
110
|
+
const [numPages, setNumPages] = (0, import_react2.useState)(0);
|
|
111
|
+
const [pdfError, setPdfError] = (0, import_react2.useState)(false);
|
|
112
|
+
const sourceUrl = source.type === "url" ? source.url : null;
|
|
113
|
+
const sourceData = source.type === "data" ? source.data : null;
|
|
114
|
+
const sourceBase64 = source.type === "base64" ? source.data : null;
|
|
115
|
+
const fileRef = (0, import_react2.useRef)(null);
|
|
116
|
+
const prevKeyRef = (0, import_react2.useRef)(null);
|
|
117
|
+
const currentKey = (_a = sourceUrl != null ? sourceUrl : sourceData) != null ? _a : sourceBase64;
|
|
118
|
+
if (currentKey !== prevKeyRef.current) {
|
|
119
|
+
prevKeyRef.current = currentKey;
|
|
120
|
+
if (sourceUrl) {
|
|
121
|
+
fileRef.current = sourceUrl;
|
|
122
|
+
} else if (sourceData) {
|
|
123
|
+
fileRef.current = { data: sourceData };
|
|
124
|
+
} else if (sourceBase64) {
|
|
125
|
+
fileRef.current = { data: base64ToUint8Array(sourceBase64) };
|
|
126
|
+
} else {
|
|
127
|
+
fileRef.current = null;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
const file = fileRef.current;
|
|
131
|
+
const onDocumentLoaded = (doc) => {
|
|
132
|
+
setNumPages(doc.numPages);
|
|
133
|
+
onDocumentLoad == null ? void 0 : onDocumentLoad(doc);
|
|
134
|
+
};
|
|
135
|
+
const onDocumentPageClick = (event, pageNumber) => {
|
|
136
|
+
const target = event.target instanceof HTMLElement ? event.target : null;
|
|
137
|
+
if (!target) return;
|
|
138
|
+
const $page = target.closest(PAGE_SELECTOR);
|
|
139
|
+
if (!$page) return;
|
|
140
|
+
const { height, width: width2, top, left } = $page.getBoundingClientRect();
|
|
141
|
+
onPageClick == null ? void 0 : onPageClick({
|
|
142
|
+
pageNumber,
|
|
143
|
+
numPages,
|
|
144
|
+
originalEvent: event,
|
|
145
|
+
pageHeight: height,
|
|
146
|
+
pageWidth: width2,
|
|
147
|
+
pageX: event.clientX - left,
|
|
148
|
+
pageY: event.clientY - top
|
|
149
|
+
});
|
|
150
|
+
};
|
|
151
|
+
(0, import_react2.useEffect)(() => {
|
|
152
|
+
if (!$el.current) return;
|
|
153
|
+
const $current = $el.current;
|
|
154
|
+
const updateWidth = () => {
|
|
155
|
+
setWidth($current.getBoundingClientRect().width);
|
|
156
|
+
};
|
|
157
|
+
updateWidth();
|
|
158
|
+
window.addEventListener("resize", updateWidth);
|
|
159
|
+
return () => window.removeEventListener("resize", updateWidth);
|
|
160
|
+
}, []);
|
|
161
|
+
const loader = loadingContent != null ? loadingContent : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex h-[80vh] max-h-[60rem] flex-col items-center justify-center", children: [
|
|
162
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-12 w-12 animate-spin rounded-full border-4 border-muted border-t-primary" }),
|
|
163
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mt-4 text-muted-foreground", children: intl.formatMessage(messages.loading) })
|
|
164
|
+
] });
|
|
165
|
+
const error = errorContent != null ? errorContent : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex h-[80vh] max-h-[60rem] flex-col items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-center text-muted-foreground", children: [
|
|
166
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: intl.formatMessage(messages.error_title) }),
|
|
167
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mt-1 text-sm", children: intl.formatMessage(messages.error_hint) })
|
|
168
|
+
] }) });
|
|
169
|
+
if (!file) return error;
|
|
170
|
+
const isLoaded = numPages > 0;
|
|
171
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.LazyMotion, { features: import_react.domAnimation, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: $el, className: (0, import_shared_utils.cn)("overflow-hidden", className), ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
172
|
+
import_react_pdf.Document,
|
|
173
|
+
{
|
|
174
|
+
file,
|
|
175
|
+
className: (0, import_shared_utils.cn)("w-full overflow-hidden rounded", {
|
|
176
|
+
"h-[80vh] max-h-[60rem]": !isLoaded
|
|
177
|
+
}),
|
|
178
|
+
onLoadSuccess: onDocumentLoaded,
|
|
179
|
+
onSourceError: () => setPdfError(true),
|
|
180
|
+
externalLinkTarget: "_blank",
|
|
181
|
+
loading: pdfError ? error : loader,
|
|
182
|
+
error,
|
|
183
|
+
options,
|
|
184
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.AnimatePresence, { mode: "wait", children: !isLoaded ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
185
|
+
import_react.m.div,
|
|
186
|
+
{
|
|
187
|
+
initial: { opacity: 1 },
|
|
188
|
+
exit: { opacity: 0 },
|
|
189
|
+
transition: FADE_TRANSITION,
|
|
190
|
+
children: pdfError ? error : loader
|
|
191
|
+
},
|
|
192
|
+
"loader"
|
|
193
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
194
|
+
import_react.m.div,
|
|
195
|
+
{
|
|
196
|
+
initial: { opacity: 0 },
|
|
197
|
+
animate: { opacity: 1 },
|
|
198
|
+
transition: FADE_TRANSITION,
|
|
199
|
+
children: Array.from({ length: numPages }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "last:-mb-2", children: [
|
|
200
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "overflow-hidden rounded border border-border will-change-transform", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
201
|
+
import_react_pdf.Page,
|
|
202
|
+
{
|
|
203
|
+
pageNumber: i + 1,
|
|
204
|
+
width,
|
|
205
|
+
renderAnnotationLayer: true,
|
|
206
|
+
renderTextLayer: true,
|
|
207
|
+
loading: () => "",
|
|
208
|
+
renderMode: customPageRenderer ? "custom" : "canvas",
|
|
209
|
+
customRenderer: customPageRenderer,
|
|
210
|
+
onClick: (e) => onDocumentPageClick(e, i + 1)
|
|
211
|
+
}
|
|
212
|
+
) }),
|
|
213
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "my-2 text-center text-[11px] text-muted-foreground/80", children: pageLabelProp ? pageLabelProp(i + 1, numPages) : intl.formatMessage(messages.page_label, {
|
|
214
|
+
page: i + 1,
|
|
215
|
+
total: numPages
|
|
216
|
+
}) })
|
|
217
|
+
] }, `page-${i + 1}`))
|
|
218
|
+
},
|
|
219
|
+
"pages"
|
|
220
|
+
) })
|
|
221
|
+
}
|
|
222
|
+
) }) });
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
// src/pdf-viewer-lazy.tsx
|
|
228
|
+
var pdf_viewer_lazy_exports = {};
|
|
229
|
+
__export(pdf_viewer_lazy_exports, {
|
|
230
|
+
PDFViewerLazy: () => PDFViewerLazy
|
|
231
|
+
});
|
|
232
|
+
module.exports = __toCommonJS(pdf_viewer_lazy_exports);
|
|
233
|
+
var import_i18n3 = require("@kopexa/i18n");
|
|
234
|
+
var import_react_utils = require("@kopexa/react-utils");
|
|
235
|
+
var import_react3 = require("react");
|
|
236
|
+
init_messages();
|
|
237
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
238
|
+
var LazyPDFViewer = (0, import_react3.lazy)(
|
|
239
|
+
() => Promise.resolve().then(() => (init_pdf_viewer(), pdf_viewer_exports)).then((mod) => ({ default: mod.PDFViewer }))
|
|
240
|
+
);
|
|
241
|
+
var DefaultFallback = () => {
|
|
242
|
+
const intl = (0, import_i18n3.useSafeIntl)();
|
|
243
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex h-[80vh] max-h-[60rem] flex-col items-center justify-center", children: [
|
|
244
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "h-12 w-12 animate-spin rounded-full border-4 border-muted border-t-primary" }),
|
|
245
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "mt-4 text-muted-foreground", children: intl.formatMessage(messages.loading) })
|
|
246
|
+
] });
|
|
247
|
+
};
|
|
248
|
+
var PDFViewerLazy = ({ fallback, ...props }) => {
|
|
249
|
+
const fb = fallback != null ? fallback : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DefaultFallback, {});
|
|
250
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_utils.ClientOnly, { fallback: fb, children: () => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react3.Suspense, { fallback: fb, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(LazyPDFViewer, { ...props }) }) });
|
|
251
|
+
};
|
|
252
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
253
|
+
0 && (module.exports = {
|
|
254
|
+
PDFViewerLazy
|
|
255
|
+
});
|