funuicss 3.8.7 → 3.8.9

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.
@@ -0,0 +1,724 @@
1
+ "use strict";
2
+ 'use client';
3
+ var __assign = (this && this.__assign) || function () {
4
+ __assign = Object.assign || function(t) {
5
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
6
+ s = arguments[i];
7
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
8
+ t[p] = s[p];
9
+ }
10
+ return t;
11
+ };
12
+ return __assign.apply(this, arguments);
13
+ };
14
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ var desc = Object.getOwnPropertyDescriptor(m, k);
17
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
+ desc = { enumerable: true, get: function() { return m[k]; } };
19
+ }
20
+ Object.defineProperty(o, k2, desc);
21
+ }) : (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ }));
25
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
26
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
27
+ }) : function(o, v) {
28
+ o["default"] = v;
29
+ });
30
+ var __importStar = (this && this.__importStar) || (function () {
31
+ var ownKeys = function(o) {
32
+ ownKeys = Object.getOwnPropertyNames || function (o) {
33
+ var ar = [];
34
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
35
+ return ar;
36
+ };
37
+ return ownKeys(o);
38
+ };
39
+ return function (mod) {
40
+ if (mod && mod.__esModule) return mod;
41
+ var result = {};
42
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
43
+ __setModuleDefault(result, mod);
44
+ return result;
45
+ };
46
+ })();
47
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
48
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
49
+ return new (P || (P = Promise))(function (resolve, reject) {
50
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
51
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
52
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
53
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
54
+ });
55
+ };
56
+ var __generator = (this && this.__generator) || function (thisArg, body) {
57
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
58
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
59
+ function verb(n) { return function (v) { return step([n, v]); }; }
60
+ function step(op) {
61
+ if (f) throw new TypeError("Generator is already executing.");
62
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
63
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
64
+ if (y = 0, t) op = [op[0] & 2, t.value];
65
+ switch (op[0]) {
66
+ case 0: case 1: t = op; break;
67
+ case 4: _.label++; return { value: op[1], done: false };
68
+ case 5: _.label++; y = op[1]; op = [0]; continue;
69
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
70
+ default:
71
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
72
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
73
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
74
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
75
+ if (t[2]) _.ops.pop();
76
+ _.trys.pop(); continue;
77
+ }
78
+ op = body.call(thisArg, _);
79
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
80
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
81
+ }
82
+ };
83
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
84
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
85
+ if (ar || !(i in from)) {
86
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
87
+ ar[i] = from[i];
88
+ }
89
+ }
90
+ return to.concat(ar || Array.prototype.slice.call(from));
91
+ };
92
+ var __importDefault = (this && this.__importDefault) || function (mod) {
93
+ return (mod && mod.__esModule) ? mod : { "default": mod };
94
+ };
95
+ Object.defineProperty(exports, "__esModule", { value: true });
96
+ var react_1 = __importStar(require("react"));
97
+ var Button_1 = __importDefault(require("../button/Button"));
98
+ var Input_1 = __importDefault(require("../input/Input"));
99
+ var Flex_1 = __importDefault(require("../flex/Flex"));
100
+ var Text_1 = __importDefault(require("../text/Text"));
101
+ var pi_1 = require("react-icons/pi");
102
+ var componentUtils_1 = require("../../utils/componentUtils");
103
+ var theme_1 = require("../theme/theme");
104
+ // Helper function to parse JSON input
105
+ var parseJsonInput = function (input, defaultValue) {
106
+ if (input === undefined || input === null) {
107
+ return defaultValue;
108
+ }
109
+ // If it's already the correct type, return as is
110
+ if (typeof input !== 'string') {
111
+ return input;
112
+ }
113
+ try {
114
+ // Try to parse as JSON
115
+ var parsed = JSON.parse(input);
116
+ return parsed;
117
+ }
118
+ catch (error) {
119
+ console.warn('Failed to parse JSON input:', input, error);
120
+ // If parsing fails, try to interpret as a string that might be valid
121
+ try {
122
+ // Try to handle common cases like arrays or objects without quotes
123
+ var trimmed = input.trim();
124
+ if (trimmed.startsWith('[') && trimmed.endsWith(']')) {
125
+ return JSON.parse(trimmed);
126
+ }
127
+ else if (trimmed.startsWith('{') && trimmed.endsWith('}')) {
128
+ return JSON.parse(trimmed);
129
+ }
130
+ }
131
+ catch (e) {
132
+ // If still fails, return default
133
+ }
134
+ return defaultValue;
135
+ }
136
+ };
137
+ // Custom Checkbox Component (unchanged)
138
+ var FormCheckbox = function (_a) {
139
+ var label = _a.label, checked = _a.checked, onChange = _a.onChange, disabled = _a.disabled, required = _a.required, value = _a.value, id = _a.id;
140
+ return (react_1.default.createElement("label", { className: "funui_form-checkbox", style: {
141
+ display: 'flex',
142
+ alignItems: 'center',
143
+ gap: '0.5rem',
144
+ cursor: disabled ? 'not-allowed' : 'pointer',
145
+ userSelect: 'none',
146
+ width: 'fit-content',
147
+ padding: '0.25rem 0',
148
+ } },
149
+ react_1.default.createElement("input", { type: "checkbox", id: id, checked: checked, onChange: function (e) { return !disabled && onChange(e.target.checked); }, disabled: disabled, required: required, value: value, style: {
150
+ position: 'absolute',
151
+ opacity: 0,
152
+ width: 0,
153
+ height: 0,
154
+ pointerEvents: 'none'
155
+ } }),
156
+ react_1.default.createElement("div", { className: "funui_form-checkbox-box", style: {
157
+ width: '1.25rem',
158
+ height: '1.25rem',
159
+ border: checked ? '2px solid var(--primary)' : '2px solid var(--borderColor)',
160
+ borderRadius: '0.25rem',
161
+ backgroundColor: checked ? 'var(--primary)' : 'transparent',
162
+ position: 'relative',
163
+ transition: 'all 0.2s ease',
164
+ display: 'flex',
165
+ alignItems: 'center',
166
+ justifyContent: 'center',
167
+ flexShrink: 0,
168
+ } }, checked && (react_1.default.createElement("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", xmlns: "http://www.w3.org/2000/svg", style: {
169
+ stroke: 'white',
170
+ strokeWidth: '2',
171
+ strokeLinecap: 'round',
172
+ strokeLinejoin: 'round',
173
+ } },
174
+ react_1.default.createElement("path", { d: "M3 7L6 10L11 4" })))),
175
+ label && (react_1.default.createElement("span", { className: "funui_form-checkbox-label", style: {
176
+ fontSize: '0.875rem',
177
+ color: disabled ? 'var(--text-muted)' : 'var(--text)',
178
+ fontWeight: checked ? '500' : '400',
179
+ } },
180
+ label,
181
+ required && ' *'))));
182
+ };
183
+ // Custom Radio Component (unchanged)
184
+ var FormRadio = function (_a) {
185
+ var label = _a.label, checked = _a.checked, onChange = _a.onChange, disabled = _a.disabled, required = _a.required, value = _a.value, id = _a.id;
186
+ return (react_1.default.createElement("label", { className: "funui_form-radio", style: {
187
+ display: 'flex',
188
+ alignItems: 'center',
189
+ gap: '0.5rem',
190
+ cursor: disabled ? 'not-allowed' : 'pointer',
191
+ userSelect: 'none',
192
+ width: 'fit-content',
193
+ padding: '0.25rem 0',
194
+ } },
195
+ react_1.default.createElement("input", { type: "radio", id: id, checked: checked, onChange: function (e) { return !disabled && onChange(e.target.checked); }, disabled: disabled, required: required, value: value, style: {
196
+ position: 'absolute',
197
+ opacity: 0,
198
+ width: 0,
199
+ height: 0,
200
+ pointerEvents: 'none'
201
+ } }),
202
+ react_1.default.createElement("div", { className: "funui_form-radio-circle", style: {
203
+ width: '1.25rem',
204
+ height: '1.25rem',
205
+ border: checked ? '2px solid var(--primary)' : '2px solid var(--borderColor)',
206
+ borderRadius: '50%',
207
+ backgroundColor: 'transparent',
208
+ position: 'relative',
209
+ transition: 'all 0.2s ease',
210
+ display: 'flex',
211
+ alignItems: 'center',
212
+ justifyContent: 'center',
213
+ flexShrink: 0,
214
+ } }, checked && (react_1.default.createElement("div", { style: {
215
+ width: '0.75rem',
216
+ height: '0.75rem',
217
+ backgroundColor: 'var(--primary)',
218
+ borderRadius: '50%',
219
+ } }))),
220
+ label && (react_1.default.createElement("span", { className: "funui_form-radio-label", style: {
221
+ fontSize: '0.875rem',
222
+ color: disabled ? 'var(--text-muted)' : 'var(--text)',
223
+ fontWeight: checked ? '500' : '400',
224
+ } },
225
+ label,
226
+ required && ' *'))));
227
+ };
228
+ // Function to format WhatsApp message (unchanged)
229
+ var formatWhatsAppMessage = function (values, fields, header, footer) {
230
+ // Build message lines
231
+ var message = '';
232
+ // Add header if provided
233
+ if (header) {
234
+ message += "".concat(header, "\n\n");
235
+ }
236
+ // Add form data
237
+ var fieldLines = fields
238
+ .filter(function (field) {
239
+ var value = values[field.name];
240
+ return value !== undefined && value !== null && value !== '' &&
241
+ !(Array.isArray(value) && value.length === 0) &&
242
+ !(typeof value === 'boolean' && !value);
243
+ })
244
+ .map(function (field) {
245
+ var value = values[field.name];
246
+ var displayValue = value;
247
+ // Format array values (for multiple checkboxes)
248
+ if (Array.isArray(value)) {
249
+ displayValue = value.join(', ');
250
+ }
251
+ // Format checkbox values
252
+ if (field.type === 'checkbox' && !field.multiple) {
253
+ displayValue = value ? 'Yes' : 'No';
254
+ }
255
+ // Format select/radio values
256
+ if ((field.type === 'select' || field.type === 'radio') && field.options) {
257
+ var option = field.options.find(function (opt) { return opt.value === value; });
258
+ displayValue = option ? option.label : value;
259
+ }
260
+ return "*".concat(field.label || field.name, ":* ").concat(displayValue);
261
+ })
262
+ .join('\n');
263
+ message += fieldLines;
264
+ // Add footer if provided
265
+ if (footer) {
266
+ message += "\n\n".concat(footer);
267
+ }
268
+ return encodeURIComponent(message);
269
+ };
270
+ // Main Form Component
271
+ var Form = function (_a) {
272
+ var fields = _a.fields, onSubmit = _a.onSubmit, _b = _a.defaultValues, defaultValues = _b === void 0 ? {} : _b, _c = _a.submitText, submitText = _c === void 0 ? 'Submit' : _c, _d = _a.submitBg, submitBg = _d === void 0 ? 'primary' : _d, submitPrefix = _a.submitPrefix, submitSuffix = _a.submitSuffix, _e = _a.resetText, resetText = _e === void 0 ? 'Reset' : _e, _f = _a.showReset, showReset = _f === void 0 ? true : _f, _g = _a.isLoading, isLoading = _g === void 0 ? false : _g, _h = _a.className, className = _h === void 0 ? '' : _h, _j = _a.layout, layout = _j === void 0 ? 'vertical' : _j, _k = _a.gap, gap = _k === void 0 ? '1.5rem' : _k, title = _a.title, titleSize = _a.titleSize, titleColor = _a.titleColor, description = _a.description, descriptionSize = _a.descriptionSize, descriptionColor = _a.descriptionColor, whatsappContact = _a.whatsappContact, width = _a.width, centered = _a.centered, whatsappHeader = _a.whatsappHeader, whatsappFooter = _a.whatsappFooter, _l = _a.fullWidth, fullWidth = _l === void 0 ? true : _l, _m = _a.variant, variant = _m === void 0 ? '' : _m;
273
+ // Use theme variant
274
+ var themeVariant = (0, theme_1.useVariant)().variant;
275
+ // Use component configuration with variant
276
+ var mergeWithLocal = (0, componentUtils_1.useComponentConfiguration)('Form', variant).mergeWithLocal;
277
+ // Parse JSON inputs
278
+ var parsedFields = (0, react_1.useMemo)(function () { return parseJsonInput(fields, []); }, [fields]);
279
+ var parsedDefaultValues = (0, react_1.useMemo)(function () { return parseJsonInput(defaultValues, {}); }, [defaultValues]);
280
+ // Create local props for configuration
281
+ var localProps = {
282
+ fields: parsedFields,
283
+ onSubmit: onSubmit,
284
+ defaultValues: parsedDefaultValues,
285
+ submitText: submitText,
286
+ submitBg: submitBg,
287
+ submitPrefix: submitPrefix,
288
+ submitSuffix: submitSuffix,
289
+ resetText: resetText,
290
+ showReset: showReset,
291
+ isLoading: isLoading,
292
+ className: className,
293
+ layout: layout,
294
+ gap: gap,
295
+ title: title,
296
+ titleSize: titleSize,
297
+ titleColor: titleColor,
298
+ description: description,
299
+ descriptionSize: descriptionSize,
300
+ descriptionColor: descriptionColor,
301
+ whatsappContact: whatsappContact,
302
+ width: width,
303
+ centered: centered,
304
+ whatsappHeader: whatsappHeader,
305
+ whatsappFooter: whatsappFooter,
306
+ fullWidth: fullWidth,
307
+ variant: variant,
308
+ };
309
+ // Merge with theme configuration
310
+ var mergedProps = mergeWithLocal(localProps).props;
311
+ // Destructure merged props with defaults
312
+ var _o = mergedProps.fields, finalFields = _o === void 0 ? parsedFields : _o, _p = mergedProps.onSubmit, finalOnSubmit = _p === void 0 ? onSubmit : _p, _q = mergedProps.defaultValues, finalDefaultValues = _q === void 0 ? parsedDefaultValues : _q, _r = mergedProps.submitText, finalSubmitText = _r === void 0 ? submitText : _r, _s = mergedProps.submitBg, finalSubmitBg = _s === void 0 ? submitBg : _s, _t = mergedProps.submitPrefix, finalSubmitPrefix = _t === void 0 ? submitPrefix : _t, _u = mergedProps.submitSuffix, finalSubmitSuffix = _u === void 0 ? submitSuffix : _u, _v = mergedProps.resetText, finalResetText = _v === void 0 ? resetText : _v, _w = mergedProps.showReset, finalShowReset = _w === void 0 ? showReset : _w, _x = mergedProps.isLoading, finalIsLoading = _x === void 0 ? isLoading : _x, _y = mergedProps.className, finalClassName = _y === void 0 ? className : _y, _z = mergedProps.layout, finalLayout = _z === void 0 ? layout : _z, _0 = mergedProps.gap, finalGap = _0 === void 0 ? gap : _0, _1 = mergedProps.title, finalTitle = _1 === void 0 ? title : _1, _2 = mergedProps.titleSize, finalTitleSize = _2 === void 0 ? titleSize : _2, _3 = mergedProps.titleColor, finalTitleColor = _3 === void 0 ? titleColor : _3, _4 = mergedProps.description, finalDescription = _4 === void 0 ? description : _4, _5 = mergedProps.descriptionSize, finalDescriptionSize = _5 === void 0 ? descriptionSize : _5, _6 = mergedProps.descriptionColor, finalDescriptionColor = _6 === void 0 ? descriptionColor : _6, _7 = mergedProps.whatsappContact, finalWhatsappContact = _7 === void 0 ? whatsappContact : _7, _8 = mergedProps.width, finalWidth = _8 === void 0 ? width : _8, _9 = mergedProps.centered, finalCentered = _9 === void 0 ? centered : _9, _10 = mergedProps.whatsappHeader, finalWhatsappHeader = _10 === void 0 ? whatsappHeader : _10, _11 = mergedProps.whatsappFooter, finalWhatsappFooter = _11 === void 0 ? whatsappFooter : _11, _12 = mergedProps.fullWidth, finalFullWidth = _12 === void 0 ? fullWidth : _12;
313
+ // State management
314
+ var _13 = (0, react_1.useState)({}), errors = _13[0], setErrors = _13[1];
315
+ var _14 = (0, react_1.useState)({}), touched = _14[0], setTouched = _14[1];
316
+ var _15 = (0, react_1.useState)(function () {
317
+ // Initialize form values from defaultValues and field values
318
+ var initialValues = {};
319
+ finalFields.forEach(function (field) {
320
+ if (field.value !== undefined) {
321
+ initialValues[field.name] = field.value;
322
+ }
323
+ else if (finalDefaultValues[field.name] !== undefined) {
324
+ initialValues[field.name] = finalDefaultValues[field.name];
325
+ }
326
+ else {
327
+ // Set default empty values
328
+ if (field.type === 'checkbox' && field.multiple) {
329
+ initialValues[field.name] = [];
330
+ }
331
+ else if (field.type === 'checkbox') {
332
+ initialValues[field.name] = false;
333
+ }
334
+ else {
335
+ initialValues[field.name] = '';
336
+ }
337
+ }
338
+ });
339
+ return initialValues;
340
+ }), formValues = _15[0], setFormValues = _15[1];
341
+ var _16 = (0, react_1.useState)(false), isSubmitting = _16[0], setIsSubmitting = _16[1];
342
+ // Update form values when defaultValues prop changes
343
+ (0, react_1.useEffect)(function () {
344
+ if (Object.keys(finalDefaultValues).length > 0) {
345
+ setFormValues(function (prev) { return (__assign(__assign({}, prev), finalDefaultValues)); });
346
+ }
347
+ }, [finalDefaultValues]);
348
+ // Validate a single field (unchanged)
349
+ var validateField = (0, react_1.useCallback)(function (field, value) {
350
+ var _a, _b, _c, _d, _e;
351
+ // Required validation
352
+ if (field.required) {
353
+ if (value === undefined || value === null || value === '') {
354
+ return "".concat(field.label || field.name, " is required");
355
+ }
356
+ if (field.type === 'checkbox' && field.multiple && Array.isArray(value) && value.length === 0) {
357
+ return "".concat(field.label || field.name, " is required");
358
+ }
359
+ if (field.type === 'checkbox' && !field.multiple && value === false) {
360
+ return "".concat(field.label || field.name, " is required");
361
+ }
362
+ }
363
+ // Type-specific validations (only for non-empty values)
364
+ if (value && (typeof value !== 'string' || value !== '')) {
365
+ // Email validation
366
+ if (field.type === 'email' && typeof value === 'string') {
367
+ var emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
368
+ if (!emailRegex.test(value)) {
369
+ return 'Please enter a valid email address';
370
+ }
371
+ }
372
+ // Number validation
373
+ if (field.type === 'number') {
374
+ var numValue = void 0;
375
+ if (typeof value === 'string') {
376
+ numValue = parseFloat(value);
377
+ }
378
+ else if (typeof value === 'number') {
379
+ numValue = value;
380
+ }
381
+ else {
382
+ return 'Please enter a valid number';
383
+ }
384
+ if (isNaN(numValue)) {
385
+ return 'Please enter a valid number';
386
+ }
387
+ var min = (_a = field.inputProps) === null || _a === void 0 ? void 0 : _a.min;
388
+ var max = (_b = field.inputProps) === null || _b === void 0 ? void 0 : _b.max;
389
+ if (min !== undefined && numValue < parseFloat(min.toString())) {
390
+ return "Minimum value is ".concat(min);
391
+ }
392
+ if (max !== undefined && numValue > parseFloat(max.toString())) {
393
+ return "Maximum value is ".concat(max);
394
+ }
395
+ }
396
+ // Phone validation (basic) - only for strings
397
+ if (field.type === 'tel' && typeof value === 'string') {
398
+ var phoneRegex = /^[\+]?[1-9][\d]{0,17}$/;
399
+ if (!phoneRegex.test(value.replace(/[\s+\-()]/g, ''))) {
400
+ return 'Please enter a valid phone number';
401
+ }
402
+ }
403
+ // Length validation for strings
404
+ if (typeof value === 'string') {
405
+ var minLength = (_c = field.inputProps) === null || _c === void 0 ? void 0 : _c.minLength;
406
+ var maxLength = (_d = field.inputProps) === null || _d === void 0 ? void 0 : _d.maxLength;
407
+ if (minLength && value.length < minLength) {
408
+ return "Minimum ".concat(minLength, " characters required");
409
+ }
410
+ if (maxLength && value.length > maxLength) {
411
+ return "Maximum ".concat(maxLength, " characters allowed");
412
+ }
413
+ }
414
+ // Pattern validation if provided - only for strings
415
+ if (((_e = field.inputProps) === null || _e === void 0 ? void 0 : _e.pattern) && typeof value === 'string') {
416
+ try {
417
+ var regex = new RegExp(field.inputProps.pattern);
418
+ if (!regex.test(value)) {
419
+ return 'Invalid format';
420
+ }
421
+ }
422
+ catch (error) {
423
+ console.warn('Invalid regex pattern:', field.inputProps.pattern);
424
+ }
425
+ }
426
+ }
427
+ return null;
428
+ }, []);
429
+ // Validate form (unchanged)
430
+ var validateForm = (0, react_1.useCallback)(function () {
431
+ var newErrors = {};
432
+ var hasErrors = false;
433
+ finalFields.forEach(function (field) {
434
+ var value = formValues[field.name];
435
+ var error = validateField(field, value);
436
+ if (error) {
437
+ newErrors[field.name] = error;
438
+ hasErrors = true;
439
+ }
440
+ });
441
+ setErrors(newErrors);
442
+ return !hasErrors;
443
+ }, [finalFields, validateField, formValues]);
444
+ // Handle field change for checkboxes and radios (unchanged)
445
+ var handleFieldChange = (0, react_1.useCallback)(function (fieldName, newValue) {
446
+ // Update form values
447
+ setFormValues(function (prev) {
448
+ var _a;
449
+ return (__assign(__assign({}, prev), (_a = {}, _a[fieldName] = newValue, _a)));
450
+ });
451
+ // Update touched state
452
+ setTouched(function (prev) {
453
+ var _a;
454
+ return (__assign(__assign({}, prev), (_a = {}, _a[fieldName] = true, _a)));
455
+ });
456
+ // Validate the changed field
457
+ var field = finalFields.find(function (f) { return f.name === fieldName; });
458
+ if (!field)
459
+ return;
460
+ var error = validateField(field, newValue);
461
+ setErrors(function (prev) {
462
+ var _a;
463
+ if (error) {
464
+ return __assign(__assign({}, prev), (_a = {}, _a[fieldName] = error, _a));
465
+ }
466
+ else {
467
+ var newErrors = __assign({}, prev);
468
+ delete newErrors[fieldName];
469
+ return newErrors;
470
+ }
471
+ });
472
+ }, [finalFields, validateField]);
473
+ // Handle input field change (unchanged)
474
+ var handleInputChange = (0, react_1.useCallback)(function (fieldName, value) {
475
+ // Update form values
476
+ setFormValues(function (prev) {
477
+ var _a;
478
+ return (__assign(__assign({}, prev), (_a = {}, _a[fieldName] = value, _a)));
479
+ });
480
+ // Update touched state
481
+ setTouched(function (prev) {
482
+ var _a;
483
+ return (__assign(__assign({}, prev), (_a = {}, _a[fieldName] = true, _a)));
484
+ });
485
+ // Validate the changed field
486
+ var field = finalFields.find(function (f) { return f.name === fieldName; });
487
+ if (!field)
488
+ return;
489
+ var error = validateField(field, value);
490
+ setErrors(function (prev) {
491
+ var _a;
492
+ if (error) {
493
+ return __assign(__assign({}, prev), (_a = {}, _a[fieldName] = error, _a));
494
+ }
495
+ else {
496
+ var newErrors = __assign({}, prev);
497
+ delete newErrors[fieldName];
498
+ return newErrors;
499
+ }
500
+ });
501
+ }, [finalFields, validateField]);
502
+ // Handle field blur (unchanged)
503
+ var handleFieldBlur = (0, react_1.useCallback)(function (fieldName) {
504
+ setTouched(function (prev) {
505
+ var _a;
506
+ return (__assign(__assign({}, prev), (_a = {}, _a[fieldName] = true, _a)));
507
+ });
508
+ // Validate the field
509
+ var field = finalFields.find(function (f) { return f.name === fieldName; });
510
+ if (!field)
511
+ return;
512
+ var value = formValues[fieldName];
513
+ var error = validateField(field, value);
514
+ setErrors(function (prev) {
515
+ var _a;
516
+ if (error) {
517
+ return __assign(__assign({}, prev), (_a = {}, _a[fieldName] = error, _a));
518
+ }
519
+ else {
520
+ var newErrors = __assign({}, prev);
521
+ delete newErrors[fieldName];
522
+ return newErrors;
523
+ }
524
+ });
525
+ }, [finalFields, validateField, formValues]);
526
+ // Handle form submission (unchanged)
527
+ var handleSubmit = (0, react_1.useCallback)(function (e) { return __awaiter(void 0, void 0, void 0, function () {
528
+ var allTouched, isValid, firstErrorField, element, message, cleanPhone, whatsappUrl, error_1;
529
+ return __generator(this, function (_a) {
530
+ switch (_a.label) {
531
+ case 0:
532
+ e.preventDefault();
533
+ allTouched = {};
534
+ finalFields.forEach(function (field) {
535
+ allTouched[field.name] = true;
536
+ });
537
+ setTouched(allTouched);
538
+ isValid = validateForm();
539
+ if (!isValid) {
540
+ firstErrorField = Object.keys(errors)[0];
541
+ if (firstErrorField) {
542
+ element = document.getElementById("form-field-".concat(firstErrorField));
543
+ element === null || element === void 0 ? void 0 : element.scrollIntoView({ behavior: 'smooth', block: 'center' });
544
+ }
545
+ return [2 /*return*/];
546
+ }
547
+ // Get form data and submit
548
+ setIsSubmitting(true);
549
+ _a.label = 1;
550
+ case 1:
551
+ _a.trys.push([1, 7, 8, 9]);
552
+ if (!finalWhatsappContact) return [3 /*break*/, 4];
553
+ message = formatWhatsAppMessage(formValues, finalFields, finalWhatsappHeader, finalWhatsappFooter);
554
+ cleanPhone = finalWhatsappContact.replace(/[\s+\-()]/g, '');
555
+ whatsappUrl = "https://wa.me/".concat(cleanPhone, "?text=").concat(message);
556
+ window.open(whatsappUrl, '_blank');
557
+ if (!finalOnSubmit) return [3 /*break*/, 3];
558
+ return [4 /*yield*/, finalOnSubmit(formValues, true)];
559
+ case 2:
560
+ _a.sent();
561
+ _a.label = 3;
562
+ case 3: return [3 /*break*/, 6];
563
+ case 4:
564
+ if (!finalOnSubmit) return [3 /*break*/, 6];
565
+ return [4 /*yield*/, finalOnSubmit(formValues, false)];
566
+ case 5:
567
+ _a.sent();
568
+ _a.label = 6;
569
+ case 6: return [3 /*break*/, 9];
570
+ case 7:
571
+ error_1 = _a.sent();
572
+ console.error('Form submission error:', error_1);
573
+ setErrors(function (prev) { return (__assign(__assign({}, prev), { _form: 'There was an error submitting the form. Please try again.' })); });
574
+ return [3 /*break*/, 9];
575
+ case 8:
576
+ setIsSubmitting(false);
577
+ return [7 /*endfinally*/];
578
+ case 9: return [2 /*return*/];
579
+ }
580
+ });
581
+ }); }, [finalFields, validateForm, formValues, finalWhatsappContact, finalWhatsappHeader, finalWhatsappFooter, finalOnSubmit, errors]);
582
+ // Handle form reset (unchanged)
583
+ var handleReset = (0, react_1.useCallback)(function () {
584
+ // Reset to initial values
585
+ var initialValues = {};
586
+ finalFields.forEach(function (field) {
587
+ if (field.value !== undefined) {
588
+ initialValues[field.name] = field.value;
589
+ }
590
+ else if (finalDefaultValues[field.name] !== undefined) {
591
+ initialValues[field.name] = finalDefaultValues[field.name];
592
+ }
593
+ else {
594
+ if (field.type === 'checkbox' && field.multiple) {
595
+ initialValues[field.name] = [];
596
+ }
597
+ else if (field.type === 'checkbox') {
598
+ initialValues[field.name] = false;
599
+ }
600
+ else {
601
+ initialValues[field.name] = '';
602
+ }
603
+ }
604
+ });
605
+ setFormValues(initialValues);
606
+ setErrors({});
607
+ setTouched({});
608
+ }, [finalFields, finalDefaultValues]);
609
+ // Get field status for Input component (unchanged)
610
+ var getFieldStatus = (0, react_1.useCallback)(function (fieldName) {
611
+ var error = errors[fieldName];
612
+ var isTouched = touched[fieldName];
613
+ if (error)
614
+ return 'danger';
615
+ if (isTouched && !error && formValues[fieldName] !== '') {
616
+ return 'success';
617
+ }
618
+ return undefined;
619
+ }, [errors, touched, formValues]);
620
+ // Check if form is valid for submission (unchanged)
621
+ var isFormValid = (0, react_1.useMemo)(function () {
622
+ // Check if any required fields are empty
623
+ var hasEmptyRequiredFields = finalFields.some(function (field) {
624
+ if (!field.required)
625
+ return false;
626
+ var value = formValues[field.name];
627
+ if (field.type === 'checkbox' && field.multiple) {
628
+ return !Array.isArray(value) || value.length === 0;
629
+ }
630
+ if (field.type === 'checkbox') {
631
+ return value === false;
632
+ }
633
+ return !value || value === '';
634
+ });
635
+ // Check if there are any validation errors
636
+ var hasValidationErrors = Object.keys(errors).length > 0;
637
+ return !hasEmptyRequiredFields && !hasValidationErrors;
638
+ }, [finalFields, formValues, errors]);
639
+ // Submit button disabled state (unchanged)
640
+ var isSubmitDisabled = isSubmitting || finalIsLoading || !isFormValid;
641
+ // Check if WhatsApp is configured (unchanged)
642
+ var hasWhatsApp = !!finalWhatsappContact;
643
+ // Render field based on type (unchanged)
644
+ var renderField = (0, react_1.useCallback)(function (field) {
645
+ var _a, _b, _c, _d, _e;
646
+ var status = getFieldStatus(field.name);
647
+ var error = errors[field.name];
648
+ var isTouched = touched[field.name];
649
+ var showError = error && isTouched;
650
+ var value = formValues[field.name];
651
+ // Field wrapper classes
652
+ var wrapperClass = "col min-w-200 field ".concat(showError ? 'field-error' : '').trim();
653
+ // Helper text (error takes priority)
654
+ var helperText = showError ? error : field.helperText;
655
+ // Generate unique ID for the input
656
+ var inputId = ((_a = field.inputProps) === null || _a === void 0 ? void 0 : _a.id) || "form-field-".concat(field.name);
657
+ // Base props for Input component
658
+ var baseProps = __assign({ id: inputId, name: field.name, label: field.label, placeholder: field.placeholder, helperText: helperText, disabled: field.disabled || finalIsLoading, fullWidth: finalFullWidth }, field.inputProps);
659
+ // Only add status if it's not undefined
660
+ if (status !== undefined) {
661
+ baseProps.status = status;
662
+ }
663
+ // Render based on field type
664
+ switch (field.type) {
665
+ case 'checkbox':
666
+ if ((_b = field.options) === null || _b === void 0 ? void 0 : _b.length) {
667
+ // Multiple checkboxes (checkbox group)
668
+ var checkedValues_1 = Array.isArray(value) ? value : [];
669
+ return (react_1.default.createElement("div", { key: field.name, className: wrapperClass },
670
+ field.label && (react_1.default.createElement("div", { className: "form-label", style: { marginBottom: '0.5rem' } },
671
+ react_1.default.createElement(Text_1.default, { text: field.label + (field.required ? ' *' : ''), size: "sm", color: "text", bold: true }))),
672
+ react_1.default.createElement(Flex_1.default, { direction: "column", gap: "0.5rem" }, field.options.map(function (option, index) {
673
+ var isChecked = checkedValues_1.includes(option.value);
674
+ return (react_1.default.createElement(FormCheckbox, { key: "".concat(field.name, "_").concat(index), id: "".concat(inputId, "_").concat(index), label: option.label, checked: isChecked, onChange: function (checked) {
675
+ if (checked) {
676
+ // Add value to array
677
+ var newValues = __spreadArray(__spreadArray([], checkedValues_1, true), [option.value], false);
678
+ handleFieldChange(field.name, newValues);
679
+ }
680
+ else {
681
+ // Remove value from array
682
+ var newValues = checkedValues_1.filter(function (v) { return v !== option.value; });
683
+ handleFieldChange(field.name, newValues);
684
+ }
685
+ }, disabled: field.disabled || option.disabled || finalIsLoading, required: field.required && index === 0, value: option.value }));
686
+ }))));
687
+ }
688
+ else {
689
+ // Single checkbox (boolean)
690
+ return (react_1.default.createElement("div", { key: field.name, className: wrapperClass },
691
+ react_1.default.createElement(FormCheckbox, { label: field.label, checked: !!value, onChange: function (checked) { return handleFieldChange(field.name, checked); }, disabled: field.disabled || finalIsLoading, required: field.required, id: inputId })));
692
+ }
693
+ case 'radio':
694
+ if (!((_c = field.options) === null || _c === void 0 ? void 0 : _c.length))
695
+ return null;
696
+ return (react_1.default.createElement("div", { key: field.name, className: wrapperClass },
697
+ field.label && (react_1.default.createElement("div", { className: "form-label", style: { marginBottom: '0.5rem' } },
698
+ react_1.default.createElement(Text_1.default, { text: field.label + (field.required ? ' *' : ''), size: "sm", color: "text", bold: true }))),
699
+ react_1.default.createElement(Flex_1.default, { direction: "column", gap: "0.5rem" }, field.options.map(function (option, index) { return (react_1.default.createElement(FormRadio, { key: "".concat(field.name, "_").concat(index), id: "".concat(inputId, "_").concat(index), label: option.label, checked: value === option.value, onChange: function () { return handleFieldChange(field.name, option.value); }, disabled: field.disabled || option.disabled || finalIsLoading, required: field.required && index === 0, value: option.value })); }))));
700
+ case 'textarea':
701
+ return (react_1.default.createElement("div", { key: field.name, className: wrapperClass },
702
+ react_1.default.createElement(Input_1.default, __assign({ multiline: true, rows: ((_d = field.inputProps) === null || _d === void 0 ? void 0 : _d.rows) || 4, value: value || '', onChange: function (e) { return handleInputChange(field.name, e.target.value); }, onBlur: function () { return handleFieldBlur(field.name); } }, baseProps))));
703
+ case 'select':
704
+ return (react_1.default.createElement("div", { key: field.name, className: wrapperClass },
705
+ react_1.default.createElement(Input_1.default, __assign({ select: true, options: ((_e = field.options) === null || _e === void 0 ? void 0 : _e.map(function (opt) { return ({ text: opt.label, value: opt.value }); })) || [], value: value || '', onChange: function (e) { return handleInputChange(field.name, e.target.value); }, onBlur: function () { return handleFieldBlur(field.name); } }, baseProps))));
706
+ default:
707
+ // text, email, number, tel, date, file, password
708
+ return (react_1.default.createElement("div", { key: field.name, className: wrapperClass },
709
+ react_1.default.createElement(Input_1.default, __assign({ type: field.type, value: value || '', onChange: function (e) { return handleInputChange(field.name, e.target.value); }, onBlur: function () { return handleFieldBlur(field.name); } }, baseProps))));
710
+ }
711
+ }, [errors, touched, formValues, finalIsLoading, getFieldStatus, handleFieldChange, handleInputChange, handleFieldBlur, finalFullWidth]);
712
+ return (react_1.default.createElement("div", { className: "form-wrapper ".concat(finalCentered ? 'center' : '', " ").concat(finalClassName), style: { width: "100%", maxWidth: finalWidth || "450px" } },
713
+ finalTitle && (react_1.default.createElement("div", { className: "form-header", style: { marginBottom: '2rem' } },
714
+ react_1.default.createElement(Text_1.default, { text: finalTitle, size: finalTitleSize || "3xl", color: finalTitleColor || "", block: true }),
715
+ finalDescription && (react_1.default.createElement(Text_1.default, { article: true, size: finalDescriptionSize || "sm", color: finalDescriptionColor || "" },
716
+ react_1.default.createElement("div", { className: "article text-sm", dangerouslySetInnerHTML: { __html: finalDescription } }))))),
717
+ react_1.default.createElement("form", { className: "form", onSubmit: handleSubmit, style: { width: '100%' } },
718
+ react_1.default.createElement(Flex_1.default, { direction: finalLayout === 'horizontal' ? 'row' : 'column', gap: finalGap, width: '100%' }, finalFields.map(renderField)),
719
+ react_1.default.createElement(Flex_1.default, { direction: "column", gap: "1rem", style: { marginTop: '2rem', width: finalFullWidth ? '100%' : undefined } },
720
+ react_1.default.createElement(Button_1.default, { type: "submit", text: hasWhatsApp ? "Send via WhatsApp" : finalSubmitText, bg: finalSubmitBg || "primary", raised: true, prefix: finalSubmitPrefix || hasWhatsApp ? react_1.default.createElement(pi_1.PiWhatsappLogo, null) : react_1.default.createElement(pi_1.PiPaperPlaneTilt, null), suffix: finalSubmitSuffix,
721
+ // startIcon={hasWhatsApp ? <PiWhatsappLogo /> : <PiPaperPlaneTilt />}
722
+ disabled: isSubmitDisabled, isLoading: isSubmitting || finalIsLoading, fullWidth: finalFullWidth })))));
723
+ };
724
+ exports.default = Form;