kviewer 0.0.9 → 0.0.11
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 +29 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +19 -0
- package/dist/runtime/annotation/checkbox-styles.d.ts +19 -0
- package/dist/runtime/annotation/checkbox-styles.js +27 -0
- package/dist/runtime/annotation/engine/config.js +44 -0
- package/dist/runtime/annotation/engine/editor/editor.d.ts +6 -3
- package/dist/runtime/annotation/engine/editor/editor.js +22 -9
- package/dist/runtime/annotation/engine/editor/selector.d.ts +9 -1
- package/dist/runtime/annotation/engine/editor/selector.js +72 -30
- package/dist/runtime/annotation/engine/painter.d.ts +6 -2
- package/dist/runtime/annotation/engine/painter.js +42 -5
- package/dist/runtime/annotation/engine/tools/form-field.d.ts +24 -0
- package/dist/runtime/annotation/engine/tools/form-field.js +117 -0
- package/dist/runtime/annotation/engine/types.d.ts +54 -1
- package/dist/runtime/annotation/engine/types.js +4 -0
- package/dist/runtime/annotation/font-style.d.ts +23 -0
- package/dist/runtime/annotation/font-style.js +57 -0
- package/dist/runtime/annotation/parsers/extractCheckboxStyles.d.ts +21 -0
- package/dist/runtime/annotation/parsers/extractCheckboxStyles.js +75 -0
- package/dist/runtime/annotation/parsers/parseFormFields.js +16 -3
- package/dist/runtime/annotation/pdf-export/export-form-fields.d.ts +8 -5
- package/dist/runtime/annotation/pdf-export/export-form-fields.js +245 -1
- package/dist/runtime/annotation/pdf-export/export.d.ts +3 -2
- package/dist/runtime/annotation/pdf-export/export.js +9 -2
- package/dist/runtime/assets/kviewer.css +1 -1
- package/dist/runtime/components/FormFieldLayer.d.vue.ts +5 -0
- package/dist/runtime/components/FormFieldLayer.vue +40 -3
- package/dist/runtime/components/FormFieldLayer.vue.d.ts +5 -0
- package/dist/runtime/components/PdfPage.d.vue.ts +6 -1
- package/dist/runtime/components/PdfPage.vue +75 -18
- package/dist/runtime/components/PdfPage.vue.d.ts +6 -1
- package/dist/runtime/components/ToolButton.d.vue.ts +4 -2
- package/dist/runtime/components/ToolButton.vue.d.ts +4 -2
- package/dist/runtime/components/Viewer.d.vue.ts +18 -3
- package/dist/runtime/components/Viewer.vue +278 -170
- package/dist/runtime/components/Viewer.vue.d.ts +18 -3
- package/dist/runtime/components/ViewerBar.vue +24 -2
- package/dist/runtime/components/form-fields/FormButton.vue +16 -4
- package/dist/runtime/components/form-fields/FormCheckbox.vue +31 -15
- package/dist/runtime/components/form-fields/FormDropdown.vue +3 -1
- package/dist/runtime/components/form-fields/FormFieldWrapper.d.vue.ts +12 -1
- package/dist/runtime/components/form-fields/FormFieldWrapper.vue +45 -9
- package/dist/runtime/components/form-fields/FormFieldWrapper.vue.d.ts +12 -1
- package/dist/runtime/components/form-fields/FormRadioButton.vue +3 -1
- package/dist/runtime/components/form-fields/FormSignatureField.vue +2 -1
- package/dist/runtime/components/form-fields/FormTextField.vue +47 -7
- package/dist/runtime/components/form-fields/PlacedFieldChrome.d.vue.ts +16 -0
- package/dist/runtime/components/form-fields/PlacedFieldChrome.vue +131 -0
- package/dist/runtime/components/form-fields/PlacedFieldChrome.vue.d.ts +16 -0
- package/dist/runtime/components/modals/FreeTextModal.vue +27 -3
- package/dist/runtime/components/modals/SignatureDrawModal.vue +70 -15
- package/dist/runtime/components/panels/PlacedFieldSidebar.d.vue.ts +3 -0
- package/dist/runtime/components/panels/PlacedFieldSidebar.vue +505 -0
- package/dist/runtime/components/panels/PlacedFieldSidebar.vue.d.ts +3 -0
- package/dist/runtime/components/tools/ActionTools.vue +4 -5
- package/dist/runtime/components/tools/FormFieldTools.d.vue.ts +3 -0
- package/dist/runtime/components/tools/FormFieldTools.vue +35 -0
- package/dist/runtime/components/tools/FormFieldTools.vue.d.ts +3 -0
- package/dist/runtime/composables/useAnnotationEngine.d.ts +2 -0
- package/dist/runtime/composables/useAnnotationEngine.js +6 -2
- package/dist/runtime/composables/useAnnotationHistory.d.ts +1 -0
- package/dist/runtime/composables/useAnnotationHistory.js +10 -3
- package/dist/runtime/composables/useFormFields.d.ts +29 -2
- package/dist/runtime/composables/useFormFields.js +259 -5
- package/dist/runtime/composables/useInertiaPanzoom.d.ts +40 -0
- package/dist/runtime/composables/useInertiaPanzoom.js +475 -0
- package/dist/runtime/composables/usePageVirtualization.d.ts +9 -0
- package/dist/runtime/composables/usePageVirtualization.js +34 -3
- package/dist/runtime/composables/useViewerSearch.d.ts +1 -0
- package/dist/runtime/composables/useViewerSearch.js +15 -5
- package/dist/runtime/composables/useViewerState.d.ts +3 -0
- package/dist/runtime/composables/useViewerState.js +22 -1
- package/package.json +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type ShallowRef } from 'vue';
|
|
2
|
-
import type { DetectedShape, FormFieldDefinition, FormFieldValue } from '../annotation/engine/types.js';
|
|
1
|
+
import { type Ref, type ShallowRef } from 'vue';
|
|
2
|
+
import type { CheckboxStyle, DetectedShape, FormFieldDefinition, FormFieldValue, PlaceFieldPayload } from '../annotation/engine/types.js';
|
|
3
3
|
export interface FormFieldsState {
|
|
4
4
|
/** Field definitions grouped by page number */
|
|
5
5
|
fieldDefinitions: ShallowRef<Map<number, FormFieldDefinition[]>>;
|
|
@@ -21,6 +21,33 @@ export interface FormFieldsState {
|
|
|
21
21
|
resetValues: () => void;
|
|
22
22
|
/** Create synthetic checkbox form fields from detected shapes */
|
|
23
23
|
registerDetectedCheckboxes: (pageNumber: number, shapes: DetectedShape[], scale: number, pageHeight: number) => void;
|
|
24
|
+
/** Add a user-placed form field (from the placement tool). Returns the created def. */
|
|
25
|
+
addPlacedField: (payload: PlaceFieldPayload) => FormFieldDefinition;
|
|
26
|
+
/** Update a placed field's rect, name, or flags. */
|
|
27
|
+
updatePlacedField: (id: string, patch: Partial<FormFieldDefinition>) => void;
|
|
28
|
+
/** Remove a placed field and its value. */
|
|
29
|
+
removePlacedField: (id: string) => void;
|
|
30
|
+
/** All user-placed field definitions (used by export). */
|
|
31
|
+
getPlacedFields: () => FormFieldDefinition[];
|
|
32
|
+
/** Look up a field definition by id (any origin). */
|
|
33
|
+
getFieldById: (id: string) => FormFieldDefinition | undefined;
|
|
34
|
+
/** Id of the currently selected placed field (null if none). */
|
|
35
|
+
selectedPlacedFieldId: Ref<string | null>;
|
|
36
|
+
/** Select or deselect a placed field. Pass null to deselect. */
|
|
37
|
+
selectPlacedField: (id: string | null) => void;
|
|
38
|
+
/** Apply checkbox-style hints (extracted from `/MK /CA` in the source PDF)
|
|
39
|
+
* to existing parsed checkbox defs and store the map for any defs
|
|
40
|
+
* parsed afterwards. Keyed by checkbox fieldName. */
|
|
41
|
+
applyCheckboxStyles: (styles: Map<string, CheckboxStyle>) => void;
|
|
42
|
+
/** Apply push-button captions (extracted from `/MK /CA` in the source
|
|
43
|
+
* PDF) to existing parsed button defs and store the map for any defs
|
|
44
|
+
* parsed afterwards. Keyed by button fieldName. */
|
|
45
|
+
applyButtonCaptions: (captions: Map<string, string>) => void;
|
|
46
|
+
/** Whether this field is locked by another (signed) signature field's
|
|
47
|
+
* lock rule. Reactive to both definitions and values, so a UI computed
|
|
48
|
+
* that calls this re-runs when any signature is signed or its lock
|
|
49
|
+
* rule changes. */
|
|
50
|
+
isFieldLocked: (fieldId: string) => boolean;
|
|
24
51
|
/** Clear all values and definitions (for document change) */
|
|
25
52
|
reset: () => void;
|
|
26
53
|
}
|
|
@@ -1,18 +1,92 @@
|
|
|
1
1
|
import {
|
|
2
2
|
shallowRef,
|
|
3
|
+
ref,
|
|
3
4
|
triggerRef,
|
|
4
5
|
provide,
|
|
5
6
|
inject
|
|
6
7
|
} from "vue";
|
|
7
8
|
import { parseFormFields } from "../annotation/parsers/parseFormFields.js";
|
|
9
|
+
import { generateUUID } from "../annotation/engine/utils.js";
|
|
8
10
|
const FORM_FIELDS_KEY = Symbol("kviewer-form-fields");
|
|
9
11
|
export function provideFormFields() {
|
|
10
12
|
const fieldDefinitions = shallowRef(/* @__PURE__ */ new Map());
|
|
11
13
|
const fieldValues = shallowRef(/* @__PURE__ */ new Map());
|
|
14
|
+
const selectedPlacedFieldId = ref(null);
|
|
15
|
+
function selectPlacedField(id) {
|
|
16
|
+
selectedPlacedFieldId.value = id;
|
|
17
|
+
}
|
|
18
|
+
function getFieldById(id) {
|
|
19
|
+
for (const defs of fieldDefinitions.value.values()) {
|
|
20
|
+
for (const d of defs) {
|
|
21
|
+
if (d.id === id) return d;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return void 0;
|
|
25
|
+
}
|
|
26
|
+
let checkboxStyleMap = null;
|
|
27
|
+
let buttonCaptionMap = null;
|
|
28
|
+
function applyCheckboxStyles(styles) {
|
|
29
|
+
checkboxStyleMap = styles;
|
|
30
|
+
let changed = false;
|
|
31
|
+
for (const [page, defs] of fieldDefinitions.value.entries()) {
|
|
32
|
+
let pageChanged = false;
|
|
33
|
+
const next = defs.map((d) => {
|
|
34
|
+
if (d.fieldType !== "checkbox" || d.origin !== "parsed") return d;
|
|
35
|
+
const style = styles.get(d.fieldName);
|
|
36
|
+
if (!style) return d;
|
|
37
|
+
if (d.originalCheckboxStyle) return d;
|
|
38
|
+
pageChanged = true;
|
|
39
|
+
return { ...d, checkboxStyle: d.checkboxStyle ?? style, originalCheckboxStyle: style };
|
|
40
|
+
});
|
|
41
|
+
if (pageChanged) {
|
|
42
|
+
fieldDefinitions.value.set(page, next);
|
|
43
|
+
changed = true;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (changed) triggerRef(fieldDefinitions);
|
|
47
|
+
}
|
|
48
|
+
function applyButtonCaptions(captions) {
|
|
49
|
+
buttonCaptionMap = captions;
|
|
50
|
+
let changed = false;
|
|
51
|
+
for (const [page, defs] of fieldDefinitions.value.entries()) {
|
|
52
|
+
let pageChanged = false;
|
|
53
|
+
const next = defs.map((d) => {
|
|
54
|
+
if (d.fieldType !== "button" || d.origin !== "parsed") return d;
|
|
55
|
+
const caption = captions.get(d.fieldName);
|
|
56
|
+
if (!caption) return d;
|
|
57
|
+
if (d.buttonLabel === caption) return d;
|
|
58
|
+
pageChanged = true;
|
|
59
|
+
return { ...d, buttonLabel: caption };
|
|
60
|
+
});
|
|
61
|
+
if (pageChanged) {
|
|
62
|
+
fieldDefinitions.value.set(page, next);
|
|
63
|
+
changed = true;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (changed) triggerRef(fieldDefinitions);
|
|
67
|
+
}
|
|
12
68
|
function parsePageFields(pageNumber, rawAnnotations) {
|
|
13
69
|
if (fieldDefinitions.value.has(pageNumber)) return;
|
|
14
70
|
const defs = parseFormFields(rawAnnotations, pageNumber);
|
|
15
71
|
if (defs.length === 0) return;
|
|
72
|
+
if (checkboxStyleMap) {
|
|
73
|
+
for (const def of defs) {
|
|
74
|
+
if (def.fieldType === "checkbox" && !def.checkboxStyle) {
|
|
75
|
+
const style = checkboxStyleMap.get(def.fieldName);
|
|
76
|
+
if (style) {
|
|
77
|
+
def.checkboxStyle = style;
|
|
78
|
+
def.originalCheckboxStyle = style;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (buttonCaptionMap) {
|
|
84
|
+
for (const def of defs) {
|
|
85
|
+
if (def.fieldType !== "button") continue;
|
|
86
|
+
const caption = buttonCaptionMap.get(def.fieldName);
|
|
87
|
+
if (caption) def.buttonLabel = caption;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
16
90
|
fieldDefinitions.value.set(pageNumber, defs);
|
|
17
91
|
triggerRef(fieldDefinitions);
|
|
18
92
|
for (const def of defs) {
|
|
@@ -30,11 +104,19 @@ export function provideFormFields() {
|
|
|
30
104
|
const existing = fieldValues.value.get(fieldId);
|
|
31
105
|
if (!existing) return;
|
|
32
106
|
existing.value = value;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
fv.
|
|
107
|
+
const { fieldName, fieldType } = existing;
|
|
108
|
+
if (fieldName) {
|
|
109
|
+
if (fieldType === "radio" && typeof value === "string" && value !== "") {
|
|
110
|
+
for (const [id, fv] of fieldValues.value.entries()) {
|
|
111
|
+
if (id !== fieldId && fv.fieldName === fieldName && fv.fieldType === "radio") {
|
|
112
|
+
fv.value = "";
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
} else if (fieldType !== "radio") {
|
|
116
|
+
for (const [id, fv] of fieldValues.value.entries()) {
|
|
117
|
+
if (id !== fieldId && fv.fieldName === fieldName && fv.fieldType === fieldType) {
|
|
118
|
+
fv.value = value;
|
|
119
|
+
}
|
|
38
120
|
}
|
|
39
121
|
}
|
|
40
122
|
}
|
|
@@ -97,6 +179,7 @@ export function provideFormFields() {
|
|
|
97
179
|
rect: [pdfX1, pdfY1, pdfX2, pdfY2],
|
|
98
180
|
readOnly: false,
|
|
99
181
|
required: false,
|
|
182
|
+
origin: "detected",
|
|
100
183
|
exportValue: "Yes",
|
|
101
184
|
defaultValue: "Off",
|
|
102
185
|
shapeType: s.shapeType
|
|
@@ -115,6 +198,164 @@ export function provideFormFields() {
|
|
|
115
198
|
}
|
|
116
199
|
triggerRef(fieldValues);
|
|
117
200
|
}
|
|
201
|
+
function nextPlacedFieldName(fieldType) {
|
|
202
|
+
const base = fieldType === "text" ? "Text" : fieldType === "checkbox" ? "Checkbox" : fieldType === "signature" ? "Signature" : fieldType === "dropdown" ? "Dropdown" : fieldType === "radio" ? "Radio" : "Field";
|
|
203
|
+
const existing = /* @__PURE__ */ new Set();
|
|
204
|
+
for (const defs of fieldDefinitions.value.values()) {
|
|
205
|
+
for (const d of defs) existing.add(d.fieldName);
|
|
206
|
+
}
|
|
207
|
+
let n = 1;
|
|
208
|
+
while (existing.has(`${base}_${n}`)) n += 1;
|
|
209
|
+
return `${base}_${n}`;
|
|
210
|
+
}
|
|
211
|
+
function placedDefaultValue(fieldType) {
|
|
212
|
+
if (fieldType === "checkbox") return false;
|
|
213
|
+
return "";
|
|
214
|
+
}
|
|
215
|
+
function addPlacedField(payload) {
|
|
216
|
+
const id = `placed-${generateUUID()}`;
|
|
217
|
+
let fieldName;
|
|
218
|
+
if (payload.fieldType === "radio" && selectedPlacedFieldId.value) {
|
|
219
|
+
const sel = getFieldById(selectedPlacedFieldId.value);
|
|
220
|
+
fieldName = sel && sel.fieldType === "radio" ? sel.fieldName : nextPlacedFieldName(payload.fieldType);
|
|
221
|
+
} else {
|
|
222
|
+
fieldName = nextPlacedFieldName(payload.fieldType);
|
|
223
|
+
}
|
|
224
|
+
const def = {
|
|
225
|
+
id,
|
|
226
|
+
pageNumber: payload.pageNumber,
|
|
227
|
+
fieldType: payload.fieldType,
|
|
228
|
+
fieldName,
|
|
229
|
+
rect: [...payload.rectPdf],
|
|
230
|
+
readOnly: false,
|
|
231
|
+
required: false,
|
|
232
|
+
origin: "placed"
|
|
233
|
+
};
|
|
234
|
+
if (payload.fieldType === "radio") {
|
|
235
|
+
def.buttonValue = nextRadioOptionValue(fieldName);
|
|
236
|
+
}
|
|
237
|
+
if (payload.fieldType === "checkbox") {
|
|
238
|
+
def.checkboxStyle = "check";
|
|
239
|
+
}
|
|
240
|
+
if (payload.fieldType === "dropdown") {
|
|
241
|
+
def.combo = true;
|
|
242
|
+
def.options = [{ exportValue: "Option 1", displayValue: "Option 1" }];
|
|
243
|
+
}
|
|
244
|
+
const existingDefs = fieldDefinitions.value.get(payload.pageNumber) ?? [];
|
|
245
|
+
fieldDefinitions.value.set(payload.pageNumber, [...existingDefs, def]);
|
|
246
|
+
triggerRef(fieldDefinitions);
|
|
247
|
+
fieldValues.value.set(id, {
|
|
248
|
+
fieldId: id,
|
|
249
|
+
fieldName: def.fieldName,
|
|
250
|
+
fieldType: def.fieldType,
|
|
251
|
+
value: placedDefaultValue(def.fieldType)
|
|
252
|
+
});
|
|
253
|
+
triggerRef(fieldValues);
|
|
254
|
+
if (payload.fieldType === "radio") {
|
|
255
|
+
selectedPlacedFieldId.value = id;
|
|
256
|
+
}
|
|
257
|
+
return def;
|
|
258
|
+
}
|
|
259
|
+
function nextRadioOptionValue(groupName) {
|
|
260
|
+
const used = /* @__PURE__ */ new Set();
|
|
261
|
+
for (const defs of fieldDefinitions.value.values()) {
|
|
262
|
+
for (const d of defs) {
|
|
263
|
+
if (d.fieldType === "radio" && d.fieldName === groupName && d.buttonValue) {
|
|
264
|
+
used.add(d.buttonValue);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
let n = 1;
|
|
269
|
+
while (used.has(`Option_${n}`)) n += 1;
|
|
270
|
+
return `Option_${n}`;
|
|
271
|
+
}
|
|
272
|
+
function updatePlacedField(id, patch) {
|
|
273
|
+
let found;
|
|
274
|
+
for (const [page, defs] of fieldDefinitions.value.entries()) {
|
|
275
|
+
const idx = defs.findIndex((d) => d.id === id);
|
|
276
|
+
if (idx === -1) continue;
|
|
277
|
+
const existing = defs[idx];
|
|
278
|
+
const next = { ...existing, ...patch, id: existing.id };
|
|
279
|
+
const nextDefs = defs.slice();
|
|
280
|
+
nextDefs[idx] = next;
|
|
281
|
+
fieldDefinitions.value.set(page, nextDefs);
|
|
282
|
+
found = next;
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
if (!found) return;
|
|
286
|
+
triggerRef(fieldDefinitions);
|
|
287
|
+
const fv = fieldValues.value.get(id);
|
|
288
|
+
if (fv && (fv.fieldName !== found.fieldName || fv.fieldType !== found.fieldType)) {
|
|
289
|
+
fv.fieldName = found.fieldName;
|
|
290
|
+
fv.fieldType = found.fieldType;
|
|
291
|
+
triggerRef(fieldValues);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
function removePlacedField(id) {
|
|
295
|
+
let removed = false;
|
|
296
|
+
for (const [page, defs] of fieldDefinitions.value.entries()) {
|
|
297
|
+
const idx = defs.findIndex((d) => d.id === id);
|
|
298
|
+
if (idx === -1) continue;
|
|
299
|
+
const nextDefs = defs.slice();
|
|
300
|
+
nextDefs.splice(idx, 1);
|
|
301
|
+
if (nextDefs.length === 0) {
|
|
302
|
+
fieldDefinitions.value.delete(page);
|
|
303
|
+
} else {
|
|
304
|
+
fieldDefinitions.value.set(page, nextDefs);
|
|
305
|
+
}
|
|
306
|
+
removed = true;
|
|
307
|
+
break;
|
|
308
|
+
}
|
|
309
|
+
if (!removed) return;
|
|
310
|
+
triggerRef(fieldDefinitions);
|
|
311
|
+
if (fieldValues.value.delete(id)) {
|
|
312
|
+
triggerRef(fieldValues);
|
|
313
|
+
}
|
|
314
|
+
if (selectedPlacedFieldId.value === id) {
|
|
315
|
+
selectedPlacedFieldId.value = null;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
function getPlacedFields() {
|
|
319
|
+
const out = [];
|
|
320
|
+
for (const defs of fieldDefinitions.value.values()) {
|
|
321
|
+
for (const d of defs) {
|
|
322
|
+
if (d.origin === "placed" || d.origin === "detected") {
|
|
323
|
+
out.push(d);
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
326
|
+
const rectMoved = d.originalRect && rectChanged(d.rect, d.originalRect);
|
|
327
|
+
const styleChanged = d.fieldType === "checkbox" && (d.checkboxStyle ?? "check") !== (d.originalCheckboxStyle ?? "check");
|
|
328
|
+
if (rectMoved || styleChanged) {
|
|
329
|
+
out.push(d);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return out;
|
|
334
|
+
}
|
|
335
|
+
function rectChanged(a, b) {
|
|
336
|
+
for (let i = 0; i < 4; i++) {
|
|
337
|
+
if (Math.abs((a[i] ?? 0) - (b[i] ?? 0)) > 0.01) return true;
|
|
338
|
+
}
|
|
339
|
+
return false;
|
|
340
|
+
}
|
|
341
|
+
function isFieldLocked(fieldId) {
|
|
342
|
+
const target = getFieldById(fieldId);
|
|
343
|
+
if (!target) return false;
|
|
344
|
+
for (const defs of fieldDefinitions.value.values()) {
|
|
345
|
+
for (const sig of defs) {
|
|
346
|
+
if (sig.fieldType !== "signature") continue;
|
|
347
|
+
if (!sig.lockAction) continue;
|
|
348
|
+
if (sig.id === fieldId) continue;
|
|
349
|
+
const fv = fieldValues.value.get(sig.id);
|
|
350
|
+
if (!fv || typeof fv.value !== "string" || fv.value === "") continue;
|
|
351
|
+
if (sig.lockAction === "all") return true;
|
|
352
|
+
const list = sig.lockFieldNames ?? [];
|
|
353
|
+
if (sig.lockAction === "include" && list.includes(target.fieldName)) return true;
|
|
354
|
+
if (sig.lockAction === "exclude" && !list.includes(target.fieldName)) return true;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return false;
|
|
358
|
+
}
|
|
118
359
|
function resetValues() {
|
|
119
360
|
for (const [, defs] of fieldDefinitions.value.entries()) {
|
|
120
361
|
for (const def of defs) {
|
|
@@ -129,6 +370,9 @@ export function provideFormFields() {
|
|
|
129
370
|
function reset() {
|
|
130
371
|
fieldDefinitions.value = /* @__PURE__ */ new Map();
|
|
131
372
|
fieldValues.value = /* @__PURE__ */ new Map();
|
|
373
|
+
selectedPlacedFieldId.value = null;
|
|
374
|
+
checkboxStyleMap = null;
|
|
375
|
+
buttonCaptionMap = null;
|
|
132
376
|
triggerRef(fieldDefinitions);
|
|
133
377
|
triggerRef(fieldValues);
|
|
134
378
|
}
|
|
@@ -142,6 +386,16 @@ export function provideFormFields() {
|
|
|
142
386
|
getAllFieldValues,
|
|
143
387
|
setFieldValueByName,
|
|
144
388
|
registerDetectedCheckboxes,
|
|
389
|
+
addPlacedField,
|
|
390
|
+
updatePlacedField,
|
|
391
|
+
removePlacedField,
|
|
392
|
+
getPlacedFields,
|
|
393
|
+
getFieldById,
|
|
394
|
+
selectedPlacedFieldId,
|
|
395
|
+
selectPlacedField,
|
|
396
|
+
applyCheckboxStyles,
|
|
397
|
+
applyButtonCaptions,
|
|
398
|
+
isFieldLocked,
|
|
145
399
|
resetValues,
|
|
146
400
|
reset
|
|
147
401
|
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export interface InertiaPanzoomOptions {
|
|
2
|
+
minScale?: number;
|
|
3
|
+
maxScale?: number;
|
|
4
|
+
/** Minimum pointer movement (px) before axis direction is committed. */
|
|
5
|
+
axisLockThreshold?: number;
|
|
6
|
+
/** Vertical must exceed horizontal by this ratio to lock to Y-axis. */
|
|
7
|
+
axisLockRatio?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface ScrollToElementOptions {
|
|
10
|
+
/** Vertical alignment within the viewport. Default: 'start'. */
|
|
11
|
+
block?: 'start' | 'center';
|
|
12
|
+
/** Animate to the target with inertia, or snap instantly. Default: true. */
|
|
13
|
+
animate?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface Transform {
|
|
16
|
+
scale: number;
|
|
17
|
+
tx: number;
|
|
18
|
+
ty: number;
|
|
19
|
+
}
|
|
20
|
+
export interface InertiaPanzoomHandle {
|
|
21
|
+
/** Bind gesture handlers to the given element (its parent becomes the viewport). */
|
|
22
|
+
attach: (target: HTMLElement) => void;
|
|
23
|
+
/** Remove handlers and clear inline styles. */
|
|
24
|
+
detach: () => void;
|
|
25
|
+
/** Reset transform and cancel any in-flight momentum. */
|
|
26
|
+
reset: () => void;
|
|
27
|
+
/** Cancel in-flight momentum without changing transform. */
|
|
28
|
+
stop: () => void;
|
|
29
|
+
getScale: () => number;
|
|
30
|
+
getTransform: () => Transform;
|
|
31
|
+
/** Animate the view so `elem` is at the top (or center) of the viewport. */
|
|
32
|
+
scrollToElement: (elem: HTMLElement, opts?: ScrollToElementOptions) => void;
|
|
33
|
+
/** Pan by a delta in viewport pixels (clamped to bounds). */
|
|
34
|
+
scrollBy: (dx: number, dy: number) => void;
|
|
35
|
+
/** Enable/disable pan+pinch gestures (wheel/scrollbar/keyboard still work). */
|
|
36
|
+
setGesturesEnabled: (enabled: boolean) => void;
|
|
37
|
+
/** Subscribe to transform updates. Returns an unsubscribe function. */
|
|
38
|
+
onChange: (cb: (t: Transform) => void) => () => void;
|
|
39
|
+
}
|
|
40
|
+
export declare function useInertiaPanzoom(options?: InertiaPanzoomOptions): InertiaPanzoomHandle;
|