teamsync-pdf-viewer 1.8.1 → 2.2.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.
@@ -5,7 +5,9 @@ import { AnnotationChangedEvent } from '../annotations/AnnotationManager';
5
5
  import { PdfAssetPaths } from './pdfAssets';
6
6
  import { WebViewerInstance } from './ViewerInstance';
7
7
  import { OfficeConverterConfig, OfficeFileType } from '../office/types';
8
- export type { PdfAssetPaths, WebViewerInstance, OfficeConverterConfig, OfficeFileType };
8
+ import { FormManager } from '../forms/FormManager';
9
+ import { FormField, FormDataRecord, FormRole, FormFeatureOptions } from '../forms/types';
10
+ export type { PdfAssetPaths, WebViewerInstance, OfficeConverterConfig, OfficeFileType, FormManager, FormField, FormDataRecord, FormRole, FormFeatureOptions, };
9
11
  export interface SearchBounds {
10
12
  x: number;
11
13
  y: number;
@@ -51,10 +53,22 @@ export interface SDKPermissions {
51
53
  canRedact?: boolean;
52
54
  /** Allow editing/deleting annotations authored by other users (default false). */
53
55
  canEditOthers?: boolean;
56
+ /** Allow designing / creating form fields in the Forms builder tab (default true). */
57
+ canCreateForms?: boolean;
58
+ /** Allow filling interactive form fields in the View tab (default true). */
59
+ canFillForms?: boolean;
54
60
  }
55
61
  export interface ViewerUser {
56
62
  id: string;
57
63
  name: string;
64
+ /** Optional email address of the user */
65
+ email?: string;
66
+ /** Form template role fulfilled by this user on the document (e.g. 'applicant', 'tenant', 'user_a') */
67
+ role?: string;
68
+ /** Alias of role */
69
+ roleId?: string;
70
+ /** User visual accent color */
71
+ color?: string;
58
72
  }
59
73
  export type InitialScale = number | 'fit-width' | 'fit-page' | {
60
74
  type: 'fit-width';
@@ -103,14 +117,66 @@ export interface WebViewerOptions {
103
117
  canAddAnnotations?: boolean;
104
118
  canEditAnnotations?: boolean;
105
119
  canDeleteAnnotations?: boolean;
120
+ /** Custom or pre-populated FormManager instance. */
121
+ formManager?: FormManager;
122
+ /**
123
+ * Form feature visibility and user interaction controls (e.g. allowUserSwitching, showSignatureFlags,
124
+ * showFlowNavigation, otherUserFieldsMode, etc.).
125
+ */
126
+ formOptions?: FormFeatureOptions;
127
+ /**
128
+ * The active form role ID (e.g. 'applicant', 'tenant', 'landlord').
129
+ * Controls which fields and signature flags are interactive/visible for this role.
130
+ */
131
+ currentRole?: string | null;
132
+ /** Custom list of form template roles. */
133
+ formRoles?: FormRole[];
134
+ /** Pre-populated form fields schema. */
135
+ formFields?: FormField[];
136
+ /** Pre-filled form values record. */
137
+ formData?: FormDataRecord;
106
138
  /** Shorthand for "no annotation/redaction editing at all". */
107
139
  readOnly?: boolean;
108
- /** Author attached to annotations created in this viewer. */
140
+ /**
141
+ * Current logged-in user details passed by the host application (name, email, role, etc.).
142
+ * If user has a `role` property, the viewer automatically activates that role for form filling.
143
+ */
109
144
  currentUser?: ViewerUser;
110
145
  /** pdf.js worker / CMap / font / wasm locations (see `configurePdfAssets`). */
111
146
  assets?: PdfAssetPaths;
112
147
  /** Send cookies with the document request (same-origin session-bound URLs). Default false. */
113
148
  withCredentials?: boolean;
149
+ /**
150
+ * Custom HTTP headers sent with every document request (e.g. Authorization: Bearer <token>).
151
+ * Passed directly to the underlying PDF.js engine.
152
+ */
153
+ httpHeaders?: Record<string, string>;
154
+ /**
155
+ * Alias for `httpHeaders` providing an alternative headers option.
156
+ */
157
+ customHeaders?: Record<string, string>;
158
+ /**
159
+ * Maximum number of bytes fetched per HTTP 206 range request.
160
+ * Default is 65536 (= 64 KB).
161
+ */
162
+ rangeChunkSize?: number;
163
+ /**
164
+ * Disable chunked streaming of PDF file data.
165
+ * Default is false.
166
+ */
167
+ disableStream?: boolean;
168
+ /**
169
+ * Disable automatic background pre-fetching of remaining PDF file chunks when range requests are enabled.
170
+ * When true, only pages explicitly navigated to are fetched.
171
+ * Automatically disables streaming as required by the underlying PDF.js engine.
172
+ * Default is false.
173
+ */
174
+ disableAutoFetch?: boolean;
175
+ /**
176
+ * Disable HTTP 206 range requests entirely, forcing the full PDF to download.
177
+ * Default is false.
178
+ */
179
+ disableRange?: boolean;
114
180
  /** Render the top toolbar. Default true. */
115
181
  toolbar?: boolean;
116
182
  /** Render the left (thumbnails) and right (comments/search) panels. Default true. */
@@ -0,0 +1,105 @@
1
+ import { FormField, FormDataRecord, FormValidationResult, FormRole, FormFeatureOptions } from './types';
2
+ import { ViewerUser } from '../core/types';
3
+ export declare const DEFAULT_FORM_OPTIONS: FormFeatureOptions;
4
+ export declare const DEFAULT_ROLES: FormRole[];
5
+ export interface FormFieldsChangeEvent {
6
+ fields: FormField[];
7
+ action: 'add' | 'update' | 'delete' | 'set' | 'clear';
8
+ }
9
+ export type FormFieldsChangeListener = (event: FormFieldsChangeEvent) => void;
10
+ export type FormDataChangeListener = (data: FormDataRecord) => void;
11
+ export declare class FormManager {
12
+ private fields;
13
+ private values;
14
+ private roles;
15
+ private currentRoleId;
16
+ private currentUser;
17
+ private activeFieldId;
18
+ private options;
19
+ private past;
20
+ private future;
21
+ private fieldsListeners;
22
+ private dataListeners;
23
+ private rolesListeners;
24
+ private activeRoleListeners;
25
+ private activeFieldListeners;
26
+ private optionsListeners;
27
+ private userListeners;
28
+ private readOnly;
29
+ constructor(initialFields?: FormField[], initialValues?: FormDataRecord, initialRoles?: FormRole[], initialOptions?: Partial<FormFeatureOptions>, initialUser?: ViewerUser | null);
30
+ onFieldsChange(listener: FormFieldsChangeListener): () => void;
31
+ onDataChange(listener: FormDataChangeListener): () => void;
32
+ private notifyFieldsChange;
33
+ private notifyDataChange;
34
+ private pushHistory;
35
+ get canUndo(): boolean;
36
+ get canRedo(): boolean;
37
+ undo(): boolean;
38
+ redo(): boolean;
39
+ getFields(): FormField[];
40
+ getFieldsForPage(pageIndex: number): FormField[];
41
+ getField(id: string): FormField | undefined;
42
+ getFieldByName(name: string): FormField | undefined;
43
+ setFields(fields: FormField[]): void;
44
+ addField(field: FormField): void;
45
+ updateField(id: string, updates: Partial<Omit<FormField, 'id'>>, recordHistory?: boolean): boolean;
46
+ deleteField(id: string): boolean;
47
+ clearFields(): void;
48
+ getValues(): FormDataRecord;
49
+ getValue(name: string): any;
50
+ setValue(name: string, value: any): void;
51
+ setValues(newValues: FormDataRecord): void;
52
+ clearValues(): void;
53
+ setReadOnly(readOnly: boolean): void;
54
+ isReadOnly(): boolean;
55
+ getRoles(): FormRole[];
56
+ setRoles(roles: FormRole[]): void;
57
+ addRole(role: FormRole): void;
58
+ updateRole(id: string, updates: Partial<Omit<FormRole, 'id'>>): void;
59
+ removeRole(id: string): void;
60
+ getRole(id?: string): FormRole | undefined;
61
+ onRolesChange(listener: (roles: FormRole[]) => void): () => void;
62
+ getCurrentRole(): string | null;
63
+ setCurrentRole(roleId: string | null): void;
64
+ onCurrentRoleChange(listener: (roleId: string | null) => void): () => void;
65
+ /** Returns the current logged-in user details passed by the host application. */
66
+ getCurrentUser(): ViewerUser | null;
67
+ /**
68
+ * Sets the current logged-in user details passed by the host application.
69
+ * If the user object specifies a `role`, automatically sets that role as the active role.
70
+ */
71
+ setCurrentUser(user: ViewerUser | null): void;
72
+ /** Subscribes to changes in the current logged-in user details. */
73
+ onCurrentUserChange(listener: (user: ViewerUser | null) => void): () => void;
74
+ /**
75
+ * Returns the effective signer name:
76
+ * Prioritizes the actual user's real name (from host application),
77
+ * falling back to the active role name or an empty string.
78
+ */
79
+ getEffectiveSignerName(): string;
80
+ /** Returns the current form feature configuration options. */
81
+ getOptions(): FormFeatureOptions;
82
+ /**
83
+ * Updates form feature options and notifies active listeners.
84
+ */
85
+ setOptions(opts: Partial<FormFeatureOptions>): void;
86
+ /** Subscribes to changes in form feature options. */
87
+ onOptionsChange(listener: (options: FormFeatureOptions) => void): () => void;
88
+ getActiveFieldId(): string | null;
89
+ setActiveFieldId(fieldId: string | null): void;
90
+ onActiveFieldChange(listener: (fieldId: string | null) => void): () => void;
91
+ /**
92
+ * Returns form fields sorted according to flow order.
93
+ * If roleId is provided, filters to fields assigned to that role.
94
+ */
95
+ getFlowFields(roleId?: string | null): FormField[];
96
+ getNextField(currentFieldId?: string | null, roleId?: string | null): FormField | null;
97
+ getPreviousField(currentFieldId?: string | null, roleId?: string | null): FormField | null;
98
+ goToNextField(roleId?: string | null): FormField | null;
99
+ goToPreviousField(roleId?: string | null): FormField | null;
100
+ validate(roleId?: string | null): FormValidationResult;
101
+ exportFieldsJson(): string;
102
+ importFieldsJson(json: string): boolean;
103
+ exportDataJson(): string;
104
+ importDataJson(json: string): boolean;
105
+ }
@@ -0,0 +1,179 @@
1
+ /**
2
+ * © 2026 AngelBot Ai Pvt Ltd. All rights reserved.
3
+ * Types and interfaces for the PDF Forms Builder and Form Filler engine.
4
+ */
5
+ export type FormFieldType = 'text' | 'textbox' | 'textarea' | 'datetime' | 'checklist' | 'checkbox' | 'dropdown' | 'radio' | 'signature' | 'digital_signature';
6
+ export type DateTimeFormat = 'date' | 'time' | 'datetime';
7
+ export type SignatureType = 'electronic' | 'digital';
8
+ export interface FormSignatureValue {
9
+ type: SignatureType;
10
+ /** PNG data URL for drawn, typed, or uploaded electronic signatures */
11
+ dataUrl?: string;
12
+ /** Name of the actual signer */
13
+ signerName?: string;
14
+ /** Optional email of the actual signer */
15
+ signerEmail?: string;
16
+ /** Optional role identifier or title fulfilled by the signer */
17
+ signerRole?: string;
18
+ /** Signing epoch timestamp */
19
+ timestamp?: number;
20
+ /** Purpose/reason for digital signing */
21
+ reason?: string;
22
+ /** Cryptographic thumbprint/hash preview for digital signature */
23
+ certificateHash?: string;
24
+ }
25
+ export interface FormField {
26
+ /** Unique identifier for the form field element */
27
+ id: string;
28
+ /** Field name identifier used when extracting form values or submitting (e.g. "applicant_name") */
29
+ name: string;
30
+ /** Form field type */
31
+ type: FormFieldType;
32
+ /** 1-based page index where this field resides */
33
+ pageIndex: number;
34
+ /** X coordinate in PDF page user space (points, 72 DPI) */
35
+ x: number;
36
+ /** Y coordinate in PDF page user space (points, 72 DPI) */
37
+ y: number;
38
+ /** Width in PDF page user space (points, 72 DPI) */
39
+ width: number;
40
+ /** Height in PDF page user space (points, 72 DPI) */
41
+ height: number;
42
+ /** Human-readable label displayed for the field */
43
+ label?: string;
44
+ /** Placeholder text for text-based inputs */
45
+ placeholder?: string;
46
+ /** Whether filling this field is required */
47
+ required?: boolean;
48
+ /** Default pre-populated value */
49
+ defaultValue?: any;
50
+ /** Current filled value */
51
+ value?: any;
52
+ /** List of selectable option strings for checklist, dropdown, or radio fields */
53
+ options?: string[];
54
+ /** Date/time picker format mode */
55
+ dateFormat?: DateTimeFormat;
56
+ /** Whether the field is locked against user input in filler mode */
57
+ readOnly?: boolean;
58
+ /** Foreground text color (hex or CSS color string, e.g. '#0f172a') */
59
+ textColor?: string;
60
+ /** Background fill color (hex, rgba, or 'transparent') */
61
+ backgroundColor?: string;
62
+ /** Custom border color (defaults to role color or neutral #94a3b8) */
63
+ borderColor?: string;
64
+ /** Border stroke width in pixels (1, 2, or 3) */
65
+ borderWidth?: number;
66
+ /** Corner border radius in pixels (0, 3, 6, 12) */
67
+ borderRadius?: number;
68
+ /** Font family for inputs, labels and choices (e.g. 'sans-serif', 'serif', 'monospace', 'cursive') */
69
+ fontFamily?: string;
70
+ /** Base font size in unscaled points (e.g. 10, 12, 14, 16, 18, 20) */
71
+ fontSize?: number;
72
+ /** Font weight */
73
+ fontWeight?: 'normal' | 'bold';
74
+ /** Font style */
75
+ fontStyle?: 'normal' | 'italic';
76
+ /** Text alignment */
77
+ textAlign?: 'left' | 'center' | 'right';
78
+ /** Role identifier responsible for filling this field (references FormRole.id) */
79
+ roleId?: string;
80
+ /** Explicit step order in the form filling sequence (1, 2, 3...) */
81
+ flowOrder?: number;
82
+ /** Specific signature mode: electronic or digital */
83
+ signatureType?: SignatureType;
84
+ /** Custom tag text displayed on the 'Sign Here' flag badge (e.g. 'Sign Here', 'Authorized Signature') */
85
+ signTagText?: string;
86
+ }
87
+ /**
88
+ * FormRole represents a role/slot defined in a document form template
89
+ * (e.g. 'applicant', 'tenant', 'landlord', 'reviewer', 'user_a').
90
+ * The form template assigns fields to roles; the host application passes the actual user details.
91
+ */
92
+ export interface FormRole {
93
+ /** Unique role identifier (e.g. 'applicant', 'tenant', 'landlord', 'user_a') */
94
+ id: string;
95
+ /** Display label for this role (e.g. 'Applicant', 'Tenant', 'Landlord') */
96
+ name: string;
97
+ /** Hex color code for badges, borders and accents (e.g. '#2563eb') */
98
+ color: string;
99
+ /** Optional human-readable description for the role */
100
+ description?: string;
101
+ }
102
+ export type FormDataRecord = Record<string, any>;
103
+ export interface FormValidationResult {
104
+ valid: boolean;
105
+ errors: Record<string, string>;
106
+ }
107
+ export type FormToolType = 'select' | 'textbox' | 'textarea' | 'datetime' | 'checklist' | 'dropdown' | 'radio' | 'signature' | 'digital_signature' | null;
108
+ /**
109
+ * Options controlling which form features and UI controls are accessible to the user.
110
+ * Allows host applications to programmatically control form filling, design permissions,
111
+ * user persona switching, and feature visibility.
112
+ */
113
+ export interface FormFeatureOptions {
114
+ /**
115
+ * Allow designing / creating form fields in the Forms builder tab.
116
+ * When false, the Forms tab is hidden or disabled.
117
+ * Default: true (or matches SDKPermissions.canCreateForms).
118
+ */
119
+ canCreateForms?: boolean;
120
+ /**
121
+ * Allow filling interactive form fields in the View tab.
122
+ * When false, all form inputs and signatures are read-only.
123
+ * Default: true (or matches SDKPermissions.canFillForms).
124
+ */
125
+ canFillForms?: boolean;
126
+ /**
127
+ * Whether the end-user can switch roles in the filler toolbar.
128
+ * When false, the role selector dropdown is locked to the assigned role.
129
+ * Default: true.
130
+ */
131
+ allowRoleSwitching?: boolean;
132
+ /**
133
+ * Show or hide the "Filling as:" role selector in the filler toolbar.
134
+ * Default: true.
135
+ */
136
+ showRoleSelector?: boolean;
137
+ /**
138
+ * Show or hide the persistent Post-it Signature Sticky / Index Flags on the side of the viewer.
139
+ * Default: true.
140
+ */
141
+ showSignatureFlags?: boolean;
142
+ /**
143
+ * Show or hide the step-by-step form flow navigation buttons (Previous / Step X of Y / Next).
144
+ * Default: true.
145
+ */
146
+ showFlowNavigation?: boolean;
147
+ /**
148
+ * Show or hide the "Validate" button and validation message in the filler toolbar.
149
+ * Default: true.
150
+ */
151
+ showValidation?: boolean;
152
+ /**
153
+ * Show or hide the "Reset" / clear form button in the filler toolbar.
154
+ * Default: true.
155
+ */
156
+ showReset?: boolean;
157
+ /**
158
+ * Show or hide the download / export filled PDF button in the filler toolbar.
159
+ * Default: true.
160
+ */
161
+ showExport?: boolean;
162
+ /**
163
+ * Controls how form fields assigned to OTHER roles are presented:
164
+ * - 'locked': rendered with disabled styling and a lock indicator badge (default)
165
+ * - 'hidden': completely hidden from view for the current user
166
+ * - 'view-only': rendered cleanly as read-only values without lock styling
167
+ */
168
+ otherRoleFieldsMode?: 'locked' | 'hidden' | 'view-only';
169
+ /**
170
+ * Hide the entire FormFillerActions toolbar in View mode.
171
+ * Default: false.
172
+ */
173
+ hideToolbar?: boolean;
174
+ /**
175
+ * Active form role identifier for form filling (e.g. 'applicant', 'tenant', 'user_a').
176
+ * Controls which fields and signature flags are active for the current user.
177
+ */
178
+ currentRole?: string | null;
179
+ }
@@ -7,6 +7,7 @@
7
7
  */
8
8
  export { createWebViewer, WebViewer } from './core/createWebViewer';
9
9
  export { WebViewerInstance } from './core/ViewerInstance';
10
+ export type { LoadDocumentOptions } from './core/ViewerInstance';
10
11
  export { TeamSyncViewer } from './components/TeamSyncViewer';
11
12
  export type { TeamSyncViewerProps } from './components/TeamSyncViewer';
12
13
  export * from './types/compare';
@@ -48,3 +49,6 @@ export { isOfficeDocumentUrl, isOfficeFile, detectOfficeType, isOfficeExtension,
48
49
  export { OfficeLoadingOverlay } from './office/OfficeLoadingOverlay';
49
50
  export type { OfficeConverterConfig, OfficeConversionConfig, OfficeConversionState, OfficeFileType, OfficeDocumentOptions, OfficeDocumentInfo, } from './office/types';
50
51
  export { VERSION } from './version';
52
+ export { FormManager, DEFAULT_FORM_OPTIONS, DEFAULT_ROLES } from './forms/FormManager';
53
+ export type { FormFieldsChangeEvent, FormFieldsChangeListener, FormDataChangeListener } from './forms/FormManager';
54
+ export type { FormField, FormFieldType, DateTimeFormat, SignatureType, FormSignatureValue, FormRole, FormDataRecord, FormValidationResult, FormToolType, FormFeatureOptions, } from './forms/types';
@@ -27,10 +27,6 @@ export interface UseOfficeDocumentResult {
27
27
  /** Manually trigger conversion or retry */
28
28
  convert: () => Promise<string | null>;
29
29
  }
30
- /**
31
- * React hook that pre-converts Office documents into viewable PDF URLs before viewer mounting.
32
- * If the input is already a PDF, it passes through immediately with `isConverting: false`.
33
- */
34
30
  export declare function useOfficeDocument(fileOrUrl: string | File | Blob | ArrayBuffer | null | undefined, options?: UseOfficeDocumentOptions): UseOfficeDocumentResult;
35
31
  /**
36
32
  * Standalone asynchronous preloader for Office documents.
@@ -21,3 +21,9 @@ export declare function isDocumentUrl(url: string): boolean;
21
21
  * Parses any link URL into structured destination information, extracting target documents and page numbers.
22
22
  */
23
23
  export declare function parseLinkTarget(linkUrl: string): ParsedLinkTarget;
24
+ /**
25
+ * Sanitizes a link URL to guarantee safe usage in anchor attributes (e.g. href).
26
+ * Rejects dangerous schemes like javascript:, vbscript:, and data:.
27
+ * Returns '#' if the scheme is unsafe or empty.
28
+ */
29
+ export declare function sanitizeLinkUrl(url?: string): string;