@blocklet/pdf 2.0.132 → 2.0.134

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocklet/pdf",
3
- "version": "2.0.132",
3
+ "version": "2.0.134",
4
4
  "description": "blocklet pdf component",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -8,15 +8,19 @@
8
8
  "sideEffects": false,
9
9
  "exports": {
10
10
  ".": {
11
- "require": "./lib/index.cjs",
12
- "import": "./lib/index.mjs",
13
- "types": "./lib/index.d.ts"
11
+ "require": "./cjs/index.js",
12
+ "import": "./es/index.js",
13
+ "types": "./es/index.d.ts"
14
14
  },
15
- "./lib/": "./lib/"
15
+ "./lib/": {
16
+ "require": "./cjs/",
17
+ "import": "./es/",
18
+ "types": "./es/"
19
+ }
16
20
  },
17
- "main": "./lib/index.cjs",
18
- "module": "./lib/index.mjs",
19
- "types": "./lib/index.d.ts",
21
+ "main": "./cjs/index.js",
22
+ "module": "./es/index.js",
23
+ "types": "./es/index.d.ts",
20
24
  "files": [
21
25
  "lib",
22
26
  "*.d.ts"
@@ -59,5 +63,5 @@
59
63
  "vitest": "^1.4.0",
60
64
  "vitest-fetch-mock": "^0.2.2"
61
65
  },
62
- "gitHead": "71a1b39f9aa329268770182b848c6b7d216facf7"
66
+ "gitHead": "26c60853821624da8f8a3894129959ec997428ad"
63
67
  }
package/lib/index.cjs DELETED
@@ -1,335 +0,0 @@
1
- 'use strict';
2
-
3
- const jsxRuntime = require('react/jsx-runtime');
4
- const react = require('react');
5
- const reactPdf = require('react-pdf');
6
- const ahooks = require('ahooks');
7
- const useTheme = require('@mui/material/styles/useTheme');
8
- const useMediaQuery = require('@mui/material/useMediaQuery');
9
- const Box = require('@mui/material/Box');
10
- const Skeleton = require('@mui/material/Skeleton');
11
- const IconButton = require('@mui/material/IconButton');
12
- const FullscreenIcon = require('@mui/icons-material/Fullscreen');
13
- const ZoomOutIcon = require('@mui/icons-material/ZoomOut');
14
- const ZoomInIcon = require('@mui/icons-material/ZoomIn');
15
- const DownloadIcon = require('@mui/icons-material/Download');
16
- const ArrowOutwardOutlinedIcon = require('@mui/icons-material/ArrowOutwardOutlined');
17
- const material = require('@mui/material');
18
- require('react-pdf/dist/Page/AnnotationLayer.css');
19
- require('react-pdf/dist/Page/TextLayer.css');
20
-
21
- function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
22
-
23
- const useTheme__default = /*#__PURE__*/_interopDefaultCompat(useTheme);
24
- const useMediaQuery__default = /*#__PURE__*/_interopDefaultCompat(useMediaQuery);
25
- const Box__default = /*#__PURE__*/_interopDefaultCompat(Box);
26
- const Skeleton__default = /*#__PURE__*/_interopDefaultCompat(Skeleton);
27
- const IconButton__default = /*#__PURE__*/_interopDefaultCompat(IconButton);
28
- const FullscreenIcon__default = /*#__PURE__*/_interopDefaultCompat(FullscreenIcon);
29
- const ZoomOutIcon__default = /*#__PURE__*/_interopDefaultCompat(ZoomOutIcon);
30
- const ZoomInIcon__default = /*#__PURE__*/_interopDefaultCompat(ZoomInIcon);
31
- const DownloadIcon__default = /*#__PURE__*/_interopDefaultCompat(DownloadIcon);
32
- const ArrowOutwardOutlinedIcon__default = /*#__PURE__*/_interopDefaultCompat(ArrowOutwardOutlinedIcon);
33
-
34
- const workerSrc = `//unpkg.com/pdfjs-dist@${reactPdf.pdfjs.version}/legacy/build/pdf.worker.min.mjs`;
35
- reactPdf.pdfjs.GlobalWorkerOptions.workerSrc = workerSrc;
36
- const preventScrollChangeThumbnailTimerMap = {};
37
- const documentOptions = { isEvalSupported: false };
38
- const getBorder = (color) => `2px solid ${color}`;
39
- const defaultLoading = (props) => {
40
- return /* @__PURE__ */ jsxRuntime.jsx(Skeleton__default, { variant: "rectangular", width: "100%", ...props });
41
- };
42
- function PdfComponent({
43
- url,
44
- backgroundColor = "#fbfbfb",
45
- loading = defaultLoading,
46
- maxHeight = "60vh",
47
- ...rest
48
- }) {
49
- const pdfPageWrapperRef = react.useRef(null);
50
- const thumbnailWrapperRef = react.useRef(null);
51
- const preventScrollChangeThumbnailRef = react.useRef(false);
52
- const state = ahooks.useReactive({
53
- currentPage: 1,
54
- totalPage: 1,
55
- scale: 1
56
- });
57
- const wrapperSize = ahooks.useSize(pdfPageWrapperRef);
58
- const theme = useTheme__default();
59
- const isMobile = useMediaQuery__default(theme.breakpoints.down("sm"));
60
- const pdfUrl = url;
61
- const getPdfItemHeight = () => pdfPageWrapperRef.current?.children[0]?.offsetHeight;
62
- const onDocumentLoadSuccess = (pdf) => {
63
- state.totalPage = pdf.numPages;
64
- };
65
- const onPageChange = (page) => {
66
- state.currentPage = page;
67
- preventScrollChangeThumbnailRef.current = true;
68
- const top = getPdfItemHeight() * (page - 1);
69
- pdfPageWrapperRef?.current?.scrollTo({
70
- top,
71
- behavior: "smooth"
72
- });
73
- if (preventScrollChangeThumbnailTimerMap[pdfUrl])
74
- clearTimeout(preventScrollChangeThumbnailTimerMap[pdfUrl]);
75
- preventScrollChangeThumbnailTimerMap[pdfUrl] = setTimeout(() => {
76
- preventScrollChangeThumbnailRef.current = false;
77
- preventScrollChangeThumbnailTimerMap[pdfUrl] = null;
78
- }, 1e3);
79
- };
80
- const scrollEvent = (value) => {
81
- if (preventScrollChangeThumbnailRef.current) {
82
- return false;
83
- }
84
- const scrollPage = Math.floor(value.top / getPdfItemHeight()) + 1;
85
- if (scrollPage > 0 && scrollPage !== state.currentPage) {
86
- state.currentPage = scrollPage;
87
- thumbnailWrapperRef.current?.scrollTo({
88
- // @ts-ignore
89
- top: document.getElementById(`thumbnail-${scrollPage}`).offsetTop,
90
- behavior: "smooth"
91
- });
92
- return true;
93
- }
94
- };
95
- const { run: runScrollEvent } = ahooks.useDebounceFn(scrollEvent, {
96
- wait: 200
97
- });
98
- ahooks.useScroll(pdfPageWrapperRef, runScrollEvent);
99
- const commonPdfProps = {
100
- canvasBackground: backgroundColor
101
- };
102
- const [, { enterFullscreen }] = ahooks.useFullscreen(() => document.querySelector(".pdf-wrapper"));
103
- return /* @__PURE__ */ jsxRuntime.jsx(Root, { children: /* @__PURE__ */ jsxRuntime.jsx(
104
- reactPdf.Document,
105
- {
106
- loading: () => loading({
107
- height: maxHeight
108
- }),
109
- file: pdfUrl,
110
- onLoadSuccess: onDocumentLoadSuccess,
111
- options: documentOptions,
112
- children: /* @__PURE__ */ jsxRuntime.jsxs(
113
- Box__default,
114
- {
115
- className: "pdf-wrapper",
116
- sx: {
117
- // default max-height: 60vh
118
- maxHeight
119
- },
120
- ...rest,
121
- children: [
122
- /* @__PURE__ */ jsxRuntime.jsxs(
123
- Box__default,
124
- {
125
- className: "pdf-page",
126
- ref: pdfPageWrapperRef,
127
- sx: {
128
- background: backgroundColor,
129
- position: "relative"
130
- },
131
- children: [
132
- new Array(state.totalPage || 0).fill(0).map((_, index) => {
133
- const currentPage = index + 1;
134
- return /* @__PURE__ */ jsxRuntime.jsx(
135
- reactPdf.Page,
136
- {
137
- pageNumber: currentPage,
138
- renderTextLayer: false,
139
- width: wrapperSize?.width,
140
- scale: state.scale,
141
- ...commonPdfProps,
142
- loading: () => loading({
143
- height: maxHeight
144
- })
145
- },
146
- `${pdfUrl}-${currentPage}`
147
- );
148
- }),
149
- /* @__PURE__ */ jsxRuntime.jsxs(Box__default, { className: "pdf-page-toolbar", children: [
150
- /* @__PURE__ */ jsxRuntime.jsx(
151
- IconButton__default,
152
- {
153
- onClick: () => {
154
- if (state.scale > 0.1) {
155
- state.scale -= 0.1;
156
- }
157
- },
158
- children: /* @__PURE__ */ jsxRuntime.jsx(ZoomOutIcon__default, {})
159
- }
160
- ),
161
- /* @__PURE__ */ jsxRuntime.jsx(
162
- IconButton__default,
163
- {
164
- onClick: () => {
165
- state.scale += 0.1;
166
- },
167
- children: /* @__PURE__ */ jsxRuntime.jsx(ZoomInIcon__default, {})
168
- }
169
- ),
170
- /* @__PURE__ */ jsxRuntime.jsx(IconButton__default, { onClick: enterFullscreen, children: /* @__PURE__ */ jsxRuntime.jsx(FullscreenIcon__default, {}) }),
171
- /* @__PURE__ */ jsxRuntime.jsx(
172
- IconButton__default,
173
- {
174
- onClick: () => {
175
- const link = document.createElement("a");
176
- link.href = pdfUrl;
177
- link.download = pdfUrl.split("/").pop() || "download.pdf";
178
- link.click();
179
- },
180
- children: /* @__PURE__ */ jsxRuntime.jsx(DownloadIcon__default, {})
181
- }
182
- ),
183
- /* @__PURE__ */ jsxRuntime.jsx(
184
- IconButton__default,
185
- {
186
- onClick: () => {
187
- window.open(pdfUrl, "_blank");
188
- },
189
- children: /* @__PURE__ */ jsxRuntime.jsx(ArrowOutwardOutlinedIcon__default, {})
190
- }
191
- )
192
- ] })
193
- ]
194
- }
195
- ),
196
- /* @__PURE__ */ jsxRuntime.jsx(
197
- Box__default,
198
- {
199
- className: "pdf-thumbnail",
200
- ref: thumbnailWrapperRef,
201
- sx: {
202
- ".active": {
203
- border: getBorder(theme?.palette?.primary?.main),
204
- ".pdf-thumbnail-index": {
205
- background: theme?.palette?.primary?.main
206
- }
207
- },
208
- ".no-active": {
209
- border: getBorder("transparent")
210
- },
211
- "*": {
212
- transition: "all 0.2s",
213
- cursor: "pointer"
214
- }
215
- },
216
- children: new Array(state.totalPage || 0).fill(0).map((_, index) => {
217
- const currentPage = index + 1;
218
- const key = `thumbnail-${currentPage}`;
219
- const width = isMobile ? 90 : 120;
220
- return /* @__PURE__ */ jsxRuntime.jsx(
221
- Box__default,
222
- {
223
- id: key,
224
- className: `${state.currentPage === currentPage ? "active" : "no-active"}`,
225
- component: "a",
226
- sx: {
227
- width: width + 4
228
- // add border width
229
- },
230
- children: /* @__PURE__ */ jsxRuntime.jsx(
231
- reactPdf.Thumbnail,
232
- {
233
- pageIndex: currentPage,
234
- pageNumber: currentPage,
235
- width,
236
- ...commonPdfProps,
237
- onClick: (e) => {
238
- e.stopPropagation();
239
- e.preventDefault();
240
- onPageChange(currentPage);
241
- },
242
- loading: loading({
243
- height: `calc(${maxHeight} / ${isMobile ? 5 : 4})`,
244
- sx: {
245
- border: getBorder("transparent")
246
- }
247
- }),
248
- children: /* @__PURE__ */ jsxRuntime.jsxs(
249
- Box__default,
250
- {
251
- className: "pdf-thumbnail-index",
252
- component: "span",
253
- sx: {
254
- position: "absolute",
255
- textAlign: "center",
256
- bottom: 0,
257
- left: 0,
258
- right: 0,
259
- color: "#fff",
260
- fontSize: 13,
261
- p: 0.5,
262
- background: "rgba(0,0,0,0.25)"
263
- },
264
- children: [
265
- "# ",
266
- currentPage
267
- ]
268
- },
269
- `index-${currentPage}`
270
- )
271
- }
272
- )
273
- },
274
- key
275
- );
276
- })
277
- }
278
- )
279
- ]
280
- }
281
- )
282
- }
283
- ) });
284
- }
285
- const Root = material.styled(Box__default)`
286
- .pdf-wrapper {
287
- display: flex;
288
- justify-content: center;
289
- align-items: stretch;
290
- }
291
-
292
- .pdf-page {
293
- flex: 1;
294
- display: flex;
295
- flex-direction: column;
296
- justify-content: flex-start;
297
- align-items: center;
298
- overflow-y: auto;
299
- }
300
-
301
- .pdf-page-toolbar {
302
- position: sticky;
303
- margin-top: 16px;
304
- bottom: 16px;
305
- right: 0;
306
- left: 0;
307
- background: rgba(0, 0, 0, 0.5);
308
- border-radius: 4px;
309
- display: flex;
310
- align-items: center;
311
- padding: 2px 8px;
312
- gap: 4px;
313
- * {
314
- color: white;
315
- }
316
- }
317
-
318
- .pdf-thumbnail {
319
- margin-left: 16px;
320
- display: flex;
321
- justify-content: flex-start;
322
- align-items: center;
323
- flex-direction: column;
324
- gap: 16px;
325
- overflow-y: auto;
326
- }
327
-
328
- .react-pdf__Page__annotations {
329
- display: none !important;
330
- height: 0px !important;
331
- width: 0px !important;
332
- }
333
- `;
334
-
335
- exports.PdfComponent = PdfComponent;
package/lib/index.d.cts DELETED
@@ -1,13 +0,0 @@
1
- import { BoxProps } from '@mui/system';
2
- import * as react_jsx_runtime from 'react/jsx-runtime';
3
-
4
- interface PdfProps extends BoxProps {
5
- url: string;
6
- backgroundColor?: string;
7
- loading?: any;
8
- maxHeight?: number | string;
9
- }
10
-
11
- declare function PdfComponent({ url, backgroundColor, loading, maxHeight, ...rest }: PdfProps): react_jsx_runtime.JSX.Element;
12
-
13
- export { PdfComponent, type PdfProps };
package/lib/index.d.mts DELETED
@@ -1,13 +0,0 @@
1
- import { BoxProps } from '@mui/system';
2
- import * as react_jsx_runtime from 'react/jsx-runtime';
3
-
4
- interface PdfProps extends BoxProps {
5
- url: string;
6
- backgroundColor?: string;
7
- loading?: any;
8
- maxHeight?: number | string;
9
- }
10
-
11
- declare function PdfComponent({ url, backgroundColor, loading, maxHeight, ...rest }: PdfProps): react_jsx_runtime.JSX.Element;
12
-
13
- export { PdfComponent, type PdfProps };
package/lib/index.d.ts DELETED
@@ -1,13 +0,0 @@
1
- import { BoxProps } from '@mui/system';
2
- import * as react_jsx_runtime from 'react/jsx-runtime';
3
-
4
- interface PdfProps extends BoxProps {
5
- url: string;
6
- backgroundColor?: string;
7
- loading?: any;
8
- maxHeight?: number | string;
9
- }
10
-
11
- declare function PdfComponent({ url, backgroundColor, loading, maxHeight, ...rest }: PdfProps): react_jsx_runtime.JSX.Element;
12
-
13
- export { PdfComponent, type PdfProps };
package/lib/index.js DELETED
@@ -1,335 +0,0 @@
1
- 'use strict';
2
-
3
- const jsxRuntime = require('react/jsx-runtime');
4
- const react = require('react');
5
- const reactPdf = require('react-pdf');
6
- const ahooks = require('ahooks');
7
- const useTheme = require('@mui/material/styles/useTheme');
8
- const useMediaQuery = require('@mui/material/useMediaQuery');
9
- const Box = require('@mui/material/Box');
10
- const Skeleton = require('@mui/material/Skeleton');
11
- const IconButton = require('@mui/material/IconButton');
12
- const FullscreenIcon = require('@mui/icons-material/Fullscreen');
13
- const ZoomOutIcon = require('@mui/icons-material/ZoomOut');
14
- const ZoomInIcon = require('@mui/icons-material/ZoomIn');
15
- const DownloadIcon = require('@mui/icons-material/Download');
16
- const ArrowOutwardOutlinedIcon = require('@mui/icons-material/ArrowOutwardOutlined');
17
- const material = require('@mui/material');
18
- require('react-pdf/dist/Page/AnnotationLayer.css');
19
- require('react-pdf/dist/Page/TextLayer.css');
20
-
21
- function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
22
-
23
- const useTheme__default = /*#__PURE__*/_interopDefaultCompat(useTheme);
24
- const useMediaQuery__default = /*#__PURE__*/_interopDefaultCompat(useMediaQuery);
25
- const Box__default = /*#__PURE__*/_interopDefaultCompat(Box);
26
- const Skeleton__default = /*#__PURE__*/_interopDefaultCompat(Skeleton);
27
- const IconButton__default = /*#__PURE__*/_interopDefaultCompat(IconButton);
28
- const FullscreenIcon__default = /*#__PURE__*/_interopDefaultCompat(FullscreenIcon);
29
- const ZoomOutIcon__default = /*#__PURE__*/_interopDefaultCompat(ZoomOutIcon);
30
- const ZoomInIcon__default = /*#__PURE__*/_interopDefaultCompat(ZoomInIcon);
31
- const DownloadIcon__default = /*#__PURE__*/_interopDefaultCompat(DownloadIcon);
32
- const ArrowOutwardOutlinedIcon__default = /*#__PURE__*/_interopDefaultCompat(ArrowOutwardOutlinedIcon);
33
-
34
- const workerSrc = `//unpkg.com/pdfjs-dist@${reactPdf.pdfjs.version}/legacy/build/pdf.worker.min.mjs`;
35
- reactPdf.pdfjs.GlobalWorkerOptions.workerSrc = workerSrc;
36
- const preventScrollChangeThumbnailTimerMap = {};
37
- const documentOptions = { isEvalSupported: false };
38
- const getBorder = (color) => `2px solid ${color}`;
39
- const defaultLoading = (props) => {
40
- return /* @__PURE__ */ jsxRuntime.jsx(Skeleton__default, { variant: "rectangular", width: "100%", ...props });
41
- };
42
- function PdfComponent({
43
- url,
44
- backgroundColor = "#fbfbfb",
45
- loading = defaultLoading,
46
- maxHeight = "60vh",
47
- ...rest
48
- }) {
49
- const pdfPageWrapperRef = react.useRef(null);
50
- const thumbnailWrapperRef = react.useRef(null);
51
- const preventScrollChangeThumbnailRef = react.useRef(false);
52
- const state = ahooks.useReactive({
53
- currentPage: 1,
54
- totalPage: 1,
55
- scale: 1
56
- });
57
- const wrapperSize = ahooks.useSize(pdfPageWrapperRef);
58
- const theme = useTheme__default();
59
- const isMobile = useMediaQuery__default(theme.breakpoints.down("sm"));
60
- const pdfUrl = url;
61
- const getPdfItemHeight = () => pdfPageWrapperRef.current?.children[0]?.offsetHeight;
62
- const onDocumentLoadSuccess = (pdf) => {
63
- state.totalPage = pdf.numPages;
64
- };
65
- const onPageChange = (page) => {
66
- state.currentPage = page;
67
- preventScrollChangeThumbnailRef.current = true;
68
- const top = getPdfItemHeight() * (page - 1);
69
- pdfPageWrapperRef?.current?.scrollTo({
70
- top,
71
- behavior: "smooth"
72
- });
73
- if (preventScrollChangeThumbnailTimerMap[pdfUrl])
74
- clearTimeout(preventScrollChangeThumbnailTimerMap[pdfUrl]);
75
- preventScrollChangeThumbnailTimerMap[pdfUrl] = setTimeout(() => {
76
- preventScrollChangeThumbnailRef.current = false;
77
- preventScrollChangeThumbnailTimerMap[pdfUrl] = null;
78
- }, 1e3);
79
- };
80
- const scrollEvent = (value) => {
81
- if (preventScrollChangeThumbnailRef.current) {
82
- return false;
83
- }
84
- const scrollPage = Math.floor(value.top / getPdfItemHeight()) + 1;
85
- if (scrollPage > 0 && scrollPage !== state.currentPage) {
86
- state.currentPage = scrollPage;
87
- thumbnailWrapperRef.current?.scrollTo({
88
- // @ts-ignore
89
- top: document.getElementById(`thumbnail-${scrollPage}`).offsetTop,
90
- behavior: "smooth"
91
- });
92
- return true;
93
- }
94
- };
95
- const { run: runScrollEvent } = ahooks.useDebounceFn(scrollEvent, {
96
- wait: 200
97
- });
98
- ahooks.useScroll(pdfPageWrapperRef, runScrollEvent);
99
- const commonPdfProps = {
100
- canvasBackground: backgroundColor
101
- };
102
- const [, { enterFullscreen }] = ahooks.useFullscreen(() => document.querySelector(".pdf-wrapper"));
103
- return /* @__PURE__ */ jsxRuntime.jsx(Root, { children: /* @__PURE__ */ jsxRuntime.jsx(
104
- reactPdf.Document,
105
- {
106
- loading: () => loading({
107
- height: maxHeight
108
- }),
109
- file: pdfUrl,
110
- onLoadSuccess: onDocumentLoadSuccess,
111
- options: documentOptions,
112
- children: /* @__PURE__ */ jsxRuntime.jsxs(
113
- Box__default,
114
- {
115
- className: "pdf-wrapper",
116
- sx: {
117
- // default max-height: 60vh
118
- maxHeight
119
- },
120
- ...rest,
121
- children: [
122
- /* @__PURE__ */ jsxRuntime.jsxs(
123
- Box__default,
124
- {
125
- className: "pdf-page",
126
- ref: pdfPageWrapperRef,
127
- sx: {
128
- background: backgroundColor,
129
- position: "relative"
130
- },
131
- children: [
132
- new Array(state.totalPage || 0).fill(0).map((_, index) => {
133
- const currentPage = index + 1;
134
- return /* @__PURE__ */ jsxRuntime.jsx(
135
- reactPdf.Page,
136
- {
137
- pageNumber: currentPage,
138
- renderTextLayer: false,
139
- width: wrapperSize?.width,
140
- scale: state.scale,
141
- ...commonPdfProps,
142
- loading: () => loading({
143
- height: maxHeight
144
- })
145
- },
146
- `${pdfUrl}-${currentPage}`
147
- );
148
- }),
149
- /* @__PURE__ */ jsxRuntime.jsxs(Box__default, { className: "pdf-page-toolbar", children: [
150
- /* @__PURE__ */ jsxRuntime.jsx(
151
- IconButton__default,
152
- {
153
- onClick: () => {
154
- if (state.scale > 0.1) {
155
- state.scale -= 0.1;
156
- }
157
- },
158
- children: /* @__PURE__ */ jsxRuntime.jsx(ZoomOutIcon__default, {})
159
- }
160
- ),
161
- /* @__PURE__ */ jsxRuntime.jsx(
162
- IconButton__default,
163
- {
164
- onClick: () => {
165
- state.scale += 0.1;
166
- },
167
- children: /* @__PURE__ */ jsxRuntime.jsx(ZoomInIcon__default, {})
168
- }
169
- ),
170
- /* @__PURE__ */ jsxRuntime.jsx(IconButton__default, { onClick: enterFullscreen, children: /* @__PURE__ */ jsxRuntime.jsx(FullscreenIcon__default, {}) }),
171
- /* @__PURE__ */ jsxRuntime.jsx(
172
- IconButton__default,
173
- {
174
- onClick: () => {
175
- const link = document.createElement("a");
176
- link.href = pdfUrl;
177
- link.download = pdfUrl.split("/").pop() || "download.pdf";
178
- link.click();
179
- },
180
- children: /* @__PURE__ */ jsxRuntime.jsx(DownloadIcon__default, {})
181
- }
182
- ),
183
- /* @__PURE__ */ jsxRuntime.jsx(
184
- IconButton__default,
185
- {
186
- onClick: () => {
187
- window.open(pdfUrl, "_blank");
188
- },
189
- children: /* @__PURE__ */ jsxRuntime.jsx(ArrowOutwardOutlinedIcon__default, {})
190
- }
191
- )
192
- ] })
193
- ]
194
- }
195
- ),
196
- /* @__PURE__ */ jsxRuntime.jsx(
197
- Box__default,
198
- {
199
- className: "pdf-thumbnail",
200
- ref: thumbnailWrapperRef,
201
- sx: {
202
- ".active": {
203
- border: getBorder(theme?.palette?.primary?.main),
204
- ".pdf-thumbnail-index": {
205
- background: theme?.palette?.primary?.main
206
- }
207
- },
208
- ".no-active": {
209
- border: getBorder("transparent")
210
- },
211
- "*": {
212
- transition: "all 0.2s",
213
- cursor: "pointer"
214
- }
215
- },
216
- children: new Array(state.totalPage || 0).fill(0).map((_, index) => {
217
- const currentPage = index + 1;
218
- const key = `thumbnail-${currentPage}`;
219
- const width = isMobile ? 90 : 120;
220
- return /* @__PURE__ */ jsxRuntime.jsx(
221
- Box__default,
222
- {
223
- id: key,
224
- className: `${state.currentPage === currentPage ? "active" : "no-active"}`,
225
- component: "a",
226
- sx: {
227
- width: width + 4
228
- // add border width
229
- },
230
- children: /* @__PURE__ */ jsxRuntime.jsx(
231
- reactPdf.Thumbnail,
232
- {
233
- pageIndex: currentPage,
234
- pageNumber: currentPage,
235
- width,
236
- ...commonPdfProps,
237
- onClick: (e) => {
238
- e.stopPropagation();
239
- e.preventDefault();
240
- onPageChange(currentPage);
241
- },
242
- loading: loading({
243
- height: `calc(${maxHeight} / ${isMobile ? 5 : 4})`,
244
- sx: {
245
- border: getBorder("transparent")
246
- }
247
- }),
248
- children: /* @__PURE__ */ jsxRuntime.jsxs(
249
- Box__default,
250
- {
251
- className: "pdf-thumbnail-index",
252
- component: "span",
253
- sx: {
254
- position: "absolute",
255
- textAlign: "center",
256
- bottom: 0,
257
- left: 0,
258
- right: 0,
259
- color: "#fff",
260
- fontSize: 13,
261
- p: 0.5,
262
- background: "rgba(0,0,0,0.25)"
263
- },
264
- children: [
265
- "# ",
266
- currentPage
267
- ]
268
- },
269
- `index-${currentPage}`
270
- )
271
- }
272
- )
273
- },
274
- key
275
- );
276
- })
277
- }
278
- )
279
- ]
280
- }
281
- )
282
- }
283
- ) });
284
- }
285
- const Root = material.styled(Box__default)`
286
- .pdf-wrapper {
287
- display: flex;
288
- justify-content: center;
289
- align-items: stretch;
290
- }
291
-
292
- .pdf-page {
293
- flex: 1;
294
- display: flex;
295
- flex-direction: column;
296
- justify-content: flex-start;
297
- align-items: center;
298
- overflow-y: auto;
299
- }
300
-
301
- .pdf-page-toolbar {
302
- position: sticky;
303
- margin-top: 16px;
304
- bottom: 16px;
305
- right: 0;
306
- left: 0;
307
- background: rgba(0, 0, 0, 0.5);
308
- border-radius: 4px;
309
- display: flex;
310
- align-items: center;
311
- padding: 2px 8px;
312
- gap: 4px;
313
- * {
314
- color: white;
315
- }
316
- }
317
-
318
- .pdf-thumbnail {
319
- margin-left: 16px;
320
- display: flex;
321
- justify-content: flex-start;
322
- align-items: center;
323
- flex-direction: column;
324
- gap: 16px;
325
- overflow-y: auto;
326
- }
327
-
328
- .react-pdf__Page__annotations {
329
- display: none !important;
330
- height: 0px !important;
331
- width: 0px !important;
332
- }
333
- `;
334
-
335
- exports.PdfComponent = PdfComponent;
package/lib/index.mjs DELETED
@@ -1,320 +0,0 @@
1
- import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { useRef } from 'react';
3
- import { pdfjs, Document, Page, Thumbnail } from 'react-pdf';
4
- import { useReactive, useSize, useDebounceFn, useScroll, useFullscreen } from 'ahooks';
5
- import useTheme from '@mui/material/styles/useTheme';
6
- import useMediaQuery from '@mui/material/useMediaQuery';
7
- import Box from '@mui/material/Box';
8
- import Skeleton from '@mui/material/Skeleton';
9
- import IconButton from '@mui/material/IconButton';
10
- import FullscreenIcon from '@mui/icons-material/Fullscreen';
11
- import ZoomOutIcon from '@mui/icons-material/ZoomOut';
12
- import ZoomInIcon from '@mui/icons-material/ZoomIn';
13
- import DownloadIcon from '@mui/icons-material/Download';
14
- import ArrowOutwardOutlinedIcon from '@mui/icons-material/ArrowOutwardOutlined';
15
- import { styled } from '@mui/material';
16
- import 'react-pdf/dist/Page/AnnotationLayer.css';
17
- import 'react-pdf/dist/Page/TextLayer.css';
18
-
19
- const workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/legacy/build/pdf.worker.min.mjs`;
20
- pdfjs.GlobalWorkerOptions.workerSrc = workerSrc;
21
- const preventScrollChangeThumbnailTimerMap = {};
22
- const documentOptions = { isEvalSupported: false };
23
- const getBorder = (color) => `2px solid ${color}`;
24
- const defaultLoading = (props) => {
25
- return /* @__PURE__ */ jsx(Skeleton, { variant: "rectangular", width: "100%", ...props });
26
- };
27
- function PdfComponent({
28
- url,
29
- backgroundColor = "#fbfbfb",
30
- loading = defaultLoading,
31
- maxHeight = "60vh",
32
- ...rest
33
- }) {
34
- const pdfPageWrapperRef = useRef(null);
35
- const thumbnailWrapperRef = useRef(null);
36
- const preventScrollChangeThumbnailRef = useRef(false);
37
- const state = useReactive({
38
- currentPage: 1,
39
- totalPage: 1,
40
- scale: 1
41
- });
42
- const wrapperSize = useSize(pdfPageWrapperRef);
43
- const theme = useTheme();
44
- const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
45
- const pdfUrl = url;
46
- const getPdfItemHeight = () => pdfPageWrapperRef.current?.children[0]?.offsetHeight;
47
- const onDocumentLoadSuccess = (pdf) => {
48
- state.totalPage = pdf.numPages;
49
- };
50
- const onPageChange = (page) => {
51
- state.currentPage = page;
52
- preventScrollChangeThumbnailRef.current = true;
53
- const top = getPdfItemHeight() * (page - 1);
54
- pdfPageWrapperRef?.current?.scrollTo({
55
- top,
56
- behavior: "smooth"
57
- });
58
- if (preventScrollChangeThumbnailTimerMap[pdfUrl])
59
- clearTimeout(preventScrollChangeThumbnailTimerMap[pdfUrl]);
60
- preventScrollChangeThumbnailTimerMap[pdfUrl] = setTimeout(() => {
61
- preventScrollChangeThumbnailRef.current = false;
62
- preventScrollChangeThumbnailTimerMap[pdfUrl] = null;
63
- }, 1e3);
64
- };
65
- const scrollEvent = (value) => {
66
- if (preventScrollChangeThumbnailRef.current) {
67
- return false;
68
- }
69
- const scrollPage = Math.floor(value.top / getPdfItemHeight()) + 1;
70
- if (scrollPage > 0 && scrollPage !== state.currentPage) {
71
- state.currentPage = scrollPage;
72
- thumbnailWrapperRef.current?.scrollTo({
73
- // @ts-ignore
74
- top: document.getElementById(`thumbnail-${scrollPage}`).offsetTop,
75
- behavior: "smooth"
76
- });
77
- return true;
78
- }
79
- };
80
- const { run: runScrollEvent } = useDebounceFn(scrollEvent, {
81
- wait: 200
82
- });
83
- useScroll(pdfPageWrapperRef, runScrollEvent);
84
- const commonPdfProps = {
85
- canvasBackground: backgroundColor
86
- };
87
- const [, { enterFullscreen }] = useFullscreen(() => document.querySelector(".pdf-wrapper"));
88
- return /* @__PURE__ */ jsx(Root, { children: /* @__PURE__ */ jsx(
89
- Document,
90
- {
91
- loading: () => loading({
92
- height: maxHeight
93
- }),
94
- file: pdfUrl,
95
- onLoadSuccess: onDocumentLoadSuccess,
96
- options: documentOptions,
97
- children: /* @__PURE__ */ jsxs(
98
- Box,
99
- {
100
- className: "pdf-wrapper",
101
- sx: {
102
- // default max-height: 60vh
103
- maxHeight
104
- },
105
- ...rest,
106
- children: [
107
- /* @__PURE__ */ jsxs(
108
- Box,
109
- {
110
- className: "pdf-page",
111
- ref: pdfPageWrapperRef,
112
- sx: {
113
- background: backgroundColor,
114
- position: "relative"
115
- },
116
- children: [
117
- new Array(state.totalPage || 0).fill(0).map((_, index) => {
118
- const currentPage = index + 1;
119
- return /* @__PURE__ */ jsx(
120
- Page,
121
- {
122
- pageNumber: currentPage,
123
- renderTextLayer: false,
124
- width: wrapperSize?.width,
125
- scale: state.scale,
126
- ...commonPdfProps,
127
- loading: () => loading({
128
- height: maxHeight
129
- })
130
- },
131
- `${pdfUrl}-${currentPage}`
132
- );
133
- }),
134
- /* @__PURE__ */ jsxs(Box, { className: "pdf-page-toolbar", children: [
135
- /* @__PURE__ */ jsx(
136
- IconButton,
137
- {
138
- onClick: () => {
139
- if (state.scale > 0.1) {
140
- state.scale -= 0.1;
141
- }
142
- },
143
- children: /* @__PURE__ */ jsx(ZoomOutIcon, {})
144
- }
145
- ),
146
- /* @__PURE__ */ jsx(
147
- IconButton,
148
- {
149
- onClick: () => {
150
- state.scale += 0.1;
151
- },
152
- children: /* @__PURE__ */ jsx(ZoomInIcon, {})
153
- }
154
- ),
155
- /* @__PURE__ */ jsx(IconButton, { onClick: enterFullscreen, children: /* @__PURE__ */ jsx(FullscreenIcon, {}) }),
156
- /* @__PURE__ */ jsx(
157
- IconButton,
158
- {
159
- onClick: () => {
160
- const link = document.createElement("a");
161
- link.href = pdfUrl;
162
- link.download = pdfUrl.split("/").pop() || "download.pdf";
163
- link.click();
164
- },
165
- children: /* @__PURE__ */ jsx(DownloadIcon, {})
166
- }
167
- ),
168
- /* @__PURE__ */ jsx(
169
- IconButton,
170
- {
171
- onClick: () => {
172
- window.open(pdfUrl, "_blank");
173
- },
174
- children: /* @__PURE__ */ jsx(ArrowOutwardOutlinedIcon, {})
175
- }
176
- )
177
- ] })
178
- ]
179
- }
180
- ),
181
- /* @__PURE__ */ jsx(
182
- Box,
183
- {
184
- className: "pdf-thumbnail",
185
- ref: thumbnailWrapperRef,
186
- sx: {
187
- ".active": {
188
- border: getBorder(theme?.palette?.primary?.main),
189
- ".pdf-thumbnail-index": {
190
- background: theme?.palette?.primary?.main
191
- }
192
- },
193
- ".no-active": {
194
- border: getBorder("transparent")
195
- },
196
- "*": {
197
- transition: "all 0.2s",
198
- cursor: "pointer"
199
- }
200
- },
201
- children: new Array(state.totalPage || 0).fill(0).map((_, index) => {
202
- const currentPage = index + 1;
203
- const key = `thumbnail-${currentPage}`;
204
- const width = isMobile ? 90 : 120;
205
- return /* @__PURE__ */ jsx(
206
- Box,
207
- {
208
- id: key,
209
- className: `${state.currentPage === currentPage ? "active" : "no-active"}`,
210
- component: "a",
211
- sx: {
212
- width: width + 4
213
- // add border width
214
- },
215
- children: /* @__PURE__ */ jsx(
216
- Thumbnail,
217
- {
218
- pageIndex: currentPage,
219
- pageNumber: currentPage,
220
- width,
221
- ...commonPdfProps,
222
- onClick: (e) => {
223
- e.stopPropagation();
224
- e.preventDefault();
225
- onPageChange(currentPage);
226
- },
227
- loading: loading({
228
- height: `calc(${maxHeight} / ${isMobile ? 5 : 4})`,
229
- sx: {
230
- border: getBorder("transparent")
231
- }
232
- }),
233
- children: /* @__PURE__ */ jsxs(
234
- Box,
235
- {
236
- className: "pdf-thumbnail-index",
237
- component: "span",
238
- sx: {
239
- position: "absolute",
240
- textAlign: "center",
241
- bottom: 0,
242
- left: 0,
243
- right: 0,
244
- color: "#fff",
245
- fontSize: 13,
246
- p: 0.5,
247
- background: "rgba(0,0,0,0.25)"
248
- },
249
- children: [
250
- "# ",
251
- currentPage
252
- ]
253
- },
254
- `index-${currentPage}`
255
- )
256
- }
257
- )
258
- },
259
- key
260
- );
261
- })
262
- }
263
- )
264
- ]
265
- }
266
- )
267
- }
268
- ) });
269
- }
270
- const Root = styled(Box)`
271
- .pdf-wrapper {
272
- display: flex;
273
- justify-content: center;
274
- align-items: stretch;
275
- }
276
-
277
- .pdf-page {
278
- flex: 1;
279
- display: flex;
280
- flex-direction: column;
281
- justify-content: flex-start;
282
- align-items: center;
283
- overflow-y: auto;
284
- }
285
-
286
- .pdf-page-toolbar {
287
- position: sticky;
288
- margin-top: 16px;
289
- bottom: 16px;
290
- right: 0;
291
- left: 0;
292
- background: rgba(0, 0, 0, 0.5);
293
- border-radius: 4px;
294
- display: flex;
295
- align-items: center;
296
- padding: 2px 8px;
297
- gap: 4px;
298
- * {
299
- color: white;
300
- }
301
- }
302
-
303
- .pdf-thumbnail {
304
- margin-left: 16px;
305
- display: flex;
306
- justify-content: flex-start;
307
- align-items: center;
308
- flex-direction: column;
309
- gap: 16px;
310
- overflow-y: auto;
311
- }
312
-
313
- .react-pdf__Page__annotations {
314
- display: none !important;
315
- height: 0px !important;
316
- width: 0px !important;
317
- }
318
- `;
319
-
320
- export { PdfComponent };