@dmitryvim/form-builder 0.3.1 → 0.3.3
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 +32 -6
- package/dist/browser/formbuilder.min.js +71 -71
- package/dist/browser/{formbuilder.v0.3.1.min.js → formbuilder.v0.3.3.min.js} +71 -71
- package/dist/cjs/index.cjs +80 -49
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/index.js +77 -48
- package/dist/esm/index.js.map +1 -1
- package/dist/form-builder.js +71 -71
- package/dist/types/instance/FormBuilderInstance.d.ts +1 -0
- package/dist/types/types/state.d.ts +10 -0
- package/dist/types/utils/styles.d.ts +15 -0
- package/package.json +1 -1
package/dist/esm/index.js
CHANGED
|
@@ -484,6 +484,20 @@ function applyAutoExpand(textarea) {
|
|
|
484
484
|
setTimeout(() => {
|
|
485
485
|
if (textarea.isConnected) resize();
|
|
486
486
|
}, 0);
|
|
487
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
488
|
+
let lastWidth = -1;
|
|
489
|
+
const ro = new ResizeObserver((entries) => {
|
|
490
|
+
if (!textarea.isConnected) {
|
|
491
|
+
ro.disconnect();
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
const entry = entries[0];
|
|
495
|
+
const w = entry?.contentBoxSize?.[0]?.inlineSize ?? entry?.contentRect?.width ?? 0;
|
|
496
|
+
if (w === lastWidth) return;
|
|
497
|
+
lastWidth = w;
|
|
498
|
+
resize();
|
|
499
|
+
});
|
|
500
|
+
ro.observe(textarea);
|
|
487
501
|
}
|
|
488
502
|
function applySingleLineMode(textarea) {
|
|
489
503
|
textarea.addEventListener("keydown", (e) => {
|
|
@@ -6711,6 +6725,7 @@ function renderSingleContainerElement(element, ctx, wrapper, pathKey) {
|
|
|
6711
6725
|
formData: ctx.formData ?? ctx.prefill,
|
|
6712
6726
|
// Complete root data for enableIf evaluation
|
|
6713
6727
|
state: ctx.state,
|
|
6728
|
+
instance: ctx.instance,
|
|
6714
6729
|
inheritedReadonly: containerIsReadonly || ctx.inheritedReadonly
|
|
6715
6730
|
};
|
|
6716
6731
|
element.elements.forEach((child) => {
|
|
@@ -6797,6 +6812,7 @@ function renderMultipleContainerElement(element, ctx, wrapper, _pathKey) {
|
|
|
6797
6812
|
const currentFormData = state.formRoot ? extractRootFormData(state.formRoot) : {};
|
|
6798
6813
|
const subCtx = {
|
|
6799
6814
|
state: ctx.state,
|
|
6815
|
+
instance: ctx.instance,
|
|
6800
6816
|
path: pathJoin(ctx.path, `${element.key}[${idx}]`),
|
|
6801
6817
|
prefill: childDefaults,
|
|
6802
6818
|
// Defaults for enableIf evaluation
|
|
@@ -6862,6 +6878,7 @@ function renderMultipleContainerElement(element, ctx, wrapper, _pathKey) {
|
|
|
6862
6878
|
const mergedPrefill = mergeWithDefaults(prefillObj || {}, childDefaults);
|
|
6863
6879
|
const subCtx = {
|
|
6864
6880
|
state: ctx.state,
|
|
6881
|
+
instance: ctx.instance,
|
|
6865
6882
|
path: pathJoin(ctx.path, `${element.key}[${idx}]`),
|
|
6866
6883
|
prefill: mergedPrefill,
|
|
6867
6884
|
// Merged prefill with defaults for enableIf
|
|
@@ -6908,6 +6925,7 @@ function renderMultipleContainerElement(element, ctx, wrapper, _pathKey) {
|
|
|
6908
6925
|
const idx = countItems();
|
|
6909
6926
|
const subCtx = {
|
|
6910
6927
|
state: ctx.state,
|
|
6928
|
+
instance: ctx.instance,
|
|
6911
6929
|
path: pathJoin(ctx.path, `${element.key}[${idx}]`),
|
|
6912
6930
|
prefill: childDefaults,
|
|
6913
6931
|
// Defaults for enableIf evaluation
|
|
@@ -8550,6 +8568,20 @@ function applyAutoExpand2(textarea, backdrop) {
|
|
|
8550
8568
|
setTimeout(() => {
|
|
8551
8569
|
if (textarea.isConnected) resize();
|
|
8552
8570
|
}, 0);
|
|
8571
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
8572
|
+
let lastWidth = -1;
|
|
8573
|
+
const ro = new ResizeObserver((entries) => {
|
|
8574
|
+
if (!textarea.isConnected) {
|
|
8575
|
+
ro.disconnect();
|
|
8576
|
+
return;
|
|
8577
|
+
}
|
|
8578
|
+
const entry = entries[0];
|
|
8579
|
+
const w = entry?.contentBoxSize?.[0]?.inlineSize ?? entry?.contentRect?.width ?? 0;
|
|
8580
|
+
if (w === lastWidth) return;
|
|
8581
|
+
lastWidth = w;
|
|
8582
|
+
resize();
|
|
8583
|
+
});
|
|
8584
|
+
ro.observe(textarea);
|
|
8553
8585
|
}
|
|
8554
8586
|
function buildFileLabels(files, state) {
|
|
8555
8587
|
const labels = /* @__PURE__ */ new Map();
|
|
@@ -10315,6 +10347,33 @@ function extractDOMValue(fieldPath, formRoot) {
|
|
|
10315
10347
|
}
|
|
10316
10348
|
return void 0;
|
|
10317
10349
|
}
|
|
10350
|
+
function buildScopedDataAtPath(path, value) {
|
|
10351
|
+
const segments = path.match(/[^.[\]]+|\[\d+\]/g);
|
|
10352
|
+
if (!segments || segments.length === 0) {
|
|
10353
|
+
return {};
|
|
10354
|
+
}
|
|
10355
|
+
const root = {};
|
|
10356
|
+
let current = root;
|
|
10357
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
10358
|
+
const seg = segments[i];
|
|
10359
|
+
const next = segments[i + 1];
|
|
10360
|
+
const placeholder = next.startsWith("[") && next.endsWith("]") ? [] : {};
|
|
10361
|
+
if (seg.startsWith("[") && seg.endsWith("]")) {
|
|
10362
|
+
const idx = parseInt(seg.slice(1, -1), 10);
|
|
10363
|
+
current[idx] = placeholder;
|
|
10364
|
+
} else {
|
|
10365
|
+
current[seg] = placeholder;
|
|
10366
|
+
}
|
|
10367
|
+
current = placeholder;
|
|
10368
|
+
}
|
|
10369
|
+
const last = segments[segments.length - 1];
|
|
10370
|
+
if (last.startsWith("[") && last.endsWith("]")) {
|
|
10371
|
+
current[parseInt(last.slice(1, -1), 10)] = value;
|
|
10372
|
+
} else {
|
|
10373
|
+
current[last] = value;
|
|
10374
|
+
}
|
|
10375
|
+
return root;
|
|
10376
|
+
}
|
|
10318
10377
|
function reevaluateEnableIf(wrapper, element, ctx) {
|
|
10319
10378
|
if (!element.enableIf) {
|
|
10320
10379
|
return;
|
|
@@ -10326,54 +10385,13 @@ function reevaluateEnableIf(wrapper, element, ctx) {
|
|
|
10326
10385
|
}
|
|
10327
10386
|
const condition = element.enableIf;
|
|
10328
10387
|
const scope = condition.scope ?? "relative";
|
|
10329
|
-
let rootFormData = {};
|
|
10330
|
-
const containerData = {};
|
|
10331
10388
|
const effectiveScope = !ctx.path || ctx.path === "" ? "absolute" : scope;
|
|
10332
|
-
|
|
10333
|
-
|
|
10334
|
-
|
|
10335
|
-
|
|
10336
|
-
|
|
10337
|
-
|
|
10338
|
-
`[data-container-item="${containerKey}[${containerIndex}]"]`
|
|
10339
|
-
);
|
|
10340
|
-
if (containerItemElement) {
|
|
10341
|
-
const inputs = containerItemElement.querySelectorAll("input, select, textarea");
|
|
10342
|
-
inputs.forEach((input) => {
|
|
10343
|
-
const fieldName = input.getAttribute("name");
|
|
10344
|
-
if (fieldName) {
|
|
10345
|
-
const fieldKeyMatch = fieldName.match(/\.([^.[\]]+)$/);
|
|
10346
|
-
if (fieldKeyMatch) {
|
|
10347
|
-
const fieldKey = fieldKeyMatch[1];
|
|
10348
|
-
if (input instanceof HTMLSelectElement) {
|
|
10349
|
-
containerData[fieldKey] = input.value;
|
|
10350
|
-
} else if (input instanceof HTMLInputElement) {
|
|
10351
|
-
if (input.type === "checkbox") {
|
|
10352
|
-
containerData[fieldKey] = input.checked;
|
|
10353
|
-
} else if (input.type === "radio") {
|
|
10354
|
-
if (input.checked) {
|
|
10355
|
-
containerData[fieldKey] = input.value;
|
|
10356
|
-
}
|
|
10357
|
-
} else {
|
|
10358
|
-
containerData[fieldKey] = input.value;
|
|
10359
|
-
}
|
|
10360
|
-
} else if (input instanceof HTMLTextAreaElement) {
|
|
10361
|
-
containerData[fieldKey] = input.value;
|
|
10362
|
-
}
|
|
10363
|
-
}
|
|
10364
|
-
}
|
|
10365
|
-
});
|
|
10366
|
-
}
|
|
10367
|
-
}
|
|
10368
|
-
} else {
|
|
10369
|
-
const dependencyKey = condition.key;
|
|
10370
|
-
const dependencyValue = extractDOMValue(dependencyKey, formRoot);
|
|
10371
|
-
if (dependencyValue !== void 0) {
|
|
10372
|
-
rootFormData[dependencyKey] = dependencyValue;
|
|
10373
|
-
} else {
|
|
10374
|
-
rootFormData = ctx.formData ?? ctx.prefill;
|
|
10375
|
-
}
|
|
10376
|
-
}
|
|
10389
|
+
const dependencyKey = condition.key;
|
|
10390
|
+
const dependencyFieldPath = effectiveScope === "relative" && ctx.path ? `${ctx.path}.${dependencyKey}` : dependencyKey;
|
|
10391
|
+
const dependencyValue = extractDOMValue(dependencyFieldPath, formRoot);
|
|
10392
|
+
const scopedData = buildScopedDataAtPath(dependencyKey, dependencyValue);
|
|
10393
|
+
const rootFormData = effectiveScope === "relative" ? {} : scopedData;
|
|
10394
|
+
const containerData = effectiveScope === "relative" ? scopedData : void 0;
|
|
10377
10395
|
try {
|
|
10378
10396
|
const shouldEnable = evaluateEnableCondition(
|
|
10379
10397
|
condition,
|
|
@@ -10426,8 +10444,10 @@ function setupEnableIfListeners(wrapper, element, ctx) {
|
|
|
10426
10444
|
reevaluateEnableIf(wrapper, element, ctx);
|
|
10427
10445
|
});
|
|
10428
10446
|
observer.disconnect();
|
|
10447
|
+
ctx.state.enableIfObservers.delete(observer);
|
|
10429
10448
|
}
|
|
10430
10449
|
});
|
|
10450
|
+
ctx.state.enableIfObservers.add(observer);
|
|
10431
10451
|
observer.observe(formRoot, {
|
|
10432
10452
|
childList: true,
|
|
10433
10453
|
subtree: true
|
|
@@ -10824,7 +10844,8 @@ function createInstanceState(config) {
|
|
|
10824
10844
|
debounceTimer: null,
|
|
10825
10845
|
prefill: {},
|
|
10826
10846
|
syntheticElementIds: /* @__PURE__ */ new WeakMap(),
|
|
10827
|
-
syntheticElementIdCounter: 0
|
|
10847
|
+
syntheticElementIdCounter: 0,
|
|
10848
|
+
enableIfObservers: /* @__PURE__ */ new Set()
|
|
10828
10849
|
};
|
|
10829
10850
|
}
|
|
10830
10851
|
function generateInstanceId() {
|
|
@@ -11506,6 +11527,7 @@ var FormBuilderInstance = class {
|
|
|
11506
11527
|
console.error("Schema validation errors:", errors);
|
|
11507
11528
|
return;
|
|
11508
11529
|
}
|
|
11530
|
+
this.disconnectEnableIfObservers();
|
|
11509
11531
|
this.state.formRoot = root;
|
|
11510
11532
|
this.state.schema = schema;
|
|
11511
11533
|
this.state.externalActions = actions || null;
|
|
@@ -11936,6 +11958,7 @@ var FormBuilderInstance = class {
|
|
|
11936
11958
|
clearTimeout(this.state.debounceTimer);
|
|
11937
11959
|
this.state.debounceTimer = null;
|
|
11938
11960
|
}
|
|
11961
|
+
this.disconnectEnableIfObservers();
|
|
11939
11962
|
this.state.resourceIndex.clear();
|
|
11940
11963
|
if (this.state.formRoot) {
|
|
11941
11964
|
clear(this.state.formRoot);
|
|
@@ -11947,6 +11970,12 @@ var FormBuilderInstance = class {
|
|
|
11947
11970
|
globalThis.__formBuilderInstances?.delete(this.instanceId);
|
|
11948
11971
|
}
|
|
11949
11972
|
}
|
|
11973
|
+
disconnectEnableIfObservers() {
|
|
11974
|
+
for (const observer of this.state.enableIfObservers) {
|
|
11975
|
+
observer.disconnect();
|
|
11976
|
+
}
|
|
11977
|
+
this.state.enableIfObservers.clear();
|
|
11978
|
+
}
|
|
11950
11979
|
};
|
|
11951
11980
|
|
|
11952
11981
|
// src/index.ts
|