kviewer 0.2.4 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +9 -0
- package/dist/runtime/annotation/engine/config.d.ts +1 -0
- package/dist/runtime/annotation/engine/config.js +4 -0
- package/dist/runtime/annotation/engine/cursor-preview.d.ts +14 -1
- package/dist/runtime/annotation/engine/cursor-preview.js +32 -6
- package/dist/runtime/annotation/engine/editor/editor.d.ts +17 -0
- package/dist/runtime/annotation/engine/editor/editor.js +44 -15
- package/dist/runtime/annotation/engine/tools/signature.js +30 -5
- package/dist/runtime/annotation/engine/tools/stamp.d.ts +9 -0
- package/dist/runtime/annotation/engine/tools/stamp.js +67 -15
- package/dist/runtime/annotation/engine/types.d.ts +25 -0
- package/dist/runtime/annotation/engine/utils.d.ts +1 -4
- package/dist/runtime/annotation/engine/utils.js +1 -10
- package/dist/runtime/annotation/pdf-export/export.js +0 -3
- package/dist/runtime/annotation/utils/placement_size.d.ts +27 -0
- package/dist/runtime/annotation/utils/placement_size.js +26 -0
- package/dist/runtime/annotation/utils/signature_image.d.ts +26 -0
- package/dist/runtime/annotation/utils/signature_image.js +20 -0
- package/dist/runtime/assets/kviewer.css +1 -1
- package/dist/runtime/components/FormFieldLayer.vue +6 -1
- package/dist/runtime/components/Viewer.d.vue.ts +56 -2
- package/dist/runtime/components/Viewer.vue +68 -2
- package/dist/runtime/components/Viewer.vue.d.ts +56 -2
- package/dist/runtime/components/ViewerTabs.d.vue.ts +29 -9
- package/dist/runtime/components/ViewerTabs.vue +10 -2
- package/dist/runtime/components/ViewerTabs.vue.d.ts +29 -9
- package/dist/runtime/components/form-fields/FormFieldWrapper.vue +4 -2
- package/dist/runtime/components/form-fields/FormSignatureField.vue +15 -2
- package/dist/runtime/components/modals/FreeTextModal.vue +1 -1
- package/dist/runtime/components/modals/SignatureDrawModal.vue +170 -4
- package/dist/runtime/components/tools/ToolProperties.vue +98 -101
- package/dist/runtime/composables/useFormFields.d.ts +17 -1
- package/dist/runtime/composables/useFormFields.js +48 -9
- package/dist/runtime/composables/useViewerSearch.js +1 -1
- package/dist/runtime/composables/useViewerState.d.ts +1 -0
- package/dist/runtime/composables/useViewerState.js +12 -13
- package/dist/runtime/embed/bridge-client.d.ts +19 -3
- package/dist/runtime/embed/bridge-client.js +24 -0
- package/dist/runtime/embed/bridge-host.d.ts +10 -1
- package/dist/runtime/embed/bridge-host.js +20 -0
- package/dist/runtime/embed/protocol.d.ts +28 -1
- package/dist/runtime/i18n/messages.d.ts +16 -2
- package/dist/runtime/i18n/messages.js +16 -2
- package/dist/runtime/public-types.d.ts +1 -1
- package/dist/runtime/toolbar-tools.d.ts +1 -1
- package/dist/runtime/toolbar-tools.js +8 -0
- package/package.json +18 -18
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export const WHITE_CUTOFF = 240;
|
|
2
|
+
export const WHITE_SOFT_EDGE = 180;
|
|
3
|
+
export function knockOutWhite(data, cutoff = WHITE_CUTOFF, softEdge = WHITE_SOFT_EDGE) {
|
|
4
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
5
|
+
const luminance = 0.299 * data[i] + 0.587 * data[i + 1] + 0.114 * data[i + 2];
|
|
6
|
+
if (luminance >= cutoff) {
|
|
7
|
+
data[i + 3] = 0;
|
|
8
|
+
} else if (luminance > softEdge) {
|
|
9
|
+
const ratio = (cutoff - luminance) / (cutoff - softEdge);
|
|
10
|
+
data[i + 3] = Math.round(data[i + 3] * ratio);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export function fitWithin(width, height, maxWidth, maxHeight) {
|
|
15
|
+
const scale = Math.min(maxWidth / width, maxHeight / height, 1);
|
|
16
|
+
return {
|
|
17
|
+
width: Math.max(1, Math.round(width * scale)),
|
|
18
|
+
height: Math.max(1, Math.round(height * scale))
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -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}
|
|
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-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}
|
|
@@ -48,7 +48,12 @@ const state = useViewerState();
|
|
|
48
48
|
const fields = computed(() => formFields.getFieldsForPage(props.pageNumber));
|
|
49
49
|
const selectedFieldId = formFields.selectedPlacedFieldId;
|
|
50
50
|
watch(() => state.formEditMode.value, (enabled) => {
|
|
51
|
-
if (
|
|
51
|
+
if (enabled) return;
|
|
52
|
+
const id = formFields.selectedPlacedFieldId.value;
|
|
53
|
+
if (!id) return;
|
|
54
|
+
const def = formFields.getFieldById(id);
|
|
55
|
+
const keepsChrome = formFields.editablePlacedFields.value && def?.origin === "placed";
|
|
56
|
+
if (!keepsChrome) formFields.selectPlacedField(null);
|
|
52
57
|
});
|
|
53
58
|
watch(() => state.activeTool.value, (tool) => {
|
|
54
59
|
const isFormFieldTool = typeof tool === "number" && (tool === AnnotationType.FORM_TEXT || tool === AnnotationType.FORM_CHECKBOX || tool === AnnotationType.FORM_RADIO || tool === AnnotationType.FORM_SIGNATURE);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ViewMode } from '../composables/useViewerState.js';
|
|
2
|
-
import type { AddFormFieldPayload, FormFieldDefinition, IAnnotationStore, StampDefinition, SignatureHandlers } from '../annotation/engine/types.js';
|
|
2
|
+
import type { AddFormFieldPayload, FormFieldDefinition, IAnnotationStore, PlacedFieldDefaults, SignatureFieldStatus, StampDefinition, SignatureHandlers } from '../annotation/engine/types.js';
|
|
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';
|
|
@@ -35,6 +35,21 @@ type __VLS_Props = {
|
|
|
35
35
|
* drives this — typically by binding it to a role picker in its own
|
|
36
36
|
* UI. Supports v-model via `v-model:active-role-id`. */
|
|
37
37
|
activeRoleId?: string | null;
|
|
38
|
+
/** When true, clicking an unsigned signature field opens kviewer's own
|
|
39
|
+
* signing flow (saved signature or draw modal). Off by default so hosts
|
|
40
|
+
* that own the signing process (e.g. an embedding e-sign app) don't get
|
|
41
|
+
* a competing canvas — fields then render as passive markers. */
|
|
42
|
+
clickToSign?: boolean;
|
|
43
|
+
/** When true, user-placed form fields show selection chrome and can be
|
|
44
|
+
* moved/resized/deleted in hand mode even outside form-edit mode.
|
|
45
|
+
* Fields parsed from the source PDF are unaffected. */
|
|
46
|
+
editablePlacedFields?: boolean;
|
|
47
|
+
/** Per-field-type presets merged into every field the user places via
|
|
48
|
+
* the placement tools (e.g. a signature `promptText` or `lockAction`).
|
|
49
|
+
* `fieldName` stays auto-generated — rename via the `field-placed`
|
|
50
|
+
* event and `updateFormField()`. Programmatic `addFormField()` calls
|
|
51
|
+
* are not affected. */
|
|
52
|
+
fieldDefaults?: PlacedFieldDefaults;
|
|
38
53
|
/** Execute embedded JavaScript inside the PDF — field-level AA scripts
|
|
39
54
|
* (Mouse Up, Calculate, Format, Validate, Keystroke), document-level
|
|
40
55
|
* open actions, and page-level scripts. Powered by pdf.js's QuickJS
|
|
@@ -98,6 +113,32 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
98
113
|
removeFormField: (id: string) => void;
|
|
99
114
|
/** All form-field definitions (parsed, detected, and placed), flat. */
|
|
100
115
|
getFormFields: () => FormFieldDefinition[];
|
|
116
|
+
/** Replace the per-field-type presets applied to tool placements.
|
|
117
|
+
* Programmatic counterpart to the `fieldDefaults` prop. */
|
|
118
|
+
setFieldDefaults: (defaults: PlacedFieldDefaults) => void;
|
|
119
|
+
/** Enable/disable kviewer's built-in click-to-sign flow at runtime.
|
|
120
|
+
* Programmatic counterpart to the `clickToSign` prop. */
|
|
121
|
+
setClickToSign: (enabled: boolean) => void;
|
|
122
|
+
/** Subscribe to tool placements (imperative mirror of the
|
|
123
|
+
* `field-placed` event, used by the embed bridge). Returns an
|
|
124
|
+
* unsubscribe function. */
|
|
125
|
+
onFieldPlaced: (cb: (field: FormFieldDefinition) => void) => (() => void);
|
|
126
|
+
/** True once every signature field in the document is signed — via a
|
|
127
|
+
* value applied in this session or a digital signature already in the
|
|
128
|
+
* source PDF. Vacuously true when the document has no signature
|
|
129
|
+
* fields, so combine with `getSignatureFieldStatus().length` if you
|
|
130
|
+
* need "at least one". Use to gate e.g. envelope finalization. */
|
|
131
|
+
getSignedStatus: () => boolean;
|
|
132
|
+
/** Per-widget signed-state snapshot (id, fieldName, pageNumber,
|
|
133
|
+
* signed, roleId). */
|
|
134
|
+
getSignatureFieldStatus: () => SignatureFieldStatus[];
|
|
135
|
+
/** Subscribe to signed-status changes (imperative mirror of the
|
|
136
|
+
* `signed-status-changed` event, used by the embed bridge). Returns
|
|
137
|
+
* an unsubscribe function. */
|
|
138
|
+
onSignedStatusChanged: (cb: (payload: {
|
|
139
|
+
allSigned: boolean;
|
|
140
|
+
fields: SignatureFieldStatus[];
|
|
141
|
+
}) => void) => (() => void);
|
|
101
142
|
/** Reactive form-edit-mode flag — read with `.value`. */
|
|
102
143
|
formEditMode: import("vue").Ref<boolean, boolean>;
|
|
103
144
|
/** Programmatically enter or leave form-edit mode. */
|
|
@@ -114,20 +155,32 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
114
155
|
resetViewedPages: () => void;
|
|
115
156
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
116
157
|
"all-pages-read": () => any;
|
|
158
|
+
"field-placed": (field: FormFieldDefinition) => any;
|
|
117
159
|
"update:formEditMode": (value: boolean) => any;
|
|
118
160
|
"update:activeRoleId": (value: string | null) => any;
|
|
119
161
|
"update:viewedPages": (pages: number[]) => any;
|
|
162
|
+
"signed-status-changed": (payload: {
|
|
163
|
+
allSigned: boolean;
|
|
164
|
+
fields: SignatureFieldStatus[];
|
|
165
|
+
}) => any;
|
|
120
166
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
121
167
|
"onAll-pages-read"?: (() => any) | undefined;
|
|
168
|
+
"onField-placed"?: ((field: FormFieldDefinition) => any) | undefined;
|
|
122
169
|
"onUpdate:formEditMode"?: ((value: boolean) => any) | undefined;
|
|
123
170
|
"onUpdate:activeRoleId"?: ((value: string | null) => any) | undefined;
|
|
124
171
|
"onUpdate:viewedPages"?: ((pages: number[]) => any) | undefined;
|
|
172
|
+
"onSigned-status-changed"?: ((payload: {
|
|
173
|
+
allSigned: boolean;
|
|
174
|
+
fields: SignatureFieldStatus[];
|
|
175
|
+
}) => any) | undefined;
|
|
125
176
|
}>, {
|
|
126
177
|
userName: string;
|
|
127
178
|
freehandGroupingDelay: number;
|
|
128
179
|
zoom: number;
|
|
180
|
+
clickToSign: boolean;
|
|
129
181
|
readonly: boolean;
|
|
130
182
|
active: boolean;
|
|
183
|
+
locale: KviewerLocale;
|
|
131
184
|
menuItems: ViewerMenuItem[];
|
|
132
185
|
tools: ViewerToolEntry[];
|
|
133
186
|
scripting: boolean;
|
|
@@ -138,7 +191,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
138
191
|
formEditMode: boolean;
|
|
139
192
|
roleColors: Record<string, string>;
|
|
140
193
|
activeRoleId: string | null;
|
|
141
|
-
|
|
194
|
+
editablePlacedFields: boolean;
|
|
195
|
+
fieldDefaults: PlacedFieldDefaults;
|
|
142
196
|
messages: KviewerMessageOverrides;
|
|
143
197
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
144
198
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
@@ -242,6 +242,9 @@ const props = defineProps({
|
|
|
242
242
|
formEditMode: { type: Boolean, required: false, default: void 0 },
|
|
243
243
|
roleColors: { type: Object, required: false, default: void 0 },
|
|
244
244
|
activeRoleId: { type: [String, null], required: false, default: void 0 },
|
|
245
|
+
clickToSign: { type: Boolean, required: false, default: false },
|
|
246
|
+
editablePlacedFields: { type: Boolean, required: false, default: false },
|
|
247
|
+
fieldDefaults: { type: Object, required: false, default: void 0 },
|
|
245
248
|
scripting: { type: Boolean, required: false, default: false },
|
|
246
249
|
menuItems: { type: Array, required: false, default: void 0 },
|
|
247
250
|
tools: { type: Array, required: false, default: void 0 },
|
|
@@ -252,7 +255,9 @@ const slots = useSlots();
|
|
|
252
255
|
const toolSlotNames = computed(
|
|
253
256
|
() => Object.keys(slots).filter((name) => name.startsWith("tool-"))
|
|
254
257
|
);
|
|
255
|
-
const emit = defineEmits(["update:formEditMode", "update:activeRoleId", "update:viewedPages", "all-pages-read"]);
|
|
258
|
+
const emit = defineEmits(["update:formEditMode", "update:activeRoleId", "update:viewedPages", "all-pages-read", "field-placed", "signed-status-changed"]);
|
|
259
|
+
const fieldPlacedCallbacks = /* @__PURE__ */ new Set();
|
|
260
|
+
const signedStatusCallbacks = /* @__PURE__ */ new Set();
|
|
256
261
|
const viewerRoot = ref(null);
|
|
257
262
|
const scrollContainer = ref(null);
|
|
258
263
|
const { state: viewerState, setScrollToPageFn, setDownloadPdfFn, setApplyScaleFn } = provideViewerState();
|
|
@@ -262,6 +267,9 @@ watchEffect(() => {
|
|
|
262
267
|
watchEffect(() => {
|
|
263
268
|
viewerState.shapeDetection.value = props.shapeDetection ?? false;
|
|
264
269
|
});
|
|
270
|
+
watchEffect(() => {
|
|
271
|
+
viewerState.clickToSign.value = props.clickToSign ?? false;
|
|
272
|
+
});
|
|
265
273
|
watch(
|
|
266
274
|
() => props.formEditMode,
|
|
267
275
|
(v) => {
|
|
@@ -293,6 +301,28 @@ watch(
|
|
|
293
301
|
},
|
|
294
302
|
{ immediate: true }
|
|
295
303
|
);
|
|
304
|
+
watch(
|
|
305
|
+
() => props.fieldDefaults,
|
|
306
|
+
(v) => {
|
|
307
|
+
formFieldsState.setPlacedFieldDefaults(v ?? {});
|
|
308
|
+
},
|
|
309
|
+
{ immediate: true }
|
|
310
|
+
);
|
|
311
|
+
watch(
|
|
312
|
+
() => props.editablePlacedFields,
|
|
313
|
+
(v) => {
|
|
314
|
+
formFieldsState.setEditablePlacedFields(v ?? false);
|
|
315
|
+
},
|
|
316
|
+
{ immediate: true }
|
|
317
|
+
);
|
|
318
|
+
const signatureStatus = computed(() => formFieldsState.getSignatureFieldStatus());
|
|
319
|
+
const signatureStatusKey = (fields) => fields.map((s) => `${s.id}|${s.fieldName}|${s.signed ? 1 : 0}`).join(";");
|
|
320
|
+
watch(signatureStatus, (next, prev) => {
|
|
321
|
+
if (prev && signatureStatusKey(next) === signatureStatusKey(prev)) return;
|
|
322
|
+
const payload = { allSigned: next.every((s) => s.signed), fields: next };
|
|
323
|
+
emit("signed-status-changed", payload);
|
|
324
|
+
for (const cb of signedStatusCallbacks) cb(payload);
|
|
325
|
+
});
|
|
296
326
|
watch(
|
|
297
327
|
() => props.activeRoleId,
|
|
298
328
|
(v) => {
|
|
@@ -918,7 +948,12 @@ onMounted(() => {
|
|
|
918
948
|
userName: props.userName,
|
|
919
949
|
onRequestTextInput,
|
|
920
950
|
onPlaceField: (payload) => {
|
|
921
|
-
formFieldsState.addPlacedField(payload);
|
|
951
|
+
const def = formFieldsState.addPlacedField(payload);
|
|
952
|
+
if (!viewerState.formEditMode.value && formFieldsState.editablePlacedFields.value) {
|
|
953
|
+
formFieldsState.selectPlacedField(def.id);
|
|
954
|
+
}
|
|
955
|
+
emit("field-placed", def);
|
|
956
|
+
for (const cb of fieldPlacedCallbacks) cb(def);
|
|
922
957
|
viewerState.selectTool("hand");
|
|
923
958
|
},
|
|
924
959
|
getFormFieldPreviewColor: () => {
|
|
@@ -1070,6 +1105,37 @@ defineExpose({
|
|
|
1070
1105
|
removeFormField: (id) => formFieldsState.removePlacedField(id),
|
|
1071
1106
|
/** All form-field definitions (parsed, detected, and placed), flat. */
|
|
1072
1107
|
getFormFields: () => formFieldsState.getAllFields(),
|
|
1108
|
+
/** Replace the per-field-type presets applied to tool placements.
|
|
1109
|
+
* Programmatic counterpart to the `fieldDefaults` prop. */
|
|
1110
|
+
setFieldDefaults: (defaults) => formFieldsState.setPlacedFieldDefaults(defaults),
|
|
1111
|
+
/** Enable/disable kviewer's built-in click-to-sign flow at runtime.
|
|
1112
|
+
* Programmatic counterpart to the `clickToSign` prop. */
|
|
1113
|
+
setClickToSign: (enabled) => {
|
|
1114
|
+
viewerState.clickToSign.value = enabled;
|
|
1115
|
+
},
|
|
1116
|
+
/** Subscribe to tool placements (imperative mirror of the
|
|
1117
|
+
* `field-placed` event, used by the embed bridge). Returns an
|
|
1118
|
+
* unsubscribe function. */
|
|
1119
|
+
onFieldPlaced: (cb) => {
|
|
1120
|
+
fieldPlacedCallbacks.add(cb);
|
|
1121
|
+
return () => fieldPlacedCallbacks.delete(cb);
|
|
1122
|
+
},
|
|
1123
|
+
/** True once every signature field in the document is signed — via a
|
|
1124
|
+
* value applied in this session or a digital signature already in the
|
|
1125
|
+
* source PDF. Vacuously true when the document has no signature
|
|
1126
|
+
* fields, so combine with `getSignatureFieldStatus().length` if you
|
|
1127
|
+
* need "at least one". Use to gate e.g. envelope finalization. */
|
|
1128
|
+
getSignedStatus: () => formFieldsState.getSignatureFieldStatus().every((s) => s.signed),
|
|
1129
|
+
/** Per-widget signed-state snapshot (id, fieldName, pageNumber,
|
|
1130
|
+
* signed, roleId). */
|
|
1131
|
+
getSignatureFieldStatus: () => formFieldsState.getSignatureFieldStatus(),
|
|
1132
|
+
/** Subscribe to signed-status changes (imperative mirror of the
|
|
1133
|
+
* `signed-status-changed` event, used by the embed bridge). Returns
|
|
1134
|
+
* an unsubscribe function. */
|
|
1135
|
+
onSignedStatusChanged: (cb) => {
|
|
1136
|
+
signedStatusCallbacks.add(cb);
|
|
1137
|
+
return () => signedStatusCallbacks.delete(cb);
|
|
1138
|
+
},
|
|
1073
1139
|
/** Reactive form-edit-mode flag — read with `.value`. */
|
|
1074
1140
|
formEditMode: viewerState.formEditMode,
|
|
1075
1141
|
/** Programmatically enter or leave form-edit mode. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ViewMode } from '../composables/useViewerState.js';
|
|
2
|
-
import type { AddFormFieldPayload, FormFieldDefinition, IAnnotationStore, StampDefinition, SignatureHandlers } from '../annotation/engine/types.js';
|
|
2
|
+
import type { AddFormFieldPayload, FormFieldDefinition, IAnnotationStore, PlacedFieldDefaults, SignatureFieldStatus, StampDefinition, SignatureHandlers } from '../annotation/engine/types.js';
|
|
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';
|
|
@@ -35,6 +35,21 @@ type __VLS_Props = {
|
|
|
35
35
|
* drives this — typically by binding it to a role picker in its own
|
|
36
36
|
* UI. Supports v-model via `v-model:active-role-id`. */
|
|
37
37
|
activeRoleId?: string | null;
|
|
38
|
+
/** When true, clicking an unsigned signature field opens kviewer's own
|
|
39
|
+
* signing flow (saved signature or draw modal). Off by default so hosts
|
|
40
|
+
* that own the signing process (e.g. an embedding e-sign app) don't get
|
|
41
|
+
* a competing canvas — fields then render as passive markers. */
|
|
42
|
+
clickToSign?: boolean;
|
|
43
|
+
/** When true, user-placed form fields show selection chrome and can be
|
|
44
|
+
* moved/resized/deleted in hand mode even outside form-edit mode.
|
|
45
|
+
* Fields parsed from the source PDF are unaffected. */
|
|
46
|
+
editablePlacedFields?: boolean;
|
|
47
|
+
/** Per-field-type presets merged into every field the user places via
|
|
48
|
+
* the placement tools (e.g. a signature `promptText` or `lockAction`).
|
|
49
|
+
* `fieldName` stays auto-generated — rename via the `field-placed`
|
|
50
|
+
* event and `updateFormField()`. Programmatic `addFormField()` calls
|
|
51
|
+
* are not affected. */
|
|
52
|
+
fieldDefaults?: PlacedFieldDefaults;
|
|
38
53
|
/** Execute embedded JavaScript inside the PDF — field-level AA scripts
|
|
39
54
|
* (Mouse Up, Calculate, Format, Validate, Keystroke), document-level
|
|
40
55
|
* open actions, and page-level scripts. Powered by pdf.js's QuickJS
|
|
@@ -98,6 +113,32 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
98
113
|
removeFormField: (id: string) => void;
|
|
99
114
|
/** All form-field definitions (parsed, detected, and placed), flat. */
|
|
100
115
|
getFormFields: () => FormFieldDefinition[];
|
|
116
|
+
/** Replace the per-field-type presets applied to tool placements.
|
|
117
|
+
* Programmatic counterpart to the `fieldDefaults` prop. */
|
|
118
|
+
setFieldDefaults: (defaults: PlacedFieldDefaults) => void;
|
|
119
|
+
/** Enable/disable kviewer's built-in click-to-sign flow at runtime.
|
|
120
|
+
* Programmatic counterpart to the `clickToSign` prop. */
|
|
121
|
+
setClickToSign: (enabled: boolean) => void;
|
|
122
|
+
/** Subscribe to tool placements (imperative mirror of the
|
|
123
|
+
* `field-placed` event, used by the embed bridge). Returns an
|
|
124
|
+
* unsubscribe function. */
|
|
125
|
+
onFieldPlaced: (cb: (field: FormFieldDefinition) => void) => (() => void);
|
|
126
|
+
/** True once every signature field in the document is signed — via a
|
|
127
|
+
* value applied in this session or a digital signature already in the
|
|
128
|
+
* source PDF. Vacuously true when the document has no signature
|
|
129
|
+
* fields, so combine with `getSignatureFieldStatus().length` if you
|
|
130
|
+
* need "at least one". Use to gate e.g. envelope finalization. */
|
|
131
|
+
getSignedStatus: () => boolean;
|
|
132
|
+
/** Per-widget signed-state snapshot (id, fieldName, pageNumber,
|
|
133
|
+
* signed, roleId). */
|
|
134
|
+
getSignatureFieldStatus: () => SignatureFieldStatus[];
|
|
135
|
+
/** Subscribe to signed-status changes (imperative mirror of the
|
|
136
|
+
* `signed-status-changed` event, used by the embed bridge). Returns
|
|
137
|
+
* an unsubscribe function. */
|
|
138
|
+
onSignedStatusChanged: (cb: (payload: {
|
|
139
|
+
allSigned: boolean;
|
|
140
|
+
fields: SignatureFieldStatus[];
|
|
141
|
+
}) => void) => (() => void);
|
|
101
142
|
/** Reactive form-edit-mode flag — read with `.value`. */
|
|
102
143
|
formEditMode: import("vue").Ref<boolean, boolean>;
|
|
103
144
|
/** Programmatically enter or leave form-edit mode. */
|
|
@@ -114,20 +155,32 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
114
155
|
resetViewedPages: () => void;
|
|
115
156
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
116
157
|
"all-pages-read": () => any;
|
|
158
|
+
"field-placed": (field: FormFieldDefinition) => any;
|
|
117
159
|
"update:formEditMode": (value: boolean) => any;
|
|
118
160
|
"update:activeRoleId": (value: string | null) => any;
|
|
119
161
|
"update:viewedPages": (pages: number[]) => any;
|
|
162
|
+
"signed-status-changed": (payload: {
|
|
163
|
+
allSigned: boolean;
|
|
164
|
+
fields: SignatureFieldStatus[];
|
|
165
|
+
}) => any;
|
|
120
166
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
121
167
|
"onAll-pages-read"?: (() => any) | undefined;
|
|
168
|
+
"onField-placed"?: ((field: FormFieldDefinition) => any) | undefined;
|
|
122
169
|
"onUpdate:formEditMode"?: ((value: boolean) => any) | undefined;
|
|
123
170
|
"onUpdate:activeRoleId"?: ((value: string | null) => any) | undefined;
|
|
124
171
|
"onUpdate:viewedPages"?: ((pages: number[]) => any) | undefined;
|
|
172
|
+
"onSigned-status-changed"?: ((payload: {
|
|
173
|
+
allSigned: boolean;
|
|
174
|
+
fields: SignatureFieldStatus[];
|
|
175
|
+
}) => any) | undefined;
|
|
125
176
|
}>, {
|
|
126
177
|
userName: string;
|
|
127
178
|
freehandGroupingDelay: number;
|
|
128
179
|
zoom: number;
|
|
180
|
+
clickToSign: boolean;
|
|
129
181
|
readonly: boolean;
|
|
130
182
|
active: boolean;
|
|
183
|
+
locale: KviewerLocale;
|
|
131
184
|
menuItems: ViewerMenuItem[];
|
|
132
185
|
tools: ViewerToolEntry[];
|
|
133
186
|
scripting: boolean;
|
|
@@ -138,7 +191,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
138
191
|
formEditMode: boolean;
|
|
139
192
|
roleColors: Record<string, string>;
|
|
140
193
|
activeRoleId: string | null;
|
|
141
|
-
|
|
194
|
+
editablePlacedFields: boolean;
|
|
195
|
+
fieldDefaults: PlacedFieldDefaults;
|
|
142
196
|
messages: KviewerMessageOverrides;
|
|
143
197
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
144
198
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ComponentPublicInstance } from 'vue';
|
|
2
2
|
import type { ViewMode } from '../composables/useViewerState.js';
|
|
3
|
-
import type { StampDefinition, SignatureHandlers } from '../annotation/engine/types.js';
|
|
3
|
+
import type { FormFieldDefinition, PlacedFieldDefaults, SignatureFieldStatus, StampDefinition, SignatureHandlers } from '../annotation/engine/types.js';
|
|
4
4
|
import type { ViewerMenuItem } from '../menu-items.js';
|
|
5
5
|
import type { ViewerToolEntry } from '../toolbar-tools.js';
|
|
6
6
|
export interface ViewerTabItem {
|
|
@@ -65,6 +65,13 @@ type __VLS_Props = {
|
|
|
65
65
|
menuItems?: ViewerMenuItem[];
|
|
66
66
|
/** Forwarded to every Viewer instance — see KViewer's `tools`. */
|
|
67
67
|
tools?: ViewerToolEntry[];
|
|
68
|
+
/** Forwarded to every Viewer instance — see KViewer's `clickToSign`. */
|
|
69
|
+
clickToSign?: boolean;
|
|
70
|
+
/** Forwarded to every Viewer instance — see KViewer's
|
|
71
|
+
* `editablePlacedFields`. */
|
|
72
|
+
editablePlacedFields?: boolean;
|
|
73
|
+
/** Forwarded to every Viewer instance — see KViewer's `fieldDefaults`. */
|
|
74
|
+
fieldDefaults?: PlacedFieldDefaults;
|
|
68
75
|
};
|
|
69
76
|
declare function addTab(item: Omit<ViewerTabItem, 'id'> & {
|
|
70
77
|
id?: string;
|
|
@@ -72,7 +79,7 @@ declare function addTab(item: Omit<ViewerTabItem, 'id'> & {
|
|
|
72
79
|
declare function removeTab(id: string): boolean;
|
|
73
80
|
declare function activateTab(id: string): void;
|
|
74
81
|
declare function getViewer(id: string): ComponentPublicInstance | null;
|
|
75
|
-
declare var __VLS_7: {}, __VLS_21: {},
|
|
82
|
+
declare var __VLS_7: {}, __VLS_21: {}, __VLS_34: {
|
|
76
83
|
tab: {
|
|
77
84
|
id: string;
|
|
78
85
|
label: string;
|
|
@@ -172,7 +179,7 @@ declare var __VLS_7: {}, __VLS_21: {}, __VLS_32: {
|
|
|
172
179
|
shapeDetection?: boolean | undefined;
|
|
173
180
|
scripting?: boolean | undefined;
|
|
174
181
|
};
|
|
175
|
-
},
|
|
182
|
+
}, __VLS_37: {
|
|
176
183
|
tab: {
|
|
177
184
|
id: string;
|
|
178
185
|
label: string;
|
|
@@ -272,21 +279,21 @@ declare var __VLS_7: {}, __VLS_21: {}, __VLS_32: {
|
|
|
272
279
|
shapeDetection?: boolean | undefined;
|
|
273
280
|
scripting?: boolean | undefined;
|
|
274
281
|
};
|
|
275
|
-
},
|
|
282
|
+
}, __VLS_41: string, __VLS_42: {
|
|
276
283
|
state: import("../composables/useViewerState.js").ViewerState;
|
|
277
|
-
},
|
|
284
|
+
}, __VLS_44: {};
|
|
278
285
|
type __VLS_Slots = {} & {
|
|
279
|
-
[K in NonNullable<typeof
|
|
286
|
+
[K in NonNullable<typeof __VLS_41>]?: (props: typeof __VLS_42) => any;
|
|
280
287
|
} & {
|
|
281
288
|
'tabs-leading'?: (props: typeof __VLS_7) => any;
|
|
282
289
|
} & {
|
|
283
290
|
'tabs-trailing'?: (props: typeof __VLS_21) => any;
|
|
284
291
|
} & {
|
|
285
|
-
header?: (props: typeof
|
|
292
|
+
header?: (props: typeof __VLS_34) => any;
|
|
286
293
|
} & {
|
|
287
|
-
footer?: (props: typeof
|
|
294
|
+
footer?: (props: typeof __VLS_37) => any;
|
|
288
295
|
} & {
|
|
289
|
-
empty?: (props: typeof
|
|
296
|
+
empty?: (props: typeof __VLS_44) => any;
|
|
290
297
|
};
|
|
291
298
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
292
299
|
addTab: typeof addTab;
|
|
@@ -394,13 +401,23 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
394
401
|
scripting?: boolean | undefined;
|
|
395
402
|
}[];
|
|
396
403
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
404
|
+
"field-placed": (field: FormFieldDefinition) => any;
|
|
397
405
|
"update:activeRoleId": (value: string | null) => any;
|
|
406
|
+
"signed-status-changed": (payload: {
|
|
407
|
+
allSigned: boolean;
|
|
408
|
+
fields: SignatureFieldStatus[];
|
|
409
|
+
}) => any;
|
|
398
410
|
"update:activeTab": (id: string) => any;
|
|
399
411
|
"tab-added": (tab: ViewerTabItem) => any;
|
|
400
412
|
"tab-close": (id: string) => any;
|
|
401
413
|
"tab-removed": (id: string) => any;
|
|
402
414
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
415
|
+
"onField-placed"?: ((field: FormFieldDefinition) => any) | undefined;
|
|
403
416
|
"onUpdate:activeRoleId"?: ((value: string | null) => any) | undefined;
|
|
417
|
+
"onSigned-status-changed"?: ((payload: {
|
|
418
|
+
allSigned: boolean;
|
|
419
|
+
fields: SignatureFieldStatus[];
|
|
420
|
+
}) => any) | undefined;
|
|
404
421
|
"onUpdate:activeTab"?: ((id: string) => any) | undefined;
|
|
405
422
|
"onTab-added"?: ((tab: ViewerTabItem) => any) | undefined;
|
|
406
423
|
"onTab-close"?: ((id: string) => any) | undefined;
|
|
@@ -408,6 +425,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
408
425
|
}>, {
|
|
409
426
|
userName: string;
|
|
410
427
|
zoom: number;
|
|
428
|
+
clickToSign: boolean;
|
|
411
429
|
menuItems: ViewerMenuItem[];
|
|
412
430
|
tools: ViewerToolEntry[];
|
|
413
431
|
scripting: boolean;
|
|
@@ -416,6 +434,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
416
434
|
viewMode: ViewMode;
|
|
417
435
|
roleColors: Record<string, string>;
|
|
418
436
|
activeRoleId: string | null;
|
|
437
|
+
editablePlacedFields: boolean;
|
|
438
|
+
fieldDefaults: PlacedFieldDefaults;
|
|
419
439
|
defaultActiveTab: string;
|
|
420
440
|
minTabs: number;
|
|
421
441
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -64,7 +64,12 @@
|
|
|
64
64
|
:tools="tools"
|
|
65
65
|
:role-colors="roleColors"
|
|
66
66
|
:active-role-id="activeRoleId"
|
|
67
|
+
:click-to-sign="clickToSign"
|
|
68
|
+
:editable-placed-fields="editablePlacedFields"
|
|
69
|
+
:field-defaults="fieldDefaults"
|
|
67
70
|
@update:active-role-id="(v) => emit('update:activeRoleId', v)"
|
|
71
|
+
@field-placed="(f) => emit('field-placed', f)"
|
|
72
|
+
@signed-status-changed="(p) => emit('signed-status-changed', p)"
|
|
68
73
|
>
|
|
69
74
|
<template v-if="$slots.header" #header>
|
|
70
75
|
<slot name="header" :tab="activeTab" />
|
|
@@ -107,13 +112,16 @@ const props = defineProps({
|
|
|
107
112
|
activeRoleId: { type: [String, null], required: false, default: void 0 },
|
|
108
113
|
scripting: { type: Boolean, required: false, default: false },
|
|
109
114
|
menuItems: { type: Array, required: false, default: void 0 },
|
|
110
|
-
tools: { type: Array, required: false, default: void 0 }
|
|
115
|
+
tools: { type: Array, required: false, default: void 0 },
|
|
116
|
+
clickToSign: { type: Boolean, required: false, default: false },
|
|
117
|
+
editablePlacedFields: { type: Boolean, required: false, default: false },
|
|
118
|
+
fieldDefaults: { type: Object, required: false, default: void 0 }
|
|
111
119
|
});
|
|
112
120
|
const slots = useSlots();
|
|
113
121
|
const toolSlotNames = computed(
|
|
114
122
|
() => Object.keys(slots).filter((name) => name.startsWith("tool-"))
|
|
115
123
|
);
|
|
116
|
-
const emit = defineEmits(["update:activeTab", "tab-added", "tab-close", "tab-removed", "update:activeRoleId"]);
|
|
124
|
+
const emit = defineEmits(["update:activeTab", "tab-added", "tab-close", "tab-removed", "update:activeRoleId", "field-placed", "signed-status-changed"]);
|
|
117
125
|
let idCounter = 0;
|
|
118
126
|
function generateId() {
|
|
119
127
|
return `tab-${Date.now()}-${++idCounter}`;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ComponentPublicInstance } from 'vue';
|
|
2
2
|
import type { ViewMode } from '../composables/useViewerState.js';
|
|
3
|
-
import type { StampDefinition, SignatureHandlers } from '../annotation/engine/types.js';
|
|
3
|
+
import type { FormFieldDefinition, PlacedFieldDefaults, SignatureFieldStatus, StampDefinition, SignatureHandlers } from '../annotation/engine/types.js';
|
|
4
4
|
import type { ViewerMenuItem } from '../menu-items.js';
|
|
5
5
|
import type { ViewerToolEntry } from '../toolbar-tools.js';
|
|
6
6
|
export interface ViewerTabItem {
|
|
@@ -65,6 +65,13 @@ type __VLS_Props = {
|
|
|
65
65
|
menuItems?: ViewerMenuItem[];
|
|
66
66
|
/** Forwarded to every Viewer instance — see KViewer's `tools`. */
|
|
67
67
|
tools?: ViewerToolEntry[];
|
|
68
|
+
/** Forwarded to every Viewer instance — see KViewer's `clickToSign`. */
|
|
69
|
+
clickToSign?: boolean;
|
|
70
|
+
/** Forwarded to every Viewer instance — see KViewer's
|
|
71
|
+
* `editablePlacedFields`. */
|
|
72
|
+
editablePlacedFields?: boolean;
|
|
73
|
+
/** Forwarded to every Viewer instance — see KViewer's `fieldDefaults`. */
|
|
74
|
+
fieldDefaults?: PlacedFieldDefaults;
|
|
68
75
|
};
|
|
69
76
|
declare function addTab(item: Omit<ViewerTabItem, 'id'> & {
|
|
70
77
|
id?: string;
|
|
@@ -72,7 +79,7 @@ declare function addTab(item: Omit<ViewerTabItem, 'id'> & {
|
|
|
72
79
|
declare function removeTab(id: string): boolean;
|
|
73
80
|
declare function activateTab(id: string): void;
|
|
74
81
|
declare function getViewer(id: string): ComponentPublicInstance | null;
|
|
75
|
-
declare var __VLS_7: {}, __VLS_21: {},
|
|
82
|
+
declare var __VLS_7: {}, __VLS_21: {}, __VLS_34: {
|
|
76
83
|
tab: {
|
|
77
84
|
id: string;
|
|
78
85
|
label: string;
|
|
@@ -172,7 +179,7 @@ declare var __VLS_7: {}, __VLS_21: {}, __VLS_32: {
|
|
|
172
179
|
shapeDetection?: boolean | undefined;
|
|
173
180
|
scripting?: boolean | undefined;
|
|
174
181
|
};
|
|
175
|
-
},
|
|
182
|
+
}, __VLS_37: {
|
|
176
183
|
tab: {
|
|
177
184
|
id: string;
|
|
178
185
|
label: string;
|
|
@@ -272,21 +279,21 @@ declare var __VLS_7: {}, __VLS_21: {}, __VLS_32: {
|
|
|
272
279
|
shapeDetection?: boolean | undefined;
|
|
273
280
|
scripting?: boolean | undefined;
|
|
274
281
|
};
|
|
275
|
-
},
|
|
282
|
+
}, __VLS_41: string, __VLS_42: {
|
|
276
283
|
state: import("../composables/useViewerState.js").ViewerState;
|
|
277
|
-
},
|
|
284
|
+
}, __VLS_44: {};
|
|
278
285
|
type __VLS_Slots = {} & {
|
|
279
|
-
[K in NonNullable<typeof
|
|
286
|
+
[K in NonNullable<typeof __VLS_41>]?: (props: typeof __VLS_42) => any;
|
|
280
287
|
} & {
|
|
281
288
|
'tabs-leading'?: (props: typeof __VLS_7) => any;
|
|
282
289
|
} & {
|
|
283
290
|
'tabs-trailing'?: (props: typeof __VLS_21) => any;
|
|
284
291
|
} & {
|
|
285
|
-
header?: (props: typeof
|
|
292
|
+
header?: (props: typeof __VLS_34) => any;
|
|
286
293
|
} & {
|
|
287
|
-
footer?: (props: typeof
|
|
294
|
+
footer?: (props: typeof __VLS_37) => any;
|
|
288
295
|
} & {
|
|
289
|
-
empty?: (props: typeof
|
|
296
|
+
empty?: (props: typeof __VLS_44) => any;
|
|
290
297
|
};
|
|
291
298
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
292
299
|
addTab: typeof addTab;
|
|
@@ -394,13 +401,23 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
394
401
|
scripting?: boolean | undefined;
|
|
395
402
|
}[];
|
|
396
403
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
404
|
+
"field-placed": (field: FormFieldDefinition) => any;
|
|
397
405
|
"update:activeRoleId": (value: string | null) => any;
|
|
406
|
+
"signed-status-changed": (payload: {
|
|
407
|
+
allSigned: boolean;
|
|
408
|
+
fields: SignatureFieldStatus[];
|
|
409
|
+
}) => any;
|
|
398
410
|
"update:activeTab": (id: string) => any;
|
|
399
411
|
"tab-added": (tab: ViewerTabItem) => any;
|
|
400
412
|
"tab-close": (id: string) => any;
|
|
401
413
|
"tab-removed": (id: string) => any;
|
|
402
414
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
415
|
+
"onField-placed"?: ((field: FormFieldDefinition) => any) | undefined;
|
|
403
416
|
"onUpdate:activeRoleId"?: ((value: string | null) => any) | undefined;
|
|
417
|
+
"onSigned-status-changed"?: ((payload: {
|
|
418
|
+
allSigned: boolean;
|
|
419
|
+
fields: SignatureFieldStatus[];
|
|
420
|
+
}) => any) | undefined;
|
|
404
421
|
"onUpdate:activeTab"?: ((id: string) => any) | undefined;
|
|
405
422
|
"onTab-added"?: ((tab: ViewerTabItem) => any) | undefined;
|
|
406
423
|
"onTab-close"?: ((id: string) => any) | undefined;
|
|
@@ -408,6 +425,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
408
425
|
}>, {
|
|
409
426
|
userName: string;
|
|
410
427
|
zoom: number;
|
|
428
|
+
clickToSign: boolean;
|
|
411
429
|
menuItems: ViewerMenuItem[];
|
|
412
430
|
tools: ViewerToolEntry[];
|
|
413
431
|
scripting: boolean;
|
|
@@ -416,6 +434,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
416
434
|
viewMode: ViewMode;
|
|
417
435
|
roleColors: Record<string, string>;
|
|
418
436
|
activeRoleId: string | null;
|
|
437
|
+
editablePlacedFields: boolean;
|
|
438
|
+
fieldDefaults: PlacedFieldDefaults;
|
|
419
439
|
defaultActiveTab: string;
|
|
420
440
|
minTabs: number;
|
|
421
441
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
>
|
|
12
12
|
<div
|
|
13
13
|
class="kviewer-form-field__body"
|
|
14
|
-
:class="{ 'kviewer-form-field__body--locked':
|
|
14
|
+
:class="{ 'kviewer-form-field__body--locked': showChrome }"
|
|
15
15
|
>
|
|
16
16
|
<FormTextField v-if="props.field.fieldType === 'text'" :field="props.field" />
|
|
17
17
|
<FormCheckbox v-else-if="props.field.fieldType === 'checkbox'" :field="props.field" />
|
|
@@ -55,7 +55,9 @@ const state = useViewerState();
|
|
|
55
55
|
const formFields = useFormFields();
|
|
56
56
|
const isPlaced = computed(() => props.field.origin === "placed");
|
|
57
57
|
const isFormEditMode = computed(() => state.formEditMode.value);
|
|
58
|
-
const showChrome = computed(
|
|
58
|
+
const showChrome = computed(
|
|
59
|
+
() => isFormEditMode.value || formFields.editablePlacedFields.value && isPlaced.value
|
|
60
|
+
);
|
|
59
61
|
const chromeColor = computed(() => {
|
|
60
62
|
const id = props.field.roleId;
|
|
61
63
|
if (!id) return "#1677ff";
|