teamsync-pdf-viewer 1.3.5 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/dist/src/annotations/types.d.ts +1 -1
- package/dist/src/components/DocumentViewer.d.ts +4 -1
- package/dist/src/components/PageRenderer.d.ts +4 -1
- package/dist/src/components/TeamSyncViewer.d.ts +8 -0
- package/dist/src/components/TextSelectionTooltip.d.ts +8 -0
- package/dist/src/core/ViewerInstance.d.ts +11 -0
- package/dist/src/core/types.d.ts +13 -0
- package/dist/src/index.d.ts +3 -1
- package/dist/src/utils/clipboardUtils.d.ts +5 -0
- package/dist/style.css +1 -1
- package/dist/teamsync-pdf-viewer.js +2266 -1423
- package/dist/teamsync-pdf-viewer.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `teamsync-pdf-viewer` are documented here.
|
|
4
4
|
|
|
5
|
+
## [1.5.0] — 2026-09-05
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **Undo & Redo Annotation Actions**: Added dedicated Undo and Redo buttons to the Annotate toolbar with live state reflection bound to history, alongside existing keyboard shortcuts (`Cmd+Z`/`Ctrl+Z` and `Cmd+Shift+Z`/`Ctrl+Y`).
|
|
9
|
+
- **Underline, Strikeout & Squiggly Tools**: Added first-class text markup annotations with toolbar tools, stroke width and color controls, drag creation, selection tooltip quick actions, SVG rendering (straight lines and sinusoidal waves), full XFDF export/import roundtrip, and PDF export baking via `pdf-lib`.
|
|
10
|
+
- **Text Annotation Automatic Word-Wrapping**: Text annotations now automatically wrap multi-line text cleanly inside SVG `<foreignObject>` containers (`word-break: break-word`, `overflow-wrap: break-word`, `white-space: pre-wrap`) and in baked PDF exports via dynamic text wrapping.
|
|
11
|
+
- **Interactive 8-Handle Text Resizing**: Text annotations now feature an interactive selection bounding box with 8 resize handles (`nw`, `n`, `ne`, `e`, `se`, `s`, `sw`, `w`) with directional cursors, real-time live text reflow during drag, and single-step undo history.
|
|
12
|
+
- **Quick-Markup Selection Tooltip**: Extended the floating selection tooltip with `[Highlight]`, `[Underline]`, `[Strikeout]`, and `[Squiggly]` quick actions.
|
|
13
|
+
|
|
14
|
+
## [1.4.0] — 2026-09-04
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
- **Text Selection & Copying Support**: Users can now select and copy text directly from PDF pages in the viewer.
|
|
18
|
+
- **Select & Pan Tool Modes**: Added `'select'` as a first-class `ToolMode`. Defaulted `activeTool` to `'select'` (matching Adobe Acrobat, Chrome, and PDF.js). Added "Select Text" (`MousePointer`) and "Pan Tool" (`Hand`) toggle buttons to the top toolbar. Added `defaultTool?: 'select' | 'pan'` and `enableTextSelection?: boolean` props to `WebViewerOptions` and `<TeamSyncViewer>`.
|
|
19
|
+
- **Triple-Layer Copy Workflows**:
|
|
20
|
+
- **Keyboard**: `Cmd+C` (macOS) / `Ctrl+C` (Windows/Linux) copies selected text to the clipboard.
|
|
21
|
+
- **Native Context Menu**: Right-clicking selected text preserves the native browser context menu ("Copy", "Look Up", "Search", "Translate").
|
|
22
|
+
- **Floating Quick-Copy Tooltip**: Rendered a sleek floating pill above active text selections with a `[Copy]` button and `✓ Copied!` visual feedback.
|
|
23
|
+
- **Public SDK APIs & Events**: Added `instance.getSelectedText(): string` and `instance.copySelectedText(): Promise<boolean>`, Apryse tool aliases in `instance.UI.setToolMode('select' | 'textSelect' | 'pan')`, and `textSelected` and `textCopied` events to `ViewerEventMap`.
|
|
24
|
+
- **Cross-Environment Clipboard Utility**: Exported `copyTextToClipboard` with modern `navigator.clipboard.writeText` and a hidden `document.execCommand('copy')` fallback for non-HTTPS and iframe environments.
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
- **Panning Drag Interference**: Drag-panning is now strictly scoped to `activeTool === 'pan'`, ensuring text selection click-and-drag is never hijacked.
|
|
28
|
+
- **SVG Overlay Pointer Events**: Configured SVG overlay to `pointerEvents: 'none'` in select and pan modes so clicks reach the text layer, while preserving `pointerEvents: 'all'` on individual annotation elements.
|
|
29
|
+
- **PDF.js v6 Text Layer CSS Variables**: Declared `--total-scale-factor: 1; --scale-factor: 1; --user-unit: 1; --min-font-size: 1; --scale-round-x: 1px; --scale-round-y: 1px;` on `.textLayer`, resolving collapsed 0px font sizes and heights. Styled `.textLayer span::selection` with transparent text so the underlying canvas raster remains crisp without double glyphs.
|
|
30
|
+
|
|
5
31
|
## [1.3.5] — 2026-09-04
|
|
6
32
|
|
|
7
33
|
### Fixed
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* /Rotate applied (top-left origin, PDF points). UI rotation applied by the viewer is composed on
|
|
7
7
|
* top of this space at render time, so stored annotations are independent of the current view.
|
|
8
8
|
*/
|
|
9
|
-
export type AnnotationType = 'rectangle' | 'ellipse' | 'line' | 'arrow' | 'freehand' | 'text' | 'note' | 'callout' | 'signature' | 'highlight' | 'digital_signature_placeholder' | 'link'
|
|
9
|
+
export type AnnotationType = 'rectangle' | 'ellipse' | 'line' | 'arrow' | 'freehand' | 'text' | 'note' | 'callout' | 'signature' | 'highlight' | 'underline' | 'strikeout' | 'squiggly' | 'digital_signature_placeholder' | 'link'
|
|
10
10
|
/**
|
|
11
11
|
* An annotation imported from XFDF that this viewer cannot edit or render natively (e.g.
|
|
12
12
|
* underline, squiggly, polygon, redaction). It is drawn as a read-only outline at its bounding
|
|
@@ -51,6 +51,9 @@ interface DocumentViewerProps {
|
|
|
51
51
|
permissions?: SDKPermissions;
|
|
52
52
|
/** Whether to hide annotations and transient highlights until the page canvas has finished rendering. Default: true. */
|
|
53
53
|
hideAnnotationsUntilPageRendered?: boolean;
|
|
54
|
+
enableTextSelection?: boolean;
|
|
55
|
+
defaultTool?: 'select' | 'pan';
|
|
56
|
+
showSelectionTooltip?: boolean;
|
|
54
57
|
}
|
|
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;
|
|
58
|
+
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, enableTextSelection, defaultTool, showSelectionTooltip }: DocumentViewerProps): React.JSX.Element;
|
|
56
59
|
export {};
|
|
@@ -27,6 +27,9 @@ interface PageRendererProps {
|
|
|
27
27
|
onMouseMove: (e: React.MouseEvent<Element>, pageNum: number) => void;
|
|
28
28
|
onMouseUp: (e: React.MouseEvent<Element>, pageNum: number) => void;
|
|
29
29
|
onAnnotationClick: (id: string, e: React.MouseEvent) => void;
|
|
30
|
+
onAnnotationDoubleClick?: (id: string, e: React.MouseEvent) => void;
|
|
31
|
+
onStartResize?: (id: string, handle: string, e: React.MouseEvent, pageNum: number) => void;
|
|
32
|
+
onStartMove?: (id: string, e: React.MouseEvent, pageNum: number) => void;
|
|
30
33
|
onAnnotationMouseEnter: (id: string) => void;
|
|
31
34
|
onClearSelection: () => void;
|
|
32
35
|
watermark?: WatermarkOptions;
|
|
@@ -38,6 +41,6 @@ interface PageRendererProps {
|
|
|
38
41
|
/** Whether to hide annotations and transient highlights until the page canvas has finished rendering. Default: true. */
|
|
39
42
|
hideAnnotationsUntilPageRendered?: boolean;
|
|
40
43
|
}
|
|
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;
|
|
44
|
+
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, onAnnotationDoubleClick, onStartResize, onStartMove, onAnnotationMouseEnter, onClearSelection, watermark, watermarkText, redactions, onDiscardRedaction, onRendered, hideAnnotationsUntilPageRendered }: PageRendererProps): React.JSX.Element;
|
|
42
45
|
declare const PageRenderer: React.MemoExoticComponent<typeof PageRendererComponent>;
|
|
43
46
|
export default PageRenderer;
|
|
@@ -35,6 +35,14 @@ export interface TeamSyncViewerProps extends Omit<WebViewerOptions, 'path'> {
|
|
|
35
35
|
onAnnotationsChange?: (annotations: Annotation[]) => void;
|
|
36
36
|
/** Fires whenever transient highlights change. */
|
|
37
37
|
onTransientHighlightsChange?: (highlights: TransientHighlight[]) => void;
|
|
38
|
+
/** Fires whenever the user selects text within the document. */
|
|
39
|
+
onTextSelected?: (info: {
|
|
40
|
+
text: string;
|
|
41
|
+
}) => void;
|
|
42
|
+
/** Fires whenever text is copied from the document. */
|
|
43
|
+
onTextCopied?: (info: {
|
|
44
|
+
text: string;
|
|
45
|
+
}) => void;
|
|
38
46
|
className?: string;
|
|
39
47
|
style?: React.CSSProperties;
|
|
40
48
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
interface TextSelectionTooltipProps {
|
|
3
|
+
containerRef: React.RefObject<HTMLDivElement | null>;
|
|
4
|
+
onCopy?: (text: string) => void;
|
|
5
|
+
onAnnotateSelection?: (type: 'highlight' | 'underline' | 'strikeout' | 'squiggly') => void;
|
|
6
|
+
}
|
|
7
|
+
export declare const TextSelectionTooltip: React.FC<TextSelectionTooltipProps>;
|
|
8
|
+
export default TextSelectionTooltip;
|
|
@@ -103,6 +103,15 @@ export declare class WebViewerInstance {
|
|
|
103
103
|
* Uses the bytes of the loaded document; never re-fetches the URL.
|
|
104
104
|
*/
|
|
105
105
|
getFileData(options?: ExportOptions): Promise<Uint8Array>;
|
|
106
|
+
/**
|
|
107
|
+
* Returns the currently selected text string from the document viewer, or an empty string if nothing is selected.
|
|
108
|
+
*/
|
|
109
|
+
getSelectedText(): string;
|
|
110
|
+
/**
|
|
111
|
+
* Copies the currently selected text to the system clipboard.
|
|
112
|
+
* Resolves to true if copying succeeded, false otherwise.
|
|
113
|
+
*/
|
|
114
|
+
copySelectedText(): Promise<boolean>;
|
|
106
115
|
readonly UI: {
|
|
107
116
|
/** Theming is not implemented; kept for API compatibility. */
|
|
108
117
|
setTheme: (_theme: string) => void;
|
|
@@ -114,6 +123,8 @@ export declare class WebViewerInstance {
|
|
|
114
123
|
disableElements: (elements: string[]) => void;
|
|
115
124
|
setActiveLeftPanel: (panel: string) => void;
|
|
116
125
|
setToolMode: (tool: string | null) => void;
|
|
126
|
+
getSelectedText: () => string;
|
|
127
|
+
copySelectedText: () => Promise<boolean>;
|
|
117
128
|
fitWidth: () => void;
|
|
118
129
|
fitPage: () => void;
|
|
119
130
|
fitToWidth: () => void;
|
package/dist/src/core/types.d.ts
CHANGED
|
@@ -54,6 +54,7 @@ export interface ViewerUser {
|
|
|
54
54
|
name: string;
|
|
55
55
|
}
|
|
56
56
|
export type InitialScale = number | 'fit-width' | 'fit-page';
|
|
57
|
+
export type ToolMode = 'select' | 'pan' | 'rectangle' | 'ellipse' | 'line' | 'arrow' | 'freehand' | 'highlight' | 'underline' | 'strikeout' | 'squiggly' | 'text' | 'eraser' | 'note' | 'callout' | 'signature' | 'digital_signature' | 'link' | 'redaction' | null;
|
|
57
58
|
/**
|
|
58
59
|
* Options accepted by `createWebViewer()` (and the deprecated `WebViewer()` alias).
|
|
59
60
|
* Every option is also available as a prop on `<TeamSyncViewer>`.
|
|
@@ -106,6 +107,12 @@ export interface WebViewerOptions {
|
|
|
106
107
|
* Default true.
|
|
107
108
|
*/
|
|
108
109
|
hideAnnotationsUntilPageRendered?: boolean;
|
|
110
|
+
/** Allow selecting text from PDF pages (default true). */
|
|
111
|
+
enableTextSelection?: boolean;
|
|
112
|
+
/** Initial tool mode on load. Defaults to 'select'. */
|
|
113
|
+
defaultTool?: 'select' | 'pan';
|
|
114
|
+
/** Show floating quick-action copy badge above selected text (default true). */
|
|
115
|
+
showSelectionTooltip?: boolean;
|
|
109
116
|
}
|
|
110
117
|
/** Events available through `instance.on(type, listener)`. */
|
|
111
118
|
export interface ViewerEventMap {
|
|
@@ -141,6 +148,12 @@ export interface ViewerEventMap {
|
|
|
141
148
|
toolChanged: {
|
|
142
149
|
tool: string | null;
|
|
143
150
|
};
|
|
151
|
+
textSelected: {
|
|
152
|
+
text: string;
|
|
153
|
+
};
|
|
154
|
+
textCopied: {
|
|
155
|
+
text: string;
|
|
156
|
+
};
|
|
144
157
|
destroy: Record<string, never>;
|
|
145
158
|
}
|
|
146
159
|
export type ViewerEventType = keyof ViewerEventMap;
|
package/dist/src/index.d.ts
CHANGED
|
@@ -17,7 +17,9 @@ export { ViewerBus } from './core/eventBus';
|
|
|
17
17
|
export type { BusListener } from './core/eventBus';
|
|
18
18
|
export { buildPdfBytes, MAX_EXPORT_BYTES } from './core/export';
|
|
19
19
|
export type { ExportInput, ExportOptions } from './core/export';
|
|
20
|
-
export type { WebViewerOptions, Redaction, WatermarkOptions, SDKPermissions, ViewerUser, InitialScale, ViewerEventMap, ViewerEventType, } from './core/types';
|
|
20
|
+
export type { WebViewerOptions, Redaction, WatermarkOptions, SDKPermissions, ViewerUser, InitialScale, ViewerEventMap, ViewerEventType, ToolMode, } from './core/types';
|
|
21
|
+
export { copyTextToClipboard } from './utils/clipboardUtils';
|
|
22
|
+
export { TextSelectionTooltip } from './components/TextSelectionTooltip';
|
|
21
23
|
export type { Annotation, AnnotationType, AnnotationPoint, AnnotationInput } from './annotations/types';
|
|
22
24
|
export { AnnotationManager } from './annotations/AnnotationManager';
|
|
23
25
|
export type { AnnotationAction, AnnotationChangedEvent, CommitOptions, ViewerUserInfo } from './annotations/AnnotationManager';
|