kviewer 0.3.4 → 0.3.6

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 (28) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/annotation/engine/painter.d.ts +2 -2
  3. package/dist/runtime/annotation/engine/tools/form-field.d.ts +5 -5
  4. package/dist/runtime/annotation/engine/tools/form-field.js +1 -1
  5. package/dist/runtime/annotation/engine/types.d.ts +18 -9
  6. package/dist/runtime/assets/kviewer.css +1 -1
  7. package/dist/runtime/components/Viewer.d.vue.ts +21 -17
  8. package/dist/runtime/components/Viewer.vue +62 -40
  9. package/dist/runtime/components/Viewer.vue.d.ts +21 -17
  10. package/dist/runtime/components/ViewerTabs.d.vue.ts +12 -17
  11. package/dist/runtime/components/ViewerTabs.vue +3 -6
  12. package/dist/runtime/components/ViewerTabs.vue.d.ts +12 -17
  13. package/dist/runtime/components/form-fields/FormFieldWrapper.vue +21 -9
  14. package/dist/runtime/components/form-fields/FormSignatureField.vue +10 -2
  15. package/dist/runtime/components/form-fields/PlacedFieldChrome.d.vue.ts +4 -0
  16. package/dist/runtime/components/form-fields/PlacedFieldChrome.vue +27 -10
  17. package/dist/runtime/components/form-fields/PlacedFieldChrome.vue.d.ts +4 -0
  18. package/dist/runtime/composables/useFormFields.d.ts +28 -17
  19. package/dist/runtime/composables/useFormFields.js +20 -24
  20. package/dist/runtime/composables/useInertiaPanzoom.d.ts +8 -2
  21. package/dist/runtime/composables/useInertiaPanzoom.js +36 -12
  22. package/dist/runtime/embed/bridge-client.d.ts +4 -2
  23. package/dist/runtime/embed/bridge-client.js +2 -1
  24. package/dist/runtime/embed/bridge-host.d.ts +4 -1
  25. package/dist/runtime/embed/bridge-host.js +24 -0
  26. package/dist/runtime/embed/protocol.d.ts +19 -0
  27. package/dist/runtime/public-types.d.ts +1 -1
  28. package/package.json +1 -1
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kviewer",
3
3
  "configKey": "kviewer",
4
- "version": "0.3.4",
4
+ "version": "0.3.6",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
@@ -1,6 +1,6 @@
1
1
  import Konva from 'konva';
2
2
  import type { IRect } from 'konva/lib/types';
3
- import { type IAnnotationStore, type IAnnotationStyle, type IAnnotationType, type PlaceFieldPayload } from './types.js';
3
+ import { type FormFieldType, type IAnnotationStore, type IAnnotationStyle, type IAnnotationType, type PlaceFieldPayload } from './types.js';
4
4
  import { type IEditorFreeTextOptions } from './tools/free-text.js';
5
5
  export interface KonvaCanvas {
6
6
  pageNumber: number;
@@ -26,7 +26,7 @@ export interface PainterCallbacks {
26
26
  /** Optional accessor returning the color to use for the form-field
27
27
  * placement preview. Lets the active role color override the default
28
28
  * blue without rebuilding the editor between placements. */
29
- getFormFieldPreviewColor?: () => string | undefined;
29
+ getFormFieldPreviewColor?: (fieldType: FormFieldType) => string | undefined;
30
30
  }
31
31
  export declare class Painter {
32
32
  private userName?;
@@ -6,11 +6,11 @@ export interface IEditorFormFieldOptions {
6
6
  /** PDF-space page height, needed to flip Konva page-local Y → PDF Y. */
7
7
  pageHeight: number;
8
8
  onPlaceField: (payload: PlaceFieldPayload) => void;
9
- /** Resolves to the active role color so the placement preview matches
10
- * the color the field will be tagged with. Re-read on every drag start
11
- * so the user can switch roles between placements without rebuilding
12
- * the editor. */
13
- getPreviewColor?: () => string | undefined;
9
+ /** Resolves to the fieldColor preset for this field type so the
10
+ * placement preview matches the color the field will land with.
11
+ * Re-read on every drag start so the host can change defaults between
12
+ * placements without rebuilding the editor. */
13
+ getPreviewColor?: (fieldType: FormFieldType) => string | undefined;
14
14
  }
15
15
  export declare class EditorFormField extends Editor {
16
16
  private fieldType;
@@ -38,7 +38,7 @@ export class EditorFormField extends Editor {
38
38
  y: pos.y,
39
39
  width: 0,
40
40
  height: 0,
41
- stroke: this.getPreviewColor?.() ?? "#1677ff",
41
+ stroke: this.getPreviewColor?.(this.fieldType) ?? "#1677ff",
42
42
  strokeWidth: 1,
43
43
  dash: [4, 4],
44
44
  strokeScaleEnabled: false,
@@ -216,11 +216,17 @@ export interface FormFieldDefinition {
216
216
  color?: number[];
217
217
  backgroundColor?: number[];
218
218
  textAlignment?: number;
219
- /** Opaque role tag for color-coding in form-edit mode. The editor
220
- * doesn't own role definitions the host (integrating app) maps
221
- * roleId color via the `roleColors` prop on KViewer. Not exported
222
- * to the PDF. */
223
- roleId?: string;
219
+ /** CSS color driving the field's editor chrome (outline, grip, hover
220
+ * accents). Host-owned; falls back to the default blue when unset.
221
+ * Not exported to the PDF use `color`/`backgroundColor` for the
222
+ * widget's native appearance. Typically set per placement via
223
+ * `fieldDefaults` (e.g. one color per signer). */
224
+ fieldColor?: string;
225
+ /** Host-owned metadata bag. The editor carries it around untouched —
226
+ * it is never read, validated, or exported to the PDF. Must stay
227
+ * JSON-serializable so it survives the embed bridge. Replaced
228
+ * wholesale by an `updateFormField()` patch (no deep merge). */
229
+ meta?: Record<string, unknown>;
224
230
  }
225
231
  export interface FormFieldValue {
226
232
  fieldId: string;
@@ -251,8 +257,13 @@ export interface AddFormFieldPayload {
251
257
  * mirrored across them on edit. Radios with the same `fieldName` form
252
258
  * one option group. */
253
259
  fieldName?: string;
254
- /** Opaque role tag for color-coding in form-edit mode. */
255
- roleId?: string;
260
+ /** CSS color for the field's editor chrome (see
261
+ * {@link FormFieldDefinition.fieldColor}). */
262
+ fieldColor?: string;
263
+ /** Host-owned metadata bag, carried untouched (see
264
+ * {@link FormFieldDefinition.meta}). Also usable as a preset in
265
+ * `fieldDefaults` so tool placements get their metadata atomically. */
266
+ meta?: Record<string, unknown>;
256
267
  /** Default value for the field. Becomes the initial value too. */
257
268
  defaultValue?: string;
258
269
  readOnly?: boolean;
@@ -316,8 +327,6 @@ export interface SignatureFieldStatus {
316
327
  fieldName: string;
317
328
  pageNumber: number;
318
329
  signed: boolean;
319
- /** Present when the field is tagged with a host role. */
320
- roleId?: string;
321
330
  }
322
331
  export interface DetectedShapeRect {
323
332
  x: number;
@@ -1 +1 @@
1
- .kviewer-text-layer{left:0;line-height:1;overflow:hidden;position:absolute;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none;z-index:1}.kviewer-text-layer--interactive{cursor:text;-webkit-user-select:text;-moz-user-select:text;user-select:text}.KViewer_is_painting.KViewer_painting_type_12 .kviewer-annotation-layer,.KViewer_is_painting.KViewer_painting_type_12 .kviewer-annotation-layer *,.KViewer_is_painting.KViewer_painting_type_13 .kviewer-annotation-layer,.KViewer_is_painting.KViewer_painting_type_13 .kviewer-annotation-layer *,.KViewer_is_painting.KViewer_painting_type_5 .kviewer-annotation-layer,.KViewer_is_painting.KViewer_painting_type_5 .kviewer-annotation-layer *,.KViewer_is_painting.KViewer_painting_type_6 .kviewer-annotation-layer,.KViewer_is_painting.KViewer_painting_type_6 .kviewer-annotation-layer *,.KViewer_is_painting.KViewer_painting_type_7 .kviewer-annotation-layer,.KViewer_is_painting.KViewer_painting_type_7 .kviewer-annotation-layer *,.KViewer_is_painting.KViewer_painting_type_8 .kviewer-annotation-layer,.KViewer_is_painting.KViewer_painting_type_8 .kviewer-annotation-layer *{cursor:crosshair!important}.KViewer_is_painting.KViewer_painting_type_4 .kviewer-annotation-layer,.KViewer_is_painting.KViewer_painting_type_4 .kviewer-annotation-layer *{cursor:text!important}.KViewer_is_painting.KViewer_painting_type_11 .kviewer-annotation-layer,.KViewer_is_painting.KViewer_painting_type_11 .kviewer-annotation-layer *{cursor:crosshair!important}.KViewer_selector_hover{cursor:pointer!important}.kviewer-form-layer{left:0;overflow:hidden;position:absolute;top:0}.kviewer-form-field{box-sizing:border-box;position:absolute}.kviewer-form-input{background-color:color-mix(in srgb,var(--kvw-field-color,#1677ff) 14%,transparent);border:1px solid transparent;box-sizing:border-box;color:#000;display:block;font-family:-apple-system,BlinkMacSystemFont,Helvetica Neue,Helvetica,Arial,sans-serif;font-weight:500;height:100%;line-height:normal;margin:0;outline:none;padding:1px 2px;resize:none;width:100%;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:optimizeLegibility;vertical-align:top}.kviewer-form-input:hover{background-color:color-mix(in srgb,var(--kvw-field-color,#1677ff) 22%,transparent);border-color:rgba(0,0,0,.2)}.kviewer-form-input:focus{background-color:color-mix(in srgb,var(--kvw-field-color,#1677ff) 28%,transparent);border-color:var(--kvw-field-color,var(--color-primary,#3b82f6));outline:2px solid var(--kvw-field-color,var(--color-primary,#3b82f6))}.kviewer-form-uselect{align-items:center;background-color:color-mix(in srgb,var(--kvw-field-color,#1677ff) 14%,transparent);border:1px solid transparent;border-radius:0;box-sizing:border-box;color:#000;cursor:pointer;display:flex;height:100%;line-height:1;padding:0 11px 0 2px;width:100%}.kviewer-form-uselect:hover{background-color:color-mix(in srgb,var(--kvw-field-color,#1677ff) 22%,transparent);border-color:rgba(0,0,0,.2)}.kviewer-form-uselect:focus-visible{background-color:color-mix(in srgb,var(--kvw-field-color,#1677ff) 28%,transparent);outline:2px solid var(--kvw-field-color,var(--color-primary,#3b82f6));outline-offset:-2px}.kviewer-form-uselect:disabled{cursor:default}.kviewer-form-listbox{overflow-y:auto;padding:0}.kviewer-form-listbox option{padding:1px 3px}.kviewer-form-editable-combo{height:100%;position:relative;width:100%}.kviewer-form-editable-combo input{height:100%;width:100%}.kviewer-form-checkbox,.kviewer-form-radio{align-items:center;background:#fff;box-sizing:border-box;cursor:pointer;display:flex;height:100%;justify-content:center;width:100%}.kviewer-form-checkbox input,.kviewer-form-radio input{accent-color:var(--kvw-field-color,var(--color-primary,#3b82f6));cursor:pointer;height:80%;margin:0;max-height:18px;max-width:18px;width:80%}.kviewer-form-checkbox--detected{background:transparent}.kviewer-form-checkbox--circle{border-radius:50%}.kviewer-form-checkbox__icon{color:#1a1a1a;height:65%;width:65%}.kviewer-form-checkbox--circle .kviewer-form-checkbox__icon{height:50%;width:50%}.kviewer-form-radio input{accent-color:var(--kvw-field-color,var(--color-primary,#3b82f6));cursor:pointer;height:80%;margin:0;max-height:18px;max-width:18px;width:80%}.kviewer-form-button{align-items:center;background:#c8c8c8;border:1px solid rgba(0,0,0,.35);box-sizing:border-box;color:#000;cursor:pointer;display:flex;font-family:inherit;font-weight:700;height:100%;justify-content:center;line-height:1;padding:0 6px;text-align:center;width:100%;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.kviewer-form-button:hover{background:#bdbdbd}.kviewer-form-button:active{background:#b0b0b0}.kviewer-form-signature{align-items:center;background:rgba(255,255,200,.15);border:1px dashed rgba(0,0,0,.2);cursor:pointer;display:flex;height:100%;justify-content:center;width:100%}.kviewer-form-signature:hover{background:color-mix(in srgb,var(--kvw-field-color,#3b82f6) 8%,transparent);border-color:var(--kvw-field-color,var(--color-primary,#3b82f6))}.kviewer-form-signature--filled{background:transparent;border-color:transparent;border-style:solid}.kviewer-form-signature__preview{max-height:100%;max-width:100%;-o-object-fit:contain;object-fit:contain}.kviewer-form-signature__placeholder{color:rgba(0,0,0,.4);font-size:10px;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.kviewer-form-field__body--locked .kviewer-form-signature,.kviewer-form-field__body--locked .kviewer-form-signature:hover{border-color:transparent}.kviewer-form-signature--static{cursor:default}.kviewer-form-signature--static:hover{background:rgba(255,255,200,.15);border-color:rgba(0,0,0,.2)}.kviewer-form-signature__marker{align-items:center;display:inline-flex;gap:4px}.kviewer-form-signature__marker-icon{flex:0 0 auto;height:12px;width:12px}
1
+ .kviewer-text-layer{left:0;line-height:1;overflow:hidden;position:absolute;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none;z-index:1}.kviewer-text-layer--interactive{cursor:text;-webkit-user-select:text;-moz-user-select:text;user-select:text}.KViewer_is_painting.KViewer_painting_type_12 .kviewer-annotation-layer,.KViewer_is_painting.KViewer_painting_type_12 .kviewer-annotation-layer *,.KViewer_is_painting.KViewer_painting_type_13 .kviewer-annotation-layer,.KViewer_is_painting.KViewer_painting_type_13 .kviewer-annotation-layer *,.KViewer_is_painting.KViewer_painting_type_5 .kviewer-annotation-layer,.KViewer_is_painting.KViewer_painting_type_5 .kviewer-annotation-layer *,.KViewer_is_painting.KViewer_painting_type_6 .kviewer-annotation-layer,.KViewer_is_painting.KViewer_painting_type_6 .kviewer-annotation-layer *,.KViewer_is_painting.KViewer_painting_type_7 .kviewer-annotation-layer,.KViewer_is_painting.KViewer_painting_type_7 .kviewer-annotation-layer *,.KViewer_is_painting.KViewer_painting_type_8 .kviewer-annotation-layer,.KViewer_is_painting.KViewer_painting_type_8 .kviewer-annotation-layer *{cursor:crosshair!important}.KViewer_is_painting.KViewer_painting_type_4 .kviewer-annotation-layer,.KViewer_is_painting.KViewer_painting_type_4 .kviewer-annotation-layer *{cursor:text!important}.KViewer_is_painting.KViewer_painting_type_11 .kviewer-annotation-layer,.KViewer_is_painting.KViewer_painting_type_11 .kviewer-annotation-layer *{cursor:crosshair!important}.KViewer_selector_hover{cursor:pointer!important}.kviewer-form-layer{left:0;overflow:hidden;position:absolute;top:0}.kviewer-form-field{box-sizing:border-box;position:absolute}.kviewer-form-field--readonly.kviewer-form-field--placed{filter:grayscale(.6);opacity:.5}.kviewer-form-field--readonly .kviewer-form-signature,.kviewer-form-field--readonly .kviewer-form-signature:hover{background:rgba(255,255,200,.15);border-color:rgba(0,0,0,.2);cursor:not-allowed}.kviewer-form-input{background-color:color-mix(in srgb,var(--kvw-field-color,#1677ff) 14%,transparent);border:1px solid transparent;box-sizing:border-box;color:#000;display:block;font-family:-apple-system,BlinkMacSystemFont,Helvetica Neue,Helvetica,Arial,sans-serif;font-weight:500;height:100%;line-height:normal;margin:0;outline:none;padding:1px 2px;resize:none;width:100%;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:optimizeLegibility;vertical-align:top}.kviewer-form-input:hover{background-color:color-mix(in srgb,var(--kvw-field-color,#1677ff) 22%,transparent);border-color:rgba(0,0,0,.2)}.kviewer-form-input:focus{background-color:color-mix(in srgb,var(--kvw-field-color,#1677ff) 28%,transparent);border-color:var(--kvw-field-color,var(--color-primary,#3b82f6));outline:2px solid var(--kvw-field-color,var(--color-primary,#3b82f6))}.kviewer-form-uselect{align-items:center;background-color:color-mix(in srgb,var(--kvw-field-color,#1677ff) 14%,transparent);border:1px solid transparent;border-radius:0;box-sizing:border-box;color:#000;cursor:pointer;display:flex;height:100%;line-height:1;padding:0 11px 0 2px;width:100%}.kviewer-form-uselect:hover{background-color:color-mix(in srgb,var(--kvw-field-color,#1677ff) 22%,transparent);border-color:rgba(0,0,0,.2)}.kviewer-form-uselect:focus-visible{background-color:color-mix(in srgb,var(--kvw-field-color,#1677ff) 28%,transparent);outline:2px solid var(--kvw-field-color,var(--color-primary,#3b82f6));outline-offset:-2px}.kviewer-form-uselect:disabled{cursor:default}.kviewer-form-listbox{overflow-y:auto;padding:0}.kviewer-form-listbox option{padding:1px 3px}.kviewer-form-editable-combo{height:100%;position:relative;width:100%}.kviewer-form-editable-combo input{height:100%;width:100%}.kviewer-form-checkbox,.kviewer-form-radio{align-items:center;background:#fff;box-sizing:border-box;cursor:pointer;display:flex;height:100%;justify-content:center;width:100%}.kviewer-form-checkbox input,.kviewer-form-radio input{accent-color:var(--kvw-field-color,var(--color-primary,#3b82f6));cursor:pointer;height:80%;margin:0;max-height:18px;max-width:18px;width:80%}.kviewer-form-checkbox--detected{background:transparent}.kviewer-form-checkbox--circle{border-radius:50%}.kviewer-form-checkbox__icon{color:#1a1a1a;height:65%;width:65%}.kviewer-form-checkbox--circle .kviewer-form-checkbox__icon{height:50%;width:50%}.kviewer-form-radio input{accent-color:var(--kvw-field-color,var(--color-primary,#3b82f6));cursor:pointer;height:80%;margin:0;max-height:18px;max-width:18px;width:80%}.kviewer-form-button{align-items:center;background:#c8c8c8;border:1px solid rgba(0,0,0,.35);box-sizing:border-box;color:#000;cursor:pointer;display:flex;font-family:inherit;font-weight:700;height:100%;justify-content:center;line-height:1;padding:0 6px;text-align:center;width:100%;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.kviewer-form-button:hover{background:#bdbdbd}.kviewer-form-button:active{background:#b0b0b0}.kviewer-form-signature{align-items:center;background:rgba(255,255,200,.15);border:1px dashed rgba(0,0,0,.2);cursor:pointer;display:flex;height:100%;justify-content:center;width:100%}.kviewer-form-signature:hover{background:color-mix(in srgb,var(--kvw-field-color,#3b82f6) 8%,transparent);border-color:var(--kvw-field-color,var(--color-primary,#3b82f6))}.kviewer-form-signature--filled{background:transparent;border-color:transparent;border-style:solid}.kviewer-form-signature__preview{max-height:100%;max-width:100%;-o-object-fit:contain;object-fit:contain}.kviewer-form-signature__placeholder{color:rgba(0,0,0,.4);font-size:10px;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.kviewer-form-field--editable .kviewer-form-signature,.kviewer-form-field__body--locked .kviewer-form-signature,.kviewer-form-field__body--locked .kviewer-form-signature:hover{border-color:transparent}.kviewer-form-signature--static{cursor:default}.kviewer-form-signature--static:hover{background:rgba(255,255,200,.15);border-color:rgba(0,0,0,.2)}.kviewer-form-signature__marker{align-items:center;display:inline-flex;gap:4px}.kviewer-form-signature__marker-icon{flex:0 0 auto;height:12px;width:12px}
@@ -1,4 +1,5 @@
1
1
  import { type ViewMode } from '../composables/useViewerState.js';
2
+ import type { ScrollBoundaryPayload } from '../embed/protocol.js';
2
3
  import type { AddFormFieldPayload, FormFieldDefinition, IAnnotationStore, PlacedFieldDefaults, SignatureFieldStatus, StampDefinition, SignatureHandlers } from '../annotation/engine/types.js';
3
4
  import { type ExportPdfOptions } from '../annotation/pdf-export/export.js';
4
5
  import type { ViewerMenuItem } from '../menu-items.js';
@@ -26,16 +27,6 @@ type __VLS_Props = {
26
27
  * with selection chrome, can be moved/resized, and the property panel
27
28
  * is shown. Supports v-model via `v-model:form-edit-mode`. */
28
29
  formEditMode?: boolean;
29
- /** Map of roleId → CSS color used to color-code form fields in
30
- * form-edit mode. The editor stays unopinionated about role
31
- * definitions: the host owns the role list, names, and color picker,
32
- * and just hands a flat lookup table to the viewer. Unknown or
33
- * missing ids fall back to the default blue. */
34
- roleColors?: Record<string, string>;
35
- /** Active role id new field placements are auto-tagged with. The host
36
- * drives this — typically by binding it to a role picker in its own
37
- * UI. Supports v-model via `v-model:active-role-id`. */
38
- activeRoleId?: string | null;
39
30
  /** When true, clicking an unsigned signature field opens kviewer's own
40
31
  * signing flow (saved signature or draw modal). Off by default so hosts
41
32
  * that own the signing process (e.g. an embedding e-sign app) don't get
@@ -122,9 +113,11 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
122
113
  * The new field is exported into the PDF on `exportPdf()` like any
123
114
  * field placed via the placement tool. */
124
115
  addFormField: (payload: AddFormFieldPayload) => FormFieldDefinition;
125
- /** Patch a form field by id (rect, name, flags, type-specific props). */
116
+ /** Patch a form field by id (rect, name, flags, type-specific props).
117
+ * Does not fire `field-updated` — that event is for user-driven edits. */
126
118
  updateFormField: (id: string, patch: Partial<FormFieldDefinition>) => void;
127
- /** Remove a form field by id (drops its value too). */
119
+ /** Remove a form field by id (drops its value too). Does not fire
120
+ * `field-removed` — that event is for user-driven removals. */
128
121
  removeFormField: (id: string) => void;
129
122
  /** All form-field definitions (parsed, detected, and placed), flat. */
130
123
  getFormFields: () => FormFieldDefinition[];
@@ -138,6 +131,14 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
138
131
  * `field-placed` event, used by the embed bridge). Returns an
139
132
  * unsubscribe function. */
140
133
  onFieldPlaced: (cb: (field: FormFieldDefinition) => void) => (() => void);
134
+ /** Subscribe to user-driven field edits (imperative mirror of the
135
+ * `field-updated` event, used by the embed bridge). Returns an
136
+ * unsubscribe function. */
137
+ onFieldUpdated: (cb: (field: FormFieldDefinition, patch: Partial<FormFieldDefinition>) => void) => (() => void);
138
+ /** Subscribe to user-driven field removals (imperative mirror of the
139
+ * `field-removed` event, used by the embed bridge). Returns an
140
+ * unsubscribe function. */
141
+ onFieldRemoved: (cb: (field: FormFieldDefinition) => void) => (() => void);
141
142
  /** True once every signature field in the document is signed — via a
142
143
  * value applied in this session or a digital signature already in the
143
144
  * source PDF. Vacuously true when the document has no signature
@@ -145,7 +146,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
145
146
  * need "at least one". Use to gate e.g. envelope finalization. */
146
147
  getSignedStatus: () => boolean;
147
148
  /** Per-widget signed-state snapshot (id, fieldName, pageNumber,
148
- * signed, roleId). */
149
+ * signed). Correlate to host data by `id`. */
149
150
  getSignatureFieldStatus: () => SignatureFieldStatus[];
150
151
  /** Subscribe to signed-status changes (imperative mirror of the
151
152
  * `signed-status-changed` event, used by the embed bridge). Returns
@@ -154,6 +155,9 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
154
155
  allSigned: boolean;
155
156
  fields: SignatureFieldStatus[];
156
157
  }) => void) => (() => void);
158
+ /** Subscribe to vertical wheel movement left over when the viewer reaches
159
+ * a document boundary. Used by the embed bridge for parent scrolling. */
160
+ onScrollBoundary: (cb: (payload: ScrollBoundaryPayload) => void) => (() => void);
157
161
  /** Reactive form-edit-mode flag — read with `.value`. */
158
162
  formEditMode: import("vue").Ref<boolean, boolean>;
159
163
  /** Programmatically enter or leave form-edit mode. */
@@ -171,8 +175,9 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
171
175
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
172
176
  "all-pages-read": () => any;
173
177
  "field-placed": (field: FormFieldDefinition) => any;
178
+ "field-updated": (field: FormFieldDefinition, patch: Partial<FormFieldDefinition>) => any;
179
+ "field-removed": (field: FormFieldDefinition) => any;
174
180
  "update:formEditMode": (value: boolean) => any;
175
- "update:activeRoleId": (value: string | null) => any;
176
181
  "update:viewedPages": (pages: number[]) => any;
177
182
  "signed-status-changed": (payload: {
178
183
  allSigned: boolean;
@@ -181,8 +186,9 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
181
186
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
182
187
  "onAll-pages-read"?: (() => any) | undefined;
183
188
  "onField-placed"?: ((field: FormFieldDefinition) => any) | undefined;
189
+ "onField-updated"?: ((field: FormFieldDefinition, patch: Partial<FormFieldDefinition>) => any) | undefined;
190
+ "onField-removed"?: ((field: FormFieldDefinition) => any) | undefined;
184
191
  "onUpdate:formEditMode"?: ((value: boolean) => any) | undefined;
185
- "onUpdate:activeRoleId"?: ((value: string | null) => any) | undefined;
186
192
  "onUpdate:viewedPages"?: ((pages: number[]) => any) | undefined;
187
193
  "onSigned-status-changed"?: ((payload: {
188
194
  allSigned: boolean;
@@ -204,8 +210,6 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
204
210
  signatureHandlers: SignatureHandlers;
205
211
  viewMode: ViewMode;
206
212
  shapeDetection: boolean;
207
- roleColors: Record<string, string>;
208
- activeRoleId: string | null;
209
213
  editablePlacedFields: boolean;
210
214
  fieldDefaults: PlacedFieldDefaults;
211
215
  selectionItems: ViewerSelectionItem[];
@@ -243,8 +243,6 @@ const props = defineProps({
243
243
  active: { type: Boolean, required: false, default: true },
244
244
  freehandGroupingDelay: { type: Number, required: false, default: 1e3 },
245
245
  formEditMode: { type: Boolean, required: false, default: void 0 },
246
- roleColors: { type: Object, required: false, default: void 0 },
247
- activeRoleId: { type: [String, null], required: false, default: void 0 },
248
246
  clickToSign: { type: Boolean, required: false, default: false },
249
247
  editablePlacedFields: { type: Boolean, required: false, default: false },
250
248
  fieldDefaults: { type: Object, required: false, default: void 0 },
@@ -260,9 +258,12 @@ const slots = useSlots();
260
258
  const toolSlotNames = computed(
261
259
  () => Object.keys(slots).filter((name) => name.startsWith("tool-"))
262
260
  );
263
- const emit = defineEmits(["update:formEditMode", "update:activeRoleId", "update:viewedPages", "all-pages-read", "field-placed", "signed-status-changed"]);
261
+ const emit = defineEmits(["update:formEditMode", "update:viewedPages", "all-pages-read", "field-placed", "field-updated", "field-removed", "signed-status-changed"]);
264
262
  const fieldPlacedCallbacks = /* @__PURE__ */ new Set();
265
263
  const signedStatusCallbacks = /* @__PURE__ */ new Set();
264
+ const fieldUpdatedCallbacks = /* @__PURE__ */ new Set();
265
+ const fieldRemovedCallbacks = /* @__PURE__ */ new Set();
266
+ const scrollBoundaryCallbacks = /* @__PURE__ */ new Set();
266
267
  const viewerRoot = ref(null);
267
268
  const scrollContainer = ref(null);
268
269
  const { state: viewerState, setScrollToPageFn, setDownloadPdfFn, setPrintPdfFn, setApplyScaleFn } = provideViewerState();
@@ -291,6 +292,15 @@ watch(
291
292
  );
292
293
  const viewerSearch = provideViewerSearch();
293
294
  const formFieldsState = provideFormFields();
295
+ formFieldsState.setFieldEventSink((event) => {
296
+ if (event.type === "updated") {
297
+ emit("field-updated", event.field, event.patch);
298
+ for (const cb of fieldUpdatedCallbacks) cb(event.field, event.patch);
299
+ } else {
300
+ emit("field-removed", event.field);
301
+ for (const cb of fieldRemovedCallbacks) cb(event.field);
302
+ }
303
+ });
294
304
  const kviewerPublicConfig = useRuntimeConfig().public.kviewer;
295
305
  provideKviewerI18n(
296
306
  computed(() => {
@@ -299,13 +309,6 @@ provideKviewerI18n(
299
309
  }),
300
310
  computed(() => props.messages ?? {})
301
311
  );
302
- watch(
303
- () => props.roleColors,
304
- (v) => {
305
- formFieldsState.setRoleColors(v ?? {});
306
- },
307
- { immediate: true }
308
- );
309
312
  watch(
310
313
  () => props.fieldDefaults,
311
314
  (v) => {
@@ -347,22 +350,6 @@ watch(signatureStatus, (next, prev) => {
347
350
  emit("signed-status-changed", payload);
348
351
  for (const cb of signedStatusCallbacks) cb(payload);
349
352
  });
350
- watch(
351
- () => props.activeRoleId,
352
- (v) => {
353
- if (v === void 0) return;
354
- if (formFieldsState.activeRoleId.value !== v) {
355
- formFieldsState.setActiveRole(v);
356
- }
357
- },
358
- { immediate: true }
359
- );
360
- watch(
361
- () => formFieldsState.activeRoleId.value,
362
- (v) => {
363
- if (props.activeRoleId !== v) emit("update:activeRoleId", v);
364
- }
365
- );
366
353
  const pageSettings = providePageSettings(viewerRoot);
367
354
  const virtualization = createPageVirtualization();
368
355
  setScrollToPageFn((pageNumber) => {
@@ -878,28 +865,43 @@ function initPanzoom() {
878
865
  inertiaPanzoom.attach(zoomWrapper.value);
879
866
  }
880
867
  let wheelCooldown = false;
868
+ function notifyScrollBoundary(deltaY) {
869
+ if (deltaY === 0) return;
870
+ const payload = {
871
+ edge: deltaY > 0 ? "end" : "start",
872
+ deltaY
873
+ };
874
+ for (const callback of scrollBoundaryCallbacks) callback(payload);
875
+ }
881
876
  function onWheel(event) {
882
877
  if (event.ctrlKey || event.metaKey) return;
883
878
  if (isSinglePageMode.value) {
884
879
  event.preventDefault();
885
- if (wheelCooldown) return;
880
+ const total = viewerState.totalPages.value;
881
+ const cur = viewerState.currentPage.value;
882
+ const isAtBoundary = event.deltaY > 0 && cur >= total || event.deltaY < 0 && cur <= 1;
883
+ if (wheelCooldown) {
884
+ if (isAtBoundary) notifyScrollBoundary(event.deltaY);
885
+ return;
886
+ }
886
887
  wheelCooldown = true;
887
888
  setTimeout(() => {
888
889
  wheelCooldown = false;
889
890
  }, 300);
890
- const total = viewerState.totalPages.value;
891
- const cur = viewerState.currentPage.value;
892
891
  if (event.deltaY > 0 && cur < total) {
893
892
  viewerState.currentPage.value = cur + 1;
894
893
  } else if (event.deltaY < 0 && cur > 1) {
895
894
  viewerState.currentPage.value = cur - 1;
895
+ } else {
896
+ notifyScrollBoundary(event.deltaY);
896
897
  }
897
898
  return;
898
899
  }
899
900
  event.preventDefault();
900
901
  const dx = event.shiftKey ? event.deltaY : event.deltaX;
901
902
  const dy = event.shiftKey ? 0 : event.deltaY;
902
- inertiaPanzoom.scrollBy(dx, dy);
903
+ const remaining = inertiaPanzoom.scrollBy(dx, dy);
904
+ notifyScrollBoundary(remaining.y);
903
905
  }
904
906
  function isTextInputTarget(target) {
905
907
  if (!(target instanceof HTMLElement)) return false;
@@ -992,11 +994,9 @@ onMounted(() => {
992
994
  for (const cb of fieldPlacedCallbacks) cb(def);
993
995
  viewerState.selectTool("hand");
994
996
  },
995
- getFormFieldPreviewColor: () => {
996
- const id = formFieldsState.activeRoleId.value;
997
- if (!id) return void 0;
998
- return formFieldsState.roleColors.value[id];
999
- },
997
+ // The placement drag preview adopts the fieldColor preset of the tool's
998
+ // field type, so the rubber-band already shows the signer's color.
999
+ getFormFieldPreviewColor: (fieldType) => formFieldsState.placedFieldDefaults.value[fieldType]?.fieldColor,
1000
1000
  freehandGroupingDelay: props.freehandGroupingDelay,
1001
1001
  // Suspend panzoom gestures while an annotation is being dragged or
1002
1002
  // transformed. Otherwise single-finger pan runs in parallel with the
@@ -1144,10 +1144,12 @@ defineExpose({
1144
1144
  * The new field is exported into the PDF on `exportPdf()` like any
1145
1145
  * field placed via the placement tool. */
1146
1146
  addFormField: (payload) => formFieldsState.addFormField(payload),
1147
- /** Patch a form field by id (rect, name, flags, type-specific props). */
1148
- updateFormField: (id, patch) => formFieldsState.updatePlacedField(id, patch),
1149
- /** Remove a form field by id (drops its value too). */
1150
- removeFormField: (id) => formFieldsState.removePlacedField(id),
1147
+ /** Patch a form field by id (rect, name, flags, type-specific props).
1148
+ * Does not fire `field-updated` — that event is for user-driven edits. */
1149
+ updateFormField: (id, patch) => formFieldsState.updatePlacedField(id, patch, { silent: true }),
1150
+ /** Remove a form field by id (drops its value too). Does not fire
1151
+ * `field-removed` — that event is for user-driven removals. */
1152
+ removeFormField: (id) => formFieldsState.removePlacedField(id, { silent: true }),
1151
1153
  /** All form-field definitions (parsed, detected, and placed), flat. */
1152
1154
  getFormFields: () => formFieldsState.getAllFields(),
1153
1155
  /** Replace the per-field-type presets applied to tool placements.
@@ -1165,6 +1167,20 @@ defineExpose({
1165
1167
  fieldPlacedCallbacks.add(cb);
1166
1168
  return () => fieldPlacedCallbacks.delete(cb);
1167
1169
  },
1170
+ /** Subscribe to user-driven field edits (imperative mirror of the
1171
+ * `field-updated` event, used by the embed bridge). Returns an
1172
+ * unsubscribe function. */
1173
+ onFieldUpdated: (cb) => {
1174
+ fieldUpdatedCallbacks.add(cb);
1175
+ return () => fieldUpdatedCallbacks.delete(cb);
1176
+ },
1177
+ /** Subscribe to user-driven field removals (imperative mirror of the
1178
+ * `field-removed` event, used by the embed bridge). Returns an
1179
+ * unsubscribe function. */
1180
+ onFieldRemoved: (cb) => {
1181
+ fieldRemovedCallbacks.add(cb);
1182
+ return () => fieldRemovedCallbacks.delete(cb);
1183
+ },
1168
1184
  /** True once every signature field in the document is signed — via a
1169
1185
  * value applied in this session or a digital signature already in the
1170
1186
  * source PDF. Vacuously true when the document has no signature
@@ -1172,7 +1188,7 @@ defineExpose({
1172
1188
  * need "at least one". Use to gate e.g. envelope finalization. */
1173
1189
  getSignedStatus: () => formFieldsState.getSignatureFieldStatus().every((s) => s.signed),
1174
1190
  /** Per-widget signed-state snapshot (id, fieldName, pageNumber,
1175
- * signed, roleId). */
1191
+ * signed). Correlate to host data by `id`. */
1176
1192
  getSignatureFieldStatus: () => formFieldsState.getSignatureFieldStatus(),
1177
1193
  /** Subscribe to signed-status changes (imperative mirror of the
1178
1194
  * `signed-status-changed` event, used by the embed bridge). Returns
@@ -1181,6 +1197,12 @@ defineExpose({
1181
1197
  signedStatusCallbacks.add(cb);
1182
1198
  return () => signedStatusCallbacks.delete(cb);
1183
1199
  },
1200
+ /** Subscribe to vertical wheel movement left over when the viewer reaches
1201
+ * a document boundary. Used by the embed bridge for parent scrolling. */
1202
+ onScrollBoundary: (cb) => {
1203
+ scrollBoundaryCallbacks.add(cb);
1204
+ return () => scrollBoundaryCallbacks.delete(cb);
1205
+ },
1184
1206
  /** Reactive form-edit-mode flag — read with `.value`. */
1185
1207
  formEditMode: viewerState.formEditMode,
1186
1208
  /** Programmatically enter or leave form-edit mode. */
@@ -1,4 +1,5 @@
1
1
  import { type ViewMode } from '../composables/useViewerState.js';
2
+ import type { ScrollBoundaryPayload } from '../embed/protocol.js';
2
3
  import type { AddFormFieldPayload, FormFieldDefinition, IAnnotationStore, PlacedFieldDefaults, SignatureFieldStatus, StampDefinition, SignatureHandlers } from '../annotation/engine/types.js';
3
4
  import { type ExportPdfOptions } from '../annotation/pdf-export/export.js';
4
5
  import type { ViewerMenuItem } from '../menu-items.js';
@@ -26,16 +27,6 @@ type __VLS_Props = {
26
27
  * with selection chrome, can be moved/resized, and the property panel
27
28
  * is shown. Supports v-model via `v-model:form-edit-mode`. */
28
29
  formEditMode?: boolean;
29
- /** Map of roleId → CSS color used to color-code form fields in
30
- * form-edit mode. The editor stays unopinionated about role
31
- * definitions: the host owns the role list, names, and color picker,
32
- * and just hands a flat lookup table to the viewer. Unknown or
33
- * missing ids fall back to the default blue. */
34
- roleColors?: Record<string, string>;
35
- /** Active role id new field placements are auto-tagged with. The host
36
- * drives this — typically by binding it to a role picker in its own
37
- * UI. Supports v-model via `v-model:active-role-id`. */
38
- activeRoleId?: string | null;
39
30
  /** When true, clicking an unsigned signature field opens kviewer's own
40
31
  * signing flow (saved signature or draw modal). Off by default so hosts
41
32
  * that own the signing process (e.g. an embedding e-sign app) don't get
@@ -122,9 +113,11 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
122
113
  * The new field is exported into the PDF on `exportPdf()` like any
123
114
  * field placed via the placement tool. */
124
115
  addFormField: (payload: AddFormFieldPayload) => FormFieldDefinition;
125
- /** Patch a form field by id (rect, name, flags, type-specific props). */
116
+ /** Patch a form field by id (rect, name, flags, type-specific props).
117
+ * Does not fire `field-updated` — that event is for user-driven edits. */
126
118
  updateFormField: (id: string, patch: Partial<FormFieldDefinition>) => void;
127
- /** Remove a form field by id (drops its value too). */
119
+ /** Remove a form field by id (drops its value too). Does not fire
120
+ * `field-removed` — that event is for user-driven removals. */
128
121
  removeFormField: (id: string) => void;
129
122
  /** All form-field definitions (parsed, detected, and placed), flat. */
130
123
  getFormFields: () => FormFieldDefinition[];
@@ -138,6 +131,14 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
138
131
  * `field-placed` event, used by the embed bridge). Returns an
139
132
  * unsubscribe function. */
140
133
  onFieldPlaced: (cb: (field: FormFieldDefinition) => void) => (() => void);
134
+ /** Subscribe to user-driven field edits (imperative mirror of the
135
+ * `field-updated` event, used by the embed bridge). Returns an
136
+ * unsubscribe function. */
137
+ onFieldUpdated: (cb: (field: FormFieldDefinition, patch: Partial<FormFieldDefinition>) => void) => (() => void);
138
+ /** Subscribe to user-driven field removals (imperative mirror of the
139
+ * `field-removed` event, used by the embed bridge). Returns an
140
+ * unsubscribe function. */
141
+ onFieldRemoved: (cb: (field: FormFieldDefinition) => void) => (() => void);
141
142
  /** True once every signature field in the document is signed — via a
142
143
  * value applied in this session or a digital signature already in the
143
144
  * source PDF. Vacuously true when the document has no signature
@@ -145,7 +146,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
145
146
  * need "at least one". Use to gate e.g. envelope finalization. */
146
147
  getSignedStatus: () => boolean;
147
148
  /** Per-widget signed-state snapshot (id, fieldName, pageNumber,
148
- * signed, roleId). */
149
+ * signed). Correlate to host data by `id`. */
149
150
  getSignatureFieldStatus: () => SignatureFieldStatus[];
150
151
  /** Subscribe to signed-status changes (imperative mirror of the
151
152
  * `signed-status-changed` event, used by the embed bridge). Returns
@@ -154,6 +155,9 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
154
155
  allSigned: boolean;
155
156
  fields: SignatureFieldStatus[];
156
157
  }) => void) => (() => void);
158
+ /** Subscribe to vertical wheel movement left over when the viewer reaches
159
+ * a document boundary. Used by the embed bridge for parent scrolling. */
160
+ onScrollBoundary: (cb: (payload: ScrollBoundaryPayload) => void) => (() => void);
157
161
  /** Reactive form-edit-mode flag — read with `.value`. */
158
162
  formEditMode: import("vue").Ref<boolean, boolean>;
159
163
  /** Programmatically enter or leave form-edit mode. */
@@ -171,8 +175,9 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
171
175
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
172
176
  "all-pages-read": () => any;
173
177
  "field-placed": (field: FormFieldDefinition) => any;
178
+ "field-updated": (field: FormFieldDefinition, patch: Partial<FormFieldDefinition>) => any;
179
+ "field-removed": (field: FormFieldDefinition) => any;
174
180
  "update:formEditMode": (value: boolean) => any;
175
- "update:activeRoleId": (value: string | null) => any;
176
181
  "update:viewedPages": (pages: number[]) => any;
177
182
  "signed-status-changed": (payload: {
178
183
  allSigned: boolean;
@@ -181,8 +186,9 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
181
186
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
182
187
  "onAll-pages-read"?: (() => any) | undefined;
183
188
  "onField-placed"?: ((field: FormFieldDefinition) => any) | undefined;
189
+ "onField-updated"?: ((field: FormFieldDefinition, patch: Partial<FormFieldDefinition>) => any) | undefined;
190
+ "onField-removed"?: ((field: FormFieldDefinition) => any) | undefined;
184
191
  "onUpdate:formEditMode"?: ((value: boolean) => any) | undefined;
185
- "onUpdate:activeRoleId"?: ((value: string | null) => any) | undefined;
186
192
  "onUpdate:viewedPages"?: ((pages: number[]) => any) | undefined;
187
193
  "onSigned-status-changed"?: ((payload: {
188
194
  allSigned: boolean;
@@ -204,8 +210,6 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
204
210
  signatureHandlers: SignatureHandlers;
205
211
  viewMode: ViewMode;
206
212
  shapeDetection: boolean;
207
- roleColors: Record<string, string>;
208
- activeRoleId: string | null;
209
213
  editablePlacedFields: boolean;
210
214
  fieldDefaults: PlacedFieldDefaults;
211
215
  selectionItems: ViewerSelectionItem[];
@@ -54,11 +54,6 @@ type __VLS_Props = {
54
54
  zoom?: number;
55
55
  /** Minimum number of tabs -- prevents closing below this count. */
56
56
  minTabs?: number;
57
- /** Forwarded to every Viewer instance — see KViewer's `roleColors`. */
58
- roleColors?: Record<string, string>;
59
- /** Forwarded to every Viewer instance — see KViewer's `activeRoleId`.
60
- * Supports v-model via `v-model:active-role-id`. */
61
- activeRoleId?: string | null;
62
57
  /** Forwarded to every Viewer instance — see KViewer's `scripting`.
63
58
  * Per-tab override via `ViewerTabItem.scripting` wins when set. */
64
59
  scripting?: boolean;
@@ -82,7 +77,7 @@ declare function addTab(item: Omit<ViewerTabItem, 'id'> & {
82
77
  declare function removeTab(id: string): boolean;
83
78
  declare function activateTab(id: string): void;
84
79
  declare function getViewer(id: string): ComponentPublicInstance | null;
85
- declare var __VLS_7: {}, __VLS_21: {}, __VLS_34: {
80
+ declare var __VLS_7: {}, __VLS_21: {}, __VLS_35: {
86
81
  tab: {
87
82
  id: string;
88
83
  label: string;
@@ -182,7 +177,7 @@ declare var __VLS_7: {}, __VLS_21: {}, __VLS_34: {
182
177
  shapeDetection?: boolean | undefined;
183
178
  scripting?: boolean | undefined;
184
179
  };
185
- }, __VLS_37: {
180
+ }, __VLS_38: {
186
181
  tab: {
187
182
  id: string;
188
183
  label: string;
@@ -282,21 +277,21 @@ declare var __VLS_7: {}, __VLS_21: {}, __VLS_34: {
282
277
  shapeDetection?: boolean | undefined;
283
278
  scripting?: boolean | undefined;
284
279
  };
285
- }, __VLS_41: string, __VLS_42: {
280
+ }, __VLS_42: string, __VLS_43: {
286
281
  state: import("../composables/useViewerState.js").ViewerState;
287
- }, __VLS_44: {};
282
+ }, __VLS_45: {};
288
283
  type __VLS_Slots = {} & {
289
- [K in NonNullable<typeof __VLS_41>]?: (props: typeof __VLS_42) => any;
284
+ [K in NonNullable<typeof __VLS_42>]?: (props: typeof __VLS_43) => any;
290
285
  } & {
291
286
  'tabs-leading'?: (props: typeof __VLS_7) => any;
292
287
  } & {
293
288
  'tabs-trailing'?: (props: typeof __VLS_21) => any;
294
289
  } & {
295
- header?: (props: typeof __VLS_34) => any;
290
+ header?: (props: typeof __VLS_35) => any;
296
291
  } & {
297
- footer?: (props: typeof __VLS_37) => any;
292
+ footer?: (props: typeof __VLS_38) => any;
298
293
  } & {
299
- empty?: (props: typeof __VLS_44) => any;
294
+ empty?: (props: typeof __VLS_45) => any;
300
295
  };
301
296
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
302
297
  addTab: typeof addTab;
@@ -405,7 +400,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
405
400
  }[];
406
401
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
407
402
  "field-placed": (field: FormFieldDefinition) => any;
408
- "update:activeRoleId": (value: string | null) => any;
403
+ "field-updated": (field: FormFieldDefinition, patch: Partial<FormFieldDefinition>) => any;
404
+ "field-removed": (field: FormFieldDefinition) => any;
409
405
  "signed-status-changed": (payload: {
410
406
  allSigned: boolean;
411
407
  fields: SignatureFieldStatus[];
@@ -416,7 +412,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
416
412
  "tab-removed": (id: string) => any;
417
413
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
418
414
  "onField-placed"?: ((field: FormFieldDefinition) => any) | undefined;
419
- "onUpdate:activeRoleId"?: ((value: string | null) => any) | undefined;
415
+ "onField-updated"?: ((field: FormFieldDefinition, patch: Partial<FormFieldDefinition>) => any) | undefined;
416
+ "onField-removed"?: ((field: FormFieldDefinition) => any) | undefined;
420
417
  "onSigned-status-changed"?: ((payload: {
421
418
  allSigned: boolean;
422
419
  fields: SignatureFieldStatus[];
@@ -435,8 +432,6 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
435
432
  stamps: StampDefinition[];
436
433
  signatureHandlers: SignatureHandlers;
437
434
  viewMode: ViewMode;
438
- roleColors: Record<string, string>;
439
- activeRoleId: string | null;
440
435
  editablePlacedFields: boolean;
441
436
  fieldDefaults: PlacedFieldDefaults;
442
437
  selectionItems: ViewerSelectionItem[];