@progress/kendo-react-pdf-viewer 5.10.0-dev.202211281232 → 5.10.0-dev.202212021346

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.
@@ -1,8 +1,9 @@
1
1
  import * as React from 'react';
2
- import { Toolbar } from '@progress/kendo-react-buttons';
2
+ import { ToolbarProps } from '@progress/kendo-react-buttons';
3
3
  import { SaveOptions } from '@progress/kendo-file-saver';
4
4
  import { TypedArray } from 'pdfjs-dist/types/src/display/api';
5
5
  import 'pdfjs-dist/build/pdf.worker.entry';
6
+ export declare type PDFViewerTool = 'pager' | 'spacer' | 'zoomInOut' | 'zoom' | 'selection' | 'search' | 'open' | 'download' | 'print';
6
7
  interface PDFViewerEvent {
7
8
  /**
8
9
  * The event target object.
@@ -42,6 +43,32 @@ export interface DownloadEvent extends PDFViewerEvent {
42
43
  */
43
44
  export interface LoadEvent extends PDFViewerEvent {
44
45
  }
46
+ /**
47
+ * The KendoReact [PDFViewer]({% slug api_pdf-viewer_pdfviewer %}) ZoomEvent object.
48
+ */
49
+ export interface ZoomEvent extends PDFViewerEvent {
50
+ /**
51
+ * The zoom value.
52
+ */
53
+ zoom: number;
54
+ /**
55
+ * A React `SyntheticEvent`.
56
+ */
57
+ syntheticEvent: React.SyntheticEvent<any>;
58
+ }
59
+ /**
60
+ * The KendoReact [PDFViewer]({% slug api_pdf-viewer_pdfviewer %}) PageEvent object.
61
+ */
62
+ export interface PageEvent extends PDFViewerEvent {
63
+ /**
64
+ * The page number.
65
+ */
66
+ page: number;
67
+ /**
68
+ * A React `SyntheticEvent`.
69
+ */
70
+ syntheticEvent: React.SyntheticEvent<any>;
71
+ }
45
72
  /**
46
73
  * The props of the KendoReact [PDFViewer]({% slug api_pdf-viewer_pdfviewer %}) component.
47
74
  */
@@ -74,6 +101,12 @@ export interface PDFViewerProps {
74
101
  * Represents the options for saving the file when the user clicks the download tool.
75
102
  */
76
103
  saveOptions?: SaveOptions;
104
+ /**
105
+ * Represents the tools collection rendered in the toolbar.
106
+ *
107
+ * @default - ['pager', 'spacer', 'zoomInOut', 'zoom', 'selection', 'spacer', 'search', 'open', 'download', 'print']
108
+ */
109
+ tools?: PDFViewerTool[];
77
110
  /**
78
111
  * Represents the zoom levels populated in the ComboBox component.
79
112
  */
@@ -84,6 +117,26 @@ export interface PDFViewerProps {
84
117
  type: string;
85
118
  locationString?: string;
86
119
  }[];
120
+ /**
121
+ * Represents the zoom value of the document.
122
+ */
123
+ zoom?: number;
124
+ /**
125
+ * Represents the default zoom value.
126
+ */
127
+ defaultZoom?: number;
128
+ /**
129
+ * Represents the minimum zoom value.
130
+ */
131
+ minZoom?: number;
132
+ /**
133
+ * Represents the maximum zoom value.
134
+ */
135
+ maxZoom?: number;
136
+ /**
137
+ * Represents the zoom rate value.
138
+ */
139
+ zoomRate?: number;
87
140
  /**
88
141
  * Fires when an error occurs.
89
142
  */
@@ -95,11 +148,19 @@ export interface PDFViewerProps {
95
148
  /**
96
149
  * Fires when the download tool has been clicked. To prevent the download, return `false`.
97
150
  */
98
- onDownload?: (event: DownloadEvent) => boolean;
151
+ onDownload?: (event: DownloadEvent) => boolean | void;
152
+ /**
153
+ * Fires when the zoom has changed.
154
+ */
155
+ onZoom?: (event: ZoomEvent) => void;
156
+ /**
157
+ * Fires when the page has changed.
158
+ */
159
+ onPageChange?: (event: PageEvent) => void;
99
160
  /**
100
161
  * Fires when the toolbar component is about to be rendered. Use it to override the default appearance of the toolbar.
101
162
  */
102
- onRenderToolbar?: (defaultRendering: React.ReactElement<Toolbar>) => React.ReactNode;
163
+ onRenderToolbar?: (defaultRendering: React.ReactElement<ToolbarProps>) => React.ReactNode;
103
164
  /**
104
165
  * Fires when the content component is about to be rendered. Use it to override the default appearance of the content.
105
166
  */
@@ -17,22 +17,32 @@ const scroller_1 = require("./scroller");
17
17
  const search_1 = require("./search");
18
18
  const utils_1 = require("./utils");
19
19
  const messages_1 = require("./messages");
20
- const zoomMin = 0.5;
21
- const zoomMax = 4;
22
- const zoomStep = 0.25;
23
- const zoomLevels = [
24
- { id: 1, value: 1, text: 'ActualWidth', type: 'ActualWidth', locationString: messages_1.actualWidth },
25
- { id: 2, value: 1, text: 'FitToWidth', type: 'FitToWidth', locationString: messages_1.fitToWidth },
26
- { id: 3, value: 1, text: 'FitToPage', type: 'FitToPage', locationString: messages_1.fitToPage },
27
- { id: 4, value: 0.5, text: '50%', type: '' },
28
- { id: 5, value: 0.75, text: '75%', type: '' },
29
- { id: 6, value: 1, text: '100%', type: '' },
30
- { id: 7, value: 1.25, text: '125%', type: '' },
31
- { id: 8, value: 1.5, text: '150%', type: '' },
32
- { id: 9, value: 2, text: '200%', type: '' },
33
- { id: 10, value: 3, text: '300%', type: '' },
34
- { id: 11, value: 4, text: '400%', type: '' }
20
+ const toolNames = [
21
+ 'pager', 'spacer', 'zoomInOut', 'zoom', 'selection', 'spacer', 'search', 'open', 'download', 'print'
35
22
  ];
23
+ // Correct declaration but typedoc does not recognize it.
24
+ // export type PDFViewerTool = typeof toolNames[number];
25
+ const defaultProps = {
26
+ minZoom: 0.5,
27
+ maxZoom: 4,
28
+ tools: [...toolNames],
29
+ zoomRate: 0.25,
30
+ zoomLevels: [
31
+ { id: 1, value: 1, text: 'ActualWidth', type: 'ActualWidth', locationString: messages_1.actualWidth },
32
+ { id: 2, value: 1, text: 'FitToWidth', type: 'FitToWidth', locationString: messages_1.fitToWidth },
33
+ { id: 3, value: 1, text: 'FitToPage', type: 'FitToPage', locationString: messages_1.fitToPage },
34
+ { id: 4, value: 0.5, text: '50%', type: '' },
35
+ { id: 5, value: 0.75, text: '75%', type: '' },
36
+ { id: 6, value: 1, text: '100%', type: '' },
37
+ { id: 7, value: 1.25, text: '125%', type: '' },
38
+ { id: 8, value: 1.5, text: '150%', type: '' },
39
+ { id: 9, value: 2, text: '200%', type: '' },
40
+ { id: 10, value: 3, text: '300%', type: '' },
41
+ { id: 11, value: 4, text: '400%', type: '' }
42
+ ],
43
+ defaultZoom: 1.25,
44
+ defaultPage: 1
45
+ };
36
46
  const navigation = [
37
47
  '.k-toolbar > button',
38
48
  '.k-toolbar .k-combobox > input',
@@ -45,14 +55,19 @@ const navigation = [
45
55
  */
46
56
  exports.PDFViewer = React.forwardRef((props, ref) => {
47
57
  (0, kendo_react_common_1.validatePackage)(package_metadata_1.packageMetadata);
58
+ const { zoom, zoomLevels = defaultProps.zoomLevels, defaultZoom = defaultProps.defaultZoom, minZoom = defaultProps.minZoom, maxZoom = defaultProps.maxZoom, zoomRate = defaultProps.zoomRate } = props;
48
59
  const loc = (0, kendo_react_intl_1.useLocalization)();
49
60
  const pagesRef = React.useRef(null);
50
- const [zoom, setZoom] = React.useState(utils_1.DEFAULT_ZOOM_LEVEL);
51
- const [zoomLevel, setZoomLevel] = React.useState(zoomLevels.find(z => z.value === utils_1.DEFAULT_ZOOM_LEVEL));
61
+ const [stateZoom, setStateZoom] = React.useState(defaultZoom);
62
+ const currentZoom = zoom !== undefined ? zoom : stateZoom;
63
+ const currentZoomLevel = zoomLevels.find(z => z.value === currentZoom) ||
64
+ { text: (currentZoom * 100) + '%', value: currentZoom, id: currentZoom, locationString: '' };
65
+ if (currentZoomLevel.locationString) {
66
+ currentZoomLevel.text = loc.toLanguageString(currentZoomLevel.locationString, messages_1.messages[currentZoomLevel.locationString]);
67
+ }
68
+ const [hasDocument, setHasDocument] = React.useState(false);
52
69
  const [loading, setLoading] = React.useState(true);
53
70
  const [skip, setSkip] = React.useState(0);
54
- const [pages, setPages] = React.useState([]);
55
- const [doc, setDoc] = React.useState(null);
56
71
  const [enabledSelection, setEnabledSelection] = React.useState(false);
57
72
  const [showSearch, setShowSearch] = React.useState(false);
58
73
  const [matches, setMatches] = React.useState(0);
@@ -60,14 +75,15 @@ exports.PDFViewer = React.forwardRef((props, ref) => {
60
75
  const [matchCase, setMatchCase] = React.useState(false);
61
76
  const [searchText, setSearchText] = React.useState('');
62
77
  const refObj = React.useMemo(() => ({}), []);
78
+ refObj.currentZoom = currentZoom;
63
79
  const target = React.useRef(null);
64
80
  const pdfViewerRef = React.useRef(null);
65
81
  React.useImperativeHandle(target, () => ({
66
82
  element: pdfViewerRef.current,
67
83
  props,
68
- pages,
69
- document: doc
70
- }), [pages, doc]);
84
+ pages: refObj.pages,
85
+ document: refObj.document
86
+ }), []);
71
87
  React.useImperativeHandle(ref, () => target.current);
72
88
  const triggerOnLoad = React.useCallback(() => {
73
89
  if (props.onLoad) {
@@ -76,7 +92,6 @@ exports.PDFViewer = React.forwardRef((props, ref) => {
76
92
  }
77
93
  }, [props.onLoad]);
78
94
  const triggerOnDownload = React.useCallback((blob, fileName, saveOptions) => {
79
- let handled = false;
80
95
  if (props.onDownload) {
81
96
  const downloadEvent = {
82
97
  target: target.current,
@@ -84,9 +99,10 @@ exports.PDFViewer = React.forwardRef((props, ref) => {
84
99
  fileName,
85
100
  saveOptions
86
101
  };
87
- handled = props.onDownload.call(undefined, downloadEvent) || false;
102
+ const result = props.onDownload.call(undefined, downloadEvent);
103
+ return result === false ? true : false;
88
104
  }
89
- return handled;
105
+ return false;
90
106
  }, [props.onDownload]);
91
107
  const initScroller = React.useCallback(() => {
92
108
  var _a;
@@ -108,17 +124,20 @@ exports.PDFViewer = React.forwardRef((props, ref) => {
108
124
  charClass: 'k-text-char'
109
125
  });
110
126
  }, []);
111
- const done = React.useCallback(({ pdfPages, pdfDoc }) => {
112
- setDoc(pdfDoc);
113
- setPages(pdfPages);
127
+ const done = React.useCallback(({ pdfPages, pdfDoc, zoom: documentZoom }) => {
128
+ refObj.document = pdfDoc;
129
+ refObj.pages = pdfPages;
130
+ refObj.zoom = documentZoom;
114
131
  initScroller();
115
132
  setLoading(false);
133
+ setHasDocument(true);
116
134
  triggerOnLoad();
117
135
  }, []);
118
136
  const error = React.useCallback((reason) => {
137
+ refObj.document = null;
138
+ refObj.pages = [];
119
139
  setLoading(false);
120
- setDoc(null);
121
- setPages([]);
140
+ setHasDocument(false);
122
141
  if (props.onError) {
123
142
  const errorEvent = {
124
143
  error: typeof reason === 'string' ? { message: reason } : reason,
@@ -127,6 +146,7 @@ exports.PDFViewer = React.forwardRef((props, ref) => {
127
146
  props.onError.call(undefined, errorEvent);
128
147
  }
129
148
  }, [props.onError]);
149
+ refObj.onError = error;
130
150
  React.useEffect(() => {
131
151
  if (pagesRef.current) {
132
152
  if (props.url || props.data || props.arrayBuffer) {
@@ -137,20 +157,21 @@ exports.PDFViewer = React.forwardRef((props, ref) => {
137
157
  data: props.data,
138
158
  arrayBuffer: props.arrayBuffer,
139
159
  dom: pagesRef.current,
140
- zoom: utils_1.DEFAULT_ZOOM_LEVEL,
160
+ zoom: refObj.currentZoom,
141
161
  done,
142
- error
162
+ error: refObj.onError
143
163
  });
144
164
  }
145
165
  else {
166
+ refObj.document = null;
167
+ refObj.pages = [];
168
+ setHasDocument(false);
146
169
  setLoading(false);
147
170
  (0, utils_1.removeChildren)(pagesRef.current);
148
- setDoc(null);
149
- setPages([]);
150
171
  }
151
172
  }
152
- }, [props.url, props.data, props.arrayBuffer, error]);
153
- const reload = React.useCallback((pdfDoc, zoomLev = utils_1.DEFAULT_ZOOM_LEVEL) => {
173
+ }, [props.url, props.data, props.arrayBuffer]);
174
+ const reload = React.useCallback((pdfDoc, zoomLev) => {
154
175
  if (pagesRef.current) {
155
176
  setLoading(true);
156
177
  (0, utils_1.removeChildren)(pagesRef.current);
@@ -159,13 +180,19 @@ exports.PDFViewer = React.forwardRef((props, ref) => {
159
180
  zoom: zoomLev,
160
181
  dom: pagesRef.current,
161
182
  done: (pdfPages) => {
162
- setPages(pdfPages);
183
+ refObj.pages = pdfPages;
184
+ refObj.zoom = zoomLev;
163
185
  setLoading(false);
164
186
  },
165
187
  error
166
188
  });
167
189
  }
168
190
  }, [error]);
191
+ React.useEffect(() => {
192
+ if (pagesRef.current && refObj.document && currentZoom !== refObj.zoom) {
193
+ reload(refObj.document, currentZoom);
194
+ }
195
+ }, [currentZoom, reload]);
169
196
  const onSearch = React.useCallback(() => {
170
197
  setShowSearch(true);
171
198
  initSearch(pagesRef.current);
@@ -210,45 +237,97 @@ exports.PDFViewer = React.forwardRef((props, ref) => {
210
237
  }
211
238
  }, [currentMatch, matches]);
212
239
  const onPageChange = React.useCallback((e) => {
213
- if (pagesRef.current && pagesRef.current.parentNode instanceof HTMLDivElement) {
214
- const page = pagesRef.current.querySelector('.k-page');
215
- if (page instanceof HTMLDivElement) {
216
- const top = (page.offsetHeight + page.offsetTop) * e.skip;
217
- pagesRef.current.parentNode.scrollTo({ top, behavior: 'auto' });
240
+ if (pagesRef.current) {
241
+ const nextPage = e.skip;
242
+ (0, utils_1.scrollToPage)(pagesRef.current, nextPage);
243
+ const pageEvent = {
244
+ page: nextPage + 1,
245
+ target: target.current,
246
+ syntheticEvent: e.syntheticEvent
247
+ };
248
+ if (props.onPageChange) {
249
+ props.onPageChange.call(undefined, pageEvent);
218
250
  }
219
251
  }
220
252
  setSkip(e.skip);
221
- }, [skip]);
253
+ }, [skip, props.onPageChange]);
222
254
  const onScroll = React.useCallback((e) => {
223
- const targetEl = e.target;
224
- const page = targetEl.querySelector('.k-page');
225
- if (page) {
226
- setSkip(Math.floor(targetEl.scrollTop / (page.offsetHeight + page.offsetTop)));
255
+ if (pdfViewerRef.current) {
256
+ const nextPage = (0, utils_1.currentPage)(pdfViewerRef.current);
257
+ if (nextPage !== skip) {
258
+ setSkip(nextPage);
259
+ const pageEvent = {
260
+ page: nextPage + 1,
261
+ target: target.current,
262
+ syntheticEvent: e
263
+ };
264
+ if (props.onPageChange) {
265
+ props.onPageChange.call(undefined, pageEvent);
266
+ }
267
+ }
227
268
  }
228
- }, []);
229
- const onZoomIn = React.useCallback(() => {
230
- const newZoom = Math.min(zoom + zoomStep, zoomMax);
231
- if (newZoom !== zoom && doc) {
232
- setZoom(newZoom);
233
- reload(doc, newZoom);
269
+ }, [skip, props.onPageChange]);
270
+ const onZoomIn = React.useCallback((e) => {
271
+ const newZoom = Math.min(currentZoom + zoomRate, maxZoom);
272
+ if (newZoom !== currentZoom && refObj.document) {
273
+ setStateZoom(newZoom);
274
+ if (zoom === undefined) {
275
+ reload(refObj.document, newZoom);
276
+ }
277
+ if (props.onZoom) {
278
+ const zoomEvent = {
279
+ zoom: newZoom,
280
+ target: target.current,
281
+ syntheticEvent: e
282
+ };
283
+ props.onZoom.call(undefined, zoomEvent);
284
+ }
234
285
  }
235
- }, [zoom, doc]);
236
- const onZoomOut = React.useCallback(() => {
237
- const newZoom = Math.max(zoom - zoomStep, zoomMin);
238
- if (newZoom !== zoom && doc) {
239
- setZoom(newZoom);
240
- reload(doc, newZoom);
286
+ }, [currentZoom, zoomRate, maxZoom, zoom, props.onZoom, reload]);
287
+ const onZoomOut = React.useCallback((e) => {
288
+ const newZoom = Math.max(stateZoom - zoomRate, minZoom);
289
+ if (newZoom !== stateZoom && refObj.document) {
290
+ setStateZoom(newZoom);
291
+ if (zoom === undefined) {
292
+ reload(refObj.document, newZoom);
293
+ }
294
+ if (props.onZoom) {
295
+ const zoomEvent = {
296
+ zoom: newZoom,
297
+ target: target.current,
298
+ syntheticEvent: e
299
+ };
300
+ props.onZoom.call(undefined, zoomEvent);
301
+ }
241
302
  }
242
- }, [zoom, doc]);
303
+ }, [currentZoom, zoomRate, minZoom, zoom, props.onZoom, reload]);
243
304
  const onZoomLevelChange = React.useCallback((e) => {
244
- const item = e.value;
245
- const newZoom = item ? (0, utils_1.calculateZoomLevel)(item.value, item.type, zoom, pagesRef.current) : 1;
246
- if (zoom !== newZoom && doc) {
247
- setZoom(newZoom);
248
- reload(doc, newZoom);
305
+ const item = e.value === null ? { text: '100%', value: 1, id: 100 } : Object.assign({}, e.value);
306
+ if (item.value === undefined) {
307
+ const parsedText = parseFloat(item.text);
308
+ if (typeof parsedText === 'number' && !Number.isNaN(parsedText)) {
309
+ item.value = parsedText / 100;
310
+ }
311
+ else {
312
+ item.value = 1;
313
+ }
249
314
  }
250
- setZoomLevel(item);
251
- }, [zoom, doc]);
315
+ const newZoom = item ? (0, utils_1.calculateZoomLevel)(item.value, item.type, currentZoom, pagesRef.current) : 1;
316
+ if (currentZoom !== newZoom && refObj.document) {
317
+ setStateZoom(newZoom);
318
+ if (zoom === undefined) {
319
+ reload(refObj.document, newZoom);
320
+ }
321
+ if (props.onZoom) {
322
+ const zoomEvent = {
323
+ zoom: newZoom,
324
+ target: target.current,
325
+ syntheticEvent: e.syntheticEvent
326
+ };
327
+ props.onZoom.call(undefined, zoomEvent);
328
+ }
329
+ }
330
+ }, [currentZoom, zoom, props.onZoom, reload]);
252
331
  const onTextSelection = React.useCallback(() => {
253
332
  refObj.scroller.disablePanEventsTracking();
254
333
  setEnabledSelection(true);
@@ -273,8 +352,8 @@ exports.PDFViewer = React.forwardRef((props, ref) => {
273
352
  const onDone = () => {
274
353
  setLoading(false);
275
354
  };
276
- (0, utils_1.print)(pages, onDone, onError);
277
- }, [pages, error]);
355
+ (0, utils_1.print)(refObj.pages, onDone, onError);
356
+ }, [error]);
278
357
  const onAdd = React.useCallback((e) => {
279
358
  const st = e.newState;
280
359
  if (st[0] && st[0].getRawFile) {
@@ -290,7 +369,7 @@ exports.PDFViewer = React.forwardRef((props, ref) => {
290
369
  done,
291
370
  error
292
371
  });
293
- setZoom(utils_1.DEFAULT_ZOOM_LEVEL);
372
+ setStateZoom(utils_1.DEFAULT_ZOOM_LEVEL);
294
373
  }
295
374
  });
296
375
  }
@@ -305,30 +384,41 @@ exports.PDFViewer = React.forwardRef((props, ref) => {
305
384
  }
306
385
  }
307
386
  }, []);
308
- const noDocument = !doc;
309
387
  const loader = (loading && React.createElement("div", { className: "k-loader-container k-loader-container-md k-loader-top" },
310
388
  React.createElement("div", { className: "k-loader-container-overlay k-overlay-light" }),
311
389
  React.createElement("div", { className: "k-loader-container-inner " },
312
390
  React.createElement(kendo_react_indicators_1.Loader, { size: 'large' }))));
313
- const toolbar = (React.createElement(kendo_react_buttons_1.Toolbar, { buttons: navigation },
314
- React.createElement(kendo_react_data_tools_1.Pager, { previousNext: true, type: 'input', skip: skip, take: 1, total: pages.length, info: false, onPageChange: onPageChange }),
315
- React.createElement(kendo_react_buttons_1.ToolbarSpacer, null),
316
- React.createElement(kendo_react_buttons_1.ButtonGroup, null,
317
- React.createElement(kendo_react_buttons_1.Button, { className: 'k-toolbar-button', title: loc.toLanguageString(messages_1.zoomIn, messages_1.messages[messages_1.zoomIn]), disabled: zoom === zoomMax || noDocument, onClick: onZoomIn, icon: 'zoom-in' }),
318
- React.createElement(kendo_react_buttons_1.Button, { className: 'k-toolbar-button', title: loc.toLanguageString(messages_1.zoomOut, messages_1.messages[messages_1.zoomOut]), disabled: zoom === zoomMin || noDocument, onClick: onZoomOut, icon: 'zoom-out' })),
319
- React.createElement(kendo_react_dropdowns_1.ComboBox, { disabled: noDocument, data: (props.zoomLevels || zoomLevels).map(level => (Object.assign(Object.assign({}, level), { text: level.locationString
320
- ? loc.toLanguageString(level.locationString, messages_1.messages[level.locationString])
321
- : level.text }))), dataItemKey: 'id', textField: 'text', value: noDocument ? null : zoomLevel, onChange: onZoomLevelChange }),
322
- React.createElement(kendo_react_buttons_1.ButtonGroup, null,
323
- React.createElement(kendo_react_buttons_1.Button, { className: 'k-toolbar-button', title: loc.toLanguageString(messages_1.enableSelection, messages_1.messages[messages_1.enableSelection]), icon: 'cursor', disabled: noDocument, togglable: true, selected: enabledSelection && !noDocument, onClick: onTextSelection }),
324
- React.createElement(kendo_react_buttons_1.Button, { className: 'k-toolbar-button', title: loc.toLanguageString(messages_1.enablePanning, messages_1.messages[messages_1.enablePanning]), icon: 'hand', disabled: noDocument, togglable: true, selected: !enabledSelection && !noDocument, onClick: onPinning })),
325
- React.createElement(kendo_react_buttons_1.ToolbarSpacer, null),
326
- React.createElement(kendo_react_buttons_1.Button, { className: 'k-toolbar-button', title: loc.toLanguageString(messages_1.search, messages_1.messages[messages_1.search]), icon: 'search', disabled: noDocument, onClick: onSearch }),
391
+ const zoomInOut = (React.createElement(kendo_react_buttons_1.ButtonGroup, null,
392
+ React.createElement(kendo_react_buttons_1.Button, { className: 'k-toolbar-button', title: loc.toLanguageString(messages_1.zoomOut, messages_1.messages[messages_1.zoomOut]), disabled: currentZoom <= minZoom || !hasDocument, onClick: onZoomOut, icon: 'zoom-out' }),
393
+ React.createElement(kendo_react_buttons_1.Button, { className: 'k-toolbar-button', title: loc.toLanguageString(messages_1.zoomIn, messages_1.messages[messages_1.zoomIn]), disabled: currentZoom >= maxZoom || !hasDocument, onClick: onZoomIn, icon: 'zoom-in' })));
394
+ const zoomComboBoxTool = (React.createElement(kendo_react_dropdowns_1.ComboBox, { disabled: !hasDocument, data: (zoomLevels).map(level => (Object.assign(Object.assign({}, level), { text: level.locationString
395
+ ? loc.toLanguageString(level.locationString, messages_1.messages[level.locationString])
396
+ : level.text }))), dataItemKey: 'id', textField: 'text', value: hasDocument ? currentZoomLevel : null, allowCustom: true, onChange: onZoomLevelChange }));
397
+ const pagerTool = (React.createElement(kendo_react_data_tools_1.Pager, { previousNext: true, type: 'input', skip: skip, take: 1, total: refObj.pages ? refObj.pages.length : 0, info: false, onPageChange: onPageChange }));
398
+ const spacer = React.createElement(kendo_react_buttons_1.ToolbarSpacer, null);
399
+ const selectionTool = (React.createElement(kendo_react_buttons_1.ButtonGroup, null,
400
+ React.createElement(kendo_react_buttons_1.Button, { className: 'k-toolbar-button', title: loc.toLanguageString(messages_1.enableSelection, messages_1.messages[messages_1.enableSelection]), icon: 'cursor', disabled: !hasDocument, togglable: true, selected: enabledSelection && hasDocument, onClick: onTextSelection }),
401
+ React.createElement(kendo_react_buttons_1.Button, { className: 'k-toolbar-button', title: loc.toLanguageString(messages_1.enablePanning, messages_1.messages[messages_1.enablePanning]), icon: 'hand', disabled: !hasDocument, togglable: true, selected: !enabledSelection && hasDocument, onClick: onPinning })));
402
+ const searchTool = (React.createElement(kendo_react_buttons_1.Button, { className: 'k-toolbar-button', title: loc.toLanguageString(messages_1.search, messages_1.messages[messages_1.search]), icon: 'search', disabled: !hasDocument, onClick: onSearch }));
403
+ const openTool = (React.createElement(React.Fragment, null,
327
404
  React.createElement(kendo_react_buttons_1.Button, { className: 'k-toolbar-button', title: loc.toLanguageString(messages_1.open, messages_1.messages[messages_1.open]), icon: 'folder-open', onClick: onFileOpen }),
328
405
  React.createElement("div", { style: { display: 'none' } },
329
- React.createElement(kendo_react_upload_1.Upload, { restrictions: { allowedExtensions: ['.pdf'] }, onAdd: onAdd, autoUpload: false, defaultFiles: [], multiple: false, accept: ".pdf,.PDF", withCredentials: false })),
330
- React.createElement(kendo_react_buttons_1.Button, { className: 'k-toolbar-button', title: loc.toLanguageString(messages_1.download, messages_1.messages[messages_1.download]), icon: 'download', disabled: noDocument, onClick: onDownload }),
331
- React.createElement(kendo_react_buttons_1.Button, { className: 'k-toolbar-button', title: loc.toLanguageString(messages_1.print, messages_1.messages[messages_1.print]), icon: 'print', disabled: noDocument, onClick: onPrint })));
406
+ React.createElement(kendo_react_upload_1.Upload, { restrictions: { allowedExtensions: ['.pdf'] }, onAdd: onAdd, autoUpload: false, defaultFiles: [], multiple: false, accept: ".pdf,.PDF", withCredentials: false }))));
407
+ const downloadTool = (React.createElement(kendo_react_buttons_1.Button, { className: 'k-toolbar-button', title: loc.toLanguageString(messages_1.download, messages_1.messages[messages_1.download]), icon: 'download', disabled: !hasDocument, onClick: onDownload }));
408
+ const printTool = (React.createElement(kendo_react_buttons_1.Button, { className: 'k-toolbar-button', title: loc.toLanguageString(messages_1.print, messages_1.messages[messages_1.print]), icon: 'print', disabled: !hasDocument, onClick: onPrint }));
409
+ const tools = {
410
+ pager: pagerTool,
411
+ spacer,
412
+ zoomInOut,
413
+ zoom: zoomComboBoxTool,
414
+ selection: selectionTool,
415
+ search: searchTool,
416
+ open: openTool,
417
+ download: downloadTool,
418
+ print: printTool
419
+ };
420
+ const buttons = (props.tools || defaultProps.tools).map((tool) => tools[tool]);
421
+ const toolbar = (React.createElement(kendo_react_buttons_1.Toolbar, { buttons: navigation }, ...buttons));
332
422
  const content = (React.createElement("div", { className: (0, kendo_react_common_1.classNames)('k-canvas k-pdf-viewer-canvas k-pos-relative k-overflow-auto', {
333
423
  'k-enable-text-select': enabledSelection,
334
424
  'k-enable-panning': !enabledSelection
@@ -358,11 +448,19 @@ exports.PDFViewer.propTypes = {
358
448
  style: PropTypes.object,
359
449
  saveFileName: PropTypes.string,
360
450
  saveOptions: PropTypes.object,
451
+ tools: PropTypes.arrayOf(PropTypes.oneOf(toolNames).isRequired),
361
452
  zoomLevels: PropTypes.arrayOf(PropTypes.any),
453
+ zoom: PropTypes.number,
454
+ defaultZoom: PropTypes.number,
455
+ minZoom: PropTypes.number,
456
+ maxZoom: PropTypes.number,
457
+ zoomRate: PropTypes.number,
362
458
  onError: PropTypes.func,
363
459
  onLoad: PropTypes.func,
364
460
  onDownload: PropTypes.func,
365
461
  onRenderToolbar: PropTypes.func,
366
462
  onRenderContent: PropTypes.func,
367
- onRenderLoader: PropTypes.func
463
+ onRenderLoader: PropTypes.func,
464
+ onZoom: PropTypes.func
368
465
  };
466
+ exports.PDFViewer.defaultProps = defaultProps;
@@ -1 +1,2 @@
1
- export { PDFViewer, PDFViewerProps, PDFViewerHandle, LoadEvent, ErrorEvent, DownloadEvent } from './PDFViewer';
1
+ export { PDFViewer, PDFViewerProps, PDFViewerHandle, PDFViewerTool, LoadEvent, ErrorEvent, DownloadEvent, ZoomEvent, PageEvent } from './PDFViewer';
2
+ export { scrollToPage, currentPage } from './utils';
package/dist/npm/main.js CHANGED
@@ -1,5 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PDFViewer = void 0;
3
+ exports.currentPage = exports.scrollToPage = exports.PDFViewer = void 0;
4
4
  var PDFViewer_1 = require("./PDFViewer");
5
5
  Object.defineProperty(exports, "PDFViewer", { enumerable: true, get: function () { return PDFViewer_1.PDFViewer; } });
6
+ var utils_1 = require("./utils");
7
+ Object.defineProperty(exports, "scrollToPage", { enumerable: true, get: function () { return utils_1.scrollToPage; } });
8
+ Object.defineProperty(exports, "currentPage", { enumerable: true, get: function () { return utils_1.currentPage; } });
@@ -8,7 +8,7 @@ exports.packageMetadata = {
8
8
  name: '@progress/kendo-react-pdf-viewer',
9
9
  productName: 'KendoReact',
10
10
  productCodes: ['KENDOUIREACT', 'KENDOUICOMPLETE'],
11
- publishDate: 1669638609,
11
+ publishDate: 1669988664,
12
12
  version: '',
13
13
  licensingDocsUrl: 'https://www.telerik.com/kendo-react-ui/my-license/?utm_medium=product&utm_source=kendoreact&utm_campaign=kendo-ui-react-purchase-license-keys-warning'
14
14
  };
@@ -7,6 +7,7 @@ import { TypedArray } from 'pdfjs-dist/types/src/display/api';
7
7
  export declare type DoneFn = (result: {
8
8
  pdfPages: PDFPageProxy[];
9
9
  pdfDoc: PDFDocumentProxy;
10
+ zoom: number;
10
11
  }) => void;
11
12
  /**
12
13
  * @hidden
@@ -76,3 +77,17 @@ export declare const calculateZoomLevel: (zoomLevel: number, zoomLevelType: stri
76
77
  * @hidden
77
78
  */
78
79
  export declare const removeChildren: (dom: HTMLElement) => void;
80
+ /**
81
+ * Scrolls the PDFViewer document to the passed page number.
82
+ *
83
+ * @param rootElement The root HTML element of the PDFViewer component.
84
+ * @param pageNumber The page number.
85
+ */
86
+ export declare const scrollToPage: (rootElement: HTMLElement, pageNumber: number) => void;
87
+ /**
88
+ * A function which gives you the page number of the document according to the scroll position.
89
+ *
90
+ * @param rootElement The root HTML element of the PDFViewer component.
91
+ * @returns The page number.
92
+ */
93
+ export declare const currentPage: (rootElement: HTMLElement) => number;
package/dist/npm/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.removeChildren = exports.calculateZoomLevel = exports.goToPreviousSearchMatch = exports.goToNextSearchMatch = exports.print = exports.reloadDocument = exports.loadPDF = exports.download = exports.DEFAULT_ZOOM_LEVEL = void 0;
3
+ exports.currentPage = exports.scrollToPage = exports.removeChildren = exports.calculateZoomLevel = exports.goToPreviousSearchMatch = exports.goToNextSearchMatch = exports.print = exports.reloadDocument = exports.loadPDF = exports.download = exports.DEFAULT_ZOOM_LEVEL = void 0;
4
4
  const kendo_file_saver_1 = require("@progress/kendo-file-saver");
5
5
  const pdfjs_dist_1 = require("pdfjs-dist");
6
6
  /**
@@ -61,7 +61,7 @@ const loadPDF = (options) => {
61
61
  return page;
62
62
  }))
63
63
  .then((pdfPages) => {
64
- done({ pdfPages, pdfDoc });
64
+ done({ pdfPages, pdfDoc, zoom });
65
65
  }).catch((reason) => { options.error(reason); });
66
66
  }).catch((reason) => { options.error(reason); });
67
67
  };
@@ -249,3 +249,33 @@ const removeChildren = (dom) => {
249
249
  }
250
250
  };
251
251
  exports.removeChildren = removeChildren;
252
+ /**
253
+ * Scrolls the PDFViewer document to the passed page number.
254
+ *
255
+ * @param rootElement The root HTML element of the PDFViewer component.
256
+ * @param pageNumber The page number.
257
+ */
258
+ const scrollToPage = (rootElement, pageNumber) => {
259
+ const pages = rootElement.querySelectorAll('.k-page');
260
+ const page = pages[0];
261
+ if (page instanceof HTMLDivElement) {
262
+ const top = (page.offsetHeight + page.offsetTop) * Math.max(0, Math.min(pageNumber, pages.length - 1));
263
+ const scrollElement = page.closest('.k-pdf-viewer-canvas');
264
+ if (scrollElement) {
265
+ scrollElement.scrollTo({ top, behavior: 'auto' });
266
+ }
267
+ }
268
+ };
269
+ exports.scrollToPage = scrollToPage;
270
+ /**
271
+ * A function which gives you the page number of the document according to the scroll position.
272
+ *
273
+ * @param rootElement The root HTML element of the PDFViewer component.
274
+ * @returns The page number.
275
+ */
276
+ const currentPage = (rootElement) => {
277
+ const scrollElement = rootElement.querySelector('.k-pdf-viewer-canvas');
278
+ const page = rootElement.querySelector('.k-page');
279
+ return (scrollElement && page) ? Math.floor(scrollElement.scrollTop / (page.offsetHeight + page.offsetTop)) : 0;
280
+ };
281
+ exports.currentPage = currentPage;