@dmitryvim/form-builder 0.2.22 → 0.2.23
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/dist/browser/formbuilder.min.js +108 -104
- package/dist/browser/formbuilder.v0.2.23.min.js +606 -0
- package/dist/cjs/index.cjs +438 -40
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/index.js +425 -37
- package/dist/esm/index.js.map +1 -1
- package/dist/form-builder.js +108 -104
- package/dist/types/components/container.d.ts +4 -1
- package/dist/types/components/file.d.ts +5 -0
- package/dist/types/instance/FormBuilderInstance.d.ts +5 -0
- package/dist/types/types/component-operations.d.ts +2 -0
- package/dist/types/types/config.d.ts +3 -0
- package/dist/types/types/schema.d.ts +1 -0
- package/package.json +1 -1
- package/dist/browser/formbuilder.v0.2.22.min.js +0 -602
package/dist/cjs/index.cjs
CHANGED
|
@@ -122,6 +122,49 @@ function validateSchema(schema) {
|
|
|
122
122
|
});
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
|
+
function checkFlatOutputCollisions(elements, scopePath) {
|
|
126
|
+
var _a, _b;
|
|
127
|
+
const allOutputKeys = /* @__PURE__ */ new Set();
|
|
128
|
+
for (const el of elements) {
|
|
129
|
+
if (el.type === "richinput" && el.flatOutput) {
|
|
130
|
+
const richEl = el;
|
|
131
|
+
const textKey = (_a = richEl.textKey) != null ? _a : "text";
|
|
132
|
+
const filesKey = (_b = richEl.filesKey) != null ? _b : "files";
|
|
133
|
+
for (const otherEl of elements) {
|
|
134
|
+
if (otherEl === el) continue;
|
|
135
|
+
if (otherEl.key === textKey) {
|
|
136
|
+
errors.push(
|
|
137
|
+
`${scopePath}: RichInput "${el.key}" flatOutput textKey "${textKey}" collides with element key "${otherEl.key}"`
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
if (otherEl.key === filesKey) {
|
|
141
|
+
errors.push(
|
|
142
|
+
`${scopePath}: RichInput "${el.key}" flatOutput filesKey "${filesKey}" collides with element key "${otherEl.key}"`
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (allOutputKeys.has(textKey)) {
|
|
147
|
+
errors.push(
|
|
148
|
+
`${scopePath}: RichInput "${el.key}" flatOutput textKey "${textKey}" collides with another flatOutput key`
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
if (allOutputKeys.has(filesKey)) {
|
|
152
|
+
errors.push(
|
|
153
|
+
`${scopePath}: RichInput "${el.key}" flatOutput filesKey "${filesKey}" collides with another flatOutput key`
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
allOutputKeys.add(textKey);
|
|
157
|
+
allOutputKeys.add(filesKey);
|
|
158
|
+
} else {
|
|
159
|
+
if (allOutputKeys.has(el.key)) {
|
|
160
|
+
errors.push(
|
|
161
|
+
`${scopePath}: Element key "${el.key}" collides with a flatOutput richinput key`
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
allOutputKeys.add(el.key);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
125
168
|
function validateElements(elements, path) {
|
|
126
169
|
elements.forEach((element, index) => {
|
|
127
170
|
const elementPath = `${path}[${index}]`;
|
|
@@ -187,6 +230,7 @@ function validateSchema(schema) {
|
|
|
187
230
|
}
|
|
188
231
|
}
|
|
189
232
|
validateElements(element.elements, `${elementPath}.elements`);
|
|
233
|
+
checkFlatOutputCollisions(element.elements, `${elementPath}.elements`);
|
|
190
234
|
}
|
|
191
235
|
if (element.type === "select" && element.options) {
|
|
192
236
|
const defaultValue = element.default;
|
|
@@ -203,8 +247,10 @@ function validateSchema(schema) {
|
|
|
203
247
|
}
|
|
204
248
|
});
|
|
205
249
|
}
|
|
206
|
-
if (Array.isArray(schema.elements))
|
|
250
|
+
if (Array.isArray(schema.elements)) {
|
|
207
251
|
validateElements(schema.elements, "elements");
|
|
252
|
+
checkFlatOutputCollisions(schema.elements, "elements");
|
|
253
|
+
}
|
|
208
254
|
return errors;
|
|
209
255
|
}
|
|
210
256
|
|
|
@@ -2036,6 +2082,26 @@ function updateSwitcherField(element, fieldPath, value, context) {
|
|
|
2036
2082
|
}
|
|
2037
2083
|
|
|
2038
2084
|
// src/components/file.ts
|
|
2085
|
+
function getAllowedExtensions(accept) {
|
|
2086
|
+
if (!accept) return [];
|
|
2087
|
+
if (typeof accept === "object" && Array.isArray(accept.extensions)) {
|
|
2088
|
+
return accept.extensions.map((ext) => ext.toLowerCase());
|
|
2089
|
+
}
|
|
2090
|
+
if (typeof accept === "string") {
|
|
2091
|
+
return accept.split(",").map((s) => s.trim()).filter((s) => s.startsWith(".")).map((s) => s.substring(1).toLowerCase());
|
|
2092
|
+
}
|
|
2093
|
+
return [];
|
|
2094
|
+
}
|
|
2095
|
+
function isFileExtensionAllowed(fileName, allowedExtensions) {
|
|
2096
|
+
var _a;
|
|
2097
|
+
if (allowedExtensions.length === 0) return true;
|
|
2098
|
+
const ext = ((_a = fileName.split(".").pop()) == null ? void 0 : _a.toLowerCase()) || "";
|
|
2099
|
+
return allowedExtensions.includes(ext);
|
|
2100
|
+
}
|
|
2101
|
+
function isFileSizeAllowed(file, maxSizeMB) {
|
|
2102
|
+
if (maxSizeMB === Infinity) return true;
|
|
2103
|
+
return file.size <= maxSizeMB * 1024 * 1024;
|
|
2104
|
+
}
|
|
2039
2105
|
function renderLocalImagePreview(container, file, fileName, state) {
|
|
2040
2106
|
const img = document.createElement("img");
|
|
2041
2107
|
img.className = "w-full h-full object-contain";
|
|
@@ -2571,8 +2637,43 @@ function setEmptyFileContainer(fileContainer, state, hint) {
|
|
|
2571
2637
|
</div>
|
|
2572
2638
|
`;
|
|
2573
2639
|
}
|
|
2574
|
-
|
|
2640
|
+
function showFileError(container, message) {
|
|
2575
2641
|
var _a, _b;
|
|
2642
|
+
const existing = (_a = container.closest(".space-y-2")) == null ? void 0 : _a.querySelector(".file-error-message");
|
|
2643
|
+
if (existing) existing.remove();
|
|
2644
|
+
const errorEl = document.createElement("div");
|
|
2645
|
+
errorEl.className = "file-error-message error-message";
|
|
2646
|
+
errorEl.style.cssText = `
|
|
2647
|
+
color: var(--fb-error-color);
|
|
2648
|
+
font-size: var(--fb-font-size-small);
|
|
2649
|
+
margin-top: 0.25rem;
|
|
2650
|
+
`;
|
|
2651
|
+
errorEl.textContent = message;
|
|
2652
|
+
(_b = container.closest(".space-y-2")) == null ? void 0 : _b.appendChild(errorEl);
|
|
2653
|
+
}
|
|
2654
|
+
function clearFileError(container) {
|
|
2655
|
+
var _a;
|
|
2656
|
+
const existing = (_a = container.closest(".space-y-2")) == null ? void 0 : _a.querySelector(".file-error-message");
|
|
2657
|
+
if (existing) existing.remove();
|
|
2658
|
+
}
|
|
2659
|
+
async function handleFileSelect(file, container, fieldName, state, deps = null, instance, allowedExtensions = [], maxSizeMB = Infinity) {
|
|
2660
|
+
var _a, _b;
|
|
2661
|
+
if (!isFileExtensionAllowed(file.name, allowedExtensions)) {
|
|
2662
|
+
const formats = allowedExtensions.join(", ");
|
|
2663
|
+
showFileError(
|
|
2664
|
+
container,
|
|
2665
|
+
t("invalidFileExtension", state, { name: file.name, formats })
|
|
2666
|
+
);
|
|
2667
|
+
return;
|
|
2668
|
+
}
|
|
2669
|
+
if (!isFileSizeAllowed(file, maxSizeMB)) {
|
|
2670
|
+
showFileError(
|
|
2671
|
+
container,
|
|
2672
|
+
t("fileTooLarge", state, { name: file.name, maxSize: maxSizeMB })
|
|
2673
|
+
);
|
|
2674
|
+
return;
|
|
2675
|
+
}
|
|
2676
|
+
clearFileError(container);
|
|
2576
2677
|
let rid;
|
|
2577
2678
|
if (state.config.uploadFile) {
|
|
2578
2679
|
try {
|
|
@@ -2778,9 +2879,51 @@ function handleInitialFileData(initial, fileContainer, pathKey, fileWrapper, sta
|
|
|
2778
2879
|
hiddenInput.value = initial;
|
|
2779
2880
|
fileWrapper.appendChild(hiddenInput);
|
|
2780
2881
|
}
|
|
2781
|
-
function setupFilesDropHandler(filesContainer, initialFiles, state, updateCallback, pathKey, instance) {
|
|
2882
|
+
function setupFilesDropHandler(filesContainer, initialFiles, state, updateCallback, constraints, pathKey, instance) {
|
|
2782
2883
|
setupDragAndDrop(filesContainer, async (files) => {
|
|
2783
|
-
const
|
|
2884
|
+
const allFiles = Array.from(files);
|
|
2885
|
+
const rejectedByExtension = allFiles.filter(
|
|
2886
|
+
(f) => !isFileExtensionAllowed(f.name, constraints.allowedExtensions)
|
|
2887
|
+
);
|
|
2888
|
+
const afterExtension = allFiles.filter(
|
|
2889
|
+
(f) => isFileExtensionAllowed(f.name, constraints.allowedExtensions)
|
|
2890
|
+
);
|
|
2891
|
+
const rejectedBySize = afterExtension.filter(
|
|
2892
|
+
(f) => !isFileSizeAllowed(f, constraints.maxSize)
|
|
2893
|
+
);
|
|
2894
|
+
const validFiles = afterExtension.filter(
|
|
2895
|
+
(f) => isFileSizeAllowed(f, constraints.maxSize)
|
|
2896
|
+
);
|
|
2897
|
+
const remaining = constraints.maxCount === Infinity ? validFiles.length : Math.max(0, constraints.maxCount - initialFiles.length);
|
|
2898
|
+
const arr = validFiles.slice(0, remaining);
|
|
2899
|
+
const skippedByCount = validFiles.length - arr.length;
|
|
2900
|
+
const errorParts = [];
|
|
2901
|
+
if (rejectedByExtension.length > 0) {
|
|
2902
|
+
const formats = constraints.allowedExtensions.join(", ");
|
|
2903
|
+
const names = rejectedByExtension.map((f) => f.name).join(", ");
|
|
2904
|
+
errorParts.push(
|
|
2905
|
+
t("invalidFileExtension", state, { name: names, formats })
|
|
2906
|
+
);
|
|
2907
|
+
}
|
|
2908
|
+
if (rejectedBySize.length > 0) {
|
|
2909
|
+
const names = rejectedBySize.map((f) => f.name).join(", ");
|
|
2910
|
+
errorParts.push(
|
|
2911
|
+
t("fileTooLarge", state, { name: names, maxSize: constraints.maxSize })
|
|
2912
|
+
);
|
|
2913
|
+
}
|
|
2914
|
+
if (skippedByCount > 0) {
|
|
2915
|
+
errorParts.push(
|
|
2916
|
+
t("filesLimitExceeded", state, {
|
|
2917
|
+
skipped: skippedByCount,
|
|
2918
|
+
max: constraints.maxCount
|
|
2919
|
+
})
|
|
2920
|
+
);
|
|
2921
|
+
}
|
|
2922
|
+
if (errorParts.length > 0) {
|
|
2923
|
+
showFileError(filesContainer, errorParts.join(" \u2022 "));
|
|
2924
|
+
} else {
|
|
2925
|
+
clearFileError(filesContainer);
|
|
2926
|
+
}
|
|
2784
2927
|
for (const file of arr) {
|
|
2785
2928
|
const rid = await uploadSingleFile(file, state);
|
|
2786
2929
|
state.resourceIndex.set(rid, {
|
|
@@ -2798,10 +2941,57 @@ function setupFilesDropHandler(filesContainer, initialFiles, state, updateCallba
|
|
|
2798
2941
|
}
|
|
2799
2942
|
});
|
|
2800
2943
|
}
|
|
2801
|
-
function setupFilesPickerHandler(filesPicker, initialFiles, state, updateCallback, pathKey, instance) {
|
|
2944
|
+
function setupFilesPickerHandler(filesPicker, initialFiles, state, updateCallback, constraints, pathKey, instance) {
|
|
2802
2945
|
filesPicker.onchange = async () => {
|
|
2803
2946
|
if (filesPicker.files) {
|
|
2804
|
-
|
|
2947
|
+
const allFiles = Array.from(filesPicker.files);
|
|
2948
|
+
const rejectedByExtension = allFiles.filter(
|
|
2949
|
+
(f) => !isFileExtensionAllowed(f.name, constraints.allowedExtensions)
|
|
2950
|
+
);
|
|
2951
|
+
const afterExtension = allFiles.filter(
|
|
2952
|
+
(f) => isFileExtensionAllowed(f.name, constraints.allowedExtensions)
|
|
2953
|
+
);
|
|
2954
|
+
const rejectedBySize = afterExtension.filter(
|
|
2955
|
+
(f) => !isFileSizeAllowed(f, constraints.maxSize)
|
|
2956
|
+
);
|
|
2957
|
+
const validFiles = afterExtension.filter(
|
|
2958
|
+
(f) => isFileSizeAllowed(f, constraints.maxSize)
|
|
2959
|
+
);
|
|
2960
|
+
const remaining = constraints.maxCount === Infinity ? validFiles.length : Math.max(0, constraints.maxCount - initialFiles.length);
|
|
2961
|
+
const arr = validFiles.slice(0, remaining);
|
|
2962
|
+
const skippedByCount = validFiles.length - arr.length;
|
|
2963
|
+
const errorParts = [];
|
|
2964
|
+
if (rejectedByExtension.length > 0) {
|
|
2965
|
+
const formats = constraints.allowedExtensions.join(", ");
|
|
2966
|
+
const names = rejectedByExtension.map((f) => f.name).join(", ");
|
|
2967
|
+
errorParts.push(
|
|
2968
|
+
t("invalidFileExtension", state, { name: names, formats })
|
|
2969
|
+
);
|
|
2970
|
+
}
|
|
2971
|
+
if (rejectedBySize.length > 0) {
|
|
2972
|
+
const names = rejectedBySize.map((f) => f.name).join(", ");
|
|
2973
|
+
errorParts.push(
|
|
2974
|
+
t("fileTooLarge", state, {
|
|
2975
|
+
name: names,
|
|
2976
|
+
maxSize: constraints.maxSize
|
|
2977
|
+
})
|
|
2978
|
+
);
|
|
2979
|
+
}
|
|
2980
|
+
if (skippedByCount > 0) {
|
|
2981
|
+
errorParts.push(
|
|
2982
|
+
t("filesLimitExceeded", state, {
|
|
2983
|
+
skipped: skippedByCount,
|
|
2984
|
+
max: constraints.maxCount
|
|
2985
|
+
})
|
|
2986
|
+
);
|
|
2987
|
+
}
|
|
2988
|
+
const wrapper = filesPicker.closest(".space-y-2") || filesPicker.parentElement;
|
|
2989
|
+
if (errorParts.length > 0 && wrapper) {
|
|
2990
|
+
showFileError(wrapper, errorParts.join(" \u2022 "));
|
|
2991
|
+
} else if (wrapper) {
|
|
2992
|
+
clearFileError(wrapper);
|
|
2993
|
+
}
|
|
2994
|
+
for (const file of arr) {
|
|
2805
2995
|
const rid = await uploadSingleFile(file, state);
|
|
2806
2996
|
state.resourceIndex.set(rid, {
|
|
2807
2997
|
name: file.name,
|
|
@@ -2821,7 +3011,7 @@ function setupFilesPickerHandler(filesPicker, initialFiles, state, updateCallbac
|
|
|
2821
3011
|
};
|
|
2822
3012
|
}
|
|
2823
3013
|
function renderFileElement(element, ctx, wrapper, pathKey) {
|
|
2824
|
-
var _a;
|
|
3014
|
+
var _a, _b;
|
|
2825
3015
|
const state = ctx.state;
|
|
2826
3016
|
if (state.config.readonly) {
|
|
2827
3017
|
const initial = ctx.prefill[element.key];
|
|
@@ -2854,6 +3044,8 @@ function renderFileElement(element, ctx, wrapper, pathKey) {
|
|
|
2854
3044
|
const fileContainer = document.createElement("div");
|
|
2855
3045
|
fileContainer.className = "file-preview-container w-full aspect-square max-w-xs bg-gray-100 rounded-lg overflow-hidden relative group cursor-pointer";
|
|
2856
3046
|
const initial = ctx.prefill[element.key];
|
|
3047
|
+
const allowedExts = getAllowedExtensions(element.accept);
|
|
3048
|
+
const maxSizeMB = (_b = element.maxSize) != null ? _b : Infinity;
|
|
2857
3049
|
const fileUploadHandler = () => picker.click();
|
|
2858
3050
|
const dragHandler = (files) => {
|
|
2859
3051
|
if (files.length > 0) {
|
|
@@ -2864,7 +3056,9 @@ function renderFileElement(element, ctx, wrapper, pathKey) {
|
|
|
2864
3056
|
pathKey,
|
|
2865
3057
|
state,
|
|
2866
3058
|
deps,
|
|
2867
|
-
ctx.instance
|
|
3059
|
+
ctx.instance,
|
|
3060
|
+
allowedExts,
|
|
3061
|
+
maxSizeMB
|
|
2868
3062
|
);
|
|
2869
3063
|
}
|
|
2870
3064
|
};
|
|
@@ -2896,7 +3090,9 @@ function renderFileElement(element, ctx, wrapper, pathKey) {
|
|
|
2896
3090
|
pathKey,
|
|
2897
3091
|
state,
|
|
2898
3092
|
deps,
|
|
2899
|
-
ctx.instance
|
|
3093
|
+
ctx.instance,
|
|
3094
|
+
allowedExts,
|
|
3095
|
+
maxSizeMB
|
|
2900
3096
|
);
|
|
2901
3097
|
}
|
|
2902
3098
|
};
|
|
@@ -2906,7 +3102,7 @@ function renderFileElement(element, ctx, wrapper, pathKey) {
|
|
|
2906
3102
|
}
|
|
2907
3103
|
}
|
|
2908
3104
|
function renderFilesElement(element, ctx, wrapper, pathKey) {
|
|
2909
|
-
var _a;
|
|
3105
|
+
var _a, _b;
|
|
2910
3106
|
const state = ctx.state;
|
|
2911
3107
|
if (state.config.readonly) {
|
|
2912
3108
|
const resultsWrapper = document.createElement("div");
|
|
@@ -2957,12 +3153,18 @@ function renderFilesElement(element, ctx, wrapper, pathKey) {
|
|
|
2957
3153
|
const initialFiles = ctx.prefill[element.key] || [];
|
|
2958
3154
|
addPrefillFilesToIndex(initialFiles, state);
|
|
2959
3155
|
const filesFieldHint = makeFieldHint(element, state);
|
|
3156
|
+
const filesConstraints = {
|
|
3157
|
+
maxCount: Infinity,
|
|
3158
|
+
allowedExtensions: getAllowedExtensions(element.accept),
|
|
3159
|
+
maxSize: (_b = element.maxSize) != null ? _b : Infinity
|
|
3160
|
+
};
|
|
2960
3161
|
updateFilesList2();
|
|
2961
3162
|
setupFilesDropHandler(
|
|
2962
3163
|
filesContainer,
|
|
2963
3164
|
initialFiles,
|
|
2964
3165
|
state,
|
|
2965
3166
|
updateFilesList2,
|
|
3167
|
+
filesConstraints,
|
|
2966
3168
|
pathKey,
|
|
2967
3169
|
ctx.instance
|
|
2968
3170
|
);
|
|
@@ -2971,6 +3173,7 @@ function renderFilesElement(element, ctx, wrapper, pathKey) {
|
|
|
2971
3173
|
initialFiles,
|
|
2972
3174
|
state,
|
|
2973
3175
|
updateFilesList2,
|
|
3176
|
+
filesConstraints,
|
|
2974
3177
|
pathKey,
|
|
2975
3178
|
ctx.instance
|
|
2976
3179
|
);
|
|
@@ -2981,7 +3184,7 @@ function renderFilesElement(element, ctx, wrapper, pathKey) {
|
|
|
2981
3184
|
}
|
|
2982
3185
|
}
|
|
2983
3186
|
function renderMultipleFileElement(element, ctx, wrapper, pathKey) {
|
|
2984
|
-
var _a, _b, _c;
|
|
3187
|
+
var _a, _b, _c, _d;
|
|
2985
3188
|
const state = ctx.state;
|
|
2986
3189
|
const minFiles = (_a = element.minCount) != null ? _a : 0;
|
|
2987
3190
|
const maxFiles = (_b = element.maxCount) != null ? _b : Infinity;
|
|
@@ -3019,6 +3222,11 @@ function renderMultipleFileElement(element, ctx, wrapper, pathKey) {
|
|
|
3019
3222
|
const initialFiles = Array.isArray(ctx.prefill[element.key]) ? [...ctx.prefill[element.key]] : [];
|
|
3020
3223
|
addPrefillFilesToIndex(initialFiles, state);
|
|
3021
3224
|
const multipleFilesHint = makeFieldHint(element, state);
|
|
3225
|
+
const multipleConstraints = {
|
|
3226
|
+
maxCount: maxFiles,
|
|
3227
|
+
allowedExtensions: getAllowedExtensions(element.accept),
|
|
3228
|
+
maxSize: (_d = element.maxSize) != null ? _d : Infinity
|
|
3229
|
+
};
|
|
3022
3230
|
const buildCountInfo = () => {
|
|
3023
3231
|
const countText = initialFiles.length === 1 ? t("fileCountSingle", state, { count: initialFiles.length }) : t("fileCountPlural", state, { count: initialFiles.length });
|
|
3024
3232
|
const minMaxText = minFiles > 0 || maxFiles < Infinity ? ` ${t("fileCountRange", state, { min: minFiles, max: maxFiles })}` : "";
|
|
@@ -3042,6 +3250,7 @@ function renderMultipleFileElement(element, ctx, wrapper, pathKey) {
|
|
|
3042
3250
|
initialFiles,
|
|
3043
3251
|
state,
|
|
3044
3252
|
updateFilesDisplay,
|
|
3253
|
+
multipleConstraints,
|
|
3045
3254
|
pathKey,
|
|
3046
3255
|
ctx.instance
|
|
3047
3256
|
);
|
|
@@ -3050,6 +3259,7 @@ function renderMultipleFileElement(element, ctx, wrapper, pathKey) {
|
|
|
3050
3259
|
initialFiles,
|
|
3051
3260
|
state,
|
|
3052
3261
|
updateFilesDisplay,
|
|
3262
|
+
multipleConstraints,
|
|
3053
3263
|
pathKey,
|
|
3054
3264
|
ctx.instance
|
|
3055
3265
|
);
|
|
@@ -3078,6 +3288,40 @@ function validateFileElement(element, key, context) {
|
|
|
3078
3288
|
errors.push(`${key2}: ${t("maxFiles", state, { max: maxFiles })}`);
|
|
3079
3289
|
}
|
|
3080
3290
|
};
|
|
3291
|
+
const validateFileExtensions = (key2, resourceIds, element2) => {
|
|
3292
|
+
var _a2;
|
|
3293
|
+
if (skipValidation) return;
|
|
3294
|
+
const { state } = context;
|
|
3295
|
+
const acceptField = "accept" in element2 ? element2.accept : void 0;
|
|
3296
|
+
const allowedExtensions = getAllowedExtensions(acceptField);
|
|
3297
|
+
if (allowedExtensions.length === 0) return;
|
|
3298
|
+
const formats = allowedExtensions.join(", ");
|
|
3299
|
+
for (const rid of resourceIds) {
|
|
3300
|
+
const meta = state.resourceIndex.get(rid);
|
|
3301
|
+
const fileName = (_a2 = meta == null ? void 0 : meta.name) != null ? _a2 : rid;
|
|
3302
|
+
if (!isFileExtensionAllowed(fileName, allowedExtensions)) {
|
|
3303
|
+
errors.push(
|
|
3304
|
+
`${key2}: ${t("invalidFileExtension", state, { name: fileName, formats })}`
|
|
3305
|
+
);
|
|
3306
|
+
}
|
|
3307
|
+
}
|
|
3308
|
+
};
|
|
3309
|
+
const validateFileSizes = (key2, resourceIds, element2) => {
|
|
3310
|
+
var _a2;
|
|
3311
|
+
if (skipValidation) return;
|
|
3312
|
+
const { state } = context;
|
|
3313
|
+
const maxSizeMB = "maxSize" in element2 ? (_a2 = element2.maxSize) != null ? _a2 : Infinity : Infinity;
|
|
3314
|
+
if (maxSizeMB === Infinity) return;
|
|
3315
|
+
for (const rid of resourceIds) {
|
|
3316
|
+
const meta = state.resourceIndex.get(rid);
|
|
3317
|
+
if (!meta) continue;
|
|
3318
|
+
if (meta.size > maxSizeMB * 1024 * 1024) {
|
|
3319
|
+
errors.push(
|
|
3320
|
+
`${key2}: ${t("fileTooLarge", state, { name: meta.name, maxSize: maxSizeMB })}`
|
|
3321
|
+
);
|
|
3322
|
+
}
|
|
3323
|
+
}
|
|
3324
|
+
};
|
|
3081
3325
|
if (isMultipleField) {
|
|
3082
3326
|
const fullKey = pathJoin(path, key);
|
|
3083
3327
|
const pickerInput = scopeRoot.querySelector(
|
|
@@ -3096,6 +3340,8 @@ function validateFileElement(element, key, context) {
|
|
|
3096
3340
|
});
|
|
3097
3341
|
}
|
|
3098
3342
|
validateFileCount(key, resourceIds, element);
|
|
3343
|
+
validateFileExtensions(key, resourceIds, element);
|
|
3344
|
+
validateFileSizes(key, resourceIds, element);
|
|
3099
3345
|
return { value: resourceIds, errors };
|
|
3100
3346
|
} else {
|
|
3101
3347
|
const input = scopeRoot.querySelector(
|
|
@@ -3106,6 +3352,10 @@ function validateFileElement(element, key, context) {
|
|
|
3106
3352
|
errors.push(`${key}: ${t("required", context.state)}`);
|
|
3107
3353
|
return { value: null, errors };
|
|
3108
3354
|
}
|
|
3355
|
+
if (!skipValidation && rid !== "") {
|
|
3356
|
+
validateFileExtensions(key, [rid], element);
|
|
3357
|
+
validateFileSizes(key, [rid], element);
|
|
3358
|
+
}
|
|
3109
3359
|
return { value: rid || null, errors };
|
|
3110
3360
|
}
|
|
3111
3361
|
}
|
|
@@ -4611,11 +4861,16 @@ function validateContainerElement(element, key, context) {
|
|
|
4611
4861
|
itemData[child.key] = child.default !== void 0 ? child.default : null;
|
|
4612
4862
|
} else {
|
|
4613
4863
|
const childKey = `${key}[${domIndex}].${child.key}`;
|
|
4614
|
-
|
|
4864
|
+
const childResult = validateElement(
|
|
4615
4865
|
{ ...child, key: childKey },
|
|
4616
4866
|
{ path },
|
|
4617
4867
|
itemContainer
|
|
4618
4868
|
);
|
|
4869
|
+
if (childResult.spread && childResult.value !== null && typeof childResult.value === "object") {
|
|
4870
|
+
Object.assign(itemData, childResult.value);
|
|
4871
|
+
} else {
|
|
4872
|
+
itemData[child.key] = childResult.value;
|
|
4873
|
+
}
|
|
4619
4874
|
}
|
|
4620
4875
|
});
|
|
4621
4876
|
items.push(itemData);
|
|
@@ -4651,11 +4906,16 @@ function validateContainerElement(element, key, context) {
|
|
|
4651
4906
|
containerData[child.key] = child.default !== void 0 ? child.default : null;
|
|
4652
4907
|
} else {
|
|
4653
4908
|
const childKey = `${key}.${child.key}`;
|
|
4654
|
-
|
|
4909
|
+
const childResult = validateElement(
|
|
4655
4910
|
{ ...child, key: childKey },
|
|
4656
4911
|
{ path },
|
|
4657
4912
|
containerContainer
|
|
4658
4913
|
);
|
|
4914
|
+
if (childResult.spread && childResult.value !== null && typeof childResult.value === "object") {
|
|
4915
|
+
Object.assign(containerData, childResult.value);
|
|
4916
|
+
} else {
|
|
4917
|
+
containerData[child.key] = childResult.value;
|
|
4918
|
+
}
|
|
4659
4919
|
}
|
|
4660
4920
|
});
|
|
4661
4921
|
return { value: containerData, errors };
|
|
@@ -4676,11 +4936,24 @@ function updateContainerField(element, fieldPath, value, context) {
|
|
|
4676
4936
|
value.forEach((itemValue, index) => {
|
|
4677
4937
|
if (isPlainObject(itemValue)) {
|
|
4678
4938
|
element.elements.forEach((childElement) => {
|
|
4679
|
-
|
|
4680
|
-
const childPath = `${fieldPath}[${index}].${
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4939
|
+
var _a, _b;
|
|
4940
|
+
const childPath = `${fieldPath}[${index}].${childElement.key}`;
|
|
4941
|
+
if (childElement.type === "richinput" && childElement.flatOutput) {
|
|
4942
|
+
const richChild = childElement;
|
|
4943
|
+
const textKey = (_a = richChild.textKey) != null ? _a : "text";
|
|
4944
|
+
const filesKey = (_b = richChild.filesKey) != null ? _b : "files";
|
|
4945
|
+
const containerValue = itemValue;
|
|
4946
|
+
const compositeValue = {};
|
|
4947
|
+
if (textKey in containerValue) compositeValue[textKey] = containerValue[textKey];
|
|
4948
|
+
if (filesKey in containerValue) compositeValue[filesKey] = containerValue[filesKey];
|
|
4949
|
+
if (Object.keys(compositeValue).length > 0) {
|
|
4950
|
+
instance.updateField(childPath, compositeValue);
|
|
4951
|
+
}
|
|
4952
|
+
} else {
|
|
4953
|
+
const childValue = itemValue[childElement.key];
|
|
4954
|
+
if (childValue !== void 0) {
|
|
4955
|
+
instance.updateField(childPath, childValue);
|
|
4956
|
+
}
|
|
4684
4957
|
}
|
|
4685
4958
|
});
|
|
4686
4959
|
}
|
|
@@ -4701,11 +4974,24 @@ function updateContainerField(element, fieldPath, value, context) {
|
|
|
4701
4974
|
return;
|
|
4702
4975
|
}
|
|
4703
4976
|
element.elements.forEach((childElement) => {
|
|
4704
|
-
|
|
4705
|
-
const childPath = `${fieldPath}.${
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4977
|
+
var _a, _b;
|
|
4978
|
+
const childPath = `${fieldPath}.${childElement.key}`;
|
|
4979
|
+
if (childElement.type === "richinput" && childElement.flatOutput) {
|
|
4980
|
+
const richChild = childElement;
|
|
4981
|
+
const textKey = (_a = richChild.textKey) != null ? _a : "text";
|
|
4982
|
+
const filesKey = (_b = richChild.filesKey) != null ? _b : "files";
|
|
4983
|
+
const containerValue = value;
|
|
4984
|
+
const compositeValue = {};
|
|
4985
|
+
if (textKey in containerValue) compositeValue[textKey] = containerValue[textKey];
|
|
4986
|
+
if (filesKey in containerValue) compositeValue[filesKey] = containerValue[filesKey];
|
|
4987
|
+
if (Object.keys(compositeValue).length > 0) {
|
|
4988
|
+
instance.updateField(childPath, compositeValue);
|
|
4989
|
+
}
|
|
4990
|
+
} else {
|
|
4991
|
+
const childValue = value[childElement.key];
|
|
4992
|
+
if (childValue !== void 0) {
|
|
4993
|
+
instance.updateField(childPath, childValue);
|
|
4994
|
+
}
|
|
4709
4995
|
}
|
|
4710
4996
|
});
|
|
4711
4997
|
}
|
|
@@ -6540,6 +6826,42 @@ function renderEditMode(element, ctx, wrapper, pathKey, initialValue) {
|
|
|
6540
6826
|
outerDiv.style.borderColor = "var(--fb-border-color, #d1d5db)";
|
|
6541
6827
|
outerDiv.style.boxShadow = "none";
|
|
6542
6828
|
});
|
|
6829
|
+
const errorEl = document.createElement("div");
|
|
6830
|
+
errorEl.className = "fb-richinput-error";
|
|
6831
|
+
errorEl.style.cssText = "display: none; color: var(--fb-error-color, #ef4444); font-size: var(--fb-font-size-small, 12px); padding: 4px 14px 8px;";
|
|
6832
|
+
let errorTimer = null;
|
|
6833
|
+
function showUploadError(message) {
|
|
6834
|
+
errorEl.textContent = message;
|
|
6835
|
+
errorEl.style.display = "block";
|
|
6836
|
+
if (errorTimer) clearTimeout(errorTimer);
|
|
6837
|
+
errorTimer = setTimeout(() => {
|
|
6838
|
+
errorEl.style.display = "none";
|
|
6839
|
+
errorEl.textContent = "";
|
|
6840
|
+
errorTimer = null;
|
|
6841
|
+
}, 5e3);
|
|
6842
|
+
}
|
|
6843
|
+
function validateFileForUpload(file) {
|
|
6844
|
+
var _a2;
|
|
6845
|
+
const allowedExtensions = getAllowedExtensions(element.accept);
|
|
6846
|
+
if (!isFileExtensionAllowed(file.name, allowedExtensions)) {
|
|
6847
|
+
const formats = allowedExtensions.join(", ");
|
|
6848
|
+
showUploadError(
|
|
6849
|
+
t("invalidFileExtension", state, { name: file.name, formats })
|
|
6850
|
+
);
|
|
6851
|
+
return false;
|
|
6852
|
+
}
|
|
6853
|
+
const maxSizeMB = (_a2 = element.maxSize) != null ? _a2 : Infinity;
|
|
6854
|
+
if (!isFileSizeAllowed(file, maxSizeMB)) {
|
|
6855
|
+
showUploadError(
|
|
6856
|
+
t("fileTooLarge", state, {
|
|
6857
|
+
name: file.name,
|
|
6858
|
+
maxSize: maxSizeMB
|
|
6859
|
+
})
|
|
6860
|
+
);
|
|
6861
|
+
return false;
|
|
6862
|
+
}
|
|
6863
|
+
return true;
|
|
6864
|
+
}
|
|
6543
6865
|
let dragCounter = 0;
|
|
6544
6866
|
outerDiv.addEventListener("dragenter", (e) => {
|
|
6545
6867
|
e.preventDefault();
|
|
@@ -6568,7 +6890,17 @@ function renderEditMode(element, ctx, wrapper, pathKey, initialValue) {
|
|
|
6568
6890
|
const droppedFiles = (_a2 = e.dataTransfer) == null ? void 0 : _a2.files;
|
|
6569
6891
|
if (!droppedFiles || !state.config.uploadFile) return;
|
|
6570
6892
|
const maxFiles = (_b = element.maxFiles) != null ? _b : Infinity;
|
|
6571
|
-
for (let i = 0; i < droppedFiles.length
|
|
6893
|
+
for (let i = 0; i < droppedFiles.length; i++) {
|
|
6894
|
+
if (files.length >= maxFiles) {
|
|
6895
|
+
showUploadError(
|
|
6896
|
+
t("filesLimitExceeded", state, {
|
|
6897
|
+
skipped: droppedFiles.length - i,
|
|
6898
|
+
max: maxFiles
|
|
6899
|
+
})
|
|
6900
|
+
);
|
|
6901
|
+
break;
|
|
6902
|
+
}
|
|
6903
|
+
if (!validateFileForUpload(droppedFiles[i])) continue;
|
|
6572
6904
|
uploadFile(droppedFiles[i]);
|
|
6573
6905
|
}
|
|
6574
6906
|
});
|
|
@@ -6728,9 +7060,13 @@ function renderEditMode(element, ctx, wrapper, pathKey, initialValue) {
|
|
|
6728
7060
|
paperclipBtn.addEventListener("click", () => {
|
|
6729
7061
|
var _a2;
|
|
6730
7062
|
const maxFiles = (_a2 = element.maxFiles) != null ? _a2 : Infinity;
|
|
6731
|
-
if (files.length
|
|
6732
|
-
|
|
7063
|
+
if (files.length >= maxFiles) {
|
|
7064
|
+
showUploadError(
|
|
7065
|
+
t("filesLimitExceeded", state, { skipped: 1, max: maxFiles })
|
|
7066
|
+
);
|
|
7067
|
+
return;
|
|
6733
7068
|
}
|
|
7069
|
+
fileInput.click();
|
|
6734
7070
|
});
|
|
6735
7071
|
const dropdown = document.createElement("div");
|
|
6736
7072
|
dropdown.className = "fb-richinput-dropdown";
|
|
@@ -7051,7 +7387,17 @@ function renderEditMode(element, ctx, wrapper, pathKey, initialValue) {
|
|
|
7051
7387
|
const selected = fileInput.files;
|
|
7052
7388
|
if (!selected || selected.length === 0) return;
|
|
7053
7389
|
const maxFiles = (_a2 = element.maxFiles) != null ? _a2 : Infinity;
|
|
7054
|
-
for (let i = 0; i < selected.length
|
|
7390
|
+
for (let i = 0; i < selected.length; i++) {
|
|
7391
|
+
if (files.length >= maxFiles) {
|
|
7392
|
+
showUploadError(
|
|
7393
|
+
t("filesLimitExceeded", state, {
|
|
7394
|
+
skipped: selected.length - i,
|
|
7395
|
+
max: maxFiles
|
|
7396
|
+
})
|
|
7397
|
+
);
|
|
7398
|
+
break;
|
|
7399
|
+
}
|
|
7400
|
+
if (!validateFileForUpload(selected[i])) continue;
|
|
7055
7401
|
uploadFile(selected[i]);
|
|
7056
7402
|
}
|
|
7057
7403
|
fileInput.value = "";
|
|
@@ -7062,6 +7408,7 @@ function renderEditMode(element, ctx, wrapper, pathKey, initialValue) {
|
|
|
7062
7408
|
textareaArea.appendChild(dropdown);
|
|
7063
7409
|
outerDiv.appendChild(filesRow);
|
|
7064
7410
|
outerDiv.appendChild(textareaArea);
|
|
7411
|
+
outerDiv.appendChild(errorEl);
|
|
7065
7412
|
if (element.minLength != null || element.maxLength != null) {
|
|
7066
7413
|
const counterRow = document.createElement("div");
|
|
7067
7414
|
counterRow.style.cssText = "position: relative; padding: 2px 14px 6px; text-align: right;";
|
|
@@ -7224,20 +7571,29 @@ function renderRichInputElement(element, ctx, wrapper, pathKey) {
|
|
|
7224
7571
|
const state = ctx.state;
|
|
7225
7572
|
const textKey = (_a = element.textKey) != null ? _a : "text";
|
|
7226
7573
|
const filesKey = (_b = element.filesKey) != null ? _b : "files";
|
|
7227
|
-
const rawPrefill = ctx.prefill[element.key];
|
|
7228
7574
|
let initialValue;
|
|
7229
|
-
if (
|
|
7230
|
-
const
|
|
7231
|
-
const
|
|
7232
|
-
const filesVal = (_d = obj[filesKey]) != null ? _d : obj["files"];
|
|
7575
|
+
if (element.flatOutput) {
|
|
7576
|
+
const textVal = ctx.prefill[textKey];
|
|
7577
|
+
const filesVal = ctx.prefill[filesKey];
|
|
7233
7578
|
initialValue = {
|
|
7234
7579
|
text: typeof textVal === "string" ? textVal : null,
|
|
7235
7580
|
files: Array.isArray(filesVal) ? filesVal : []
|
|
7236
7581
|
};
|
|
7237
|
-
} else if (typeof rawPrefill === "string") {
|
|
7238
|
-
initialValue = { text: rawPrefill || null, files: [] };
|
|
7239
7582
|
} else {
|
|
7240
|
-
|
|
7583
|
+
const rawPrefill = ctx.prefill[element.key];
|
|
7584
|
+
if (rawPrefill && typeof rawPrefill === "object" && !Array.isArray(rawPrefill)) {
|
|
7585
|
+
const obj = rawPrefill;
|
|
7586
|
+
const textVal = (_c = obj[textKey]) != null ? _c : obj["text"];
|
|
7587
|
+
const filesVal = (_d = obj[filesKey]) != null ? _d : obj["files"];
|
|
7588
|
+
initialValue = {
|
|
7589
|
+
text: typeof textVal === "string" ? textVal : null,
|
|
7590
|
+
files: Array.isArray(filesVal) ? filesVal : []
|
|
7591
|
+
};
|
|
7592
|
+
} else if (typeof rawPrefill === "string") {
|
|
7593
|
+
initialValue = { text: rawPrefill || null, files: [] };
|
|
7594
|
+
} else {
|
|
7595
|
+
initialValue = { text: null, files: [] };
|
|
7596
|
+
}
|
|
7241
7597
|
}
|
|
7242
7598
|
for (const rid of initialValue.files) {
|
|
7243
7599
|
if (!state.resourceIndex.has(rid)) {
|
|
@@ -7318,7 +7674,7 @@ function validateRichInputElement(element, key, context) {
|
|
|
7318
7674
|
);
|
|
7319
7675
|
}
|
|
7320
7676
|
}
|
|
7321
|
-
return { value, errors };
|
|
7677
|
+
return { value, errors, spread: !!element.flatOutput };
|
|
7322
7678
|
}
|
|
7323
7679
|
function updateRichInputField(element, fieldPath, value, context) {
|
|
7324
7680
|
var _a, _b, _c, _d;
|
|
@@ -7798,6 +8154,9 @@ var defaultConfig = {
|
|
|
7798
8154
|
invalidHexColour: "Invalid hex color",
|
|
7799
8155
|
minFiles: "Minimum {min} files required",
|
|
7800
8156
|
maxFiles: "Maximum {max} files allowed",
|
|
8157
|
+
invalidFileExtension: 'File "{name}" has unsupported format. Allowed: {formats}',
|
|
8158
|
+
fileTooLarge: 'File "{name}" exceeds maximum size of {maxSize}MB',
|
|
8159
|
+
filesLimitExceeded: "{skipped} file(s) skipped: maximum {max} files allowed",
|
|
7801
8160
|
unsupportedFieldType: "Unsupported field type: {type}",
|
|
7802
8161
|
invalidOption: "Invalid option",
|
|
7803
8162
|
tableAddRow: "Add row",
|
|
@@ -7857,6 +8216,9 @@ var defaultConfig = {
|
|
|
7857
8216
|
invalidHexColour: "\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 \u0444\u043E\u0440\u043C\u0430\u0442 \u0446\u0432\u0435\u0442\u0430",
|
|
7858
8217
|
minFiles: "\u041C\u0438\u043D\u0438\u043C\u0443\u043C {min} \u0444\u0430\u0439\u043B\u043E\u0432",
|
|
7859
8218
|
maxFiles: "\u041C\u0430\u043A\u0441\u0438\u043C\u0443\u043C {max} \u0444\u0430\u0439\u043B\u043E\u0432",
|
|
8219
|
+
invalidFileExtension: '\u0424\u0430\u0439\u043B "{name}" \u0438\u043C\u0435\u0435\u0442 \u043D\u0435\u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043C\u044B\u0439 \u0444\u043E\u0440\u043C\u0430\u0442. \u0414\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u044B\u0435: {formats}',
|
|
8220
|
+
fileTooLarge: '\u0424\u0430\u0439\u043B "{name}" \u043F\u0440\u0435\u0432\u044B\u0448\u0430\u0435\u0442 \u043C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u044B\u0439 \u0440\u0430\u0437\u043C\u0435\u0440 {maxSize}\u041C\u0411',
|
|
8221
|
+
filesLimitExceeded: "{skipped} \u0444\u0430\u0439\u043B(\u043E\u0432) \u043F\u0440\u043E\u043F\u0443\u0449\u0435\u043D\u043E: \u043C\u0430\u043A\u0441\u0438\u043C\u0443\u043C {max} \u0444\u0430\u0439\u043B\u043E\u0432",
|
|
7860
8222
|
unsupportedFieldType: "\u041D\u0435\u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043C\u044B\u0439 \u0442\u0438\u043F \u043F\u043E\u043B\u044F: {type}",
|
|
7861
8223
|
invalidOption: "\u041D\u0435\u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u043E\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435",
|
|
7862
8224
|
tableAddRow: "\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0441\u0442\u0440\u043E\u043A\u0443",
|
|
@@ -8628,10 +8990,10 @@ var FormBuilderInstance = class {
|
|
|
8628
8990
|
);
|
|
8629
8991
|
if (componentResult !== null) {
|
|
8630
8992
|
errors.push(...componentResult.errors);
|
|
8631
|
-
return componentResult.value;
|
|
8993
|
+
return { value: componentResult.value, spread: !!componentResult.spread };
|
|
8632
8994
|
}
|
|
8633
8995
|
console.warn(`Unknown field type "${element.type}" for key "${key}"`);
|
|
8634
|
-
return null;
|
|
8996
|
+
return { value: null, spread: false };
|
|
8635
8997
|
};
|
|
8636
8998
|
setValidateElement(validateElement2);
|
|
8637
8999
|
this.state.schema.elements.forEach((element) => {
|
|
@@ -8654,7 +9016,12 @@ var FormBuilderInstance = class {
|
|
|
8654
9016
|
if (element.hidden) {
|
|
8655
9017
|
data[element.key] = element.default !== void 0 ? element.default : null;
|
|
8656
9018
|
} else {
|
|
8657
|
-
|
|
9019
|
+
const result = validateElement2(element, { path: "" });
|
|
9020
|
+
if (result.spread && result.value !== null && typeof result.value === "object") {
|
|
9021
|
+
Object.assign(data, result.value);
|
|
9022
|
+
} else {
|
|
9023
|
+
data[element.key] = result.value;
|
|
9024
|
+
}
|
|
8658
9025
|
}
|
|
8659
9026
|
});
|
|
8660
9027
|
return {
|
|
@@ -8748,6 +9115,24 @@ var FormBuilderInstance = class {
|
|
|
8748
9115
|
}
|
|
8749
9116
|
return data;
|
|
8750
9117
|
}
|
|
9118
|
+
/**
|
|
9119
|
+
* Build a map from flat output keys (textKey/filesKey) to the richinput schema element info.
|
|
9120
|
+
* Used by setFormData to detect flat richinput keys and remap them to their composite values.
|
|
9121
|
+
*/
|
|
9122
|
+
buildFlatKeyMap(elements) {
|
|
9123
|
+
var _a, _b;
|
|
9124
|
+
const map = /* @__PURE__ */ new Map();
|
|
9125
|
+
for (const el of elements) {
|
|
9126
|
+
if (el.type === "richinput" && el.flatOutput) {
|
|
9127
|
+
const richEl = el;
|
|
9128
|
+
const textKey = (_a = richEl.textKey) != null ? _a : "text";
|
|
9129
|
+
const filesKey = (_b = richEl.filesKey) != null ? _b : "files";
|
|
9130
|
+
map.set(textKey, { schemaKey: el.key, role: "text" });
|
|
9131
|
+
map.set(filesKey, { schemaKey: el.key, role: "files" });
|
|
9132
|
+
}
|
|
9133
|
+
}
|
|
9134
|
+
return map;
|
|
9135
|
+
}
|
|
8751
9136
|
/**
|
|
8752
9137
|
* Set form data - update multiple fields without full re-render
|
|
8753
9138
|
* @param data - Object with field paths and their values
|
|
@@ -8759,8 +9144,21 @@ var FormBuilderInstance = class {
|
|
|
8759
9144
|
);
|
|
8760
9145
|
return;
|
|
8761
9146
|
}
|
|
9147
|
+
const flatKeyMap = this.buildFlatKeyMap(this.state.schema.elements);
|
|
9148
|
+
const flatUpdates = /* @__PURE__ */ new Map();
|
|
8762
9149
|
for (const fieldPath in data) {
|
|
8763
|
-
|
|
9150
|
+
const flatInfo = flatKeyMap.get(fieldPath);
|
|
9151
|
+
if (flatInfo) {
|
|
9152
|
+
if (!flatUpdates.has(flatInfo.schemaKey)) {
|
|
9153
|
+
flatUpdates.set(flatInfo.schemaKey, {});
|
|
9154
|
+
}
|
|
9155
|
+
flatUpdates.get(flatInfo.schemaKey)[fieldPath] = data[fieldPath];
|
|
9156
|
+
} else {
|
|
9157
|
+
this.updateField(fieldPath, data[fieldPath]);
|
|
9158
|
+
}
|
|
9159
|
+
}
|
|
9160
|
+
for (const [schemaKey, compositeValue] of flatUpdates) {
|
|
9161
|
+
this.updateField(schemaKey, compositeValue);
|
|
8764
9162
|
}
|
|
8765
9163
|
}
|
|
8766
9164
|
/**
|