@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.
Files changed (43) hide show
  1. package/dist/form-context.cjs +99 -0
  2. package/dist/form-context.cjs.map +1 -0
  3. package/dist/form-context.d.cts +55 -0
  4. package/dist/form-context.d.ts +55 -0
  5. package/dist/form-context.js +80 -0
  6. package/dist/form-context.js.map +1 -0
  7. package/dist/index.cjs +25 -943
  8. package/dist/index.cjs.map +1 -1
  9. package/dist/index.d.cts +6 -84
  10. package/dist/index.d.ts +6 -84
  11. package/dist/index.js +3 -939
  12. package/dist/index.js.map +1 -1
  13. package/dist/use-form-action.cjs +281 -0
  14. package/dist/use-form-action.cjs.map +1 -0
  15. package/dist/use-form-action.d.cts +12 -0
  16. package/dist/use-form-action.d.ts +12 -0
  17. package/dist/use-form-action.js +264 -0
  18. package/dist/use-form-action.js.map +1 -0
  19. package/dist/use-form-field.cjs +181 -0
  20. package/dist/use-form-field.cjs.map +1 -0
  21. package/dist/use-form-field.d.cts +19 -0
  22. package/dist/use-form-field.d.ts +19 -0
  23. package/dist/use-form-field.js +160 -0
  24. package/dist/use-form-field.js.map +1 -0
  25. package/dist/utils/page.utils.cjs +76 -0
  26. package/dist/utils/page.utils.cjs.map +1 -0
  27. package/dist/utils/page.utils.d.cts +7 -0
  28. package/dist/utils/page.utils.d.ts +7 -0
  29. package/dist/utils/page.utils.js +50 -0
  30. package/dist/utils/page.utils.js.map +1 -0
  31. package/dist/utils/rule.utils.cjs +94 -0
  32. package/dist/utils/rule.utils.cjs.map +1 -0
  33. package/dist/utils/rule.utils.d.cts +6 -0
  34. package/dist/utils/rule.utils.d.ts +6 -0
  35. package/dist/utils/rule.utils.js +69 -0
  36. package/dist/utils/rule.utils.js.map +1 -0
  37. package/dist/utils/validation.utils.cjs +391 -0
  38. package/dist/utils/validation.utils.cjs.map +1 -0
  39. package/dist/utils/validation.utils.d.cts +15 -0
  40. package/dist/utils/validation.utils.d.ts +15 -0
  41. package/dist/utils/validation.utils.js +366 -0
  42. package/dist/utils/validation.utils.js.map +1 -0
  43. package/package.json +2 -2
@@ -0,0 +1,264 @@
1
+ "use client";
2
+ import { useCallback, useMemo } from "react";
3
+ import { useForm } from "./form-context";
4
+ import {
5
+ findBlockInDocument,
6
+ getNextPage,
7
+ getPreviousPage
8
+ } from "./utils/page.utils";
9
+ import {
10
+ evaluateDisabledRules,
11
+ evaluateVisibilityRules
12
+ } from "./utils/rule.utils";
13
+ import { validatePage } from "./utils/validation.utils";
14
+ function useFormAction(id) {
15
+ const {
16
+ formId,
17
+ document,
18
+ formValues,
19
+ setErrors,
20
+ loading,
21
+ currentPage,
22
+ setCurrentPage,
23
+ setFormValues,
24
+ setGlobalError,
25
+ settings,
26
+ analyticsSettings,
27
+ onAnalyticsEvent,
28
+ formName,
29
+ environmentVariantId,
30
+ formVariantId,
31
+ locale
32
+ } = useForm();
33
+ const block = useMemo(() => {
34
+ return findBlockInDocument(id, document);
35
+ }, [document, id]);
36
+ const navigate = useCallback(
37
+ (to) => {
38
+ const currentPageValid = to === "first" || validatePage(currentPage, formValues, settings);
39
+ if (currentPageValid !== true) {
40
+ setErrors(currentPageValid);
41
+ return;
42
+ }
43
+ setErrors(null);
44
+ setGlobalError(null);
45
+ let targetPage = null;
46
+ switch (to) {
47
+ case "prev":
48
+ const previousPage = getPreviousPage(currentPage, document);
49
+ if (previousPage) {
50
+ targetPage = previousPage;
51
+ setCurrentPage(previousPage);
52
+ } else {
53
+ console.error("[ERROR] No previous page found.");
54
+ setGlobalError("Configuration Error: No previous page found.");
55
+ }
56
+ break;
57
+ case "next":
58
+ const nextPage = getNextPage(currentPage, document);
59
+ if (nextPage) {
60
+ targetPage = nextPage;
61
+ setCurrentPage(nextPage);
62
+ } else {
63
+ console.error("[ERROR] No next page found.");
64
+ setGlobalError("Configuration Error: No next page found.");
65
+ }
66
+ break;
67
+ case "first":
68
+ targetPage = document.pages[0];
69
+ setCurrentPage(document.pages[0]);
70
+ break;
71
+ case "last":
72
+ targetPage = document.pages[document.pages.length - 1];
73
+ setCurrentPage(document.pages[document.pages.length - 1]);
74
+ break;
75
+ default:
76
+ targetPage = document.pages.find((page) => page.id === to) || document.pages[0];
77
+ setCurrentPage(targetPage);
78
+ break;
79
+ }
80
+ if (targetPage && typeof window !== "undefined" && window.parent) {
81
+ window.parent.postMessage(
82
+ { type: "FORM_PAGE_CHANGED", pageId: targetPage.id },
83
+ window.location.origin
84
+ );
85
+ }
86
+ if (targetPage && analyticsSettings?.track_page_navigation && onAnalyticsEvent) {
87
+ const targetIndex = document.pages.findIndex(
88
+ (p) => p.id === targetPage.id
89
+ );
90
+ onAnalyticsEvent("form_page_change", {
91
+ form_id: formId,
92
+ form_name: formName,
93
+ page_id: targetPage.id,
94
+ page_index: targetIndex,
95
+ total_pages: document.pages.length
96
+ });
97
+ }
98
+ },
99
+ [
100
+ currentPage,
101
+ setCurrentPage,
102
+ document,
103
+ formId,
104
+ formValues,
105
+ settings,
106
+ setErrors,
107
+ setGlobalError,
108
+ analyticsSettings,
109
+ onAnalyticsEvent,
110
+ formName
111
+ ]
112
+ );
113
+ const submit = useCallback(async () => {
114
+ if (!block) {
115
+ return;
116
+ }
117
+ let allErrors = {};
118
+ let hasErrors = false;
119
+ for (const page of document.pages) {
120
+ const result = validatePage(page, formValues, settings);
121
+ if (result !== true) {
122
+ allErrors = { ...allErrors, ...result };
123
+ hasErrors = true;
124
+ }
125
+ }
126
+ if (hasErrors) {
127
+ setErrors(allErrors);
128
+ if (analyticsSettings?.track_form_error && onAnalyticsEvent) {
129
+ onAnalyticsEvent("form_error", {
130
+ form_id: formId,
131
+ form_name: formName,
132
+ error_count: Object.keys(allErrors).length,
133
+ error_fields: Object.keys(allErrors)
134
+ });
135
+ }
136
+ return;
137
+ }
138
+ setErrors(null);
139
+ setGlobalError(null);
140
+ try {
141
+ const buttonTypeOverride = block && typeof block.config.submission_type === "string" && block.config.submission_type ? block.config.submission_type : void 0;
142
+ const submissionData = {
143
+ form_id: formId,
144
+ type: buttonTypeOverride ?? settings?.form_type ?? "General",
145
+ locale: locale ?? "en",
146
+ data: formValues,
147
+ environment_type: "page",
148
+ environment_id: formId,
149
+ environment_path: typeof window !== "undefined" ? window.location.pathname : void 0,
150
+ form_variant_id: formVariantId ?? "",
151
+ environment_variant_id: environmentVariantId ?? ""
152
+ };
153
+ const response = await fetch("/api/submission", {
154
+ method: "POST",
155
+ headers: {
156
+ "Content-Type": "application/json"
157
+ },
158
+ body: JSON.stringify(submissionData)
159
+ });
160
+ const result = await response.json();
161
+ if (!response.ok || !result.success) {
162
+ setGlobalError(
163
+ result.message || "Failed to submit form. Please try again."
164
+ );
165
+ return;
166
+ }
167
+ if (analyticsSettings?.track_form_submit && onAnalyticsEvent) {
168
+ onAnalyticsEvent("form_submit", {
169
+ form_id: formId,
170
+ form_name: formName,
171
+ total_pages: document.pages.length,
172
+ custom_event_name: analyticsSettings.submit_event_name,
173
+ target_providers: analyticsSettings.target_providers
174
+ });
175
+ }
176
+ } catch (error) {
177
+ setGlobalError("An error occurred while submitting the form.");
178
+ }
179
+ return Promise.resolve();
180
+ }, [
181
+ block,
182
+ document,
183
+ formId,
184
+ formValues,
185
+ setErrors,
186
+ setGlobalError,
187
+ settings,
188
+ analyticsSettings,
189
+ onAnalyticsEvent,
190
+ formName,
191
+ locale,
192
+ formVariantId,
193
+ environmentVariantId
194
+ ]);
195
+ const reset = useCallback(async () => {
196
+ if (!block) {
197
+ return;
198
+ }
199
+ setFormValues({});
200
+ setErrors(null);
201
+ setGlobalError(null);
202
+ return Promise.resolve();
203
+ }, [block, setFormValues, setErrors, setGlobalError]);
204
+ const executeAction = useCallback(async () => {
205
+ if (!block) {
206
+ return;
207
+ }
208
+ const action = block.config.action;
209
+ let to = String(block.config.navigate_to_page || "next");
210
+ if (action === "reset") {
211
+ await reset();
212
+ to = "first";
213
+ navigate(to);
214
+ } else if (action === "submit") {
215
+ await submit();
216
+ navigate(to);
217
+ } else if (action === "navigate") {
218
+ navigate(to);
219
+ }
220
+ return Promise.resolve();
221
+ }, [block, navigate, submit, reset]);
222
+ const display = useMemo(() => {
223
+ if (!block) {
224
+ return "none";
225
+ }
226
+ const rules = block.config.advanced_options?.rules;
227
+ if (!rules) {
228
+ return "block";
229
+ }
230
+ return evaluateVisibilityRules(rules, formValues);
231
+ }, [block, formValues]);
232
+ const disabled = useMemo(() => {
233
+ if (!block) {
234
+ return false;
235
+ }
236
+ if (loading) {
237
+ return true;
238
+ }
239
+ if (typeof block.config.disabled === "boolean" && block.config.disabled) {
240
+ return block.config.disabled;
241
+ }
242
+ const rules = block.config.advanced_options?.rules;
243
+ if (!rules) {
244
+ return false;
245
+ }
246
+ return evaluateDisabledRules(rules, formValues);
247
+ }, [block, formValues, loading]);
248
+ if (!block) {
249
+ return null;
250
+ }
251
+ return {
252
+ variant: typeof block.config.variant === "string" ? block.config.variant : "primary",
253
+ size: typeof block.config.size === "string" ? block.config.size : "md",
254
+ disabled,
255
+ loading,
256
+ display,
257
+ text: typeof block.config.text === "string" ? block.config.text : typeof block.config.label === "string" ? block.config.label : "",
258
+ onClick: executeAction
259
+ };
260
+ }
261
+ export {
262
+ useFormAction
263
+ };
264
+ //# sourceMappingURL=use-form-action.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/use-form-action.tsx"],"sourcesContent":["\"use client\";\n\nimport type {\n BlockInstance,\n FormAdvancedOptions,\n FormPage,\n} from \"@otl-core/cms-types\";\nimport { useCallback, useMemo } from \"react\";\nimport { useForm } from \"./form-context\";\nimport {\n findBlockInDocument,\n getNextPage,\n getPreviousPage,\n} from \"./utils/page.utils\";\nimport {\n evaluateDisabledRules,\n evaluateVisibilityRules,\n} from \"./utils/rule.utils\";\nimport { validatePage } from \"./utils/validation.utils\";\n\ninterface FormAction {\n variant: \"primary\" | \"secondary\" | \"outline\" | \"ghost\";\n size: \"sm\" | \"md\" | \"lg\";\n disabled: boolean;\n loading: boolean;\n display: \"block\" | \"none\";\n text: string;\n onClick: () => Promise<void>;\n}\n\nexport function useFormAction(id: string): FormAction | null {\n const {\n formId,\n document,\n formValues,\n setErrors,\n loading,\n currentPage,\n setCurrentPage,\n setFormValues,\n setGlobalError,\n settings,\n analyticsSettings,\n onAnalyticsEvent,\n formName,\n environmentVariantId,\n formVariantId,\n locale,\n } = useForm();\n\n const block: BlockInstance | null = useMemo(() => {\n return findBlockInDocument(id, document);\n }, [document, id]);\n\n const navigate = useCallback(\n (to: string) => {\n const currentPageValid: true | { [key: string]: string } =\n to === \"first\" || validatePage(currentPage, formValues, settings);\n\n if (currentPageValid !== true) {\n // Replace errors, don't accumulate\n setErrors(currentPageValid);\n return;\n }\n\n // Clear errors when navigation is successful\n setErrors(null);\n setGlobalError(null);\n\n let targetPage: FormPage | null = null;\n\n switch (to) {\n case \"prev\":\n const previousPage = getPreviousPage(currentPage, document);\n if (previousPage) {\n targetPage = previousPage;\n setCurrentPage(previousPage);\n } else {\n console.error(\"[ERROR] No previous page found.\");\n setGlobalError(\"Configuration Error: No previous page found.\");\n }\n break;\n case \"next\":\n const nextPage = getNextPage(currentPage, document);\n if (nextPage) {\n targetPage = nextPage;\n setCurrentPage(nextPage);\n } else {\n console.error(\"[ERROR] No next page found.\");\n setGlobalError(\"Configuration Error: No next page found.\");\n }\n break;\n case \"first\":\n targetPage = document.pages[0];\n setCurrentPage(document.pages[0]);\n break;\n case \"last\":\n targetPage = document.pages[document.pages.length - 1];\n setCurrentPage(document.pages[document.pages.length - 1]);\n break;\n default:\n targetPage =\n document.pages.find((page) => page.id === to) || document.pages[0];\n setCurrentPage(targetPage);\n break;\n }\n\n // Notify parent window of page change (for editor sync)\n if (targetPage && typeof window !== \"undefined\" && window.parent) {\n window.parent.postMessage(\n { type: \"FORM_PAGE_CHANGED\", pageId: targetPage.id },\n window.location.origin,\n );\n }\n\n // Emit form_page_change analytics event\n if (\n targetPage &&\n analyticsSettings?.track_page_navigation &&\n onAnalyticsEvent\n ) {\n const targetIndex = document.pages.findIndex(\n (p) => p.id === targetPage.id,\n );\n onAnalyticsEvent(\"form_page_change\", {\n form_id: formId,\n form_name: formName,\n page_id: targetPage.id,\n page_index: targetIndex,\n total_pages: document.pages.length,\n });\n }\n },\n [\n currentPage,\n setCurrentPage,\n document,\n formId,\n formValues,\n settings,\n setErrors,\n setGlobalError,\n analyticsSettings,\n onAnalyticsEvent,\n formName,\n ],\n );\n\n const submit = useCallback(async () => {\n if (!block) {\n return;\n }\n\n // Collect all errors from all pages\n let allErrors: { [key: string]: string } = {};\n let hasErrors = false;\n\n for (const page of document.pages) {\n const result = validatePage(page, formValues, settings);\n if (result !== true) {\n allErrors = { ...allErrors, ...result };\n hasErrors = true;\n }\n }\n\n if (hasErrors) {\n setErrors(allErrors);\n\n // Emit form_error analytics event\n if (analyticsSettings?.track_form_error && onAnalyticsEvent) {\n onAnalyticsEvent(\"form_error\", {\n form_id: formId,\n form_name: formName,\n error_count: Object.keys(allErrors).length,\n error_fields: Object.keys(allErrors),\n });\n }\n\n return;\n }\n\n // Clear all errors on successful validation\n setErrors(null);\n setGlobalError(null);\n\n try {\n // Button-level submission_type override takes precedence over the form-level setting\n const buttonTypeOverride =\n block &&\n typeof block.config.submission_type === \"string\" &&\n block.config.submission_type\n ? block.config.submission_type\n : undefined;\n\n const submissionData = {\n form_id: formId,\n type: buttonTypeOverride ?? settings?.form_type ?? \"General\",\n locale: locale ?? \"en\",\n data: formValues,\n environment_type: \"page\",\n environment_id: formId,\n environment_path:\n typeof window !== \"undefined\" ? window.location.pathname : undefined,\n form_variant_id: formVariantId ?? \"\",\n environment_variant_id: environmentVariantId ?? \"\",\n };\n\n const response = await fetch(\"/api/submission\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(submissionData),\n });\n\n const result = await response.json();\n\n if (!response.ok || !result.success) {\n setGlobalError(\n result.message || \"Failed to submit form. Please try again.\",\n );\n return;\n }\n\n // Emit form_submit analytics event on success\n if (analyticsSettings?.track_form_submit && onAnalyticsEvent) {\n onAnalyticsEvent(\"form_submit\", {\n form_id: formId,\n form_name: formName,\n total_pages: document.pages.length,\n custom_event_name: analyticsSettings.submit_event_name,\n target_providers: analyticsSettings.target_providers,\n });\n }\n } catch (error) {\n setGlobalError(\"An error occurred while submitting the form.\");\n }\n\n return Promise.resolve();\n }, [\n block,\n document,\n formId,\n formValues,\n setErrors,\n setGlobalError,\n settings,\n analyticsSettings,\n onAnalyticsEvent,\n formName,\n locale,\n formVariantId,\n environmentVariantId,\n ]);\n\n const reset = useCallback(async () => {\n if (!block) {\n return;\n }\n setFormValues({});\n setErrors(null);\n setGlobalError(null);\n return Promise.resolve();\n }, [block, setFormValues, setErrors, setGlobalError]);\n\n const executeAction = useCallback(async () => {\n if (!block) {\n return;\n }\n\n const action = block.config.action as string;\n let to = String(block.config.navigate_to_page || \"next\");\n\n if (action === \"reset\") {\n await reset();\n to = \"first\"; // always navigate to first page after reset\n navigate(to);\n } else if (action === \"submit\") {\n await submit();\n // Only navigate if submit was successful (no errors set)\n navigate(to);\n } else if (action === \"navigate\") {\n navigate(to);\n }\n\n return Promise.resolve();\n }, [block, navigate, submit, reset]);\n\n const display: \"block\" | \"none\" = useMemo(() => {\n if (!block) {\n return \"none\";\n }\n\n const rules = (block.config.advanced_options as FormAdvancedOptions)?.rules;\n if (!rules) {\n return \"block\";\n }\n\n return evaluateVisibilityRules(rules, formValues);\n }, [block, formValues]);\n\n const disabled: boolean = useMemo(() => {\n if (!block) {\n return false;\n }\n\n if (loading) {\n return true;\n }\n\n if (typeof block.config.disabled === \"boolean\" && block.config.disabled) {\n return block.config.disabled;\n }\n\n const rules = (block.config.advanced_options as FormAdvancedOptions)?.rules;\n if (!rules) {\n return false;\n }\n\n return evaluateDisabledRules(rules, formValues);\n }, [block, formValues, loading]);\n\n if (!block) {\n return null;\n }\n\n return {\n variant:\n typeof block.config.variant === \"string\"\n ? (block.config.variant as FormAction[\"variant\"])\n : \"primary\",\n size:\n typeof block.config.size === \"string\"\n ? (block.config.size as FormAction[\"size\"])\n : \"md\",\n disabled,\n loading,\n display,\n text:\n typeof block.config.text === \"string\"\n ? block.config.text\n : typeof block.config.label === \"string\"\n ? block.config.label\n : \"\",\n onClick: executeAction,\n };\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,181 @@
1
+ "use strict";
2
+ "use client";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var use_form_field_exports = {};
21
+ __export(use_form_field_exports, {
22
+ useFormField: () => useFormField
23
+ });
24
+ module.exports = __toCommonJS(use_form_field_exports);
25
+ var import_react = require("react");
26
+ var import_form_context = require("./form-context");
27
+ var import_page = require("./utils/page.utils");
28
+ var import_rule = require("./utils/rule.utils");
29
+ var import_validation = require("./utils/validation.utils");
30
+ function useFormField(id) {
31
+ const {
32
+ formId,
33
+ document,
34
+ settings,
35
+ loading,
36
+ formValues,
37
+ setFormValues,
38
+ errors,
39
+ setErrors,
40
+ analyticsSettings,
41
+ onAnalyticsEvent,
42
+ formName,
43
+ hasStarted,
44
+ setHasStarted
45
+ } = (0, import_form_context.useForm)();
46
+ const block = (0, import_react.useMemo)(() => {
47
+ return (0, import_page.findBlockInDocument)(id, document);
48
+ }, [document, id]);
49
+ const fieldId = (0, import_react.useMemo)(() => {
50
+ if (!block) return null;
51
+ return typeof block.config.field_id === "string" ? block.config.field_id : block.id;
52
+ }, [block]);
53
+ const initialValue = (0, import_react.useMemo)(() => {
54
+ if (!block) {
55
+ return void 0;
56
+ }
57
+ if (typeof block.config.initialValue === "string") {
58
+ return String(block.config.initialValue);
59
+ } else if (typeof block.config.initialValue === "number") {
60
+ return Number(block.config.initialValue);
61
+ } else if (typeof block.config.initialValue === "boolean") {
62
+ return Boolean(block.config.initialValue);
63
+ }
64
+ if (block.config.initialValue !== void 0) {
65
+ return block.config.initialValue;
66
+ }
67
+ return void 0;
68
+ }, [block]);
69
+ const value = (0, import_react.useMemo)(() => {
70
+ if (!fieldId) {
71
+ return void 0;
72
+ }
73
+ return formValues[fieldId] ?? initialValue;
74
+ }, [fieldId, formValues, initialValue]);
75
+ const setValue = (0, import_react.useCallback)(
76
+ (value2) => {
77
+ if (!fieldId) {
78
+ return;
79
+ }
80
+ setFormValues((prev) => ({ ...prev, [fieldId]: value2 }));
81
+ setErrors((prev) => {
82
+ if (!prev || !prev[fieldId]) return prev;
83
+ const { [fieldId]: _, ...rest } = prev;
84
+ return Object.keys(rest).length > 0 ? rest : null;
85
+ });
86
+ if (!hasStarted && analyticsSettings?.track_form_start && onAnalyticsEvent) {
87
+ setHasStarted(true);
88
+ onAnalyticsEvent("form_start", {
89
+ form_id: formId,
90
+ form_name: formName
91
+ });
92
+ }
93
+ },
94
+ [
95
+ fieldId,
96
+ setFormValues,
97
+ setErrors,
98
+ hasStarted,
99
+ setHasStarted,
100
+ analyticsSettings,
101
+ onAnalyticsEvent,
102
+ formId,
103
+ formName
104
+ ]
105
+ );
106
+ const handleBlur = (0, import_react.useCallback)(() => {
107
+ if (!(settings.validate_on_blur ?? false) || !block || !fieldId) {
108
+ return;
109
+ }
110
+ const currentValue = formValues[fieldId] ?? initialValue;
111
+ const error = (0, import_validation.validateField)(block, currentValue, settings);
112
+ if (error) {
113
+ setErrors((prev) => ({ ...prev, [fieldId]: error }));
114
+ } else {
115
+ setErrors((prev) => {
116
+ if (!prev || !prev[fieldId]) return prev;
117
+ const { [fieldId]: _, ...rest } = prev;
118
+ return Object.keys(rest).length > 0 ? rest : null;
119
+ });
120
+ }
121
+ }, [settings, block, fieldId, formValues, initialValue, setErrors]);
122
+ const display = (0, import_react.useMemo)(() => {
123
+ if (!block) {
124
+ return "none";
125
+ }
126
+ const rules = block.config.advanced_options?.rules;
127
+ if (!rules) {
128
+ return "block";
129
+ }
130
+ return (0, import_rule.evaluateVisibilityRules)(rules, formValues);
131
+ }, [block, formValues]);
132
+ const disabled = (0, import_react.useMemo)(() => {
133
+ if (!block) {
134
+ return false;
135
+ }
136
+ if (loading) {
137
+ return true;
138
+ }
139
+ if (typeof block.config.disabled === "boolean" && block.config.disabled) {
140
+ return block.config.disabled;
141
+ }
142
+ const rules = block.config.advanced_options?.rules;
143
+ if (!rules) {
144
+ return false;
145
+ }
146
+ return (0, import_rule.evaluateDisabledRules)(rules, formValues);
147
+ }, [block, formValues, loading]);
148
+ if (!block || !fieldId) {
149
+ return null;
150
+ }
151
+ return {
152
+ name: fieldId,
153
+ label: typeof block.config.label === "string" ? block.config.label : "",
154
+ type: typeof block.config.input_type === "string" ? block.config.input_type : typeof block.config.type === "string" ? block.config.type : "",
155
+ helperText: typeof block.config.help_text === "string" ? block.config.help_text : typeof block.config.helperText === "string" ? block.config.helperText : "",
156
+ placeholder: typeof block.config.placeholder === "string" ? block.config.placeholder : null,
157
+ additionalSettings: {
158
+ rows: typeof block.config.rows === "number" ? block.config.rows : void 0,
159
+ options: block.config.options || void 0,
160
+ multiple: typeof block.config.multiple === "boolean" ? block.config.multiple : void 0,
161
+ min: typeof block.config.min === "number" ? block.config.min : void 0,
162
+ max: typeof block.config.max === "number" ? block.config.max : void 0,
163
+ step: typeof block.config.step === "number" ? block.config.step : void 0,
164
+ blocks: block.config.blocks || void 0,
165
+ gap: block.config.gap || void 0
166
+ },
167
+ loading,
168
+ disabled,
169
+ display,
170
+ required: typeof block.config.required === "boolean" ? block.config.required : false,
171
+ error: errors?.[fieldId] || errors?.[block.id] || void 0,
172
+ value,
173
+ onChange: setValue,
174
+ onBlur: handleBlur
175
+ };
176
+ }
177
+ // Annotate the CommonJS export names for ESM import in node:
178
+ 0 && (module.exports = {
179
+ useFormField
180
+ });
181
+ //# sourceMappingURL=use-form-field.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/use-form-field.tsx"],"sourcesContent":["\"use client\";\n\nimport type { BlockInstance, FormAdvancedOptions } from \"@otl-core/cms-types\";\nimport { useCallback, useMemo } from \"react\";\nimport { useForm } from \"./form-context\";\nimport { findBlockInDocument } from \"./utils/page.utils\";\nimport {\n evaluateDisabledRules,\n evaluateVisibilityRules,\n} from \"./utils/rule.utils\";\nimport { validateField } from \"./utils/validation.utils\";\n\ninterface FormField<T> {\n name: string;\n label: string;\n type: string;\n helperText: string;\n placeholder: string | null;\n additionalSettings: Record<string, unknown>;\n\n loading: boolean;\n\n display: \"block\" | \"none\";\n required: boolean;\n disabled: boolean;\n error?: string;\n\n value: T;\n onChange: React.Dispatch<React.SetStateAction<T>>;\n onBlur: () => void;\n}\n\nexport function useFormField<T>(id: string): FormField<T> | null {\n const {\n formId,\n document,\n settings,\n loading,\n formValues,\n setFormValues,\n errors,\n setErrors,\n analyticsSettings,\n onAnalyticsEvent,\n formName,\n hasStarted,\n setHasStarted,\n } = useForm();\n\n const block: BlockInstance | null = useMemo(() => {\n return findBlockInDocument(id, document);\n }, [document, id]);\n\n const fieldId = useMemo(() => {\n if (!block) return null;\n return typeof block.config.field_id === \"string\"\n ? block.config.field_id\n : block.id;\n }, [block]);\n\n const initialValue: T | undefined = useMemo(() => {\n if (!block) {\n return undefined;\n }\n\n if (typeof block.config.initialValue === \"string\") {\n return String(block.config.initialValue) as T;\n } else if (typeof block.config.initialValue === \"number\") {\n return Number(block.config.initialValue) as T;\n } else if (typeof block.config.initialValue === \"boolean\") {\n return Boolean(block.config.initialValue) as T;\n }\n\n if (block.config.initialValue !== undefined) {\n return block.config.initialValue as T;\n }\n\n return undefined;\n }, [block]);\n\n const value = useMemo<T | undefined>(() => {\n if (!fieldId) {\n return undefined;\n }\n return (formValues[fieldId] as T) ?? initialValue;\n }, [fieldId, formValues, initialValue]);\n\n const setValue = useCallback(\n (value: T) => {\n if (!fieldId) {\n return;\n }\n setFormValues((prev) => ({ ...prev, [fieldId]: value }));\n // Clear error for this field when value changes\n setErrors((prev) => {\n if (!prev || !prev[fieldId]) return prev;\n const { [fieldId]: _, ...rest } = prev;\n return Object.keys(rest).length > 0 ? rest : null;\n });\n\n // Emit form_start on first interaction\n if (\n !hasStarted &&\n analyticsSettings?.track_form_start &&\n onAnalyticsEvent\n ) {\n setHasStarted(true);\n onAnalyticsEvent(\"form_start\", {\n form_id: formId,\n form_name: formName,\n });\n }\n },\n [\n fieldId,\n setFormValues,\n setErrors,\n hasStarted,\n setHasStarted,\n analyticsSettings,\n onAnalyticsEvent,\n formId,\n formName,\n ],\n );\n\n const handleBlur = useCallback(() => {\n // Only validate on blur if the setting is enabled\n if (!(settings.validate_on_blur ?? false) || !block || !fieldId) {\n return;\n }\n\n const currentValue = formValues[fieldId] ?? initialValue;\n const error = validateField(block, currentValue, settings);\n\n if (error) {\n setErrors((prev) => ({ ...prev, [fieldId]: error }));\n } else {\n // Clear error if validation passes\n setErrors((prev) => {\n if (!prev || !prev[fieldId]) return prev;\n const { [fieldId]: _, ...rest } = prev;\n return Object.keys(rest).length > 0 ? rest : null;\n });\n }\n }, [settings, block, fieldId, formValues, initialValue, setErrors]);\n\n const display: \"block\" | \"none\" = useMemo(() => {\n if (!block) {\n return \"none\";\n }\n\n // check logic\n const rules = (block.config.advanced_options as FormAdvancedOptions)?.rules;\n if (!rules) {\n return \"block\";\n }\n\n return evaluateVisibilityRules(rules, formValues);\n }, [block, formValues]);\n\n const disabled: boolean = useMemo(() => {\n if (!block) {\n return false;\n }\n\n if (loading) {\n return true;\n }\n\n if (typeof block.config.disabled === \"boolean\" && block.config.disabled) {\n return block.config.disabled;\n }\n\n // check logic\n const rules = (block.config.advanced_options as FormAdvancedOptions)?.rules;\n if (!rules) {\n return false;\n }\n\n return evaluateDisabledRules(rules, formValues);\n }, [block, formValues, loading]);\n\n if (!block || !fieldId) {\n return null;\n }\n\n return {\n name: fieldId,\n label: typeof block.config.label === \"string\" ? block.config.label : \"\",\n type:\n typeof block.config.input_type === \"string\"\n ? block.config.input_type\n : typeof block.config.type === \"string\"\n ? block.config.type\n : \"\",\n helperText:\n typeof block.config.help_text === \"string\"\n ? block.config.help_text\n : typeof block.config.helperText === \"string\"\n ? block.config.helperText\n : \"\",\n placeholder:\n typeof block.config.placeholder === \"string\"\n ? block.config.placeholder\n : null,\n\n additionalSettings: {\n rows:\n typeof block.config.rows === \"number\" ? block.config.rows : undefined,\n options: block.config.options || undefined,\n multiple:\n typeof block.config.multiple === \"boolean\"\n ? block.config.multiple\n : undefined,\n min: typeof block.config.min === \"number\" ? block.config.min : undefined,\n max: typeof block.config.max === \"number\" ? block.config.max : undefined,\n step:\n typeof block.config.step === \"number\" ? block.config.step : undefined,\n blocks: block.config.blocks || undefined,\n gap: block.config.gap || undefined,\n },\n\n loading,\n\n disabled,\n display,\n required:\n typeof block.config.required === \"boolean\"\n ? block.config.required\n : false,\n error: errors?.[fieldId] || errors?.[block.id] || undefined,\n\n value: value as T,\n onChange: setValue as React.Dispatch<React.SetStateAction<T>>,\n onBlur: handleBlur,\n };\n}\n"],"mappings":"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","names":["value"]}
@@ -0,0 +1,19 @@
1
+ interface FormField<T> {
2
+ name: string;
3
+ label: string;
4
+ type: string;
5
+ helperText: string;
6
+ placeholder: string | null;
7
+ additionalSettings: Record<string, unknown>;
8
+ loading: boolean;
9
+ display: "block" | "none";
10
+ required: boolean;
11
+ disabled: boolean;
12
+ error?: string;
13
+ value: T;
14
+ onChange: React.Dispatch<React.SetStateAction<T>>;
15
+ onBlur: () => void;
16
+ }
17
+ declare function useFormField<T>(id: string): FormField<T> | null;
18
+
19
+ export { useFormField };
@@ -0,0 +1,19 @@
1
+ interface FormField<T> {
2
+ name: string;
3
+ label: string;
4
+ type: string;
5
+ helperText: string;
6
+ placeholder: string | null;
7
+ additionalSettings: Record<string, unknown>;
8
+ loading: boolean;
9
+ display: "block" | "none";
10
+ required: boolean;
11
+ disabled: boolean;
12
+ error?: string;
13
+ value: T;
14
+ onChange: React.Dispatch<React.SetStateAction<T>>;
15
+ onBlur: () => void;
16
+ }
17
+ declare function useFormField<T>(id: string): FormField<T> | null;
18
+
19
+ export { useFormField };