@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/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 };
@@ -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,6 @@
1
+ import {
2
+ messages
3
+ } from "./chunk-UJB5LFCW.mjs";
4
+ export {
5
+ messages
6
+ };
@@ -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
+ });