@octanejs/pdf 0.0.27 → 0.0.29

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.
Files changed (2) hide show
  1. package/package.json +3 -3
  2. package/src/components.tsrx +339 -295
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@octanejs/pdf",
3
- "version": "0.0.27",
3
+ "version": "0.0.29",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "engines": {
@@ -46,7 +46,7 @@
46
46
  "pdfjs-dist": "5.4.296"
47
47
  },
48
48
  "peerDependencies": {
49
- "octane": "^0.10.0"
49
+ "octane": "^0.11.0"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@types/react": "19.2.7",
@@ -57,7 +57,7 @@
57
57
  "dequal": "^2.0.3",
58
58
  "make-cancellable-promise": "^2.0.0",
59
59
  "merge-refs": "^2.0.0",
60
- "octane": "0.10.0",
60
+ "octane": "0.11.0",
61
61
  "playwright": "^1.61.1",
62
62
  "react": "19.2.3",
63
63
  "react-dom": "19.2.3",
@@ -41,10 +41,12 @@ const BLOCKED_CUSTOM_TEXT_TAGS = new Set([
41
41
  const URL_ATTRIBUTES = new Set(['action', 'formaction', 'href', 'poster', 'src', 'xlink:href']);
42
42
 
43
43
  function isDangerousUrl(value: string): boolean {
44
- return value.replace(/[\u0000-\u0020\u007f]/g, '').toLowerCase().match(
45
- /^(?:javascript|vbscript):/,
46
- ) !==
47
- null;
44
+ return (
45
+ value
46
+ .replace(/[\u0000-\u0020\u007f]/g, '')
47
+ .toLowerCase()
48
+ .match(/^(?:javascript|vbscript):/) !== null
49
+ );
48
50
  }
49
51
 
50
52
  function sanitizeCustomTextNode(node: ChildNode): Node {
@@ -174,18 +176,19 @@ export function Document(props: DocumentProps = {}) {
174
176
  let active = true;
175
177
  setSource(undefined);
176
178
  setSourceError(null);
177
- void resolveSource(file).then((nextSource) => {
178
- if (!active) return;
179
- setSource(nextSource);
180
- onSourceSuccess?.();
181
- }).catch((caught: unknown) => {
182
- if (!active) return;
183
- const nextError =
184
- caught instanceof Error ? caught : new Error(String(caught));
185
- setSource(false);
186
- setSourceError(nextError);
187
- onSourceError?.(nextError);
188
- });
179
+ void resolveSource(file)
180
+ .then((nextSource) => {
181
+ if (!active) return;
182
+ setSource(nextSource);
183
+ onSourceSuccess?.();
184
+ })
185
+ .catch((caught: unknown) => {
186
+ if (!active) return;
187
+ const nextError = caught instanceof Error ? caught : new Error(String(caught));
188
+ setSource(false);
189
+ setSourceError(nextError);
190
+ onSourceError?.(nextError);
191
+ });
189
192
  return () => {
190
193
  active = false;
191
194
  };
@@ -198,26 +201,28 @@ export function Document(props: DocumentProps = {}) {
198
201
  setPdfError(null);
199
202
  if (!source) return;
200
203
 
201
- void import('pdfjs-dist').then((pdfjs) => {
202
- if (!active) return;
203
- loadingTask = pdfjs.getDocument({ ...source, ...options } as never);
204
- if (onLoadProgress) loadingTask.onProgress = onLoadProgress;
205
- loadingTask.onPassword = onPassword;
206
- return loadingTask.promise;
207
- }).then((nextPdf) => {
208
- if (!active || !nextPdf) return;
209
- setPdf(nextPdf);
210
- pagesRef.current = new Array(nextPdf.numPages);
211
- linkService.setDocument(nextPdf);
212
- onLoadSuccess?.(nextPdf);
213
- }).catch((caught: unknown) => {
214
- if (!active) return;
215
- const nextError =
216
- caught instanceof Error ? caught : new Error(String(caught));
217
- setPdf(false);
218
- setPdfError(nextError);
219
- onLoadError?.(nextError);
220
- });
204
+ void import('pdfjs-dist')
205
+ .then((pdfjs) => {
206
+ if (!active) return;
207
+ loadingTask = pdfjs.getDocument({ ...source, ...options } as never);
208
+ if (onLoadProgress) loadingTask.onProgress = onLoadProgress;
209
+ loadingTask.onPassword = onPassword;
210
+ return loadingTask.promise;
211
+ })
212
+ .then((nextPdf) => {
213
+ if (!active || !nextPdf) return;
214
+ setPdf(nextPdf);
215
+ pagesRef.current = new Array(nextPdf.numPages);
216
+ linkService.setDocument(nextPdf);
217
+ onLoadSuccess?.(nextPdf);
218
+ })
219
+ .catch((caught: unknown) => {
220
+ if (!active) return;
221
+ const nextError = caught instanceof Error ? caught : new Error(String(caught));
222
+ setPdf(false);
223
+ setPdfError(nextError);
224
+ onLoadError?.(nextError);
225
+ });
221
226
 
222
227
  return () => {
223
228
  active = false;
@@ -260,30 +265,33 @@ export function Document(props: DocumentProps = {}) {
260
265
 
261
266
  let content: unknown;
262
267
  if (!file) {
263
- content = <div class="react-pdf__message react-pdf__message--no-data">{renderMessage(
264
- noData,
265
- )}</div>;
268
+ content = (
269
+ <div class="react-pdf__message react-pdf__message--no-data">{renderMessage(noData)}</div>
270
+ );
266
271
  } else if (sourceError || pdfError || source === false || pdf === false) {
267
- content = <div class="react-pdf__message react-pdf__message--error">{renderMessage(
268
- error,
269
- )}</div>;
272
+ content = (
273
+ <div class="react-pdf__message react-pdf__message--error">{renderMessage(error)}</div>
274
+ );
270
275
  } else if (!pdf) {
271
- content = <div class="react-pdf__message react-pdf__message--loading">{renderMessage(
272
- loading,
273
- )}</div>;
276
+ content = (
277
+ <div class="react-pdf__message react-pdf__message--loading">{renderMessage(loading)}</div>
278
+ );
274
279
  } else {
275
- content = typeof children === 'function' && !isChildrenBlock(children)
276
- ? children(contextValue as DocumentRenderProps)
277
- : children;
280
+ content =
281
+ typeof children === 'function' && !isChildrenBlock(children)
282
+ ? children(contextValue as DocumentRenderProps)
283
+ : children;
278
284
  }
279
285
 
280
- return <div
281
- {...withEventData(hostProps, pdf)}
282
- ref={documentElement}
283
- class={['react-pdf__Document', classProp, className]}
284
- >
285
- <DocumentContext value={contextValue}>{content}</DocumentContext>
286
- </div>;
286
+ return (
287
+ <div
288
+ {...withEventData(hostProps, pdf)}
289
+ ref={documentElement}
290
+ class={['react-pdf__Document', classProp, className]}
291
+ >
292
+ <DocumentContext value={contextValue}>{content}</DocumentContext>
293
+ </div>
294
+ );
287
295
  }
288
296
 
289
297
  function makePageCallback(page: PDFPageProxy, viewport: PageViewport): PageCallback {
@@ -341,16 +349,19 @@ function StructTreeItem({ node, className }: { node: unknown; className?: string
341
349
  }
342
350
  }
343
351
  const onlyContentChild =
344
- value.children?.length === 1 && value.children[0] != null &&
345
- typeof value.children[0] === 'object' &&
346
- 'id' in value.children[0];
352
+ value.children?.length === 1 &&
353
+ value.children[0] != null &&
354
+ typeof value.children[0] === 'object' &&
355
+ 'id' in value.children[0];
347
356
  if (onlyContentChild) {
348
357
  const child = value.children?.[0] as { id?: string };
349
358
  if (child.id !== undefined) attributes['aria-owns'] = child.id;
350
359
  }
351
- return <span class={className} {...attributes}>
352
- {onlyContentChild ? null : value.children?.map((child) => <StructTreeItem node={child} />)}
353
- </span>;
360
+ return (
361
+ <span class={className} {...attributes}>
362
+ {onlyContentChild ? null : value.children?.map((child) => <StructTreeItem node={child} />)}
363
+ </span>
364
+ );
354
365
  }
355
366
 
356
367
  export function Page(props: PageProps = {}) {
@@ -412,8 +423,7 @@ export function Page(props: PageProps = {}) {
412
423
  const [page, setPage] = useState<PDFPageProxy | false | undefined>(undefined);
413
424
  const [pageError, setPageError] = useState<Error | null>(null);
414
425
  const [structTree, setStructTree] = useState<StructTreeNode | null | undefined>(undefined);
415
- const pageIndex =
416
- pageNumberProp != null ? pageNumberProp - 1 : pageIndexProp;
426
+ const pageIndex = pageNumberProp != null ? pageNumberProp - 1 : pageIndexProp;
417
427
  const pageNumber = pageNumberProp ?? (pageIndexProp != null ? pageIndexProp + 1 : undefined);
418
428
 
419
429
  if (pdf === undefined && documentContext === null) {
@@ -424,12 +434,7 @@ export function Page(props: PageProps = {}) {
424
434
  if (!page || !pageNumber) return null;
425
435
  const rotation = rotateProp ?? page.rotate;
426
436
  const base = page.getViewport({ scale: 1, rotation });
427
- const sizeScale =
428
- width
429
- ? width / base.width
430
- : height
431
- ? height / base.height
432
- : 1;
437
+ const sizeScale = width ? width / base.width : height ? height / base.height : 1;
433
438
  return page.getViewport({ scale: scaleProp * sizeScale, rotation });
434
439
  }, [height, page, pageNumber, rotateProp, scaleProp, width]);
435
440
 
@@ -438,17 +443,19 @@ export function Page(props: PageProps = {}) {
438
443
  setPage(undefined);
439
444
  setPageError(null);
440
445
  if (!pdf || !pageNumber) return;
441
- void pdf.getPage(pageNumber).then((nextPage) => {
442
- if (!active) return;
443
- setPage(nextPage);
444
- }).catch((caught: unknown) => {
445
- if (!active) return;
446
- const nextError =
447
- caught instanceof Error ? caught : new Error(String(caught));
448
- setPage(false);
449
- setPageError(nextError);
450
- onLoadError?.(nextError);
451
- });
446
+ void pdf
447
+ .getPage(pageNumber)
448
+ .then((nextPage) => {
449
+ if (!active) return;
450
+ setPage(nextPage);
451
+ })
452
+ .catch((caught: unknown) => {
453
+ if (!active) return;
454
+ const nextError = caught instanceof Error ? caught : new Error(String(caught));
455
+ setPage(false);
456
+ setPageError(nextError);
457
+ onLoadError?.(nextError);
458
+ });
452
459
  return () => {
453
460
  active = false;
454
461
  };
@@ -492,27 +499,30 @@ export function Page(props: PageProps = {}) {
492
499
  canvas.style.width = `${Math.floor(viewport.width)}px`;
493
500
  canvas.style.height = `${Math.floor(viewport.height)}px`;
494
501
  canvas.style.visibility = 'hidden';
495
- void import('pdfjs-dist').then((pdfjs) => {
496
- if (!active) return;
497
- renderTask = page.render({
498
- annotationMode: renderForms
499
- ? pdfjs.AnnotationMode.ENABLE_FORMS
500
- : pdfjs.AnnotationMode.ENABLE,
501
- canvas,
502
- canvasContext: canvas.getContext('2d', { alpha: false })!,
503
- background: canvasBackground,
504
- pageColors,
505
- viewport: renderViewport,
502
+ void import('pdfjs-dist')
503
+ .then((pdfjs) => {
504
+ if (!active) return;
505
+ renderTask = page.render({
506
+ annotationMode: renderForms
507
+ ? pdfjs.AnnotationMode.ENABLE_FORMS
508
+ : pdfjs.AnnotationMode.ENABLE,
509
+ canvas,
510
+ canvasContext: canvas.getContext('2d', { alpha: false })!,
511
+ background: canvasBackground,
512
+ pageColors,
513
+ viewport: renderViewport,
514
+ });
515
+ return renderTask.promise;
516
+ })
517
+ .then(() => {
518
+ if (!active || !renderTask) return;
519
+ canvas.style.visibility = '';
520
+ onRenderSuccess?.(makePageCallback(page, viewport));
521
+ })
522
+ .catch((caught: unknown) => {
523
+ if (!active || (caught instanceof Error && caught.name === 'AbortException')) return;
524
+ onRenderError?.(caught instanceof Error ? caught : new Error(String(caught)));
506
525
  });
507
- return renderTask.promise;
508
- }).then(() => {
509
- if (!active || !renderTask) return;
510
- canvas.style.visibility = '';
511
- onRenderSuccess?.(makePageCallback(page, viewport));
512
- }).catch((caught: unknown) => {
513
- if (!active || caught instanceof Error && caught.name === 'AbortException') return;
514
- onRenderError?.(caught instanceof Error ? caught : new Error(String(caught)));
515
- });
516
526
  return () => {
517
527
  active = false;
518
528
  renderTask?.cancel();
@@ -529,50 +539,52 @@ export function Page(props: PageProps = {}) {
529
539
  const element = textElement.current;
530
540
  if (!element) return;
531
541
  element.replaceChildren();
532
- void page.getTextContent().then(async (content) => {
533
- if (!active) return;
534
- contentLoaded = true;
535
- onGetTextSuccess?.(content);
536
- const pdfjs = await import('pdfjs-dist');
537
- if (!active) return;
538
- textLayer = new pdfjs.TextLayer({
539
- container: element,
540
- textContentSource: page.streamTextContent({ includeMarkedContent: true }),
541
- viewport,
542
- }) as { cancel: () => void; render: () => Promise<void> };
543
- await textLayer.render();
544
- if (!active) return;
545
- const end = document.createElement('div');
546
- end.className = 'endOfContent';
547
- element.append(end);
548
- if (customTextRenderer) {
549
- const children = element.querySelectorAll('[role="presentation"]');
550
- let childIndex = 0;
551
- content.items.forEach((item, itemIndex) => {
552
- if (!('str' in item)) return;
553
- const child = children[childIndex];
554
- if (child) {
555
- renderSafeCustomText(
556
- child,
557
- customTextRenderer({
558
- ...item,
559
- itemIndex,
560
- pageIndex,
561
- pageNumber,
562
- }),
563
- );
564
- }
565
- childIndex += item.str && item.hasEOL ? 2 : 1;
566
- });
567
- }
568
- onRenderTextLayerSuccess?.();
569
- }).catch((caught: unknown) => {
570
- if (!active || caught instanceof Error && caught.name === 'AbortException') return;
571
- const error =
572
- caught instanceof Error ? caught : new Error(String(caught));
573
- if (contentLoaded) onRenderTextLayerError?.(error);
574
- else onGetTextError?.(error);
575
- });
542
+ void page
543
+ .getTextContent()
544
+ .then(async (content) => {
545
+ if (!active) return;
546
+ contentLoaded = true;
547
+ onGetTextSuccess?.(content);
548
+ const pdfjs = await import('pdfjs-dist');
549
+ if (!active) return;
550
+ textLayer = new pdfjs.TextLayer({
551
+ container: element,
552
+ textContentSource: page.streamTextContent({ includeMarkedContent: true }),
553
+ viewport,
554
+ }) as { cancel: () => void; render: () => Promise<void> };
555
+ await textLayer.render();
556
+ if (!active) return;
557
+ const end = document.createElement('div');
558
+ end.className = 'endOfContent';
559
+ element.append(end);
560
+ if (customTextRenderer) {
561
+ const children = element.querySelectorAll('[role="presentation"]');
562
+ let childIndex = 0;
563
+ content.items.forEach((item, itemIndex) => {
564
+ if (!('str' in item)) return;
565
+ const child = children[childIndex];
566
+ if (child) {
567
+ renderSafeCustomText(
568
+ child,
569
+ customTextRenderer({
570
+ ...item,
571
+ itemIndex,
572
+ pageIndex,
573
+ pageNumber,
574
+ }),
575
+ );
576
+ }
577
+ childIndex += item.str && item.hasEOL ? 2 : 1;
578
+ });
579
+ }
580
+ onRenderTextLayerSuccess?.();
581
+ })
582
+ .catch((caught: unknown) => {
583
+ if (!active || (caught instanceof Error && caught.name === 'AbortException')) return;
584
+ const error = caught instanceof Error ? caught : new Error(String(caught));
585
+ if (contentLoaded) onRenderTextLayerError?.(error);
586
+ else onGetTextError?.(error);
587
+ });
576
588
  return () => {
577
589
  active = false;
578
590
  textLayer?.cancel();
@@ -587,32 +599,32 @@ export function Page(props: PageProps = {}) {
587
599
  const element = annotationElement.current;
588
600
  if (!element) return;
589
601
  element.replaceChildren();
590
- void page.getAnnotations().then(async (loadedAnnotations) => {
591
- if (!active) return;
592
- annotationsLoaded = true;
593
- onGetAnnotationsSuccess?.(loadedAnnotations);
594
- const annotations =
595
- filterAnnotations
602
+ void page
603
+ .getAnnotations()
604
+ .then(async (loadedAnnotations) => {
605
+ if (!active) return;
606
+ annotationsLoaded = true;
607
+ onGetAnnotationsSuccess?.(loadedAnnotations);
608
+ const annotations = filterAnnotations
596
609
  ? filterAnnotations({ annotations: loadedAnnotations })
597
610
  : loadedAnnotations;
598
- const pdfjs = await import('pdfjs-dist');
599
- if (!active) return;
600
- const annotationViewport = viewport.clone({ dontFlip: true });
601
- const parameters = {
602
- accessibilityManager: null,
603
- annotationCanvasMap: null,
604
- annotationEditorUIManager: null,
605
- annotationStorage: pdf.annotationStorage,
606
- commentManager: null,
607
- div: element,
608
- l10n: null,
609
- linkService: documentContext?.linkService,
610
- page,
611
- structTreeLayer: null,
612
- viewport: annotationViewport,
613
- };
614
- new pdfjs.AnnotationLayer(parameters as never).render(
615
- {
611
+ const pdfjs = await import('pdfjs-dist');
612
+ if (!active) return;
613
+ const annotationViewport = viewport.clone({ dontFlip: true });
614
+ const parameters = {
615
+ accessibilityManager: null,
616
+ annotationCanvasMap: null,
617
+ annotationEditorUIManager: null,
618
+ annotationStorage: pdf.annotationStorage,
619
+ commentManager: null,
620
+ div: element,
621
+ l10n: null,
622
+ linkService: documentContext?.linkService,
623
+ page,
624
+ structTreeLayer: null,
625
+ viewport: annotationViewport,
626
+ };
627
+ new pdfjs.AnnotationLayer(parameters as never).render({
616
628
  annotations,
617
629
  annotationStorage: pdf.annotationStorage,
618
630
  div: element,
@@ -621,37 +633,46 @@ export function Page(props: PageProps = {}) {
621
633
  page,
622
634
  renderForms,
623
635
  viewport: annotationViewport,
624
- } as never,
625
- );
626
- onRenderAnnotationLayerSuccess?.();
627
- }).catch((caught: unknown) => {
628
- if (!active) return;
629
- const error =
630
- caught instanceof Error ? caught : new Error(String(caught));
631
- if (annotationsLoaded) onRenderAnnotationLayerError?.(error);
632
- else onGetAnnotationsError?.(error);
633
- });
636
+ } as never);
637
+ onRenderAnnotationLayerSuccess?.();
638
+ })
639
+ .catch((caught: unknown) => {
640
+ if (!active) return;
641
+ const error = caught instanceof Error ? caught : new Error(String(caught));
642
+ if (annotationsLoaded) onRenderAnnotationLayerError?.(error);
643
+ else onGetAnnotationsError?.(error);
644
+ });
634
645
  return () => {
635
646
  active = false;
636
647
  element.replaceChildren();
637
648
  };
638
- }, [filterAnnotations, imageResourcesPath, page, pdf, renderAnnotationLayer, renderForms, viewport]);
649
+ }, [
650
+ filterAnnotations,
651
+ imageResourcesPath,
652
+ page,
653
+ pdf,
654
+ renderAnnotationLayer,
655
+ renderForms,
656
+ viewport,
657
+ ]);
639
658
 
640
659
  useEffect(() => {
641
660
  let active = true;
642
661
  setStructTree(undefined);
643
662
  if (!page || customTextRenderer || !renderTextLayer) return;
644
- void page.getStructTree().then((tree) => {
645
- if (!active) return;
646
- setStructTree(tree);
647
- if (tree) onGetStructTreeSuccess?.(tree);
648
- }).catch((caught: unknown) => {
649
- if (!active) return;
650
- const error =
651
- caught instanceof Error ? caught : new Error(String(caught));
652
- setStructTree(null);
653
- onGetStructTreeError?.(error);
654
- });
663
+ void page
664
+ .getStructTree()
665
+ .then((tree) => {
666
+ if (!active) return;
667
+ setStructTree(tree);
668
+ if (tree) onGetStructTreeSuccess?.(tree);
669
+ })
670
+ .catch((caught: unknown) => {
671
+ if (!active) return;
672
+ const error = caught instanceof Error ? caught : new Error(String(caught));
673
+ setStructTree(null);
674
+ onGetStructTreeError?.(error);
675
+ });
655
676
  return () => {
656
677
  active = false;
657
678
  };
@@ -670,68 +691,76 @@ export function Page(props: PageProps = {}) {
670
691
 
671
692
  let content: unknown;
672
693
  if (!pageNumber) {
673
- content = <div class="react-pdf__message react-pdf__message--no-data">{renderMessage(
674
- noData,
675
- )}</div>;
694
+ content = (
695
+ <div class="react-pdf__message react-pdf__message--no-data">{renderMessage(noData)}</div>
696
+ );
676
697
  } else if (pdf === false || page === false || pageError) {
677
- content = <div class="react-pdf__message react-pdf__message--error">{renderMessage(
678
- error,
679
- )}</div>;
698
+ content = (
699
+ <div class="react-pdf__message react-pdf__message--error">{renderMessage(error)}</div>
700
+ );
680
701
  } else if (!page || !viewport || !contextValue) {
681
- content = <div class="react-pdf__message react-pdf__message--loading">{renderMessage(
682
- loading,
683
- )}</div>;
702
+ content = (
703
+ <div class="react-pdf__message react-pdf__message--loading">{renderMessage(loading)}</div>
704
+ );
684
705
  } else {
685
706
  if (renderMode === 'custom' && !customRenderer) {
686
707
  throw new Error('renderMode was set to "custom", but no customRenderer was passed.');
687
708
  }
688
709
  const renderProps = contextValue as PageRenderProps;
689
- content = <PageContext value={contextValue}>
690
- {renderMode === 'canvas'
691
- ? <canvas
710
+ content = (
711
+ <PageContext value={contextValue}>
712
+ {renderMode === 'canvas' ? (
713
+ <canvas
692
714
  ref={canvasElement}
693
715
  class="react-pdf__Page__canvas"
694
716
  dir="ltr"
695
717
  style={{ display: 'block', userSelect: 'none' }}
696
718
  >
697
- {renderTextLayer && structTree
698
- ? <StructTreeItem
699
- className="react-pdf__Page__structTree structTree"
700
- node={structTree}
701
- />
702
- : null}
719
+ {renderTextLayer && structTree ? (
720
+ <StructTreeItem
721
+ className="react-pdf__Page__structTree structTree"
722
+ node={structTree}
723
+ />
724
+ ) : null}
703
725
  </canvas>
704
- : null}
705
- {renderMode === 'custom' && customRenderer ? createElement(customRenderer, {}) : null}
706
- {renderTextLayer
707
- ? <div ref={textElement} class="react-pdf__Page__textContent textLayer" />
708
- : null}
709
- {renderAnnotationLayer
710
- ? <div ref={annotationElement} class="react-pdf__Page__annotations annotationLayer" />
711
- : null}
712
- {typeof children === 'function' && !isChildrenBlock(children)
713
- ? children(renderProps)
714
- : children}
715
- </PageContext>;
726
+ ) : null}
727
+ {renderMode === 'custom' && customRenderer ? createElement(customRenderer, {}) : null}
728
+ {renderTextLayer ? (
729
+ <div ref={textElement} class="react-pdf__Page__textContent textLayer" />
730
+ ) : null}
731
+ {renderAnnotationLayer ? (
732
+ <div ref={annotationElement} class="react-pdf__Page__annotations annotationLayer" />
733
+ ) : null}
734
+ {typeof children === 'function' && !isChildrenBlock(children)
735
+ ? children(renderProps)
736
+ : children}
737
+ </PageContext>
738
+ );
716
739
  }
717
740
 
718
- return <div
719
- {...withEventData(hostProps, page && viewport ? makePageCallback(page, viewport) : page)}
720
- ref={pageElement}
721
- class={[_className, classProp, className]}
722
- data-page-number={pageNumber}
723
- style={{
724
- '--scale-round-x': '1px',
725
- '--scale-round-y': '1px',
726
- '--scale-factor': '1',
727
- '--user-unit': `${viewport?.scale ?? scaleProp}`,
728
- '--total-scale-factor': 'calc(var(--scale-factor) * var(--user-unit))',
729
- backgroundColor: canvasBackground || 'white',
730
- minHeight: 'min-content',
731
- minWidth: 'min-content',
732
- position: 'relative',
733
- } as never}
734
- >{content}</div>;
741
+ return (
742
+ <div
743
+ {...withEventData(hostProps, page && viewport ? makePageCallback(page, viewport) : page)}
744
+ ref={pageElement}
745
+ class={[_className, classProp, className]}
746
+ data-page-number={pageNumber}
747
+ style={
748
+ {
749
+ '--scale-round-x': '1px',
750
+ '--scale-round-y': '1px',
751
+ '--scale-factor': '1',
752
+ '--user-unit': `${viewport?.scale ?? scaleProp}`,
753
+ '--total-scale-factor': 'calc(var(--scale-factor) * var(--user-unit))',
754
+ backgroundColor: canvasBackground || 'white',
755
+ minHeight: 'min-content',
756
+ minWidth: 'min-content',
757
+ position: 'relative',
758
+ } as never
759
+ }
760
+ >
761
+ {content}
762
+ </div>
763
+ );
735
764
  }
736
765
 
737
766
  export function Thumbnail(props: ThumbnailProps = {}) {
@@ -742,8 +771,7 @@ export function Thumbnail(props: ThumbnailProps = {}) {
742
771
  throw new Error('Attempted to load a thumbnail, but no document was specified.');
743
772
  }
744
773
  const resolvedPageNumber = pageNumber ?? (pageIndex != null ? pageIndex + 1 : undefined);
745
- const resolvedPageIndex =
746
- resolvedPageNumber != null ? resolvedPageNumber - 1 : 0;
774
+ const resolvedPageIndex = resolvedPageNumber != null ? resolvedPageNumber - 1 : 0;
747
775
 
748
776
  function handleClick(event: MouseEvent) {
749
777
  event.preventDefault();
@@ -751,25 +779,30 @@ export function Thumbnail(props: ThumbnailProps = {}) {
751
779
  const args = { pageIndex: resolvedPageIndex, pageNumber: resolvedPageNumber };
752
780
  if (onItemClick) onItemClick(args);
753
781
  else if (documentContext?.linkService) documentContext.linkService.goToPage(resolvedPageNumber);
754
- else throw new Error('Either onItemClick callback or linkService must be defined in order to navigate to an outline item.');
782
+ else
783
+ throw new Error(
784
+ 'Either onItemClick callback or linkService must be defined in order to navigate to an outline item.',
785
+ );
755
786
  }
756
787
 
757
788
  const { class: _class, className: _className, onItemClick: _onItemClick, ...pageProps } = props;
758
- return <a
759
- class={['react-pdf__Thumbnail', classProp, className]}
760
- href={resolvedPageNumber ? '#' : undefined}
761
- onClick={handleClick}
762
- >
763
- <Page
764
- {...pageProps}
765
- _className="react-pdf__Thumbnail__page"
766
- _enableRegisterUnregisterPage={false}
767
- pageIndex={pageIndex}
768
- pageNumber={pageNumber}
769
- renderAnnotationLayer={false}
770
- renderTextLayer={false}
771
- />
772
- </a>;
789
+ return (
790
+ <a
791
+ class={['react-pdf__Thumbnail', classProp, className]}
792
+ href={resolvedPageNumber ? '#' : undefined}
793
+ onClick={handleClick}
794
+ >
795
+ <Page
796
+ {...pageProps}
797
+ _className="react-pdf__Thumbnail__page"
798
+ _enableRegisterUnregisterPage={false}
799
+ pageIndex={pageIndex}
800
+ pageNumber={pageNumber}
801
+ renderAnnotationLayer={false}
802
+ renderTextLayer={false}
803
+ />
804
+ </a>
805
+ );
773
806
  }
774
807
 
775
808
  type OutlineEntry = NonNullable<Awaited<ReturnType<PDFDocumentProxy['getOutline']>>>[number];
@@ -788,14 +821,15 @@ function OutlineItem({
788
821
  async function activate(event: Event) {
789
822
  event.preventDefault();
790
823
  if (!onItemClick && !linkService) {
791
- throw new Error('Either onItemClick callback or linkService must be defined in order to navigate to an outline item.');
824
+ throw new Error(
825
+ 'Either onItemClick callback or linkService must be defined in order to navigate to an outline item.',
826
+ );
792
827
  }
793
828
  if (!onItemClick) {
794
829
  void linkService?.goToDestination(item.dest);
795
830
  return;
796
831
  }
797
- const dest =
798
- typeof item.dest === 'string' ? await pdf.getDestination(item.dest) : item.dest;
832
+ const dest = typeof item.dest === 'string' ? await pdf.getDestination(item.dest) : item.dest;
799
833
  if (!dest) throw new Error('Destination not found.');
800
834
  const reference = dest[0];
801
835
  const pageIndex =
@@ -804,20 +838,25 @@ function OutlineItem({
804
838
  onItemClick(args);
805
839
  }
806
840
 
807
- return <li>
808
- <a href="#" onClick={activate}>{item.title}</a>
809
- {item.items?.length
810
- ? <ul>{item.items.map(
811
- (child) =>
841
+ return (
842
+ <li>
843
+ <a href="#" onClick={activate}>
844
+ {item.title}
845
+ </a>
846
+ {item.items?.length ? (
847
+ <ul>
848
+ {item.items.map((child) => (
812
849
  <OutlineItem
813
850
  item={child}
814
851
  linkService={linkService}
815
852
  pdf={pdf}
816
853
  onItemClick={onItemClick}
817
- />,
818
- )}</ul>
819
- : null}
820
- </li>;
854
+ />
855
+ ))}
856
+ </ul>
857
+ ) : null}
858
+ </li>
859
+ );
821
860
  }
822
861
 
823
862
  export function Outline(props: OutlineProps = {}) {
@@ -850,17 +889,19 @@ export function Outline(props: OutlineProps = {}) {
850
889
  let active = true;
851
890
  setOutline(undefined);
852
891
  setFailed(false);
853
- void pdf.getOutline().then((nextOutline) => {
854
- if (!active) return;
855
- setOutline(nextOutline);
856
- onLoadSuccess?.(nextOutline);
857
- }).catch((caught: unknown) => {
858
- if (!active) return;
859
- const error =
860
- caught instanceof Error ? caught : new Error(String(caught));
861
- setFailed(true);
862
- onLoadError?.(error);
863
- });
892
+ void pdf
893
+ .getOutline()
894
+ .then((nextOutline) => {
895
+ if (!active) return;
896
+ setOutline(nextOutline);
897
+ onLoadSuccess?.(nextOutline);
898
+ })
899
+ .catch((caught: unknown) => {
900
+ if (!active) return;
901
+ const error = caught instanceof Error ? caught : new Error(String(caught));
902
+ setFailed(true);
903
+ onLoadError?.(error);
904
+ });
864
905
  return () => {
865
906
  active = false;
866
907
  };
@@ -868,21 +909,24 @@ export function Outline(props: OutlineProps = {}) {
868
909
 
869
910
  if (failed || !outline) return null;
870
911
  const clickHandler = onItemClick ?? documentContext?.onItemClick;
871
- return <div
872
- {...withEventData(hostProps, outline)}
873
- ref={outlineElement}
874
- class={['react-pdf__Outline', classProp, className]}
875
- >
876
- <OutlineContext value={{ onItemClick: clickHandler }}>
877
- <ul>{outline.map(
878
- (item) =>
879
- <OutlineItem
880
- item={item}
881
- linkService={documentContext?.linkService}
882
- pdf={pdf}
883
- onItemClick={clickHandler}
884
- />,
885
- )}</ul>
886
- </OutlineContext>
887
- </div>;
912
+ return (
913
+ <div
914
+ {...withEventData(hostProps, outline)}
915
+ ref={outlineElement}
916
+ class={['react-pdf__Outline', classProp, className]}
917
+ >
918
+ <OutlineContext value={{ onItemClick: clickHandler }}>
919
+ <ul>
920
+ {outline.map((item) => (
921
+ <OutlineItem
922
+ item={item}
923
+ linkService={documentContext?.linkService}
924
+ pdf={pdf}
925
+ onItemClick={clickHandler}
926
+ />
927
+ ))}
928
+ </ul>
929
+ </OutlineContext>
930
+ </div>
931
+ );
888
932
  }