kviewer 0.3.3 → 0.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.
Files changed (47) hide show
  1. package/dist/module.d.mts +1 -1
  2. package/dist/module.json +1 -1
  3. package/dist/runtime/annotation/engine/editor/selector.d.ts +1 -0
  4. package/dist/runtime/annotation/engine/editor/selector.js +17 -5
  5. package/dist/runtime/annotation/engine/painter.d.ts +4 -2
  6. package/dist/runtime/annotation/engine/painter.js +4 -0
  7. package/dist/runtime/annotation/engine/tools/form-field.d.ts +5 -5
  8. package/dist/runtime/annotation/engine/tools/form-field.js +1 -1
  9. package/dist/runtime/annotation/engine/types.d.ts +18 -9
  10. package/dist/runtime/annotation/pdf-export/export-form-fields.js +6 -29
  11. package/dist/runtime/assets/kviewer.css +1 -1
  12. package/dist/runtime/components/AnnotationToolbar.vue +12 -1
  13. package/dist/runtime/components/FormFieldLayer.vue +7 -2
  14. package/dist/runtime/components/PdfPage.vue +24 -1
  15. package/dist/runtime/components/SelectionToolbarItems.d.vue.ts +8 -0
  16. package/dist/runtime/components/SelectionToolbarItems.vue +43 -0
  17. package/dist/runtime/components/SelectionToolbarItems.vue.d.ts +8 -0
  18. package/dist/runtime/components/Viewer.d.vue.ts +24 -17
  19. package/dist/runtime/components/Viewer.vue +60 -37
  20. package/dist/runtime/components/Viewer.vue.d.ts +24 -17
  21. package/dist/runtime/components/ViewerBar.d.vue.ts +4 -4
  22. package/dist/runtime/components/ViewerBar.vue +2 -1
  23. package/dist/runtime/components/ViewerBar.vue.d.ts +4 -4
  24. package/dist/runtime/components/ViewerTabs.d.vue.ts +16 -17
  25. package/dist/runtime/components/ViewerTabs.vue +5 -6
  26. package/dist/runtime/components/ViewerTabs.vue.d.ts +16 -17
  27. package/dist/runtime/components/form-fields/FormFieldWrapper.vue +35 -10
  28. package/dist/runtime/components/form-fields/FormSignatureField.vue +10 -2
  29. package/dist/runtime/components/form-fields/PlacedFieldChrome.d.vue.ts +4 -0
  30. package/dist/runtime/components/form-fields/PlacedFieldChrome.vue +35 -18
  31. package/dist/runtime/components/form-fields/PlacedFieldChrome.vue.d.ts +4 -0
  32. package/dist/runtime/components/form-fields/PlacedFieldToolbar.d.vue.ts +7 -0
  33. package/dist/runtime/components/form-fields/PlacedFieldToolbar.vue +51 -0
  34. package/dist/runtime/components/form-fields/PlacedFieldToolbar.vue.d.ts +7 -0
  35. package/dist/runtime/composables/useFormFields.d.ts +28 -17
  36. package/dist/runtime/composables/useFormFields.js +20 -24
  37. package/dist/runtime/embed/bridge-client.d.ts +4 -2
  38. package/dist/runtime/embed/bridge-client.js +2 -1
  39. package/dist/runtime/embed/bridge-host.d.ts +2 -0
  40. package/dist/runtime/embed/bridge-host.js +16 -0
  41. package/dist/runtime/embed/protocol.d.ts +12 -0
  42. package/dist/runtime/public-types.d.ts +2 -1
  43. package/dist/runtime/selection-items.d.ts +61 -0
  44. package/dist/runtime/selection-items.js +1 -0
  45. package/dist/runtime/toolbar-tools.d.ts +4 -1
  46. package/dist/types.d.mts +1 -1
  47. package/package.json +1 -1
@@ -193,7 +193,8 @@ import {
193
193
  triggerRef,
194
194
  onMounted,
195
195
  onBeforeUnmount,
196
- useSlots
196
+ useSlots,
197
+ provide
197
198
  } from "vue";
198
199
  import { useRuntimeConfig } from "#imports";
199
200
  import ViewerBar from "./ViewerBar.vue";
@@ -226,6 +227,7 @@ import { isIPad } from "../annotation/engine/input-device";
226
227
  import { useInertiaPanzoom } from "../composables/useInertiaPanzoom";
227
228
  import { createScriptingManager } from "../composables/useScriptingManager";
228
229
  import { createScriptingBridge } from "../composables/useScriptingBridge";
230
+ import { SELECTION_ITEMS_KEY } from "../selection-items";
229
231
  import { provideKviewerI18n } from "../composables/useKviewerI18n";
230
232
  import { KVIEWER_LOCALES } from "../i18n/messages";
231
233
  const props = defineProps({
@@ -241,24 +243,26 @@ const props = defineProps({
241
243
  active: { type: Boolean, required: false, default: true },
242
244
  freehandGroupingDelay: { type: Number, required: false, default: 1e3 },
243
245
  formEditMode: { type: Boolean, required: false, default: void 0 },
244
- roleColors: { type: Object, required: false, default: void 0 },
245
- activeRoleId: { type: [String, null], required: false, default: void 0 },
246
246
  clickToSign: { type: Boolean, required: false, default: false },
247
247
  editablePlacedFields: { type: Boolean, required: false, default: false },
248
248
  fieldDefaults: { type: Object, required: false, default: void 0 },
249
249
  scripting: { type: Boolean, required: false, default: false },
250
250
  menuItems: { type: Array, required: false, default: void 0 },
251
+ selectionItems: { type: Array, required: false, default: void 0 },
251
252
  tools: { type: Array, required: false, default: void 0 },
252
253
  locale: { type: null, required: false, default: void 0 },
253
254
  messages: { type: Object, required: false, default: void 0 }
254
255
  });
256
+ provide(SELECTION_ITEMS_KEY, computed(() => props.selectionItems));
255
257
  const slots = useSlots();
256
258
  const toolSlotNames = computed(
257
259
  () => Object.keys(slots).filter((name) => name.startsWith("tool-"))
258
260
  );
259
- 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"]);
260
262
  const fieldPlacedCallbacks = /* @__PURE__ */ new Set();
261
263
  const signedStatusCallbacks = /* @__PURE__ */ new Set();
264
+ const fieldUpdatedCallbacks = /* @__PURE__ */ new Set();
265
+ const fieldRemovedCallbacks = /* @__PURE__ */ new Set();
262
266
  const viewerRoot = ref(null);
263
267
  const scrollContainer = ref(null);
264
268
  const { state: viewerState, setScrollToPageFn, setDownloadPdfFn, setPrintPdfFn, setApplyScaleFn } = provideViewerState();
@@ -287,6 +291,15 @@ watch(
287
291
  );
288
292
  const viewerSearch = provideViewerSearch();
289
293
  const formFieldsState = provideFormFields();
294
+ formFieldsState.setFieldEventSink((event) => {
295
+ if (event.type === "updated") {
296
+ emit("field-updated", event.field, event.patch);
297
+ for (const cb of fieldUpdatedCallbacks) cb(event.field, event.patch);
298
+ } else {
299
+ emit("field-removed", event.field);
300
+ for (const cb of fieldRemovedCallbacks) cb(event.field);
301
+ }
302
+ });
290
303
  const kviewerPublicConfig = useRuntimeConfig().public.kviewer;
291
304
  provideKviewerI18n(
292
305
  computed(() => {
@@ -295,13 +308,6 @@ provideKviewerI18n(
295
308
  }),
296
309
  computed(() => props.messages ?? {})
297
310
  );
298
- watch(
299
- () => props.roleColors,
300
- (v) => {
301
- formFieldsState.setRoleColors(v ?? {});
302
- },
303
- { immediate: true }
304
- );
305
311
  watch(
306
312
  () => props.fieldDefaults,
307
313
  (v) => {
@@ -316,6 +322,25 @@ watch(
316
322
  },
317
323
  { immediate: true }
318
324
  );
325
+ watch(
326
+ () => formFieldsState.selectedPlacedFieldId.value,
327
+ (id) => {
328
+ if (!id) return;
329
+ viewerState.painter.value?.clearSelection();
330
+ viewerState.selectedAnnotation.value = null;
331
+ viewerState.selectedAnnotations.value = [];
332
+ viewerState.selectionRect.value = null;
333
+ }
334
+ );
335
+ watch(
336
+ [
337
+ () => viewerState.selectedAnnotation.value,
338
+ () => viewerState.selectedAnnotations.value
339
+ ],
340
+ ([single, multi]) => {
341
+ if (single || multi.length > 0) formFieldsState.selectPlacedField(null);
342
+ }
343
+ );
319
344
  const signatureStatus = computed(() => formFieldsState.getSignatureFieldStatus());
320
345
  const signatureStatusKey = (fields) => fields.map((s) => `${s.id}|${s.fieldName}|${s.signed ? 1 : 0}`).join(";");
321
346
  watch(signatureStatus, (next, prev) => {
@@ -324,22 +349,6 @@ watch(signatureStatus, (next, prev) => {
324
349
  emit("signed-status-changed", payload);
325
350
  for (const cb of signedStatusCallbacks) cb(payload);
326
351
  });
327
- watch(
328
- () => props.activeRoleId,
329
- (v) => {
330
- if (v === void 0) return;
331
- if (formFieldsState.activeRoleId.value !== v) {
332
- formFieldsState.setActiveRole(v);
333
- }
334
- },
335
- { immediate: true }
336
- );
337
- watch(
338
- () => formFieldsState.activeRoleId.value,
339
- (v) => {
340
- if (props.activeRoleId !== v) emit("update:activeRoleId", v);
341
- }
342
- );
343
352
  const pageSettings = providePageSettings(viewerRoot);
344
353
  const virtualization = createPageVirtualization();
345
354
  setScrollToPageFn((pageNumber) => {
@@ -969,11 +978,9 @@ onMounted(() => {
969
978
  for (const cb of fieldPlacedCallbacks) cb(def);
970
979
  viewerState.selectTool("hand");
971
980
  },
972
- getFormFieldPreviewColor: () => {
973
- const id = formFieldsState.activeRoleId.value;
974
- if (!id) return void 0;
975
- return formFieldsState.roleColors.value[id];
976
- },
981
+ // The placement drag preview adopts the fieldColor preset of the tool's
982
+ // field type, so the rubber-band already shows the signer's color.
983
+ getFormFieldPreviewColor: (fieldType) => formFieldsState.placedFieldDefaults.value[fieldType]?.fieldColor,
977
984
  freehandGroupingDelay: props.freehandGroupingDelay,
978
985
  // Suspend panzoom gestures while an annotation is being dragged or
979
986
  // transformed. Otherwise single-finger pan runs in parallel with the
@@ -1121,10 +1128,12 @@ defineExpose({
1121
1128
  * The new field is exported into the PDF on `exportPdf()` like any
1122
1129
  * field placed via the placement tool. */
1123
1130
  addFormField: (payload) => formFieldsState.addFormField(payload),
1124
- /** Patch a form field by id (rect, name, flags, type-specific props). */
1125
- updateFormField: (id, patch) => formFieldsState.updatePlacedField(id, patch),
1126
- /** Remove a form field by id (drops its value too). */
1127
- removeFormField: (id) => formFieldsState.removePlacedField(id),
1131
+ /** Patch a form field by id (rect, name, flags, type-specific props).
1132
+ * Does not fire `field-updated` — that event is for user-driven edits. */
1133
+ updateFormField: (id, patch) => formFieldsState.updatePlacedField(id, patch, { silent: true }),
1134
+ /** Remove a form field by id (drops its value too). Does not fire
1135
+ * `field-removed` — that event is for user-driven removals. */
1136
+ removeFormField: (id) => formFieldsState.removePlacedField(id, { silent: true }),
1128
1137
  /** All form-field definitions (parsed, detected, and placed), flat. */
1129
1138
  getFormFields: () => formFieldsState.getAllFields(),
1130
1139
  /** Replace the per-field-type presets applied to tool placements.
@@ -1142,6 +1151,20 @@ defineExpose({
1142
1151
  fieldPlacedCallbacks.add(cb);
1143
1152
  return () => fieldPlacedCallbacks.delete(cb);
1144
1153
  },
1154
+ /** Subscribe to user-driven field edits (imperative mirror of the
1155
+ * `field-updated` event, used by the embed bridge). Returns an
1156
+ * unsubscribe function. */
1157
+ onFieldUpdated: (cb) => {
1158
+ fieldUpdatedCallbacks.add(cb);
1159
+ return () => fieldUpdatedCallbacks.delete(cb);
1160
+ },
1161
+ /** Subscribe to user-driven field removals (imperative mirror of the
1162
+ * `field-removed` event, used by the embed bridge). Returns an
1163
+ * unsubscribe function. */
1164
+ onFieldRemoved: (cb) => {
1165
+ fieldRemovedCallbacks.add(cb);
1166
+ return () => fieldRemovedCallbacks.delete(cb);
1167
+ },
1145
1168
  /** True once every signature field in the document is signed — via a
1146
1169
  * value applied in this session or a digital signature already in the
1147
1170
  * source PDF. Vacuously true when the document has no signature
@@ -1149,7 +1172,7 @@ defineExpose({
1149
1172
  * need "at least one". Use to gate e.g. envelope finalization. */
1150
1173
  getSignedStatus: () => formFieldsState.getSignatureFieldStatus().every((s) => s.signed),
1151
1174
  /** Per-widget signed-state snapshot (id, fieldName, pageNumber,
1152
- * signed, roleId). */
1175
+ * signed). Correlate to host data by `id`. */
1153
1176
  getSignatureFieldStatus: () => formFieldsState.getSignatureFieldStatus(),
1154
1177
  /** Subscribe to signed-status changes (imperative mirror of the
1155
1178
  * `signed-status-changed` event, used by the embed bridge). Returns
@@ -3,6 +3,7 @@ import type { AddFormFieldPayload, FormFieldDefinition, IAnnotationStore, Placed
3
3
  import { type ExportPdfOptions } from '../annotation/pdf-export/export.js';
4
4
  import type { ViewerMenuItem } from '../menu-items.js';
5
5
  import type { ViewerToolEntry } from '../toolbar-tools.js';
6
+ import { type ViewerSelectionItem } from '../selection-items.js';
6
7
  import { type KviewerMessageOverrides } from '../composables/useKviewerI18n.js';
7
8
  import { type KviewerLocale } from '../i18n/messages.js';
8
9
  type __VLS_Props = {
@@ -25,16 +26,6 @@ type __VLS_Props = {
25
26
  * with selection chrome, can be moved/resized, and the property panel
26
27
  * is shown. Supports v-model via `v-model:form-edit-mode`. */
27
28
  formEditMode?: boolean;
28
- /** Map of roleId → CSS color used to color-code form fields in
29
- * form-edit mode. The editor stays unopinionated about role
30
- * definitions: the host owns the role list, names, and color picker,
31
- * and just hands a flat lookup table to the viewer. Unknown or
32
- * missing ids fall back to the default blue. */
33
- roleColors?: Record<string, string>;
34
- /** Active role id new field placements are auto-tagged with. The host
35
- * drives this — typically by binding it to a role picker in its own
36
- * UI. Supports v-model via `v-model:active-role-id`. */
37
- activeRoleId?: string | null;
38
29
  /** When true, clicking an unsigned signature field opens kviewer's own
39
30
  * signing flow (saved signature or draw modal). Off by default so hosts
40
31
  * that own the signing process (e.g. an embedding e-sign app) don't get
@@ -63,6 +54,11 @@ type __VLS_Props = {
63
54
  * toggles or actions without replacing the entire header. Ignored
64
55
  * when the host supplies a custom `#header` slot. */
65
56
  menuItems?: ViewerMenuItem[];
57
+ /** Custom controls appended to the floating selection popover — shown
58
+ * when an annotation or a placed form field (e.g. a signature field)
59
+ * is selected. Buttons and selects; every callback receives the
60
+ * current selection. See {@link ViewerSelectionItem}. */
61
+ selectionItems?: ViewerSelectionItem[];
66
62
  /** Configures which toolbar tools render and in what order. Entries are
67
63
  * built-in tool IDs (strings) or `{ type: 'slot', ... }` objects that
68
64
  * inject a custom button via a `#tool-<name>` slot. When omitted, the
@@ -116,9 +112,11 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
116
112
  * The new field is exported into the PDF on `exportPdf()` like any
117
113
  * field placed via the placement tool. */
118
114
  addFormField: (payload: AddFormFieldPayload) => FormFieldDefinition;
119
- /** Patch a form field by id (rect, name, flags, type-specific props). */
115
+ /** Patch a form field by id (rect, name, flags, type-specific props).
116
+ * Does not fire `field-updated` — that event is for user-driven edits. */
120
117
  updateFormField: (id: string, patch: Partial<FormFieldDefinition>) => void;
121
- /** Remove a form field by id (drops its value too). */
118
+ /** Remove a form field by id (drops its value too). Does not fire
119
+ * `field-removed` — that event is for user-driven removals. */
122
120
  removeFormField: (id: string) => void;
123
121
  /** All form-field definitions (parsed, detected, and placed), flat. */
124
122
  getFormFields: () => FormFieldDefinition[];
@@ -132,6 +130,14 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
132
130
  * `field-placed` event, used by the embed bridge). Returns an
133
131
  * unsubscribe function. */
134
132
  onFieldPlaced: (cb: (field: FormFieldDefinition) => void) => (() => void);
133
+ /** Subscribe to user-driven field edits (imperative mirror of the
134
+ * `field-updated` event, used by the embed bridge). Returns an
135
+ * unsubscribe function. */
136
+ onFieldUpdated: (cb: (field: FormFieldDefinition, patch: Partial<FormFieldDefinition>) => void) => (() => void);
137
+ /** Subscribe to user-driven field removals (imperative mirror of the
138
+ * `field-removed` event, used by the embed bridge). Returns an
139
+ * unsubscribe function. */
140
+ onFieldRemoved: (cb: (field: FormFieldDefinition) => void) => (() => void);
135
141
  /** True once every signature field in the document is signed — via a
136
142
  * value applied in this session or a digital signature already in the
137
143
  * source PDF. Vacuously true when the document has no signature
@@ -139,7 +145,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
139
145
  * need "at least one". Use to gate e.g. envelope finalization. */
140
146
  getSignedStatus: () => boolean;
141
147
  /** Per-widget signed-state snapshot (id, fieldName, pageNumber,
142
- * signed, roleId). */
148
+ * signed). Correlate to host data by `id`. */
143
149
  getSignatureFieldStatus: () => SignatureFieldStatus[];
144
150
  /** Subscribe to signed-status changes (imperative mirror of the
145
151
  * `signed-status-changed` event, used by the embed bridge). Returns
@@ -165,8 +171,9 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
165
171
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
166
172
  "all-pages-read": () => any;
167
173
  "field-placed": (field: FormFieldDefinition) => any;
174
+ "field-updated": (field: FormFieldDefinition, patch: Partial<FormFieldDefinition>) => any;
175
+ "field-removed": (field: FormFieldDefinition) => any;
168
176
  "update:formEditMode": (value: boolean) => any;
169
- "update:activeRoleId": (value: string | null) => any;
170
177
  "update:viewedPages": (pages: number[]) => any;
171
178
  "signed-status-changed": (payload: {
172
179
  allSigned: boolean;
@@ -175,8 +182,9 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
175
182
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
176
183
  "onAll-pages-read"?: (() => any) | undefined;
177
184
  "onField-placed"?: ((field: FormFieldDefinition) => any) | undefined;
185
+ "onField-updated"?: ((field: FormFieldDefinition, patch: Partial<FormFieldDefinition>) => any) | undefined;
186
+ "onField-removed"?: ((field: FormFieldDefinition) => any) | undefined;
178
187
  "onUpdate:formEditMode"?: ((value: boolean) => any) | undefined;
179
- "onUpdate:activeRoleId"?: ((value: string | null) => any) | undefined;
180
188
  "onUpdate:viewedPages"?: ((pages: number[]) => any) | undefined;
181
189
  "onSigned-status-changed"?: ((payload: {
182
190
  allSigned: boolean;
@@ -198,10 +206,9 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
198
206
  signatureHandlers: SignatureHandlers;
199
207
  viewMode: ViewMode;
200
208
  shapeDetection: boolean;
201
- roleColors: Record<string, string>;
202
- activeRoleId: string | null;
203
209
  editablePlacedFields: boolean;
204
210
  fieldDefaults: PlacedFieldDefaults;
211
+ selectionItems: ViewerSelectionItem[];
205
212
  messages: KviewerMessageOverrides;
206
213
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
207
214
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -8,15 +8,15 @@ type __VLS_Props = {
8
8
  * omitted, the default toolbar is rendered. See {@link ViewerToolEntry}. */
9
9
  tools?: ViewerToolEntry[];
10
10
  };
11
- declare var __VLS_109: string, __VLS_110: {
11
+ declare var __VLS_104: string, __VLS_105: {
12
12
  state: import("../composables/useViewerState.js").ViewerState;
13
- }, __VLS_154: string, __VLS_155: {
13
+ }, __VLS_149: string, __VLS_150: {
14
14
  state: import("../composables/useViewerState.js").ViewerState;
15
15
  };
16
16
  type __VLS_Slots = {} & {
17
- [K in NonNullable<typeof __VLS_109>]?: (props: typeof __VLS_110) => any;
17
+ [K in NonNullable<typeof __VLS_104>]?: (props: typeof __VLS_105) => any;
18
18
  } & {
19
- [K in NonNullable<typeof __VLS_154>]?: (props: typeof __VLS_155) => any;
19
+ [K in NonNullable<typeof __VLS_149>]?: (props: typeof __VLS_150) => any;
20
20
  };
21
21
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
22
22
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -11,11 +11,12 @@
11
11
 
12
12
  <ZoomControls />
13
13
 
14
+ <!-- No MarqueeTool button: hand mode covers mouse rubber-band
15
+ selection; `marquee` stays available via the `tools` prop. -->
14
16
  <template v-if="!state.readonly.value">
15
17
  <USeparator orientation="vertical" class="h-5" :ui="{ border: 'border-accented' }" />
16
18
 
17
19
  <HandTool />
18
- <MarqueeTool />
19
20
  </template>
20
21
 
21
22
  <div class="ml-auto flex items-center gap-2">
@@ -8,15 +8,15 @@ type __VLS_Props = {
8
8
  * omitted, the default toolbar is rendered. See {@link ViewerToolEntry}. */
9
9
  tools?: ViewerToolEntry[];
10
10
  };
11
- declare var __VLS_109: string, __VLS_110: {
11
+ declare var __VLS_104: string, __VLS_105: {
12
12
  state: import("../composables/useViewerState.js").ViewerState;
13
- }, __VLS_154: string, __VLS_155: {
13
+ }, __VLS_149: string, __VLS_150: {
14
14
  state: import("../composables/useViewerState.js").ViewerState;
15
15
  };
16
16
  type __VLS_Slots = {} & {
17
- [K in NonNullable<typeof __VLS_109>]?: (props: typeof __VLS_110) => any;
17
+ [K in NonNullable<typeof __VLS_104>]?: (props: typeof __VLS_105) => any;
18
18
  } & {
19
- [K in NonNullable<typeof __VLS_154>]?: (props: typeof __VLS_155) => any;
19
+ [K in NonNullable<typeof __VLS_149>]?: (props: typeof __VLS_150) => any;
20
20
  };
21
21
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
22
22
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -2,6 +2,7 @@ import { type ComponentPublicInstance } from 'vue';
2
2
  import type { ViewMode } from '../composables/useViewerState.js';
3
3
  import type { FormFieldDefinition, PlacedFieldDefaults, SignatureFieldStatus, StampDefinition, SignatureHandlers } from '../annotation/engine/types.js';
4
4
  import type { ViewerMenuItem } from '../menu-items.js';
5
+ import type { ViewerSelectionItem } from '../selection-items.js';
5
6
  import type { ViewerToolEntry } from '../toolbar-tools.js';
6
7
  export interface ViewerTabItem {
7
8
  /** Unique identifier for the tab. */
@@ -53,16 +54,13 @@ type __VLS_Props = {
53
54
  zoom?: number;
54
55
  /** Minimum number of tabs -- prevents closing below this count. */
55
56
  minTabs?: number;
56
- /** Forwarded to every Viewer instance — see KViewer's `roleColors`. */
57
- roleColors?: Record<string, string>;
58
- /** Forwarded to every Viewer instance — see KViewer's `activeRoleId`.
59
- * Supports v-model via `v-model:active-role-id`. */
60
- activeRoleId?: string | null;
61
57
  /** Forwarded to every Viewer instance — see KViewer's `scripting`.
62
58
  * Per-tab override via `ViewerTabItem.scripting` wins when set. */
63
59
  scripting?: boolean;
64
60
  /** Forwarded to every Viewer instance — see KViewer's `menuItems`. */
65
61
  menuItems?: ViewerMenuItem[];
62
+ /** Forwarded to every Viewer instance — see KViewer's `selectionItems`. */
63
+ selectionItems?: ViewerSelectionItem[];
66
64
  /** Forwarded to every Viewer instance — see KViewer's `tools`. */
67
65
  tools?: ViewerToolEntry[];
68
66
  /** Forwarded to every Viewer instance — see KViewer's `clickToSign`. */
@@ -79,7 +77,7 @@ declare function addTab(item: Omit<ViewerTabItem, 'id'> & {
79
77
  declare function removeTab(id: string): boolean;
80
78
  declare function activateTab(id: string): void;
81
79
  declare function getViewer(id: string): ComponentPublicInstance | null;
82
- declare var __VLS_7: {}, __VLS_21: {}, __VLS_34: {
80
+ declare var __VLS_7: {}, __VLS_21: {}, __VLS_35: {
83
81
  tab: {
84
82
  id: string;
85
83
  label: string;
@@ -179,7 +177,7 @@ declare var __VLS_7: {}, __VLS_21: {}, __VLS_34: {
179
177
  shapeDetection?: boolean | undefined;
180
178
  scripting?: boolean | undefined;
181
179
  };
182
- }, __VLS_37: {
180
+ }, __VLS_38: {
183
181
  tab: {
184
182
  id: string;
185
183
  label: string;
@@ -279,21 +277,21 @@ declare var __VLS_7: {}, __VLS_21: {}, __VLS_34: {
279
277
  shapeDetection?: boolean | undefined;
280
278
  scripting?: boolean | undefined;
281
279
  };
282
- }, __VLS_41: string, __VLS_42: {
280
+ }, __VLS_42: string, __VLS_43: {
283
281
  state: import("../composables/useViewerState.js").ViewerState;
284
- }, __VLS_44: {};
282
+ }, __VLS_45: {};
285
283
  type __VLS_Slots = {} & {
286
- [K in NonNullable<typeof __VLS_41>]?: (props: typeof __VLS_42) => any;
284
+ [K in NonNullable<typeof __VLS_42>]?: (props: typeof __VLS_43) => any;
287
285
  } & {
288
286
  'tabs-leading'?: (props: typeof __VLS_7) => any;
289
287
  } & {
290
288
  'tabs-trailing'?: (props: typeof __VLS_21) => any;
291
289
  } & {
292
- header?: (props: typeof __VLS_34) => any;
290
+ header?: (props: typeof __VLS_35) => any;
293
291
  } & {
294
- footer?: (props: typeof __VLS_37) => any;
292
+ footer?: (props: typeof __VLS_38) => any;
295
293
  } & {
296
- empty?: (props: typeof __VLS_44) => any;
294
+ empty?: (props: typeof __VLS_45) => any;
297
295
  };
298
296
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
299
297
  addTab: typeof addTab;
@@ -402,7 +400,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
402
400
  }[];
403
401
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
404
402
  "field-placed": (field: FormFieldDefinition) => any;
405
- "update:activeRoleId": (value: string | null) => any;
403
+ "field-updated": (field: FormFieldDefinition, patch: Partial<FormFieldDefinition>) => any;
404
+ "field-removed": (field: FormFieldDefinition) => any;
406
405
  "signed-status-changed": (payload: {
407
406
  allSigned: boolean;
408
407
  fields: SignatureFieldStatus[];
@@ -413,7 +412,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
413
412
  "tab-removed": (id: string) => any;
414
413
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
415
414
  "onField-placed"?: ((field: FormFieldDefinition) => any) | undefined;
416
- "onUpdate:activeRoleId"?: ((value: string | null) => any) | undefined;
415
+ "onField-updated"?: ((field: FormFieldDefinition, patch: Partial<FormFieldDefinition>) => any) | undefined;
416
+ "onField-removed"?: ((field: FormFieldDefinition) => any) | undefined;
417
417
  "onSigned-status-changed"?: ((payload: {
418
418
  allSigned: boolean;
419
419
  fields: SignatureFieldStatus[];
@@ -432,10 +432,9 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
432
432
  stamps: StampDefinition[];
433
433
  signatureHandlers: SignatureHandlers;
434
434
  viewMode: ViewMode;
435
- roleColors: Record<string, string>;
436
- activeRoleId: string | null;
437
435
  editablePlacedFields: boolean;
438
436
  fieldDefaults: PlacedFieldDefaults;
437
+ selectionItems: ViewerSelectionItem[];
439
438
  defaultActiveTab: string;
440
439
  minTabs: number;
441
440
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -61,14 +61,14 @@
61
61
  :shape-detection="activeTab.shapeDetection ?? shapeDetection"
62
62
  :scripting="activeTab.scripting ?? scripting"
63
63
  :menu-items="menuItems"
64
+ :selection-items="selectionItems"
64
65
  :tools="tools"
65
- :role-colors="roleColors"
66
- :active-role-id="activeRoleId"
67
66
  :click-to-sign="clickToSign"
68
67
  :editable-placed-fields="editablePlacedFields"
69
68
  :field-defaults="fieldDefaults"
70
- @update:active-role-id="(v) => emit('update:activeRoleId', v)"
71
69
  @field-placed="(f) => emit('field-placed', f)"
70
+ @field-updated="(f, p) => emit('field-updated', f, p)"
71
+ @field-removed="(f) => emit('field-removed', f)"
72
72
  @signed-status-changed="(p) => emit('signed-status-changed', p)"
73
73
  >
74
74
  <template v-if="$slots.header" #header>
@@ -108,10 +108,9 @@ const props = defineProps({
108
108
  viewMode: { type: String, required: false, default: "fit-width" },
109
109
  zoom: { type: Number, required: false, default: 1 },
110
110
  minTabs: { type: Number, required: false, default: 0 },
111
- roleColors: { type: Object, required: false, default: void 0 },
112
- activeRoleId: { type: [String, null], required: false, default: void 0 },
113
111
  scripting: { type: Boolean, required: false, default: false },
114
112
  menuItems: { type: Array, required: false, default: void 0 },
113
+ selectionItems: { type: Array, required: false, default: void 0 },
115
114
  tools: { type: Array, required: false, default: void 0 },
116
115
  clickToSign: { type: Boolean, required: false, default: false },
117
116
  editablePlacedFields: { type: Boolean, required: false, default: false },
@@ -121,7 +120,7 @@ const slots = useSlots();
121
120
  const toolSlotNames = computed(
122
121
  () => Object.keys(slots).filter((name) => name.startsWith("tool-"))
123
122
  );
124
- const emit = defineEmits(["update:activeTab", "tab-added", "tab-close", "tab-removed", "update:activeRoleId", "field-placed", "signed-status-changed"]);
123
+ const emit = defineEmits(["update:activeTab", "tab-added", "tab-close", "tab-removed", "field-placed", "field-updated", "field-removed", "signed-status-changed"]);
125
124
  let idCounter = 0;
126
125
  function generateId() {
127
126
  return `tab-${Date.now()}-${++idCounter}`;
@@ -2,6 +2,7 @@ import { type ComponentPublicInstance } from 'vue';
2
2
  import type { ViewMode } from '../composables/useViewerState.js';
3
3
  import type { FormFieldDefinition, PlacedFieldDefaults, SignatureFieldStatus, StampDefinition, SignatureHandlers } from '../annotation/engine/types.js';
4
4
  import type { ViewerMenuItem } from '../menu-items.js';
5
+ import type { ViewerSelectionItem } from '../selection-items.js';
5
6
  import type { ViewerToolEntry } from '../toolbar-tools.js';
6
7
  export interface ViewerTabItem {
7
8
  /** Unique identifier for the tab. */
@@ -53,16 +54,13 @@ type __VLS_Props = {
53
54
  zoom?: number;
54
55
  /** Minimum number of tabs -- prevents closing below this count. */
55
56
  minTabs?: number;
56
- /** Forwarded to every Viewer instance — see KViewer's `roleColors`. */
57
- roleColors?: Record<string, string>;
58
- /** Forwarded to every Viewer instance — see KViewer's `activeRoleId`.
59
- * Supports v-model via `v-model:active-role-id`. */
60
- activeRoleId?: string | null;
61
57
  /** Forwarded to every Viewer instance — see KViewer's `scripting`.
62
58
  * Per-tab override via `ViewerTabItem.scripting` wins when set. */
63
59
  scripting?: boolean;
64
60
  /** Forwarded to every Viewer instance — see KViewer's `menuItems`. */
65
61
  menuItems?: ViewerMenuItem[];
62
+ /** Forwarded to every Viewer instance — see KViewer's `selectionItems`. */
63
+ selectionItems?: ViewerSelectionItem[];
66
64
  /** Forwarded to every Viewer instance — see KViewer's `tools`. */
67
65
  tools?: ViewerToolEntry[];
68
66
  /** Forwarded to every Viewer instance — see KViewer's `clickToSign`. */
@@ -79,7 +77,7 @@ declare function addTab(item: Omit<ViewerTabItem, 'id'> & {
79
77
  declare function removeTab(id: string): boolean;
80
78
  declare function activateTab(id: string): void;
81
79
  declare function getViewer(id: string): ComponentPublicInstance | null;
82
- declare var __VLS_7: {}, __VLS_21: {}, __VLS_34: {
80
+ declare var __VLS_7: {}, __VLS_21: {}, __VLS_35: {
83
81
  tab: {
84
82
  id: string;
85
83
  label: string;
@@ -179,7 +177,7 @@ declare var __VLS_7: {}, __VLS_21: {}, __VLS_34: {
179
177
  shapeDetection?: boolean | undefined;
180
178
  scripting?: boolean | undefined;
181
179
  };
182
- }, __VLS_37: {
180
+ }, __VLS_38: {
183
181
  tab: {
184
182
  id: string;
185
183
  label: string;
@@ -279,21 +277,21 @@ declare var __VLS_7: {}, __VLS_21: {}, __VLS_34: {
279
277
  shapeDetection?: boolean | undefined;
280
278
  scripting?: boolean | undefined;
281
279
  };
282
- }, __VLS_41: string, __VLS_42: {
280
+ }, __VLS_42: string, __VLS_43: {
283
281
  state: import("../composables/useViewerState.js").ViewerState;
284
- }, __VLS_44: {};
282
+ }, __VLS_45: {};
285
283
  type __VLS_Slots = {} & {
286
- [K in NonNullable<typeof __VLS_41>]?: (props: typeof __VLS_42) => any;
284
+ [K in NonNullable<typeof __VLS_42>]?: (props: typeof __VLS_43) => any;
287
285
  } & {
288
286
  'tabs-leading'?: (props: typeof __VLS_7) => any;
289
287
  } & {
290
288
  'tabs-trailing'?: (props: typeof __VLS_21) => any;
291
289
  } & {
292
- header?: (props: typeof __VLS_34) => any;
290
+ header?: (props: typeof __VLS_35) => any;
293
291
  } & {
294
- footer?: (props: typeof __VLS_37) => any;
292
+ footer?: (props: typeof __VLS_38) => any;
295
293
  } & {
296
- empty?: (props: typeof __VLS_44) => any;
294
+ empty?: (props: typeof __VLS_45) => any;
297
295
  };
298
296
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
299
297
  addTab: typeof addTab;
@@ -402,7 +400,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
402
400
  }[];
403
401
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
404
402
  "field-placed": (field: FormFieldDefinition) => any;
405
- "update:activeRoleId": (value: string | null) => any;
403
+ "field-updated": (field: FormFieldDefinition, patch: Partial<FormFieldDefinition>) => any;
404
+ "field-removed": (field: FormFieldDefinition) => any;
406
405
  "signed-status-changed": (payload: {
407
406
  allSigned: boolean;
408
407
  fields: SignatureFieldStatus[];
@@ -413,7 +412,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
413
412
  "tab-removed": (id: string) => any;
414
413
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
415
414
  "onField-placed"?: ((field: FormFieldDefinition) => any) | undefined;
416
- "onUpdate:activeRoleId"?: ((value: string | null) => any) | undefined;
415
+ "onField-updated"?: ((field: FormFieldDefinition, patch: Partial<FormFieldDefinition>) => any) | undefined;
416
+ "onField-removed"?: ((field: FormFieldDefinition) => any) | undefined;
417
417
  "onSigned-status-changed"?: ((payload: {
418
418
  allSigned: boolean;
419
419
  fields: SignatureFieldStatus[];
@@ -432,10 +432,9 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
432
432
  stamps: StampDefinition[];
433
433
  signatureHandlers: SignatureHandlers;
434
434
  viewMode: ViewMode;
435
- roleColors: Record<string, string>;
436
- activeRoleId: string | null;
437
435
  editablePlacedFields: boolean;
438
436
  fieldDefaults: PlacedFieldDefaults;
437
+ selectionItems: ViewerSelectionItem[];
439
438
  defaultActiveTab: string;
440
439
  minTabs: number;
441
440
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;