teamsync-pdf-viewer 1.3.3 → 1.3.5

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/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  All notable changes to `teamsync-pdf-viewer` are documented here.
4
4
 
5
+ ## [1.3.5] — 2026-09-04
6
+
7
+ ### Fixed
8
+ - **Annotations Before Document Canvas**: Fixed bug where the SVG annotation overlay and transient citation highlights rendered synchronously over a still-blank white container on initial load, virtualized scroll (pages 2+), and post-open fit re-renders. Annotations now wait until the underlying page canvas has finished rendering its pixels before becoming visible.
9
+ - **`hideAnnotationsUntilPageRendered` Option**: Added `hideAnnotationsUntilPageRendered?: boolean` (defaults to `true`) across `WebViewerOptions`, `TeamSyncViewerProps`, and `DocumentViewerProps`.
10
+ - **`pageRendered` Lifecycle Event**: Added `pageRendered: { url: string; pageNumber: number }` to `ViewerEventMap` and `onPageRendered` callback to `TeamSyncViewerProps` and `DocumentViewerProps`, giving consumers a lifecycle hook whenever any page finishes canvas rendering.
11
+ - **Capped Zoom Level to 800%**: Changed `MAX_SCALE = 8.0` (800%), updated zoom stepping and boundary checks, and updated toolbar preset dropdown to cap at 800%.
12
+
13
+ ## [1.3.4] — 2026-09-04
14
+
15
+ ### Fixed
16
+ - **Mobile & Android Canvas Clamping**: Expanded `isMobileOrTablet()` to comprehensively detect Android and mobile devices, capping max dimension to 2048px and pixel buffer to 4.2 MP (~16MB) to eliminate canvas crashes and blank pages on mobile devices.
17
+ - **Render Task Lifecycle & Race Condition Fix**: Scoped `currentPage` locally within `renderCanvas` so cancelling in-flight renders during rapid zoom clicks never accidentally destroys resources of a newly scheduled page proxy.
18
+ - **Graceful Context Allocation Fallback**: Added half-resolution fallback if `getContext('2d')` ever encounters device memory pressure, preventing invisible pages.
19
+ - **Rapid Click Selection Prevention**: Added `userSelect: none` on toolbar zoom buttons to eliminate browser text selection during rapid clicking.
20
+
5
21
  ## [1.3.3] — 2026-09-04
6
22
 
7
23
  ### Fixed
@@ -35,6 +35,8 @@ interface DocumentViewerProps {
35
35
  onLoadError?: (error: Error, info: DocumentLoadErrorInfo) => void;
36
36
  /** Fires once per loaded document, after the first page canvas has been painted. */
37
37
  onFirstPageRendered?: (pageNumber: number) => void;
38
+ /** Fires whenever any page canvas has finished rendering. */
39
+ onPageRendered?: (pageNumber: number) => void;
38
40
  onPageChange?: (pageNumber: number, numPages: number) => void;
39
41
  pageTransition: 'continuous' | 'page-by-page';
40
42
  pageLayout: 'single' | 'double' | 'cover-facing';
@@ -47,6 +49,8 @@ interface DocumentViewerProps {
47
49
  page?: number;
48
50
  transientHighlights?: TransientHighlight[];
49
51
  permissions?: SDKPermissions;
52
+ /** Whether to hide annotations and transient highlights until the page canvas has finished rendering. Default: true. */
53
+ hideAnnotationsUntilPageRendered?: boolean;
50
54
  }
51
- export default function DocumentViewer({ leftSidebarOpen, rightSidebarOpen, activeTab, annotationManager, initialDoc, loadNonce, withCredentials, assets, sidebars, redactions, regexRedactions, scale, setScale, sidebarTab, setSidebarTab, onAnnotationsChange, onRedactionsChange, onDocumentLoaded, onLoadError, onFirstPageRendered, onPageChange, pageTransition, pageLayout, rotation, setRotation, watermark, watermarkText, enableAnnotations: _enableAnnotations, initialPage, page, transientHighlights, permissions }: DocumentViewerProps): React.JSX.Element;
55
+ export default function DocumentViewer({ leftSidebarOpen, rightSidebarOpen, activeTab, annotationManager, initialDoc, loadNonce, withCredentials, assets, sidebars, redactions, regexRedactions, scale, setScale, sidebarTab, setSidebarTab, onAnnotationsChange, onRedactionsChange, onDocumentLoaded, onLoadError, onFirstPageRendered, onPageRendered, onPageChange, pageTransition, pageLayout, rotation, setRotation, watermark, watermarkText, enableAnnotations: _enableAnnotations, initialPage, page, transientHighlights, permissions, hideAnnotationsUntilPageRendered }: DocumentViewerProps): React.JSX.Element;
52
56
  export {};
@@ -35,7 +35,9 @@ interface PageRendererProps {
35
35
  onDiscardRedaction?: (redaction: Redaction) => void;
36
36
  /** Called after the page canvas has been painted (used for first-page-rendered telemetry). */
37
37
  onRendered?: (pageNum: number) => void;
38
+ /** Whether to hide annotations and transient highlights until the page canvas has finished rendering. Default: true. */
39
+ hideAnnotationsUntilPageRendered?: boolean;
38
40
  }
39
- declare function PageRendererComponent({ pageNum, pdfDoc, scale, rotation, containerWidth: _containerWidth, containerHeight: _containerHeight, scrollTop: _scrollTop, scrollLeft: _scrollLeft, pageTop, pageLeft, basePageWidth, basePageHeight, activeTab, activeTool, annotations, selectedAnnotationId, activeSearchResult, transientHighlights, onMouseDown, onMouseMove, onMouseUp, onAnnotationClick, onAnnotationMouseEnter, onClearSelection, watermark, watermarkText, redactions, onDiscardRedaction, onRendered }: PageRendererProps): React.JSX.Element;
41
+ declare function PageRendererComponent({ pageNum, pdfDoc, scale, rotation, containerWidth: _containerWidth, containerHeight: _containerHeight, scrollTop: _scrollTop, scrollLeft: _scrollLeft, pageTop, pageLeft, basePageWidth, basePageHeight, activeTab, activeTool, annotations, selectedAnnotationId, activeSearchResult, transientHighlights, onMouseDown, onMouseMove, onMouseUp, onAnnotationClick, onAnnotationMouseEnter, onClearSelection, watermark, watermarkText, redactions, onDiscardRedaction, onRendered, hideAnnotationsUntilPageRendered }: PageRendererProps): React.JSX.Element;
40
42
  declare const PageRenderer: React.MemoExoticComponent<typeof PageRendererComponent>;
41
43
  export default PageRenderer;
@@ -24,6 +24,7 @@ interface SideBySideViewerProps {
24
24
  selectedDiffId?: string | null;
25
25
  onSelectDiff?: (id: string) => void;
26
26
  onScrollSync?: (scrollTop: number, scrollLeft: number) => void;
27
+ hideAnnotationsUntilPageRendered?: boolean;
27
28
  }
28
- export default function SideBySideViewer({ pdfDocA, pdfDocB, pageNum, scale, rotation, basePageDims, activeTab, activeTool, annotations, watermark, watermarkText, redactions, diffsA, diffsB, selectedDiffId, onSelectDiff }: SideBySideViewerProps): React.JSX.Element;
29
+ export default function SideBySideViewer({ pdfDocA, pdfDocB, pageNum, scale, rotation, basePageDims, activeTab, activeTool, annotations, watermark, watermarkText, redactions, diffsA, diffsB, selectedDiffId, onSelectDiff, hideAnnotationsUntilPageRendered }: SideBySideViewerProps): React.JSX.Element;
29
30
  export {};
@@ -22,6 +22,11 @@ export interface TeamSyncViewerProps extends Omit<WebViewerOptions, 'path'> {
22
22
  url: string;
23
23
  pageNumber: number;
24
24
  }) => void;
25
+ /** Fires whenever any page canvas has finished rendering. */
26
+ onPageRendered?: (info: {
27
+ url: string;
28
+ pageNumber: number;
29
+ }) => void;
25
30
  /** Fires (in addition to onDocumentLoadError) when the document is password protected. */
26
31
  onPasswordRequired?: (info: {
27
32
  url: string;
@@ -100,6 +100,12 @@ export interface WebViewerOptions {
100
100
  leftPanelOpen?: boolean;
101
101
  /** Focus the viewer on mount so keyboard shortcuts work immediately. Default false. */
102
102
  autoFocus?: boolean;
103
+ /**
104
+ * Hide SVG annotation overlays and transient highlights until the underlying page canvas has finished rendering.
105
+ * Prevents annotations from rendering over a blank white page container on initial load, scroll, or fit re-render.
106
+ * Default true.
107
+ */
108
+ hideAnnotationsUntilPageRendered?: boolean;
103
109
  }
104
110
  /** Events available through `instance.on(type, listener)`. */
105
111
  export interface ViewerEventMap {
@@ -116,6 +122,10 @@ export interface ViewerEventMap {
116
122
  url: string;
117
123
  pageNumber: number;
118
124
  };
125
+ pageRendered: {
126
+ url: string;
127
+ pageNumber: number;
128
+ };
119
129
  pageChanged: {
120
130
  pageNumber: number;
121
131
  numPages: number;
@@ -2,16 +2,18 @@
2
2
  * © 2026 AngelBot Ai Pvt Ltd. All rights reserved.
3
3
  */
4
4
  export declare const MIN_SCALE = 0.1;
5
- export declare const MAX_SCALE = 10;
5
+ export declare const MAX_SCALE = 8;
6
+ export declare const isMobileOrTablet: () => boolean;
6
7
  export declare const isSafariOrMobile: () => boolean;
7
- export declare const MAX_CANVAS_DIM = 8192;
8
- export declare const MAX_CANVAS_DIM_MOBILE = 4096;
9
- export declare const MAX_CANVAS_PIXELS = 16777216;
8
+ export declare const MAX_CANVAS_DIM = 4096;
9
+ export declare const MAX_CANVAS_DIM_MOBILE = 2048;
10
+ export declare const MAX_CANVAS_PIXELS = 8388608;
11
+ export declare const MAX_CANVAS_PIXELS_MOBILE = 4194304;
10
12
  /**
11
13
  * Calculates the next step when zooming in.
12
14
  * - Below 200%: steps by +25%
13
15
  * - 200% to 500%: steps by +50%
14
- * - 500% to 1000%: steps by +100%
16
+ * - 500% to 800%: steps by +100%
15
17
  */
16
18
  export declare function calculateNextZoomIn(currentScale: number, maxScale?: number): number;
17
19
  /**