@otl-core/forms 1.1.19 → 1.1.21
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/form-context.cjs +99 -0
- package/dist/form-context.cjs.map +1 -0
- package/dist/form-context.d.cts +55 -0
- package/dist/form-context.d.ts +55 -0
- package/dist/form-context.js +80 -0
- package/dist/form-context.js.map +1 -0
- package/dist/index.cjs +25 -943
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -84
- package/dist/index.d.ts +6 -84
- package/dist/index.js +3 -939
- package/dist/index.js.map +1 -1
- package/dist/use-form-action.cjs +281 -0
- package/dist/use-form-action.cjs.map +1 -0
- package/dist/use-form-action.d.cts +12 -0
- package/dist/use-form-action.d.ts +12 -0
- package/dist/use-form-action.js +264 -0
- package/dist/use-form-action.js.map +1 -0
- package/dist/use-form-field.cjs +181 -0
- package/dist/use-form-field.cjs.map +1 -0
- package/dist/use-form-field.d.cts +19 -0
- package/dist/use-form-field.d.ts +19 -0
- package/dist/use-form-field.js +160 -0
- package/dist/use-form-field.js.map +1 -0
- package/dist/utils/page.utils.cjs +76 -0
- package/dist/utils/page.utils.cjs.map +1 -0
- package/dist/utils/page.utils.d.cts +7 -0
- package/dist/utils/page.utils.d.ts +7 -0
- package/dist/utils/page.utils.js +50 -0
- package/dist/utils/page.utils.js.map +1 -0
- package/dist/utils/rule.utils.cjs +94 -0
- package/dist/utils/rule.utils.cjs.map +1 -0
- package/dist/utils/rule.utils.d.cts +6 -0
- package/dist/utils/rule.utils.d.ts +6 -0
- package/dist/utils/rule.utils.js +69 -0
- package/dist/utils/rule.utils.js.map +1 -0
- package/dist/utils/validation.utils.cjs +391 -0
- package/dist/utils/validation.utils.cjs.map +1 -0
- package/dist/utils/validation.utils.d.cts +15 -0
- package/dist/utils/validation.utils.d.ts +15 -0
- package/dist/utils/validation.utils.js +366 -0
- package/dist/utils/validation.utils.js.map +1 -0
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1,945 +1,27 @@
|
|
|
1
|
-
"use
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
return context;
|
|
15
|
-
}
|
|
16
|
-
function FormProvider({
|
|
17
|
-
children,
|
|
18
|
-
formId,
|
|
19
|
-
document,
|
|
20
|
-
settings,
|
|
21
|
-
analyticsSettings,
|
|
22
|
-
onAnalyticsEvent,
|
|
23
|
-
formName,
|
|
24
|
-
environmentVariantId,
|
|
25
|
-
formVariantId,
|
|
26
|
-
locale
|
|
27
|
-
}) {
|
|
28
|
-
const [currentPageId, setCurrentPageId] = react.useState(
|
|
29
|
-
document.pages[0]?.id ?? ""
|
|
30
|
-
);
|
|
31
|
-
const [formValues, setFormValues] = react.useState({});
|
|
32
|
-
const [loading, setLoading] = react.useState(false);
|
|
33
|
-
const [errors, setErrors] = react.useState(null);
|
|
34
|
-
const [globalError, setGlobalError] = react.useState(null);
|
|
35
|
-
const [hasStarted, setHasStarted] = react.useState(false);
|
|
36
|
-
const currentPage = react.useMemo(
|
|
37
|
-
() => document.pages.find((p) => p.id === currentPageId) ?? document.pages[0],
|
|
38
|
-
[document, currentPageId]
|
|
39
|
-
);
|
|
40
|
-
const setCurrentPage = react.useCallback(
|
|
41
|
-
(page) => setCurrentPageId(page.id),
|
|
42
|
-
[]
|
|
43
|
-
);
|
|
44
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
45
|
-
FormContext.Provider,
|
|
46
|
-
{
|
|
47
|
-
value: {
|
|
48
|
-
formId,
|
|
49
|
-
document,
|
|
50
|
-
settings,
|
|
51
|
-
loading,
|
|
52
|
-
setLoading,
|
|
53
|
-
currentPage,
|
|
54
|
-
setCurrentPage,
|
|
55
|
-
formValues,
|
|
56
|
-
setFormValues,
|
|
57
|
-
errors,
|
|
58
|
-
setErrors,
|
|
59
|
-
globalError,
|
|
60
|
-
setGlobalError,
|
|
61
|
-
analyticsSettings,
|
|
62
|
-
onAnalyticsEvent,
|
|
63
|
-
formName,
|
|
64
|
-
hasStarted,
|
|
65
|
-
setHasStarted,
|
|
66
|
-
environmentVariantId,
|
|
67
|
-
formVariantId,
|
|
68
|
-
locale
|
|
69
|
-
},
|
|
70
|
-
children
|
|
71
|
-
}
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// src/utils/page.utils.ts
|
|
76
|
-
function getPreviousPage(currentPage, formDocument) {
|
|
77
|
-
const index = formDocument.pages.findIndex(
|
|
78
|
-
(page) => page.id === currentPage.id
|
|
79
|
-
);
|
|
80
|
-
if (index === 0) {
|
|
81
|
-
return null;
|
|
82
|
-
}
|
|
83
|
-
return formDocument.pages[index - 1];
|
|
84
|
-
}
|
|
85
|
-
function getNextPage(currentPage, formDocument) {
|
|
86
|
-
const index = formDocument.pages.findIndex(
|
|
87
|
-
(page) => page.id === currentPage.id
|
|
88
|
-
);
|
|
89
|
-
if (index === formDocument.pages.length - 1) {
|
|
90
|
-
return null;
|
|
91
|
-
}
|
|
92
|
-
return formDocument.pages[index + 1];
|
|
93
|
-
}
|
|
94
|
-
function findBlockInDocument(blockId, document) {
|
|
95
|
-
for (const page of document.pages) {
|
|
96
|
-
const block = findBlockRecursive(blockId, page.blocks);
|
|
97
|
-
if (block) return block;
|
|
98
|
-
}
|
|
99
|
-
return null;
|
|
100
|
-
}
|
|
101
|
-
function findBlockRecursive(blockId, blocks) {
|
|
102
|
-
for (const block of blocks) {
|
|
103
|
-
if (block.id === blockId) {
|
|
104
|
-
return block;
|
|
105
|
-
}
|
|
106
|
-
if (block.config.blocks && Array.isArray(block.config.blocks)) {
|
|
107
|
-
const nestedBlocks = block.config.blocks.map(
|
|
108
|
-
(b) => ({
|
|
109
|
-
id: b.id,
|
|
110
|
-
type: b.type,
|
|
111
|
-
config: b.config || {}
|
|
112
|
-
})
|
|
113
|
-
);
|
|
114
|
-
const found = findBlockRecursive(blockId, nestedBlocks);
|
|
115
|
-
if (found) return found;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
return null;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// src/utils/rule.utils.ts
|
|
122
|
-
function evaluateCondition(operator, fieldValue, ruleValue) {
|
|
123
|
-
switch (operator) {
|
|
124
|
-
case "equals":
|
|
125
|
-
return fieldValue === ruleValue;
|
|
126
|
-
case "not_equals":
|
|
127
|
-
return fieldValue !== ruleValue;
|
|
128
|
-
case "contains":
|
|
129
|
-
return String(fieldValue || "").includes(String(ruleValue));
|
|
130
|
-
case "not_contains":
|
|
131
|
-
return !String(fieldValue || "").includes(String(ruleValue));
|
|
132
|
-
case "starts_with":
|
|
133
|
-
return String(fieldValue || "").startsWith(String(ruleValue));
|
|
134
|
-
case "ends_with":
|
|
135
|
-
return String(fieldValue || "").endsWith(String(ruleValue));
|
|
136
|
-
case "greater_than":
|
|
137
|
-
return Number(fieldValue) > Number(ruleValue);
|
|
138
|
-
case "less_than":
|
|
139
|
-
return Number(fieldValue) < Number(ruleValue);
|
|
140
|
-
case "greater_than_or_equal":
|
|
141
|
-
return Number(fieldValue) >= Number(ruleValue);
|
|
142
|
-
case "less_than_or_equal":
|
|
143
|
-
return Number(fieldValue) <= Number(ruleValue);
|
|
144
|
-
case "is_empty":
|
|
145
|
-
return !fieldValue || fieldValue === "" || Array.isArray(fieldValue) && fieldValue.length === 0;
|
|
146
|
-
case "is_not_empty":
|
|
147
|
-
return !!fieldValue && fieldValue !== "" && (!Array.isArray(fieldValue) || fieldValue.length > 0);
|
|
148
|
-
case "is_checked":
|
|
149
|
-
return fieldValue === true;
|
|
150
|
-
case "is_not_checked":
|
|
151
|
-
return fieldValue !== true;
|
|
152
|
-
case "includes":
|
|
153
|
-
return Array.isArray(fieldValue) && fieldValue.includes(ruleValue);
|
|
154
|
-
case "not_includes":
|
|
155
|
-
return !Array.isArray(fieldValue) || !fieldValue.includes(ruleValue);
|
|
156
|
-
default:
|
|
157
|
-
return false;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
function evaluateVisibilityRules(rules, formValues) {
|
|
161
|
-
const visibilityRules = rules.filter((r) => r.type === "visible_when");
|
|
162
|
-
if (visibilityRules.length === 0) {
|
|
163
|
-
return "block";
|
|
164
|
-
}
|
|
165
|
-
for (const rule of visibilityRules) {
|
|
166
|
-
const fieldValue = formValues[rule.field];
|
|
167
|
-
if (evaluateCondition(rule.operator, fieldValue, rule.value)) {
|
|
168
|
-
return "block";
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
return "none";
|
|
172
|
-
}
|
|
173
|
-
function evaluateDisabledRules(rules, formValues) {
|
|
174
|
-
const disabledRules = rules.filter((r) => r.type === "disabled_when");
|
|
175
|
-
if (disabledRules.length === 0) {
|
|
176
|
-
return false;
|
|
177
|
-
}
|
|
178
|
-
for (const rule of disabledRules) {
|
|
179
|
-
const fieldValue = formValues[rule.field];
|
|
180
|
-
if (evaluateCondition(rule.operator, fieldValue, rule.value)) {
|
|
181
|
-
return true;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
return false;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// src/utils/validation.utils.ts
|
|
188
|
-
function isEmpty(value) {
|
|
189
|
-
return value === void 0 || value === null || value === "";
|
|
190
|
-
}
|
|
191
|
-
function interpolateMessage(template, params) {
|
|
192
|
-
return template.replace(/\{(\w+)\}/g, (_, key) => String(params[key] || ""));
|
|
193
|
-
}
|
|
194
|
-
function validateMinLength(value, minLength) {
|
|
195
|
-
if (isEmpty(value)) return true;
|
|
196
|
-
return typeof value === "string" && value.length >= parseInt(minLength);
|
|
197
|
-
}
|
|
198
|
-
function validateMaxLength(value, maxLength) {
|
|
199
|
-
if (isEmpty(value)) return true;
|
|
200
|
-
return typeof value === "string" && value.length <= parseInt(maxLength);
|
|
201
|
-
}
|
|
202
|
-
function validatePattern(value, pattern) {
|
|
203
|
-
if (isEmpty(value)) return true;
|
|
204
|
-
return typeof value === "string" && new RegExp(pattern).test(value);
|
|
205
|
-
}
|
|
206
|
-
function validateMinValue(value, min) {
|
|
207
|
-
if (isEmpty(value)) return true;
|
|
208
|
-
const numValue = typeof value === "number" ? value : parseFloat(value);
|
|
209
|
-
const minValue = typeof min === "number" ? min : parseFloat(min);
|
|
210
|
-
return !isNaN(numValue) && !isNaN(minValue) && numValue >= minValue;
|
|
211
|
-
}
|
|
212
|
-
function validateMaxValue(value, max) {
|
|
213
|
-
if (isEmpty(value)) return true;
|
|
214
|
-
const numValue = typeof value === "number" ? value : parseFloat(value);
|
|
215
|
-
const maxValue = typeof max === "number" ? max : parseFloat(max);
|
|
216
|
-
return !isNaN(numValue) && !isNaN(maxValue) && numValue <= maxValue;
|
|
217
|
-
}
|
|
218
|
-
function validateEmail(value) {
|
|
219
|
-
if (isEmpty(value)) return true;
|
|
220
|
-
if (typeof value !== "string") return false;
|
|
221
|
-
const emailRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
|
|
222
|
-
return emailRegex.test(value);
|
|
223
|
-
}
|
|
224
|
-
function validateURL(value) {
|
|
225
|
-
if (isEmpty(value)) return true;
|
|
226
|
-
if (typeof value !== "string") return false;
|
|
227
|
-
try {
|
|
228
|
-
const url = new URL(value);
|
|
229
|
-
return url.protocol === "http:" || url.protocol === "https:";
|
|
230
|
-
} catch {
|
|
231
|
-
return false;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
function validatePhoneNumber(value) {
|
|
235
|
-
if (isEmpty(value)) return true;
|
|
236
|
-
if (typeof value !== "string") return false;
|
|
237
|
-
const phoneRegex = /^[\+]?[(]?[0-9]{1,4}[)]?[-\s\.]?[(]?[0-9]{1,4}[)]?[-\s\.]?[0-9]{1,4}[-\s\.]?[0-9]{1,9}$/;
|
|
238
|
-
return phoneRegex.test(value.replace(/\s/g, ""));
|
|
239
|
-
}
|
|
240
|
-
function validateDate(value) {
|
|
241
|
-
if (isEmpty(value)) return true;
|
|
242
|
-
if (typeof value !== "string") return false;
|
|
243
|
-
const date = new Date(value);
|
|
244
|
-
return !isNaN(date.getTime());
|
|
245
|
-
}
|
|
246
|
-
function validateTime(value) {
|
|
247
|
-
if (isEmpty(value)) return true;
|
|
248
|
-
if (typeof value !== "string") return false;
|
|
249
|
-
const timeRegex = /^([0-1]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?$/;
|
|
250
|
-
return timeRegex.test(value);
|
|
251
|
-
}
|
|
252
|
-
function validateColor(value) {
|
|
253
|
-
if (isEmpty(value)) return true;
|
|
254
|
-
if (typeof value !== "string") return false;
|
|
255
|
-
const hexRegex = /^#([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$/;
|
|
256
|
-
return hexRegex.test(value);
|
|
257
|
-
}
|
|
258
|
-
function validateZipCode(value) {
|
|
259
|
-
if (isEmpty(value)) return true;
|
|
260
|
-
if (typeof value !== "string") return false;
|
|
261
|
-
const usZipRegex = /^\d{5}(-\d{4})?$/;
|
|
262
|
-
const ukPostcodeRegex = /^[A-Z]{1,2}\d{1,2}[A-Z]?\s?\d[A-Z]{2}$/i;
|
|
263
|
-
const dePostcodeRegex = /^\d{5}$/;
|
|
264
|
-
return usZipRegex.test(value) || ukPostcodeRegex.test(value) || dePostcodeRegex.test(value);
|
|
265
|
-
}
|
|
266
|
-
function validateCreditCard(value) {
|
|
267
|
-
if (isEmpty(value)) return true;
|
|
268
|
-
if (typeof value !== "string") return false;
|
|
269
|
-
const cleaned = value.replace(/[\s-]/g, "");
|
|
270
|
-
if (!/^\d{13,19}$/.test(cleaned)) return false;
|
|
271
|
-
let sum = 0;
|
|
272
|
-
let isEven = false;
|
|
273
|
-
for (let i = cleaned.length - 1; i >= 0; i--) {
|
|
274
|
-
let digit = parseInt(cleaned.charAt(i), 10);
|
|
275
|
-
if (isEven) {
|
|
276
|
-
digit *= 2;
|
|
277
|
-
if (digit > 9) {
|
|
278
|
-
digit -= 9;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
sum += digit;
|
|
282
|
-
isEven = !isEven;
|
|
283
|
-
}
|
|
284
|
-
return sum % 10 === 0;
|
|
285
|
-
}
|
|
286
|
-
function validateIPAddress(value) {
|
|
287
|
-
if (isEmpty(value)) return true;
|
|
288
|
-
if (typeof value !== "string") return false;
|
|
289
|
-
const ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
|
|
290
|
-
const ipv6Regex = /^(?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4}$/i;
|
|
291
|
-
return ipv4Regex.test(value) || ipv6Regex.test(value);
|
|
292
|
-
}
|
|
293
|
-
var TYPE_ERROR_MESSAGES = {
|
|
294
|
-
zipcode: "Please enter a valid ZIP/postal code",
|
|
295
|
-
creditcard: "Please enter a valid credit card number",
|
|
296
|
-
ip: "Please enter a valid IP address"
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
297
13
|
};
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
return allBlocks;
|
|
314
|
-
}
|
|
315
|
-
function validatePage(page, formValues, settings) {
|
|
316
|
-
const errors = {};
|
|
317
|
-
const allBlocks = getAllBlocksFromPage(page.blocks);
|
|
318
|
-
const errorMessages = settings?.error_messages || {};
|
|
319
|
-
for (const block of allBlocks) {
|
|
320
|
-
if (block.type === "form-button" || block.type === "form-inline-group") {
|
|
321
|
-
continue;
|
|
322
|
-
}
|
|
323
|
-
const fieldId = typeof block.config.field_id === "string" ? block.config.field_id : block.id;
|
|
324
|
-
const value = formValues[fieldId];
|
|
325
|
-
const inputType = typeof block.config.input_type === "string" ? block.config.input_type : "";
|
|
326
|
-
if (block.config.required && isEmpty(value)) {
|
|
327
|
-
errors[fieldId] = errorMessages.required || "This field is required";
|
|
328
|
-
continue;
|
|
329
|
-
}
|
|
330
|
-
if (block.config.check_required && block.type === "form-checkbox") {
|
|
331
|
-
const isChecked = value === true || Array.isArray(value) && value.length > 0;
|
|
332
|
-
if (!isChecked) {
|
|
333
|
-
errors[fieldId] = errorMessages.check_required || "You must check this box to continue";
|
|
334
|
-
continue;
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
if (block.type === "form-checkbox" && block.config.options) {
|
|
338
|
-
const options = block.config.options;
|
|
339
|
-
const checkedValues = Array.isArray(value) ? value : [];
|
|
340
|
-
for (const option of options) {
|
|
341
|
-
if (option.check_required && !checkedValues.includes(option.value)) {
|
|
342
|
-
errors[fieldId] = `You must check "${option.label}" to continue`;
|
|
343
|
-
break;
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
if (errors[fieldId]) {
|
|
347
|
-
continue;
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
if (isEmpty(value)) {
|
|
351
|
-
continue;
|
|
352
|
-
}
|
|
353
|
-
switch (inputType) {
|
|
354
|
-
case "email":
|
|
355
|
-
if (!validateEmail(value)) {
|
|
356
|
-
errors[fieldId] = errorMessages.invalid_email || "Please enter a valid email address";
|
|
357
|
-
continue;
|
|
358
|
-
}
|
|
359
|
-
break;
|
|
360
|
-
case "url":
|
|
361
|
-
if (!validateURL(value)) {
|
|
362
|
-
errors[fieldId] = errorMessages.invalid_url || "Please enter a valid URL (e.g., https://example.com)";
|
|
363
|
-
continue;
|
|
364
|
-
}
|
|
365
|
-
break;
|
|
366
|
-
case "tel":
|
|
367
|
-
if (!validatePhoneNumber(value)) {
|
|
368
|
-
errors[fieldId] = errorMessages.invalid_phone || "Please enter a valid phone number";
|
|
369
|
-
continue;
|
|
370
|
-
}
|
|
371
|
-
break;
|
|
372
|
-
case "date":
|
|
373
|
-
if (!validateDate(value)) {
|
|
374
|
-
errors[fieldId] = errorMessages.invalid_date || "Please enter a valid date";
|
|
375
|
-
continue;
|
|
376
|
-
}
|
|
377
|
-
break;
|
|
378
|
-
case "time":
|
|
379
|
-
if (!validateTime(value)) {
|
|
380
|
-
errors[fieldId] = errorMessages.invalid_time || "Please enter a valid time";
|
|
381
|
-
continue;
|
|
382
|
-
}
|
|
383
|
-
break;
|
|
384
|
-
case "color":
|
|
385
|
-
if (!validateColor(value)) {
|
|
386
|
-
errors[fieldId] = errorMessages.invalid_color || "Please enter a valid color code (e.g., #FF0000)";
|
|
387
|
-
continue;
|
|
388
|
-
}
|
|
389
|
-
break;
|
|
390
|
-
}
|
|
391
|
-
if (block.config.validation_type) {
|
|
392
|
-
const validationType = block.config.validation_type;
|
|
393
|
-
switch (validationType) {
|
|
394
|
-
case "zipcode":
|
|
395
|
-
if (!validateZipCode(value)) {
|
|
396
|
-
errors[fieldId] = TYPE_ERROR_MESSAGES.zipcode;
|
|
397
|
-
continue;
|
|
398
|
-
}
|
|
399
|
-
break;
|
|
400
|
-
case "creditcard":
|
|
401
|
-
if (!validateCreditCard(value)) {
|
|
402
|
-
errors[fieldId] = TYPE_ERROR_MESSAGES.creditcard;
|
|
403
|
-
continue;
|
|
404
|
-
}
|
|
405
|
-
break;
|
|
406
|
-
case "ip":
|
|
407
|
-
if (!validateIPAddress(value)) {
|
|
408
|
-
errors[fieldId] = TYPE_ERROR_MESSAGES.ip;
|
|
409
|
-
continue;
|
|
410
|
-
}
|
|
411
|
-
break;
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
if (block.config.minLength && !validateMinLength(value, block.config.minLength)) {
|
|
415
|
-
errors[fieldId] = errorMessages.min_length ? interpolateMessage(errorMessages.min_length, {
|
|
416
|
-
min: block.config.minLength
|
|
417
|
-
}) : "This field must be at least " + block.config.minLength + " characters long";
|
|
418
|
-
continue;
|
|
419
|
-
}
|
|
420
|
-
if (block.config.maxLength && !validateMaxLength(value, block.config.maxLength)) {
|
|
421
|
-
errors[fieldId] = errorMessages.max_length ? interpolateMessage(errorMessages.max_length, {
|
|
422
|
-
max: block.config.maxLength
|
|
423
|
-
}) : "This field must be less than " + block.config.maxLength + " characters long";
|
|
424
|
-
continue;
|
|
425
|
-
}
|
|
426
|
-
if (block.config.min !== void 0 && !validateMinValue(value, block.config.min)) {
|
|
427
|
-
errors[fieldId] = errorMessages.min_value ? interpolateMessage(errorMessages.min_value, { min: block.config.min }) : "Value must be at least " + block.config.min;
|
|
428
|
-
continue;
|
|
429
|
-
}
|
|
430
|
-
if (block.config.max !== void 0 && !validateMaxValue(value, block.config.max)) {
|
|
431
|
-
errors[fieldId] = errorMessages.max_value ? interpolateMessage(errorMessages.max_value, { max: block.config.max }) : "Value must be no more than " + block.config.max;
|
|
432
|
-
continue;
|
|
433
|
-
}
|
|
434
|
-
if (block.config.pattern && !validatePattern(value, block.config.pattern)) {
|
|
435
|
-
const patternMessage = block.config.pattern_message ? block.config.pattern_message : "This field has an invalid format";
|
|
436
|
-
errors[fieldId] = patternMessage;
|
|
437
|
-
continue;
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
return Object.keys(errors).length > 0 ? errors : true;
|
|
441
|
-
}
|
|
442
|
-
function validateField(block, value, settings) {
|
|
443
|
-
if (block.type === "form-button" || block.type === "form-inline-group") {
|
|
444
|
-
return void 0;
|
|
445
|
-
}
|
|
446
|
-
const errorMessages = settings?.error_messages || {};
|
|
447
|
-
const inputType = typeof block.config.input_type === "string" ? block.config.input_type : "";
|
|
448
|
-
if (block.config.required && isEmpty(value)) {
|
|
449
|
-
return errorMessages.required || "This field is required";
|
|
450
|
-
}
|
|
451
|
-
if (block.config.check_required && block.type === "form-checkbox") {
|
|
452
|
-
const isChecked = value === true || Array.isArray(value) && value.length > 0;
|
|
453
|
-
if (!isChecked) {
|
|
454
|
-
return errorMessages.check_required || "You must check this box to continue";
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
if (block.type === "form-checkbox" && block.config.options) {
|
|
458
|
-
const options = block.config.options;
|
|
459
|
-
const checkedValues = Array.isArray(value) ? value : [];
|
|
460
|
-
for (const option of options) {
|
|
461
|
-
if (option.check_required && !checkedValues.includes(option.value)) {
|
|
462
|
-
return `You must check "${option.label}" to continue`;
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
if (isEmpty(value)) {
|
|
467
|
-
return void 0;
|
|
468
|
-
}
|
|
469
|
-
switch (inputType) {
|
|
470
|
-
case "email":
|
|
471
|
-
if (!validateEmail(value)) {
|
|
472
|
-
return errorMessages.invalid_email || "Please enter a valid email address";
|
|
473
|
-
}
|
|
474
|
-
break;
|
|
475
|
-
case "url":
|
|
476
|
-
if (!validateURL(value)) {
|
|
477
|
-
return errorMessages.invalid_url || "Please enter a valid URL (e.g., https://example.com)";
|
|
478
|
-
}
|
|
479
|
-
break;
|
|
480
|
-
case "tel":
|
|
481
|
-
if (!validatePhoneNumber(value)) {
|
|
482
|
-
return errorMessages.invalid_phone || "Please enter a valid phone number";
|
|
483
|
-
}
|
|
484
|
-
break;
|
|
485
|
-
case "date":
|
|
486
|
-
if (!validateDate(value)) {
|
|
487
|
-
return errorMessages.invalid_date || "Please enter a valid date";
|
|
488
|
-
}
|
|
489
|
-
break;
|
|
490
|
-
case "time":
|
|
491
|
-
if (!validateTime(value)) {
|
|
492
|
-
return errorMessages.invalid_time || "Please enter a valid time";
|
|
493
|
-
}
|
|
494
|
-
break;
|
|
495
|
-
case "color":
|
|
496
|
-
if (!validateColor(value)) {
|
|
497
|
-
return errorMessages.invalid_color || "Please enter a valid color code (e.g., #FF0000)";
|
|
498
|
-
}
|
|
499
|
-
break;
|
|
500
|
-
}
|
|
501
|
-
if (block.config.validation_type) {
|
|
502
|
-
const validationType = block.config.validation_type;
|
|
503
|
-
switch (validationType) {
|
|
504
|
-
case "zipcode":
|
|
505
|
-
if (!validateZipCode(value)) {
|
|
506
|
-
return TYPE_ERROR_MESSAGES.zipcode;
|
|
507
|
-
}
|
|
508
|
-
break;
|
|
509
|
-
case "creditcard":
|
|
510
|
-
if (!validateCreditCard(value)) {
|
|
511
|
-
return TYPE_ERROR_MESSAGES.creditcard;
|
|
512
|
-
}
|
|
513
|
-
break;
|
|
514
|
-
case "ip":
|
|
515
|
-
if (!validateIPAddress(value)) {
|
|
516
|
-
return TYPE_ERROR_MESSAGES.ip;
|
|
517
|
-
}
|
|
518
|
-
break;
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
if (block.config.minLength && !validateMinLength(value, block.config.minLength)) {
|
|
522
|
-
return errorMessages.min_length ? interpolateMessage(errorMessages.min_length, {
|
|
523
|
-
min: block.config.minLength
|
|
524
|
-
}) : "This field must be at least " + block.config.minLength + " characters long";
|
|
525
|
-
}
|
|
526
|
-
if (block.config.maxLength && !validateMaxLength(value, block.config.maxLength)) {
|
|
527
|
-
return errorMessages.max_length ? interpolateMessage(errorMessages.max_length, {
|
|
528
|
-
max: block.config.maxLength
|
|
529
|
-
}) : "This field must be less than " + block.config.maxLength + " characters long";
|
|
530
|
-
}
|
|
531
|
-
if (block.config.min !== void 0 && !validateMinValue(value, block.config.min)) {
|
|
532
|
-
return errorMessages.min_value ? interpolateMessage(errorMessages.min_value, { min: block.config.min }) : "Value must be at least " + block.config.min;
|
|
533
|
-
}
|
|
534
|
-
if (block.config.max !== void 0 && !validateMaxValue(value, block.config.max)) {
|
|
535
|
-
return errorMessages.max_value ? interpolateMessage(errorMessages.max_value, { max: block.config.max }) : "Value must be no more than " + block.config.max;
|
|
536
|
-
}
|
|
537
|
-
if (block.config.pattern && !validatePattern(value, block.config.pattern)) {
|
|
538
|
-
const patternMessage = block.config.pattern_message ? block.config.pattern_message : "This field has an invalid format";
|
|
539
|
-
return patternMessage;
|
|
540
|
-
}
|
|
541
|
-
return void 0;
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
// src/use-form-action.tsx
|
|
545
|
-
function useFormAction(id) {
|
|
546
|
-
const {
|
|
547
|
-
formId,
|
|
548
|
-
document,
|
|
549
|
-
formValues,
|
|
550
|
-
setErrors,
|
|
551
|
-
loading,
|
|
552
|
-
currentPage,
|
|
553
|
-
setCurrentPage,
|
|
554
|
-
setFormValues,
|
|
555
|
-
setGlobalError,
|
|
556
|
-
settings,
|
|
557
|
-
analyticsSettings,
|
|
558
|
-
onAnalyticsEvent,
|
|
559
|
-
formName,
|
|
560
|
-
environmentVariantId,
|
|
561
|
-
formVariantId,
|
|
562
|
-
locale
|
|
563
|
-
} = useForm();
|
|
564
|
-
const block = react.useMemo(() => {
|
|
565
|
-
return findBlockInDocument(id, document);
|
|
566
|
-
}, [document, id]);
|
|
567
|
-
const navigate = react.useCallback(
|
|
568
|
-
(to) => {
|
|
569
|
-
const currentPageValid = to === "first" || validatePage(currentPage, formValues, settings);
|
|
570
|
-
if (currentPageValid !== true) {
|
|
571
|
-
setErrors(currentPageValid);
|
|
572
|
-
return;
|
|
573
|
-
}
|
|
574
|
-
setErrors(null);
|
|
575
|
-
setGlobalError(null);
|
|
576
|
-
let targetPage = null;
|
|
577
|
-
switch (to) {
|
|
578
|
-
case "prev":
|
|
579
|
-
const previousPage = getPreviousPage(currentPage, document);
|
|
580
|
-
if (previousPage) {
|
|
581
|
-
targetPage = previousPage;
|
|
582
|
-
setCurrentPage(previousPage);
|
|
583
|
-
} else {
|
|
584
|
-
console.error("[ERROR] No previous page found.");
|
|
585
|
-
setGlobalError("Configuration Error: No previous page found.");
|
|
586
|
-
}
|
|
587
|
-
break;
|
|
588
|
-
case "next":
|
|
589
|
-
const nextPage = getNextPage(currentPage, document);
|
|
590
|
-
if (nextPage) {
|
|
591
|
-
targetPage = nextPage;
|
|
592
|
-
setCurrentPage(nextPage);
|
|
593
|
-
} else {
|
|
594
|
-
console.error("[ERROR] No next page found.");
|
|
595
|
-
setGlobalError("Configuration Error: No next page found.");
|
|
596
|
-
}
|
|
597
|
-
break;
|
|
598
|
-
case "first":
|
|
599
|
-
targetPage = document.pages[0];
|
|
600
|
-
setCurrentPage(document.pages[0]);
|
|
601
|
-
break;
|
|
602
|
-
case "last":
|
|
603
|
-
targetPage = document.pages[document.pages.length - 1];
|
|
604
|
-
setCurrentPage(document.pages[document.pages.length - 1]);
|
|
605
|
-
break;
|
|
606
|
-
default:
|
|
607
|
-
targetPage = document.pages.find((page) => page.id === to) || document.pages[0];
|
|
608
|
-
setCurrentPage(targetPage);
|
|
609
|
-
break;
|
|
610
|
-
}
|
|
611
|
-
if (targetPage && typeof window !== "undefined" && window.parent) {
|
|
612
|
-
window.parent.postMessage(
|
|
613
|
-
{ type: "FORM_PAGE_CHANGED", pageId: targetPage.id },
|
|
614
|
-
window.location.origin
|
|
615
|
-
);
|
|
616
|
-
}
|
|
617
|
-
if (targetPage && analyticsSettings?.track_page_navigation && onAnalyticsEvent) {
|
|
618
|
-
const targetIndex = document.pages.findIndex(
|
|
619
|
-
(p) => p.id === targetPage.id
|
|
620
|
-
);
|
|
621
|
-
onAnalyticsEvent("form_page_change", {
|
|
622
|
-
form_id: formId,
|
|
623
|
-
form_name: formName,
|
|
624
|
-
page_id: targetPage.id,
|
|
625
|
-
page_index: targetIndex,
|
|
626
|
-
total_pages: document.pages.length
|
|
627
|
-
});
|
|
628
|
-
}
|
|
629
|
-
},
|
|
630
|
-
[
|
|
631
|
-
currentPage,
|
|
632
|
-
setCurrentPage,
|
|
633
|
-
document,
|
|
634
|
-
formId,
|
|
635
|
-
formValues,
|
|
636
|
-
settings,
|
|
637
|
-
setErrors,
|
|
638
|
-
setGlobalError,
|
|
639
|
-
analyticsSettings,
|
|
640
|
-
onAnalyticsEvent,
|
|
641
|
-
formName
|
|
642
|
-
]
|
|
643
|
-
);
|
|
644
|
-
const submit = react.useCallback(async () => {
|
|
645
|
-
if (!block) {
|
|
646
|
-
return;
|
|
647
|
-
}
|
|
648
|
-
let allErrors = {};
|
|
649
|
-
let hasErrors = false;
|
|
650
|
-
for (const page of document.pages) {
|
|
651
|
-
const result = validatePage(page, formValues, settings);
|
|
652
|
-
if (result !== true) {
|
|
653
|
-
allErrors = { ...allErrors, ...result };
|
|
654
|
-
hasErrors = true;
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
if (hasErrors) {
|
|
658
|
-
setErrors(allErrors);
|
|
659
|
-
if (analyticsSettings?.track_form_error && onAnalyticsEvent) {
|
|
660
|
-
onAnalyticsEvent("form_error", {
|
|
661
|
-
form_id: formId,
|
|
662
|
-
form_name: formName,
|
|
663
|
-
error_count: Object.keys(allErrors).length,
|
|
664
|
-
error_fields: Object.keys(allErrors)
|
|
665
|
-
});
|
|
666
|
-
}
|
|
667
|
-
return;
|
|
668
|
-
}
|
|
669
|
-
setErrors(null);
|
|
670
|
-
setGlobalError(null);
|
|
671
|
-
try {
|
|
672
|
-
const buttonTypeOverride = block && typeof block.config.submission_type === "string" && block.config.submission_type ? block.config.submission_type : void 0;
|
|
673
|
-
const submissionData = {
|
|
674
|
-
form_id: formId,
|
|
675
|
-
type: buttonTypeOverride ?? settings?.form_type ?? "General",
|
|
676
|
-
locale: locale ?? "en",
|
|
677
|
-
data: formValues,
|
|
678
|
-
environment_type: "page",
|
|
679
|
-
environment_id: formId,
|
|
680
|
-
environment_path: typeof window !== "undefined" ? window.location.pathname : void 0,
|
|
681
|
-
form_variant_id: formVariantId ?? "",
|
|
682
|
-
environment_variant_id: environmentVariantId ?? ""
|
|
683
|
-
};
|
|
684
|
-
const response = await fetch("/api/submission", {
|
|
685
|
-
method: "POST",
|
|
686
|
-
headers: {
|
|
687
|
-
"Content-Type": "application/json"
|
|
688
|
-
},
|
|
689
|
-
body: JSON.stringify(submissionData)
|
|
690
|
-
});
|
|
691
|
-
const result = await response.json();
|
|
692
|
-
if (!response.ok || !result.success) {
|
|
693
|
-
setGlobalError(
|
|
694
|
-
result.message || "Failed to submit form. Please try again."
|
|
695
|
-
);
|
|
696
|
-
return;
|
|
697
|
-
}
|
|
698
|
-
if (analyticsSettings?.track_form_submit && onAnalyticsEvent) {
|
|
699
|
-
onAnalyticsEvent("form_submit", {
|
|
700
|
-
form_id: formId,
|
|
701
|
-
form_name: formName,
|
|
702
|
-
total_pages: document.pages.length,
|
|
703
|
-
custom_event_name: analyticsSettings.submit_event_name,
|
|
704
|
-
target_providers: analyticsSettings.target_providers
|
|
705
|
-
});
|
|
706
|
-
}
|
|
707
|
-
} catch (error) {
|
|
708
|
-
setGlobalError("An error occurred while submitting the form.");
|
|
709
|
-
}
|
|
710
|
-
return Promise.resolve();
|
|
711
|
-
}, [
|
|
712
|
-
block,
|
|
713
|
-
document,
|
|
714
|
-
formId,
|
|
715
|
-
formValues,
|
|
716
|
-
setErrors,
|
|
717
|
-
setGlobalError,
|
|
718
|
-
settings,
|
|
719
|
-
analyticsSettings,
|
|
720
|
-
onAnalyticsEvent,
|
|
721
|
-
formName,
|
|
722
|
-
locale,
|
|
723
|
-
formVariantId,
|
|
724
|
-
environmentVariantId
|
|
725
|
-
]);
|
|
726
|
-
const reset = react.useCallback(async () => {
|
|
727
|
-
if (!block) {
|
|
728
|
-
return;
|
|
729
|
-
}
|
|
730
|
-
setFormValues({});
|
|
731
|
-
setErrors(null);
|
|
732
|
-
setGlobalError(null);
|
|
733
|
-
return Promise.resolve();
|
|
734
|
-
}, [block, setFormValues, setErrors, setGlobalError]);
|
|
735
|
-
const executeAction = react.useCallback(async () => {
|
|
736
|
-
if (!block) {
|
|
737
|
-
return;
|
|
738
|
-
}
|
|
739
|
-
const action = block.config.action;
|
|
740
|
-
let to = String(block.config.navigate_to_page || "next");
|
|
741
|
-
if (action === "reset") {
|
|
742
|
-
await reset();
|
|
743
|
-
to = "first";
|
|
744
|
-
navigate(to);
|
|
745
|
-
} else if (action === "submit") {
|
|
746
|
-
await submit();
|
|
747
|
-
navigate(to);
|
|
748
|
-
} else if (action === "navigate") {
|
|
749
|
-
navigate(to);
|
|
750
|
-
}
|
|
751
|
-
return Promise.resolve();
|
|
752
|
-
}, [block, navigate, submit, reset]);
|
|
753
|
-
const display = react.useMemo(() => {
|
|
754
|
-
if (!block) {
|
|
755
|
-
return "none";
|
|
756
|
-
}
|
|
757
|
-
const rules = block.config.advanced_options?.rules;
|
|
758
|
-
if (!rules) {
|
|
759
|
-
return "block";
|
|
760
|
-
}
|
|
761
|
-
return evaluateVisibilityRules(rules, formValues);
|
|
762
|
-
}, [block, formValues]);
|
|
763
|
-
const disabled = react.useMemo(() => {
|
|
764
|
-
if (!block) {
|
|
765
|
-
return false;
|
|
766
|
-
}
|
|
767
|
-
if (loading) {
|
|
768
|
-
return true;
|
|
769
|
-
}
|
|
770
|
-
if (typeof block.config.disabled === "boolean" && block.config.disabled) {
|
|
771
|
-
return block.config.disabled;
|
|
772
|
-
}
|
|
773
|
-
const rules = block.config.advanced_options?.rules;
|
|
774
|
-
if (!rules) {
|
|
775
|
-
return false;
|
|
776
|
-
}
|
|
777
|
-
return evaluateDisabledRules(rules, formValues);
|
|
778
|
-
}, [block, formValues, loading]);
|
|
779
|
-
if (!block) {
|
|
780
|
-
return null;
|
|
781
|
-
}
|
|
782
|
-
return {
|
|
783
|
-
variant: typeof block.config.variant === "string" ? block.config.variant : "primary",
|
|
784
|
-
size: typeof block.config.size === "string" ? block.config.size : "md",
|
|
785
|
-
disabled,
|
|
786
|
-
loading,
|
|
787
|
-
display,
|
|
788
|
-
text: typeof block.config.text === "string" ? block.config.text : typeof block.config.label === "string" ? block.config.label : "",
|
|
789
|
-
onClick: executeAction
|
|
790
|
-
};
|
|
791
|
-
}
|
|
792
|
-
function useFormField(id) {
|
|
793
|
-
const {
|
|
794
|
-
formId,
|
|
795
|
-
document,
|
|
796
|
-
settings,
|
|
797
|
-
loading,
|
|
798
|
-
formValues,
|
|
799
|
-
setFormValues,
|
|
800
|
-
errors,
|
|
801
|
-
setErrors,
|
|
802
|
-
analyticsSettings,
|
|
803
|
-
onAnalyticsEvent,
|
|
804
|
-
formName,
|
|
805
|
-
hasStarted,
|
|
806
|
-
setHasStarted
|
|
807
|
-
} = useForm();
|
|
808
|
-
const block = react.useMemo(() => {
|
|
809
|
-
return findBlockInDocument(id, document);
|
|
810
|
-
}, [document, id]);
|
|
811
|
-
const fieldId = react.useMemo(() => {
|
|
812
|
-
if (!block) return null;
|
|
813
|
-
return typeof block.config.field_id === "string" ? block.config.field_id : block.id;
|
|
814
|
-
}, [block]);
|
|
815
|
-
const initialValue = react.useMemo(() => {
|
|
816
|
-
if (!block) {
|
|
817
|
-
return void 0;
|
|
818
|
-
}
|
|
819
|
-
if (typeof block.config.initialValue === "string") {
|
|
820
|
-
return String(block.config.initialValue);
|
|
821
|
-
} else if (typeof block.config.initialValue === "number") {
|
|
822
|
-
return Number(block.config.initialValue);
|
|
823
|
-
} else if (typeof block.config.initialValue === "boolean") {
|
|
824
|
-
return Boolean(block.config.initialValue);
|
|
825
|
-
}
|
|
826
|
-
if (block.config.initialValue !== void 0) {
|
|
827
|
-
return block.config.initialValue;
|
|
828
|
-
}
|
|
829
|
-
return void 0;
|
|
830
|
-
}, [block]);
|
|
831
|
-
const value = react.useMemo(() => {
|
|
832
|
-
if (!fieldId) {
|
|
833
|
-
return void 0;
|
|
834
|
-
}
|
|
835
|
-
return formValues[fieldId] ?? initialValue;
|
|
836
|
-
}, [fieldId, formValues, initialValue]);
|
|
837
|
-
const setValue = react.useCallback(
|
|
838
|
-
(value2) => {
|
|
839
|
-
if (!fieldId) {
|
|
840
|
-
return;
|
|
841
|
-
}
|
|
842
|
-
setFormValues((prev) => ({ ...prev, [fieldId]: value2 }));
|
|
843
|
-
setErrors((prev) => {
|
|
844
|
-
if (!prev || !prev[fieldId]) return prev;
|
|
845
|
-
const { [fieldId]: _, ...rest } = prev;
|
|
846
|
-
return Object.keys(rest).length > 0 ? rest : null;
|
|
847
|
-
});
|
|
848
|
-
if (!hasStarted && analyticsSettings?.track_form_start && onAnalyticsEvent) {
|
|
849
|
-
setHasStarted(true);
|
|
850
|
-
onAnalyticsEvent("form_start", {
|
|
851
|
-
form_id: formId,
|
|
852
|
-
form_name: formName
|
|
853
|
-
});
|
|
854
|
-
}
|
|
855
|
-
},
|
|
856
|
-
[
|
|
857
|
-
fieldId,
|
|
858
|
-
setFormValues,
|
|
859
|
-
setErrors,
|
|
860
|
-
hasStarted,
|
|
861
|
-
setHasStarted,
|
|
862
|
-
analyticsSettings,
|
|
863
|
-
onAnalyticsEvent,
|
|
864
|
-
formId,
|
|
865
|
-
formName
|
|
866
|
-
]
|
|
867
|
-
);
|
|
868
|
-
const handleBlur = react.useCallback(() => {
|
|
869
|
-
if (!(settings.validate_on_blur ?? false) || !block || !fieldId) {
|
|
870
|
-
return;
|
|
871
|
-
}
|
|
872
|
-
const currentValue = formValues[fieldId] ?? initialValue;
|
|
873
|
-
const error = validateField(block, currentValue, settings);
|
|
874
|
-
if (error) {
|
|
875
|
-
setErrors((prev) => ({ ...prev, [fieldId]: error }));
|
|
876
|
-
} else {
|
|
877
|
-
setErrors((prev) => {
|
|
878
|
-
if (!prev || !prev[fieldId]) return prev;
|
|
879
|
-
const { [fieldId]: _, ...rest } = prev;
|
|
880
|
-
return Object.keys(rest).length > 0 ? rest : null;
|
|
881
|
-
});
|
|
882
|
-
}
|
|
883
|
-
}, [settings, block, fieldId, formValues, initialValue, setErrors]);
|
|
884
|
-
const display = react.useMemo(() => {
|
|
885
|
-
if (!block) {
|
|
886
|
-
return "none";
|
|
887
|
-
}
|
|
888
|
-
const rules = block.config.advanced_options?.rules;
|
|
889
|
-
if (!rules) {
|
|
890
|
-
return "block";
|
|
891
|
-
}
|
|
892
|
-
return evaluateVisibilityRules(rules, formValues);
|
|
893
|
-
}, [block, formValues]);
|
|
894
|
-
const disabled = react.useMemo(() => {
|
|
895
|
-
if (!block) {
|
|
896
|
-
return false;
|
|
897
|
-
}
|
|
898
|
-
if (loading) {
|
|
899
|
-
return true;
|
|
900
|
-
}
|
|
901
|
-
if (typeof block.config.disabled === "boolean" && block.config.disabled) {
|
|
902
|
-
return block.config.disabled;
|
|
903
|
-
}
|
|
904
|
-
const rules = block.config.advanced_options?.rules;
|
|
905
|
-
if (!rules) {
|
|
906
|
-
return false;
|
|
907
|
-
}
|
|
908
|
-
return evaluateDisabledRules(rules, formValues);
|
|
909
|
-
}, [block, formValues, loading]);
|
|
910
|
-
if (!block || !fieldId) {
|
|
911
|
-
return null;
|
|
912
|
-
}
|
|
913
|
-
return {
|
|
914
|
-
name: fieldId,
|
|
915
|
-
label: typeof block.config.label === "string" ? block.config.label : "",
|
|
916
|
-
type: typeof block.config.input_type === "string" ? block.config.input_type : typeof block.config.type === "string" ? block.config.type : "",
|
|
917
|
-
helperText: typeof block.config.help_text === "string" ? block.config.help_text : typeof block.config.helperText === "string" ? block.config.helperText : "",
|
|
918
|
-
placeholder: typeof block.config.placeholder === "string" ? block.config.placeholder : null,
|
|
919
|
-
additionalSettings: {
|
|
920
|
-
rows: typeof block.config.rows === "number" ? block.config.rows : void 0,
|
|
921
|
-
options: block.config.options || void 0,
|
|
922
|
-
multiple: typeof block.config.multiple === "boolean" ? block.config.multiple : void 0,
|
|
923
|
-
min: typeof block.config.min === "number" ? block.config.min : void 0,
|
|
924
|
-
max: typeof block.config.max === "number" ? block.config.max : void 0,
|
|
925
|
-
step: typeof block.config.step === "number" ? block.config.step : void 0,
|
|
926
|
-
blocks: block.config.blocks || void 0,
|
|
927
|
-
gap: block.config.gap || void 0
|
|
928
|
-
},
|
|
929
|
-
loading,
|
|
930
|
-
disabled,
|
|
931
|
-
display,
|
|
932
|
-
required: typeof block.config.required === "boolean" ? block.config.required : false,
|
|
933
|
-
error: errors?.[fieldId] || errors?.[block.id] || void 0,
|
|
934
|
-
value,
|
|
935
|
-
onChange: setValue,
|
|
936
|
-
onBlur: handleBlur
|
|
937
|
-
};
|
|
938
|
-
}
|
|
939
|
-
|
|
940
|
-
exports.FormProvider = FormProvider;
|
|
941
|
-
exports.useForm = useForm;
|
|
942
|
-
exports.useFormAction = useFormAction;
|
|
943
|
-
exports.useFormField = useFormField;
|
|
944
|
-
//# sourceMappingURL=index.cjs.map
|
|
14
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
15
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
16
|
+
var index_exports = {};
|
|
17
|
+
module.exports = __toCommonJS(index_exports);
|
|
18
|
+
__reExport(index_exports, require("./form-context"), module.exports);
|
|
19
|
+
__reExport(index_exports, require("./use-form-action"), module.exports);
|
|
20
|
+
__reExport(index_exports, require("./use-form-field"), module.exports);
|
|
21
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
22
|
+
0 && (module.exports = {
|
|
23
|
+
...require("./form-context"),
|
|
24
|
+
...require("./use-form-action"),
|
|
25
|
+
...require("./use-form-field")
|
|
26
|
+
});
|
|
945
27
|
//# sourceMappingURL=index.cjs.map
|