funuicss 3.8.9 → 3.8.10
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/css/fun.css +0 -1
- package/package.json +1 -1
- package/ui/carousel/Carousel.d.ts +3 -0
- package/ui/carousel/Carousel.js +140 -16
- package/ui/feature/Feature.d.ts +17 -1
- package/ui/feature/Feature.js +25 -1
- package/ui/form/Form.d.ts +2 -2
- package/ui/form/Form.js +163 -120
- package/ui/input/Input.js +23 -988
- package/ui/notification/Notification.js +6 -2
package/ui/form/Form.js
CHANGED
|
@@ -100,7 +100,6 @@ var Flex_1 = __importDefault(require("../flex/Flex"));
|
|
|
100
100
|
var Text_1 = __importDefault(require("../text/Text"));
|
|
101
101
|
var pi_1 = require("react-icons/pi");
|
|
102
102
|
var componentUtils_1 = require("../../utils/componentUtils");
|
|
103
|
-
var theme_1 = require("../theme/theme");
|
|
104
103
|
// Helper function to parse JSON input
|
|
105
104
|
var parseJsonInput = function (input, defaultValue) {
|
|
106
105
|
if (input === undefined || input === null) {
|
|
@@ -165,7 +164,7 @@ var FormCheckbox = function (_a) {
|
|
|
165
164
|
alignItems: 'center',
|
|
166
165
|
justifyContent: 'center',
|
|
167
166
|
flexShrink: 0,
|
|
168
|
-
} }, checked && (react_1.default.createElement("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", xmlns: "http://www.w3.
|
|
167
|
+
} }, checked && (react_1.default.createElement("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", xmlns: "http://www.w3.org2000/svg", style: {
|
|
169
168
|
stroke: 'white',
|
|
170
169
|
strokeWidth: '2',
|
|
171
170
|
strokeLinecap: 'round',
|
|
@@ -225,7 +224,7 @@ var FormRadio = function (_a) {
|
|
|
225
224
|
label,
|
|
226
225
|
required && ' *'))));
|
|
227
226
|
};
|
|
228
|
-
// Function to format WhatsApp message
|
|
227
|
+
// Function to format WhatsApp message - UPDATED with proper formatting
|
|
229
228
|
var formatWhatsAppMessage = function (values, fields, header, footer) {
|
|
230
229
|
// Build message lines
|
|
231
230
|
var message = '';
|
|
@@ -233,15 +232,25 @@ var formatWhatsAppMessage = function (values, fields, header, footer) {
|
|
|
233
232
|
if (header) {
|
|
234
233
|
message += "".concat(header, "\n\n");
|
|
235
234
|
}
|
|
236
|
-
//
|
|
237
|
-
var
|
|
238
|
-
.filter(function (field) {
|
|
235
|
+
// Filter out empty/null/undefined values
|
|
236
|
+
var nonEmptyFields = fields.filter(function (field) {
|
|
239
237
|
var value = values[field.name];
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
238
|
+
// Skip if value is undefined, null, or empty string
|
|
239
|
+
if (value === undefined || value === null || value === '') {
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
// Skip if array is empty
|
|
243
|
+
if (Array.isArray(value) && value.length === 0) {
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
// Skip if checkbox is false
|
|
247
|
+
if (field.type === 'checkbox' && !field.multiple && value === false) {
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
return true;
|
|
251
|
+
});
|
|
252
|
+
// Format each field
|
|
253
|
+
var fieldLines = nonEmptyFields.map(function (field) {
|
|
245
254
|
var value = values[field.name];
|
|
246
255
|
var displayValue = value;
|
|
247
256
|
// Format array values (for multiple checkboxes)
|
|
@@ -257,71 +266,99 @@ var formatWhatsAppMessage = function (values, fields, header, footer) {
|
|
|
257
266
|
var option = field.options.find(function (opt) { return opt.value === value; });
|
|
258
267
|
displayValue = option ? option.label : value;
|
|
259
268
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
269
|
+
// Ensure displayValue is a string and preserve spaces/newlines
|
|
270
|
+
displayValue = String(displayValue);
|
|
271
|
+
// WhatsApp formatting:
|
|
272
|
+
// - Field label on its own line
|
|
273
|
+
// - Value on next line wrapped in backticks
|
|
274
|
+
// - Double newline between fields for readability
|
|
275
|
+
return "".concat(field.label || field.name, "\n`").concat(displayValue, "`");
|
|
276
|
+
});
|
|
277
|
+
// Join with double newline for spacing
|
|
278
|
+
message += fieldLines.join('\n\n');
|
|
264
279
|
// Add footer if provided
|
|
265
280
|
if (footer) {
|
|
266
281
|
message += "\n\n".concat(footer);
|
|
267
282
|
}
|
|
268
283
|
return encodeURIComponent(message);
|
|
269
284
|
};
|
|
270
|
-
// Main Form Component
|
|
271
|
-
var Form = function (
|
|
272
|
-
var
|
|
273
|
-
// Use theme variant
|
|
274
|
-
var themeVariant = (0, theme_1.useVariant)().variant;
|
|
285
|
+
// Main Form Component - FIXED
|
|
286
|
+
var Form = function (props) {
|
|
287
|
+
var fieldsProp = props.fields, onSubmitProp = props.onSubmit, _a = props.defaultValues, defaultValuesProp = _a === void 0 ? {} : _a, _b = props.submitText, submitTextProp = _b === void 0 ? 'Submit' : _b, _c = props.submitBg, submitBgProp = _c === void 0 ? 'primary' : _c, submitPrefixProp = props.submitPrefix, submitSuffixProp = props.submitSuffix, _d = props.resetText, resetTextProp = _d === void 0 ? 'Reset' : _d, _e = props.showReset, showResetProp = _e === void 0 ? true : _e, _f = props.isLoading, isLoadingProp = _f === void 0 ? false : _f, _g = props.className, classNameProp = _g === void 0 ? '' : _g, _h = props.layout, layoutProp = _h === void 0 ? 'vertical' : _h, _j = props.gap, gapProp = _j === void 0 ? '1.5rem' : _j, titleProp = props.title, titleSizeProp = props.titleSize, titleColorProp = props.titleColor, descriptionProp = props.description, descriptionSizeProp = props.descriptionSize, descriptionColorProp = props.descriptionColor, whatsappContactProp = props.whatsappContact, widthProp = props.width, centeredProp = props.centered, whatsappHeaderProp = props.whatsappHeader, whatsappFooterProp = props.whatsappFooter, _k = props.fullWidth, fullWidthProp = _k === void 0 ? true : _k, _l = props.variant, variant = _l === void 0 ? '' : _l;
|
|
275
288
|
// Use component configuration with variant
|
|
276
289
|
var mergeWithLocal = (0, componentUtils_1.useComponentConfiguration)('Form', variant).mergeWithLocal;
|
|
277
|
-
//
|
|
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
|
|
290
|
+
// Create local props object
|
|
281
291
|
var localProps = {
|
|
282
|
-
fields:
|
|
283
|
-
onSubmit:
|
|
284
|
-
defaultValues:
|
|
285
|
-
submitText:
|
|
286
|
-
submitBg:
|
|
287
|
-
submitPrefix:
|
|
288
|
-
submitSuffix:
|
|
289
|
-
resetText:
|
|
290
|
-
showReset:
|
|
291
|
-
isLoading:
|
|
292
|
-
className:
|
|
293
|
-
layout:
|
|
294
|
-
gap:
|
|
295
|
-
title:
|
|
296
|
-
titleSize:
|
|
297
|
-
titleColor:
|
|
298
|
-
description:
|
|
299
|
-
descriptionSize:
|
|
300
|
-
descriptionColor:
|
|
301
|
-
whatsappContact:
|
|
302
|
-
width:
|
|
303
|
-
centered:
|
|
304
|
-
whatsappHeader:
|
|
305
|
-
whatsappFooter:
|
|
306
|
-
fullWidth:
|
|
292
|
+
fields: fieldsProp,
|
|
293
|
+
onSubmit: onSubmitProp,
|
|
294
|
+
defaultValues: defaultValuesProp,
|
|
295
|
+
submitText: submitTextProp,
|
|
296
|
+
submitBg: submitBgProp,
|
|
297
|
+
submitPrefix: submitPrefixProp,
|
|
298
|
+
submitSuffix: submitSuffixProp,
|
|
299
|
+
resetText: resetTextProp,
|
|
300
|
+
showReset: showResetProp,
|
|
301
|
+
isLoading: isLoadingProp,
|
|
302
|
+
className: classNameProp,
|
|
303
|
+
layout: layoutProp,
|
|
304
|
+
gap: gapProp,
|
|
305
|
+
title: titleProp,
|
|
306
|
+
titleSize: titleSizeProp,
|
|
307
|
+
titleColor: titleColorProp,
|
|
308
|
+
description: descriptionProp,
|
|
309
|
+
descriptionSize: descriptionSizeProp,
|
|
310
|
+
descriptionColor: descriptionColorProp,
|
|
311
|
+
whatsappContact: whatsappContactProp,
|
|
312
|
+
width: widthProp,
|
|
313
|
+
centered: centeredProp,
|
|
314
|
+
whatsappHeader: whatsappHeaderProp,
|
|
315
|
+
whatsappFooter: whatsappFooterProp,
|
|
316
|
+
fullWidth: fullWidthProp,
|
|
307
317
|
variant: variant,
|
|
308
318
|
};
|
|
309
319
|
// Merge with theme configuration
|
|
310
320
|
var mergedProps = mergeWithLocal(localProps).props;
|
|
311
|
-
// Destructure
|
|
312
|
-
var
|
|
321
|
+
// Destructure with proper priority: local props override config props
|
|
322
|
+
var fields = fieldsProp !== undefined ? fieldsProp : mergedProps.fields;
|
|
323
|
+
var onSubmit = onSubmitProp !== undefined ? onSubmitProp : mergedProps.onSubmit;
|
|
324
|
+
var defaultValues = defaultValuesProp !== undefined ? defaultValuesProp : mergedProps.defaultValues;
|
|
325
|
+
var submitText = submitTextProp !== undefined ? submitTextProp : mergedProps.submitText;
|
|
326
|
+
var submitBg = submitBgProp !== undefined ? submitBgProp : mergedProps.submitBg;
|
|
327
|
+
var submitPrefix = submitPrefixProp !== undefined ? submitPrefixProp : mergedProps.submitPrefix;
|
|
328
|
+
var submitSuffix = submitSuffixProp !== undefined ? submitSuffixProp : mergedProps.submitSuffix;
|
|
329
|
+
var resetText = resetTextProp !== undefined ? resetTextProp : mergedProps.resetText;
|
|
330
|
+
var showReset = showResetProp !== undefined ? showResetProp : mergedProps.showReset;
|
|
331
|
+
var isLoading = isLoadingProp !== undefined ? isLoadingProp : mergedProps.isLoading;
|
|
332
|
+
var className = classNameProp !== undefined ? classNameProp : mergedProps.className;
|
|
333
|
+
var layout = layoutProp !== undefined ? layoutProp : mergedProps.layout;
|
|
334
|
+
var gap = gapProp !== undefined ? gapProp : mergedProps.gap;
|
|
335
|
+
var title = titleProp !== undefined ? titleProp : mergedProps.title;
|
|
336
|
+
var titleSize = titleSizeProp !== undefined ? titleSizeProp : mergedProps.titleSize;
|
|
337
|
+
var titleColor = titleColorProp !== undefined ? titleColorProp : mergedProps.titleColor;
|
|
338
|
+
var description = descriptionProp !== undefined ? descriptionProp : mergedProps.description;
|
|
339
|
+
var descriptionSize = descriptionSizeProp !== undefined ? descriptionSizeProp : mergedProps.descriptionSize;
|
|
340
|
+
var descriptionColor = descriptionColorProp !== undefined ? descriptionColorProp : mergedProps.descriptionColor;
|
|
341
|
+
var whatsappContact = whatsappContactProp !== undefined ? whatsappContactProp : mergedProps.whatsappContact;
|
|
342
|
+
var width = widthProp !== undefined ? widthProp : mergedProps.width;
|
|
343
|
+
var centered = centeredProp !== undefined ? centeredProp : mergedProps.centered;
|
|
344
|
+
var whatsappHeader = whatsappHeaderProp !== undefined ? whatsappHeaderProp : mergedProps.whatsappHeader;
|
|
345
|
+
var whatsappFooter = whatsappFooterProp !== undefined ? whatsappFooterProp : mergedProps.whatsappFooter;
|
|
346
|
+
var fullWidth = fullWidthProp !== undefined ? fullWidthProp : mergedProps.fullWidth;
|
|
347
|
+
// Parse JSON inputs
|
|
348
|
+
var parsedFields = (0, react_1.useMemo)(function () { return parseJsonInput(fields, []); }, [fields]);
|
|
349
|
+
var parsedDefaultValues = (0, react_1.useMemo)(function () { return parseJsonInput(defaultValues, {}); }, [defaultValues]);
|
|
313
350
|
// State management
|
|
314
|
-
var
|
|
315
|
-
var
|
|
316
|
-
var
|
|
351
|
+
var _m = (0, react_1.useState)({}), errors = _m[0], setErrors = _m[1];
|
|
352
|
+
var _o = (0, react_1.useState)({}), touched = _o[0], setTouched = _o[1];
|
|
353
|
+
var _p = (0, react_1.useState)(function () {
|
|
317
354
|
// Initialize form values from defaultValues and field values
|
|
318
355
|
var initialValues = {};
|
|
319
|
-
|
|
356
|
+
parsedFields.forEach(function (field) {
|
|
320
357
|
if (field.value !== undefined) {
|
|
321
358
|
initialValues[field.name] = field.value;
|
|
322
359
|
}
|
|
323
|
-
else if (
|
|
324
|
-
initialValues[field.name] =
|
|
360
|
+
else if (parsedDefaultValues[field.name] !== undefined) {
|
|
361
|
+
initialValues[field.name] = parsedDefaultValues[field.name];
|
|
325
362
|
}
|
|
326
363
|
else {
|
|
327
364
|
// Set default empty values
|
|
@@ -337,15 +374,15 @@ var Form = function (_a) {
|
|
|
337
374
|
}
|
|
338
375
|
});
|
|
339
376
|
return initialValues;
|
|
340
|
-
}), formValues =
|
|
341
|
-
var
|
|
377
|
+
}), formValues = _p[0], setFormValues = _p[1];
|
|
378
|
+
var _q = (0, react_1.useState)(false), isSubmitting = _q[0], setIsSubmitting = _q[1];
|
|
342
379
|
// Update form values when defaultValues prop changes
|
|
343
380
|
(0, react_1.useEffect)(function () {
|
|
344
|
-
if (Object.keys(
|
|
345
|
-
setFormValues(function (prev) { return (__assign(__assign({}, prev),
|
|
381
|
+
if (Object.keys(parsedDefaultValues).length > 0) {
|
|
382
|
+
setFormValues(function (prev) { return (__assign(__assign({}, prev), parsedDefaultValues)); });
|
|
346
383
|
}
|
|
347
|
-
}, [
|
|
348
|
-
// Validate a single field
|
|
384
|
+
}, [parsedDefaultValues]);
|
|
385
|
+
// Validate a single field
|
|
349
386
|
var validateField = (0, react_1.useCallback)(function (field, value) {
|
|
350
387
|
var _a, _b, _c, _d, _e;
|
|
351
388
|
// Required validation
|
|
@@ -426,11 +463,11 @@ var Form = function (_a) {
|
|
|
426
463
|
}
|
|
427
464
|
return null;
|
|
428
465
|
}, []);
|
|
429
|
-
// Validate form
|
|
466
|
+
// Validate form
|
|
430
467
|
var validateForm = (0, react_1.useCallback)(function () {
|
|
431
468
|
var newErrors = {};
|
|
432
469
|
var hasErrors = false;
|
|
433
|
-
|
|
470
|
+
parsedFields.forEach(function (field) {
|
|
434
471
|
var value = formValues[field.name];
|
|
435
472
|
var error = validateField(field, value);
|
|
436
473
|
if (error) {
|
|
@@ -440,8 +477,8 @@ var Form = function (_a) {
|
|
|
440
477
|
});
|
|
441
478
|
setErrors(newErrors);
|
|
442
479
|
return !hasErrors;
|
|
443
|
-
}, [
|
|
444
|
-
// Handle field change for checkboxes and radios
|
|
480
|
+
}, [parsedFields, validateField, formValues]);
|
|
481
|
+
// Handle field change for checkboxes and radios
|
|
445
482
|
var handleFieldChange = (0, react_1.useCallback)(function (fieldName, newValue) {
|
|
446
483
|
// Update form values
|
|
447
484
|
setFormValues(function (prev) {
|
|
@@ -454,7 +491,7 @@ var Form = function (_a) {
|
|
|
454
491
|
return (__assign(__assign({}, prev), (_a = {}, _a[fieldName] = true, _a)));
|
|
455
492
|
});
|
|
456
493
|
// Validate the changed field
|
|
457
|
-
var field =
|
|
494
|
+
var field = parsedFields.find(function (f) { return f.name === fieldName; });
|
|
458
495
|
if (!field)
|
|
459
496
|
return;
|
|
460
497
|
var error = validateField(field, newValue);
|
|
@@ -469,10 +506,12 @@ var Form = function (_a) {
|
|
|
469
506
|
return newErrors;
|
|
470
507
|
}
|
|
471
508
|
});
|
|
472
|
-
}, [
|
|
473
|
-
// Handle input
|
|
474
|
-
var
|
|
475
|
-
|
|
509
|
+
}, [parsedFields, validateField]);
|
|
510
|
+
// FIXED: Handle input change - pass event directly to Input component
|
|
511
|
+
var handleInputEventChange = (0, react_1.useCallback)(function (e) {
|
|
512
|
+
var fieldName = e.target.name;
|
|
513
|
+
var value = e.target.value;
|
|
514
|
+
// Update form values - PASS VALUE AS-IS (preserves spaces)
|
|
476
515
|
setFormValues(function (prev) {
|
|
477
516
|
var _a;
|
|
478
517
|
return (__assign(__assign({}, prev), (_a = {}, _a[fieldName] = value, _a)));
|
|
@@ -483,7 +522,7 @@ var Form = function (_a) {
|
|
|
483
522
|
return (__assign(__assign({}, prev), (_a = {}, _a[fieldName] = true, _a)));
|
|
484
523
|
});
|
|
485
524
|
// Validate the changed field
|
|
486
|
-
var field =
|
|
525
|
+
var field = parsedFields.find(function (f) { return f.name === fieldName; });
|
|
487
526
|
if (!field)
|
|
488
527
|
return;
|
|
489
528
|
var error = validateField(field, value);
|
|
@@ -498,15 +537,16 @@ var Form = function (_a) {
|
|
|
498
537
|
return newErrors;
|
|
499
538
|
}
|
|
500
539
|
});
|
|
501
|
-
}, [
|
|
502
|
-
// Handle
|
|
503
|
-
var
|
|
540
|
+
}, [parsedFields, validateField]);
|
|
541
|
+
// FIXED: Handle blur event - pass event directly to Input component
|
|
542
|
+
var handleInputEventBlur = (0, react_1.useCallback)(function (e) {
|
|
543
|
+
var fieldName = e.target.name;
|
|
504
544
|
setTouched(function (prev) {
|
|
505
545
|
var _a;
|
|
506
546
|
return (__assign(__assign({}, prev), (_a = {}, _a[fieldName] = true, _a)));
|
|
507
547
|
});
|
|
508
548
|
// Validate the field
|
|
509
|
-
var field =
|
|
549
|
+
var field = parsedFields.find(function (f) { return f.name === fieldName; });
|
|
510
550
|
if (!field)
|
|
511
551
|
return;
|
|
512
552
|
var value = formValues[fieldName];
|
|
@@ -522,8 +562,8 @@ var Form = function (_a) {
|
|
|
522
562
|
return newErrors;
|
|
523
563
|
}
|
|
524
564
|
});
|
|
525
|
-
}, [
|
|
526
|
-
// Handle form submission
|
|
565
|
+
}, [parsedFields, validateField, formValues]);
|
|
566
|
+
// Handle form submission
|
|
527
567
|
var handleSubmit = (0, react_1.useCallback)(function (e) { return __awaiter(void 0, void 0, void 0, function () {
|
|
528
568
|
var allTouched, isValid, firstErrorField, element, message, cleanPhone, whatsappUrl, error_1;
|
|
529
569
|
return __generator(this, function (_a) {
|
|
@@ -531,7 +571,7 @@ var Form = function (_a) {
|
|
|
531
571
|
case 0:
|
|
532
572
|
e.preventDefault();
|
|
533
573
|
allTouched = {};
|
|
534
|
-
|
|
574
|
+
parsedFields.forEach(function (field) {
|
|
535
575
|
allTouched[field.name] = true;
|
|
536
576
|
});
|
|
537
577
|
setTouched(allTouched);
|
|
@@ -549,20 +589,20 @@ var Form = function (_a) {
|
|
|
549
589
|
_a.label = 1;
|
|
550
590
|
case 1:
|
|
551
591
|
_a.trys.push([1, 7, 8, 9]);
|
|
552
|
-
if (!
|
|
553
|
-
message = formatWhatsAppMessage(formValues,
|
|
554
|
-
cleanPhone =
|
|
592
|
+
if (!whatsappContact) return [3 /*break*/, 4];
|
|
593
|
+
message = formatWhatsAppMessage(formValues, parsedFields, whatsappHeader, whatsappFooter);
|
|
594
|
+
cleanPhone = whatsappContact.replace(/[\s+\-()]/g, '');
|
|
555
595
|
whatsappUrl = "https://wa.me/".concat(cleanPhone, "?text=").concat(message);
|
|
556
596
|
window.open(whatsappUrl, '_blank');
|
|
557
|
-
if (!
|
|
558
|
-
return [4 /*yield*/,
|
|
597
|
+
if (!onSubmit) return [3 /*break*/, 3];
|
|
598
|
+
return [4 /*yield*/, onSubmit(formValues, true)];
|
|
559
599
|
case 2:
|
|
560
600
|
_a.sent();
|
|
561
601
|
_a.label = 3;
|
|
562
602
|
case 3: return [3 /*break*/, 6];
|
|
563
603
|
case 4:
|
|
564
|
-
if (!
|
|
565
|
-
return [4 /*yield*/,
|
|
604
|
+
if (!onSubmit) return [3 /*break*/, 6];
|
|
605
|
+
return [4 /*yield*/, onSubmit(formValues, false)];
|
|
566
606
|
case 5:
|
|
567
607
|
_a.sent();
|
|
568
608
|
_a.label = 6;
|
|
@@ -578,17 +618,17 @@ var Form = function (_a) {
|
|
|
578
618
|
case 9: return [2 /*return*/];
|
|
579
619
|
}
|
|
580
620
|
});
|
|
581
|
-
}); }, [
|
|
582
|
-
// Handle form reset
|
|
621
|
+
}); }, [parsedFields, validateForm, formValues, whatsappContact, whatsappHeader, whatsappFooter, onSubmit, errors]);
|
|
622
|
+
// Handle form reset
|
|
583
623
|
var handleReset = (0, react_1.useCallback)(function () {
|
|
584
624
|
// Reset to initial values
|
|
585
625
|
var initialValues = {};
|
|
586
|
-
|
|
626
|
+
parsedFields.forEach(function (field) {
|
|
587
627
|
if (field.value !== undefined) {
|
|
588
628
|
initialValues[field.name] = field.value;
|
|
589
629
|
}
|
|
590
|
-
else if (
|
|
591
|
-
initialValues[field.name] =
|
|
630
|
+
else if (parsedDefaultValues[field.name] !== undefined) {
|
|
631
|
+
initialValues[field.name] = parsedDefaultValues[field.name];
|
|
592
632
|
}
|
|
593
633
|
else {
|
|
594
634
|
if (field.type === 'checkbox' && field.multiple) {
|
|
@@ -605,8 +645,8 @@ var Form = function (_a) {
|
|
|
605
645
|
setFormValues(initialValues);
|
|
606
646
|
setErrors({});
|
|
607
647
|
setTouched({});
|
|
608
|
-
}, [
|
|
609
|
-
// Get field status for Input component
|
|
648
|
+
}, [parsedFields, parsedDefaultValues]);
|
|
649
|
+
// Get field status for Input component
|
|
610
650
|
var getFieldStatus = (0, react_1.useCallback)(function (fieldName) {
|
|
611
651
|
var error = errors[fieldName];
|
|
612
652
|
var isTouched = touched[fieldName];
|
|
@@ -617,10 +657,10 @@ var Form = function (_a) {
|
|
|
617
657
|
}
|
|
618
658
|
return undefined;
|
|
619
659
|
}, [errors, touched, formValues]);
|
|
620
|
-
// Check if form is valid for submission
|
|
660
|
+
// Check if form is valid for submission
|
|
621
661
|
var isFormValid = (0, react_1.useMemo)(function () {
|
|
622
662
|
// Check if any required fields are empty
|
|
623
|
-
var hasEmptyRequiredFields =
|
|
663
|
+
var hasEmptyRequiredFields = parsedFields.some(function (field) {
|
|
624
664
|
if (!field.required)
|
|
625
665
|
return false;
|
|
626
666
|
var value = formValues[field.name];
|
|
@@ -635,12 +675,12 @@ var Form = function (_a) {
|
|
|
635
675
|
// Check if there are any validation errors
|
|
636
676
|
var hasValidationErrors = Object.keys(errors).length > 0;
|
|
637
677
|
return !hasEmptyRequiredFields && !hasValidationErrors;
|
|
638
|
-
}, [
|
|
639
|
-
// Submit button disabled state
|
|
640
|
-
var isSubmitDisabled = isSubmitting ||
|
|
641
|
-
// Check if WhatsApp is configured
|
|
642
|
-
var hasWhatsApp = !!
|
|
643
|
-
// Render field based on type
|
|
678
|
+
}, [parsedFields, formValues, errors]);
|
|
679
|
+
// Submit button disabled state
|
|
680
|
+
var isSubmitDisabled = isSubmitting || isLoading || !isFormValid;
|
|
681
|
+
// Check if WhatsApp is configured
|
|
682
|
+
var hasWhatsApp = !!whatsappContact;
|
|
683
|
+
// Render field based on type - FIXED
|
|
644
684
|
var renderField = (0, react_1.useCallback)(function (field) {
|
|
645
685
|
var _a, _b, _c, _d, _e;
|
|
646
686
|
var status = getFieldStatus(field.name);
|
|
@@ -655,7 +695,7 @@ var Form = function (_a) {
|
|
|
655
695
|
// Generate unique ID for the input
|
|
656
696
|
var inputId = ((_a = field.inputProps) === null || _a === void 0 ? void 0 : _a.id) || "form-field-".concat(field.name);
|
|
657
697
|
// 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 ||
|
|
698
|
+
var baseProps = __assign({ id: inputId, name: field.name, label: field.label, placeholder: field.placeholder, helperText: helperText, disabled: field.disabled || isLoading, fullWidth: fullWidth }, field.inputProps);
|
|
659
699
|
// Only add status if it's not undefined
|
|
660
700
|
if (status !== undefined) {
|
|
661
701
|
baseProps.status = status;
|
|
@@ -682,13 +722,13 @@ var Form = function (_a) {
|
|
|
682
722
|
var newValues = checkedValues_1.filter(function (v) { return v !== option.value; });
|
|
683
723
|
handleFieldChange(field.name, newValues);
|
|
684
724
|
}
|
|
685
|
-
}, disabled: field.disabled || option.disabled ||
|
|
725
|
+
}, disabled: field.disabled || option.disabled || isLoading, required: field.required && index === 0, value: option.value }));
|
|
686
726
|
}))));
|
|
687
727
|
}
|
|
688
728
|
else {
|
|
689
729
|
// Single checkbox (boolean)
|
|
690
730
|
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 ||
|
|
731
|
+
react_1.default.createElement(FormCheckbox, { label: field.label, checked: !!value, onChange: function (checked) { return handleFieldChange(field.name, checked); }, disabled: field.disabled || isLoading, required: field.required, id: inputId })));
|
|
692
732
|
}
|
|
693
733
|
case 'radio':
|
|
694
734
|
if (!((_c = field.options) === null || _c === void 0 ? void 0 : _c.length))
|
|
@@ -696,29 +736,32 @@ var Form = function (_a) {
|
|
|
696
736
|
return (react_1.default.createElement("div", { key: field.name, className: wrapperClass },
|
|
697
737
|
field.label && (react_1.default.createElement("div", { className: "form-label", style: { marginBottom: '0.5rem' } },
|
|
698
738
|
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 ||
|
|
739
|
+
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 || isLoading, required: field.required && index === 0, value: option.value })); }))));
|
|
700
740
|
case 'textarea':
|
|
701
741
|
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:
|
|
742
|
+
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: handleInputEventChange, onBlur: handleInputEventBlur }, baseProps))));
|
|
703
743
|
case 'select':
|
|
704
744
|
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:
|
|
745
|
+
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: handleInputEventChange, onBlur: handleInputEventBlur }, baseProps))));
|
|
706
746
|
default:
|
|
707
747
|
// text, email, number, tel, date, file, password
|
|
708
748
|
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:
|
|
749
|
+
react_1.default.createElement(Input_1.default, __assign({ type: field.type, value: value || '', onChange: handleInputEventChange, onBlur: handleInputEventBlur }, baseProps))));
|
|
710
750
|
}
|
|
711
|
-
}, [errors, touched, formValues,
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
751
|
+
}, [errors, touched, formValues, isLoading, getFieldStatus, handleFieldChange, handleInputEventChange, handleInputEventBlur, fullWidth]);
|
|
752
|
+
// Don't render if no fields are configured
|
|
753
|
+
if (parsedFields.length === 0) {
|
|
754
|
+
console.warn('Form: No fields configured. Please provide fields prop or configure via theme.');
|
|
755
|
+
return null;
|
|
756
|
+
}
|
|
757
|
+
return (react_1.default.createElement("div", { className: "form-wrapper ".concat(centered ? 'center' : '', " ").concat(className), style: { width: "100%", maxWidth: width || "450px" } },
|
|
758
|
+
title && (react_1.default.createElement("div", { className: "form-header", style: { marginBottom: '2rem' } },
|
|
759
|
+
react_1.default.createElement(Text_1.default, { text: title, size: titleSize || "3xl", color: titleColor || "", block: true }),
|
|
760
|
+
description && (react_1.default.createElement(Text_1.default, { article: true, size: descriptionSize || "sm", color: descriptionColor || "" },
|
|
761
|
+
react_1.default.createElement("div", { className: "article text-sm", dangerouslySetInnerHTML: { __html: description } }))))),
|
|
717
762
|
react_1.default.createElement("form", { className: "form", onSubmit: handleSubmit, style: { width: '100%' } },
|
|
718
|
-
react_1.default.createElement(Flex_1.default, { direction:
|
|
719
|
-
react_1.default.createElement(Flex_1.default, { direction: "column", gap: "1rem", style: { marginTop: '2rem', width:
|
|
720
|
-
react_1.default.createElement(Button_1.default, { type: "submit", text: hasWhatsApp ? "Send via WhatsApp" :
|
|
721
|
-
// startIcon={hasWhatsApp ? <PiWhatsappLogo /> : <PiPaperPlaneTilt />}
|
|
722
|
-
disabled: isSubmitDisabled, isLoading: isSubmitting || finalIsLoading, fullWidth: finalFullWidth })))));
|
|
763
|
+
react_1.default.createElement(Flex_1.default, { direction: layout === 'horizontal' ? 'row' : 'column', gap: gap, width: '100%' }, parsedFields.map(renderField)),
|
|
764
|
+
react_1.default.createElement(Flex_1.default, { direction: "column", gap: "1rem", style: { marginTop: '2rem', width: fullWidth ? '100%' : undefined } },
|
|
765
|
+
react_1.default.createElement(Button_1.default, { type: "submit", text: hasWhatsApp ? "Send via WhatsApp" : submitText, bg: submitBg || "primary", raised: true, prefix: submitPrefix || hasWhatsApp ? react_1.default.createElement(pi_1.PiWhatsappLogo, null) : react_1.default.createElement(pi_1.PiPaperPlaneTilt, null), suffix: submitSuffix, disabled: isSubmitDisabled, isLoading: isSubmitting || isLoading, fullWidth: fullWidth })))));
|
|
723
766
|
};
|
|
724
767
|
exports.default = Form;
|