funuicss 3.8.8 → 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.
- package/css/fun.css +311 -0
- package/index.d.ts +2 -0
- package/index.js +6 -2
- package/package.json +1 -1
- package/ui/button/Button.d.ts +4 -4
- package/ui/button/Button.js +187 -82
- package/ui/feature/Feature.d.ts +9 -38
- package/ui/feature/Feature.js +62 -147
- package/ui/flex/Flex.d.ts +11 -10
- package/ui/flex/Flex.js +102 -6
- package/ui/form/Form.d.ts +21 -12
- package/ui/form/Form.js +382 -316
- package/ui/input/Input.d.ts +16 -21
- package/ui/input/Input.js +135 -359
- package/ui/products/ProductDetail.js +31 -23
- package/ui/products/Store.js +5 -5
- package/ui/sidebar/SideBar.js +1 -2
- package/ui/specials/CircleGroup.d.ts +2 -1
- package/ui/specials/CircleGroup.js +3 -3
package/ui/form/Form.js
CHANGED
|
@@ -97,10 +97,44 @@ var react_1 = __importStar(require("react"));
|
|
|
97
97
|
var Button_1 = __importDefault(require("../button/Button"));
|
|
98
98
|
var Input_1 = __importDefault(require("../input/Input"));
|
|
99
99
|
var Flex_1 = __importDefault(require("../flex/Flex"));
|
|
100
|
-
var Div_1 = __importDefault(require("../div/Div"));
|
|
101
100
|
var Text_1 = __importDefault(require("../text/Text"));
|
|
102
101
|
var pi_1 = require("react-icons/pi");
|
|
103
|
-
|
|
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)
|
|
104
138
|
var FormCheckbox = function (_a) {
|
|
105
139
|
var label = _a.label, checked = _a.checked, onChange = _a.onChange, disabled = _a.disabled, required = _a.required, value = _a.value, id = _a.id;
|
|
106
140
|
return (react_1.default.createElement("label", { className: "funui_form-checkbox", style: {
|
|
@@ -110,12 +144,19 @@ var FormCheckbox = function (_a) {
|
|
|
110
144
|
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
111
145
|
userSelect: 'none',
|
|
112
146
|
width: 'fit-content',
|
|
147
|
+
padding: '0.25rem 0',
|
|
113
148
|
} },
|
|
114
|
-
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: {
|
|
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
|
+
} }),
|
|
115
156
|
react_1.default.createElement("div", { className: "funui_form-checkbox-box", style: {
|
|
116
157
|
width: '1.25rem',
|
|
117
158
|
height: '1.25rem',
|
|
118
|
-
border: checked ? '2px solid var(--primary)' : '2px solid var(--
|
|
159
|
+
border: checked ? '2px solid var(--primary)' : '2px solid var(--borderColor)',
|
|
119
160
|
borderRadius: '0.25rem',
|
|
120
161
|
backgroundColor: checked ? 'var(--primary)' : 'transparent',
|
|
121
162
|
position: 'relative',
|
|
@@ -124,17 +165,22 @@ var FormCheckbox = function (_a) {
|
|
|
124
165
|
alignItems: 'center',
|
|
125
166
|
justifyContent: 'center',
|
|
126
167
|
flexShrink: 0,
|
|
127
|
-
} }, checked && (react_1.default.createElement("
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
} }
|
|
133
|
-
|
|
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
|
+
} },
|
|
134
180
|
label,
|
|
135
181
|
required && ' *'))));
|
|
136
182
|
};
|
|
137
|
-
// Custom Radio Component
|
|
183
|
+
// Custom Radio Component (unchanged)
|
|
138
184
|
var FormRadio = function (_a) {
|
|
139
185
|
var label = _a.label, checked = _a.checked, onChange = _a.onChange, disabled = _a.disabled, required = _a.required, value = _a.value, id = _a.id;
|
|
140
186
|
return (react_1.default.createElement("label", { className: "funui_form-radio", style: {
|
|
@@ -144,12 +190,19 @@ var FormRadio = function (_a) {
|
|
|
144
190
|
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
145
191
|
userSelect: 'none',
|
|
146
192
|
width: 'fit-content',
|
|
193
|
+
padding: '0.25rem 0',
|
|
147
194
|
} },
|
|
148
|
-
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: {
|
|
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
|
+
} }),
|
|
149
202
|
react_1.default.createElement("div", { className: "funui_form-radio-circle", style: {
|
|
150
203
|
width: '1.25rem',
|
|
151
204
|
height: '1.25rem',
|
|
152
|
-
border: checked ? '2px solid var(--primary)' : '2px solid var(--
|
|
205
|
+
border: checked ? '2px solid var(--primary)' : '2px solid var(--borderColor)',
|
|
153
206
|
borderRadius: '50%',
|
|
154
207
|
backgroundColor: 'transparent',
|
|
155
208
|
position: 'relative',
|
|
@@ -164,33 +217,30 @@ var FormRadio = function (_a) {
|
|
|
164
217
|
backgroundColor: 'var(--primary)',
|
|
165
218
|
borderRadius: '50%',
|
|
166
219
|
} }))),
|
|
167
|
-
label && (react_1.default.createElement("span", { className: "funui_form-radio-label", style: {
|
|
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
|
+
} },
|
|
168
225
|
label,
|
|
169
226
|
required && ' *'))));
|
|
170
227
|
};
|
|
171
|
-
//
|
|
172
|
-
var
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
display: 'flex',
|
|
181
|
-
alignItems: 'center',
|
|
182
|
-
justifyContent: 'center',
|
|
183
|
-
}, "aria-label": isVisible ? 'Hide password' : 'Show password' }, isVisible ? react_1.default.createElement(pi_1.PiEyeSlash, { size: 18 }) : react_1.default.createElement(pi_1.PiEye, { size: 18 })));
|
|
184
|
-
};
|
|
185
|
-
// WhatsApp Button Component
|
|
186
|
-
var WhatsAppButton = function (_a) {
|
|
187
|
-
var onClick = _a.onClick, disabled = _a.disabled, _b = _a.text, text = _b === void 0 ? 'Send via WhatsApp' : _b;
|
|
188
|
-
return (react_1.default.createElement(Button_1.default, { type: "button", text: text, bg: "#25D366", color: "white", raised: true, startIcon: react_1.default.createElement(pi_1.PiWhatsappLogo, null), disabled: disabled, onClick: onClick, funcss: "funui_form-whatsapp-button" }));
|
|
189
|
-
};
|
|
190
|
-
// Function to format WhatsApp message
|
|
191
|
-
var formatWhatsAppMessage = function (values, fields, headerMessage, footerMessage) {
|
|
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
|
|
192
237
|
var fieldLines = fields
|
|
193
|
-
.filter(function (field) {
|
|
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
|
+
})
|
|
194
244
|
.map(function (field) {
|
|
195
245
|
var value = values[field.name];
|
|
196
246
|
var displayValue = value;
|
|
@@ -210,69 +260,92 @@ var formatWhatsAppMessage = function (values, fields, headerMessage, footerMessa
|
|
|
210
260
|
return "*".concat(field.label || field.name, ":* ").concat(displayValue);
|
|
211
261
|
})
|
|
212
262
|
.join('\n');
|
|
213
|
-
var message = '';
|
|
214
|
-
if (headerMessage) {
|
|
215
|
-
message += "".concat(headerMessage, "\n\n");
|
|
216
|
-
}
|
|
217
263
|
message += fieldLines;
|
|
218
|
-
if
|
|
219
|
-
|
|
264
|
+
// Add footer if provided
|
|
265
|
+
if (footer) {
|
|
266
|
+
message += "\n\n".concat(footer);
|
|
220
267
|
}
|
|
221
268
|
return encodeURIComponent(message);
|
|
222
269
|
};
|
|
223
270
|
// Main Form Component
|
|
224
271
|
var Form = function (_a) {
|
|
225
|
-
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.
|
|
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;
|
|
226
313
|
// State management
|
|
227
|
-
var
|
|
228
|
-
var
|
|
229
|
-
var
|
|
230
|
-
|
|
231
|
-
var _p = (0, react_1.useState)(false), isSubmitting = _p[0], setIsSubmitting = _p[1];
|
|
232
|
-
var _q = (0, react_1.useState)(''), whatsappPhone = _q[0], setWhatsappPhone = _q[1];
|
|
233
|
-
// Initialize form values
|
|
234
|
-
(0, react_1.useEffect)(function () {
|
|
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
|
|
235
318
|
var initialValues = {};
|
|
236
|
-
|
|
237
|
-
var _a, _b;
|
|
238
|
-
// Priority: field.value > defaultValues > default based on type
|
|
319
|
+
finalFields.forEach(function (field) {
|
|
239
320
|
if (field.value !== undefined) {
|
|
240
321
|
initialValues[field.name] = field.value;
|
|
241
322
|
}
|
|
242
|
-
else if (
|
|
243
|
-
initialValues[field.name] =
|
|
244
|
-
}
|
|
245
|
-
else if (field.type === 'checkbox') {
|
|
246
|
-
initialValues[field.name] = field.multiple ? [] : false;
|
|
247
|
-
}
|
|
248
|
-
else if (field.type === 'radio' && ((_a = field.options) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
249
|
-
initialValues[field.name] = '';
|
|
250
|
-
}
|
|
251
|
-
else if (field.type === 'select' && ((_b = field.options) === null || _b === void 0 ? void 0 : _b.length)) {
|
|
252
|
-
initialValues[field.name] = '';
|
|
323
|
+
else if (finalDefaultValues[field.name] !== undefined) {
|
|
324
|
+
initialValues[field.name] = finalDefaultValues[field.name];
|
|
253
325
|
}
|
|
254
326
|
else {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
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
|
+
}
|
|
263
337
|
}
|
|
264
338
|
});
|
|
265
|
-
|
|
266
|
-
}, [
|
|
267
|
-
|
|
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
|
|
268
343
|
(0, react_1.useEffect)(function () {
|
|
269
|
-
if (
|
|
270
|
-
|
|
271
|
-
var cleanPhone = whatsappIntegration.phoneNumber.replace(/[\s+\-()]/g, '');
|
|
272
|
-
setWhatsappPhone(cleanPhone);
|
|
344
|
+
if (Object.keys(finalDefaultValues).length > 0) {
|
|
345
|
+
setFormValues(function (prev) { return (__assign(__assign({}, prev), finalDefaultValues)); });
|
|
273
346
|
}
|
|
274
|
-
}, [
|
|
275
|
-
// Validate a single field
|
|
347
|
+
}, [finalDefaultValues]);
|
|
348
|
+
// Validate a single field (unchanged)
|
|
276
349
|
var validateField = (0, react_1.useCallback)(function (field, value) {
|
|
277
350
|
var _a, _b, _c, _d, _e;
|
|
278
351
|
// Required validation
|
|
@@ -287,10 +360,10 @@ var Form = function (_a) {
|
|
|
287
360
|
return "".concat(field.label || field.name, " is required");
|
|
288
361
|
}
|
|
289
362
|
}
|
|
290
|
-
// Type-specific validations
|
|
291
|
-
if (value && value !== '') {
|
|
363
|
+
// Type-specific validations (only for non-empty values)
|
|
364
|
+
if (value && (typeof value !== 'string' || value !== '')) {
|
|
292
365
|
// Email validation
|
|
293
|
-
if (field.type === 'email') {
|
|
366
|
+
if (field.type === 'email' && typeof value === 'string') {
|
|
294
367
|
var emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
295
368
|
if (!emailRegex.test(value)) {
|
|
296
369
|
return 'Please enter a valid email address';
|
|
@@ -298,7 +371,16 @@ var Form = function (_a) {
|
|
|
298
371
|
}
|
|
299
372
|
// Number validation
|
|
300
373
|
if (field.type === 'number') {
|
|
301
|
-
var numValue =
|
|
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
|
+
}
|
|
302
384
|
if (isNaN(numValue)) {
|
|
303
385
|
return 'Please enter a valid number';
|
|
304
386
|
}
|
|
@@ -311,14 +393,14 @@ var Form = function (_a) {
|
|
|
311
393
|
return "Maximum value is ".concat(max);
|
|
312
394
|
}
|
|
313
395
|
}
|
|
314
|
-
// Phone validation (basic)
|
|
315
|
-
if (field.type === 'tel') {
|
|
396
|
+
// Phone validation (basic) - only for strings
|
|
397
|
+
if (field.type === 'tel' && typeof value === 'string') {
|
|
316
398
|
var phoneRegex = /^[\+]?[1-9][\d]{0,17}$/;
|
|
317
399
|
if (!phoneRegex.test(value.replace(/[\s+\-()]/g, ''))) {
|
|
318
400
|
return 'Please enter a valid phone number';
|
|
319
401
|
}
|
|
320
402
|
}
|
|
321
|
-
// Length validation
|
|
403
|
+
// Length validation for strings
|
|
322
404
|
if (typeof value === 'string') {
|
|
323
405
|
var minLength = (_c = field.inputProps) === null || _c === void 0 ? void 0 : _c.minLength;
|
|
324
406
|
var maxLength = (_d = field.inputProps) === null || _d === void 0 ? void 0 : _d.maxLength;
|
|
@@ -329,53 +411,81 @@ var Form = function (_a) {
|
|
|
329
411
|
return "Maximum ".concat(maxLength, " characters allowed");
|
|
330
412
|
}
|
|
331
413
|
}
|
|
332
|
-
// Pattern validation if provided
|
|
333
|
-
if ((_e = field.inputProps) === null || _e === void 0 ? void 0 : _e.pattern) {
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
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);
|
|
337
424
|
}
|
|
338
425
|
}
|
|
339
426
|
}
|
|
340
427
|
return null;
|
|
341
428
|
}, []);
|
|
342
|
-
//
|
|
343
|
-
var
|
|
344
|
-
var
|
|
345
|
-
|
|
346
|
-
|
|
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
|
|
347
447
|
setFormValues(function (prev) {
|
|
348
448
|
var _a;
|
|
349
|
-
|
|
350
|
-
// Validate on change if field has been touched
|
|
351
|
-
if (touched[fieldName]) {
|
|
352
|
-
var error_1 = validateField(field, value);
|
|
353
|
-
setErrors(function (prevErrors) {
|
|
354
|
-
var _a;
|
|
355
|
-
if (error_1) {
|
|
356
|
-
return __assign(__assign({}, prevErrors), (_a = {}, _a[fieldName] = error_1, _a));
|
|
357
|
-
}
|
|
358
|
-
else {
|
|
359
|
-
var newErrors = __assign({}, prevErrors);
|
|
360
|
-
delete newErrors[fieldName];
|
|
361
|
-
return newErrors;
|
|
362
|
-
}
|
|
363
|
-
});
|
|
364
|
-
}
|
|
365
|
-
return newValues;
|
|
449
|
+
return (__assign(__assign({}, prev), (_a = {}, _a[fieldName] = newValue, _a)));
|
|
366
450
|
});
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
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; });
|
|
371
458
|
if (!field)
|
|
372
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
|
|
373
481
|
setTouched(function (prev) {
|
|
374
482
|
var _a;
|
|
375
483
|
return (__assign(__assign({}, prev), (_a = {}, _a[fieldName] = true, _a)));
|
|
376
484
|
});
|
|
377
|
-
// Validate
|
|
378
|
-
var
|
|
485
|
+
// Validate the changed field
|
|
486
|
+
var field = finalFields.find(function (f) { return f.name === fieldName; });
|
|
487
|
+
if (!field)
|
|
488
|
+
return;
|
|
379
489
|
var error = validateField(field, value);
|
|
380
490
|
setErrors(function (prev) {
|
|
381
491
|
var _a;
|
|
@@ -388,271 +498,227 @@ var Form = function (_a) {
|
|
|
388
498
|
return newErrors;
|
|
389
499
|
}
|
|
390
500
|
});
|
|
391
|
-
}, [
|
|
392
|
-
//
|
|
393
|
-
var
|
|
394
|
-
|
|
501
|
+
}, [finalFields, validateField]);
|
|
502
|
+
// Handle field blur (unchanged)
|
|
503
|
+
var handleFieldBlur = (0, react_1.useCallback)(function (fieldName) {
|
|
504
|
+
setTouched(function (prev) {
|
|
395
505
|
var _a;
|
|
396
|
-
return (__assign(__assign({}, prev), (_a = {}, _a[fieldName] =
|
|
506
|
+
return (__assign(__assign({}, prev), (_a = {}, _a[fieldName] = true, _a)));
|
|
397
507
|
});
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
if (!(whatsappIntegration === null || whatsappIntegration === void 0 ? void 0 : whatsappIntegration.enabled) || !whatsappPhone) {
|
|
402
|
-
console.error('WhatsApp integration not properly configured');
|
|
508
|
+
// Validate the field
|
|
509
|
+
var field = finalFields.find(function (f) { return f.name === fieldName; });
|
|
510
|
+
if (!field)
|
|
403
511
|
return;
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
fields.forEach(function (field) {
|
|
409
|
-
var value = formValues[field.name];
|
|
410
|
-
var error = validateField(field, value);
|
|
512
|
+
var value = formValues[fieldName];
|
|
513
|
+
var error = validateField(field, value);
|
|
514
|
+
setErrors(function (prev) {
|
|
515
|
+
var _a;
|
|
411
516
|
if (error) {
|
|
412
|
-
|
|
413
|
-
|
|
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;
|
|
414
523
|
}
|
|
415
524
|
});
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
// Mark all fields as touched to show errors
|
|
419
|
-
var allTouched_1 = {};
|
|
420
|
-
fields.forEach(function (field) {
|
|
421
|
-
allTouched_1[field.name] = true;
|
|
422
|
-
});
|
|
423
|
-
setTouched(allTouched_1);
|
|
424
|
-
return;
|
|
425
|
-
}
|
|
426
|
-
// Format the message
|
|
427
|
-
var message = formatWhatsAppMessage(formValues, fields, whatsappIntegration.headerMessage, whatsappIntegration.footerMessage);
|
|
428
|
-
// Create WhatsApp URL
|
|
429
|
-
var whatsappUrl = "https://wa.me/".concat(whatsappPhone, "?text=").concat(message);
|
|
430
|
-
// Open WhatsApp in new tab
|
|
431
|
-
window.open(whatsappUrl, '_blank');
|
|
432
|
-
}, [whatsappIntegration, whatsappPhone, fields, formValues, validateField]);
|
|
433
|
-
// Handle form submission
|
|
525
|
+
}, [finalFields, validateField, formValues]);
|
|
526
|
+
// Handle form submission (unchanged)
|
|
434
527
|
var handleSubmit = (0, react_1.useCallback)(function (e) { return __awaiter(void 0, void 0, void 0, function () {
|
|
435
|
-
var allTouched,
|
|
528
|
+
var allTouched, isValid, firstErrorField, element, message, cleanPhone, whatsappUrl, error_1;
|
|
436
529
|
return __generator(this, function (_a) {
|
|
437
530
|
switch (_a.label) {
|
|
438
531
|
case 0:
|
|
439
532
|
e.preventDefault();
|
|
440
533
|
allTouched = {};
|
|
441
|
-
|
|
534
|
+
finalFields.forEach(function (field) {
|
|
442
535
|
allTouched[field.name] = true;
|
|
443
536
|
});
|
|
444
537
|
setTouched(allTouched);
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
newErrors[field.name] = error;
|
|
452
|
-
hasErrors = true;
|
|
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' });
|
|
453
544
|
}
|
|
454
|
-
});
|
|
455
|
-
setErrors(newErrors);
|
|
456
|
-
if (hasErrors)
|
|
457
545
|
return [2 /*return*/];
|
|
458
|
-
|
|
546
|
+
}
|
|
547
|
+
// Get form data and submit
|
|
459
548
|
setIsSubmitting(true);
|
|
460
549
|
_a.label = 1;
|
|
461
550
|
case 1:
|
|
462
|
-
_a.trys.push([1,
|
|
463
|
-
return [
|
|
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)];
|
|
464
559
|
case 2:
|
|
465
560
|
_a.sent();
|
|
466
|
-
|
|
467
|
-
case 3:
|
|
468
|
-
error_2 = _a.sent();
|
|
469
|
-
console.error('Form submission error:', error_2);
|
|
470
|
-
setErrors(function (prev) { return (__assign(__assign({}, prev), { _form: 'There was an error submitting the form. Please try again.' })); });
|
|
471
|
-
return [3 /*break*/, 5];
|
|
561
|
+
_a.label = 3;
|
|
562
|
+
case 3: return [3 /*break*/, 6];
|
|
472
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:
|
|
473
576
|
setIsSubmitting(false);
|
|
474
577
|
return [7 /*endfinally*/];
|
|
475
|
-
case
|
|
578
|
+
case 9: return [2 /*return*/];
|
|
476
579
|
}
|
|
477
580
|
});
|
|
478
|
-
}); }, [
|
|
479
|
-
// Handle form reset
|
|
581
|
+
}); }, [finalFields, validateForm, formValues, finalWhatsappContact, finalWhatsappHeader, finalWhatsappFooter, finalOnSubmit, errors]);
|
|
582
|
+
// Handle form reset (unchanged)
|
|
480
583
|
var handleReset = (0, react_1.useCallback)(function () {
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
if (field.
|
|
485
|
-
|
|
486
|
-
}
|
|
487
|
-
else if (field.type === 'radio' && ((_a = field.options) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
488
|
-
resetValues[field.name] = '';
|
|
584
|
+
// Reset to initial values
|
|
585
|
+
var initialValues = {};
|
|
586
|
+
finalFields.forEach(function (field) {
|
|
587
|
+
if (field.value !== undefined) {
|
|
588
|
+
initialValues[field.name] = field.value;
|
|
489
589
|
}
|
|
490
|
-
else if (field.
|
|
491
|
-
|
|
590
|
+
else if (finalDefaultValues[field.name] !== undefined) {
|
|
591
|
+
initialValues[field.name] = finalDefaultValues[field.name];
|
|
492
592
|
}
|
|
493
593
|
else {
|
|
494
|
-
|
|
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
|
+
}
|
|
495
603
|
}
|
|
496
604
|
});
|
|
497
|
-
setFormValues(
|
|
605
|
+
setFormValues(initialValues);
|
|
498
606
|
setErrors({});
|
|
499
607
|
setTouched({});
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
// Get field status for Input component
|
|
608
|
+
}, [finalFields, finalDefaultValues]);
|
|
609
|
+
// Get field status for Input component (unchanged)
|
|
503
610
|
var getFieldStatus = (0, react_1.useCallback)(function (fieldName) {
|
|
504
611
|
var error = errors[fieldName];
|
|
505
612
|
var isTouched = touched[fieldName];
|
|
506
|
-
var value = formValues[fieldName];
|
|
507
613
|
if (error)
|
|
508
|
-
return '
|
|
509
|
-
if (isTouched && !error &&
|
|
614
|
+
return 'danger';
|
|
615
|
+
if (isTouched && !error && formValues[fieldName] !== '') {
|
|
510
616
|
return 'success';
|
|
511
617
|
}
|
|
512
|
-
return
|
|
618
|
+
return undefined;
|
|
513
619
|
}, [errors, touched, formValues]);
|
|
514
|
-
//
|
|
515
|
-
var
|
|
516
|
-
if
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
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;
|
|
523
629
|
}
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
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)
|
|
528
644
|
var renderField = (0, react_1.useCallback)(function (field) {
|
|
529
|
-
var _a, _b, _c, _d, _e
|
|
530
|
-
var value = (_a = formValues[field.name]) !== null && _a !== void 0 ? _a : '';
|
|
645
|
+
var _a, _b, _c, _d, _e;
|
|
531
646
|
var status = getFieldStatus(field.name);
|
|
532
647
|
var error = errors[field.name];
|
|
533
648
|
var isTouched = touched[field.name];
|
|
534
649
|
var showError = error && isTouched;
|
|
650
|
+
var value = formValues[field.name];
|
|
535
651
|
// Field wrapper classes
|
|
536
|
-
var wrapperClass = "
|
|
652
|
+
var wrapperClass = "col min-w-200 field ".concat(showError ? 'field-error' : '').trim();
|
|
537
653
|
// Helper text (error takes priority)
|
|
538
654
|
var helperText = showError ? error : field.helperText;
|
|
539
|
-
|
|
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);
|
|
540
657
|
// Base props for Input component
|
|
541
|
-
var baseProps = __assign({ id:
|
|
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
|
+
}
|
|
542
663
|
// Render based on field type
|
|
543
664
|
switch (field.type) {
|
|
544
665
|
case 'checkbox':
|
|
545
|
-
if ((
|
|
666
|
+
if ((_b = field.options) === null || _b === void 0 ? void 0 : _b.length) {
|
|
546
667
|
// Multiple checkboxes (checkbox group)
|
|
547
|
-
|
|
548
|
-
|
|
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' } },
|
|
549
671
|
react_1.default.createElement(Text_1.default, { text: field.label + (field.required ? ' *' : ''), size: "sm", color: "text", bold: true }))),
|
|
550
672
|
react_1.default.createElement(Flex_1.default, { direction: "column", gap: "0.5rem" }, field.options.map(function (option, index) {
|
|
551
|
-
var isChecked =
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
if (checked) {
|
|
558
|
-
handleFieldChange(field.name, __spreadArray(__spreadArray([], currentValues, true), [option.value], false));
|
|
559
|
-
}
|
|
560
|
-
else {
|
|
561
|
-
handleFieldChange(field.name, currentValues.filter(function (v) { return v !== option.value; }));
|
|
562
|
-
}
|
|
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);
|
|
563
679
|
}
|
|
564
680
|
else {
|
|
565
|
-
|
|
681
|
+
// Remove value from array
|
|
682
|
+
var newValues = checkedValues_1.filter(function (v) { return v !== option.value; });
|
|
683
|
+
handleFieldChange(field.name, newValues);
|
|
566
684
|
}
|
|
567
|
-
}, disabled: field.disabled || option.disabled ||
|
|
685
|
+
}, disabled: field.disabled || option.disabled || finalIsLoading, required: field.required && index === 0, value: option.value }));
|
|
568
686
|
}))));
|
|
569
687
|
}
|
|
570
688
|
else {
|
|
571
689
|
// Single checkbox (boolean)
|
|
572
|
-
return (react_1.default.createElement(
|
|
573
|
-
react_1.default.createElement(FormCheckbox, { label: field.label, checked: !!value, onChange: function (checked) { return handleFieldChange(field.name, checked); }, disabled: field.disabled ||
|
|
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 })));
|
|
574
692
|
}
|
|
575
693
|
case 'radio':
|
|
576
|
-
if (!((
|
|
694
|
+
if (!((_c = field.options) === null || _c === void 0 ? void 0 : _c.length))
|
|
577
695
|
return null;
|
|
578
|
-
return (react_1.default.createElement(
|
|
579
|
-
field.label && (react_1.default.createElement("div", { className: "
|
|
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' } },
|
|
580
698
|
react_1.default.createElement(Text_1.default, { text: field.label + (field.required ? ' *' : ''), size: "sm", color: "text", bold: true }))),
|
|
581
|
-
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(
|
|
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 })); }))));
|
|
582
700
|
case 'textarea':
|
|
583
|
-
return (react_1.default.createElement(
|
|
584
|
-
react_1.default.createElement(Input_1.default, { multiline: true, rows: ((
|
|
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))));
|
|
585
703
|
case 'select':
|
|
586
|
-
return (react_1.default.createElement(
|
|
587
|
-
react_1.default.createElement(Input_1.default, { select: true, options: ((
|
|
588
|
-
case 'password':
|
|
589
|
-
return (react_1.default.createElement(Div_1.default, { key: field.name, className: wrapperClass },
|
|
590
|
-
react_1.default.createElement(Input_1.default, { type: showPassword[field.name] ? 'text' : 'password', value: value, onChange: function (e) { return handleFieldChange(field.name, e.target.value); }, onBlur: function () { return handleFieldBlur(field.name); }, endIcon: react_1.default.createElement(PasswordToggle, { isVisible: !!showPassword[field.name], onToggle: function () { return togglePasswordVisibility(field.name); }, disabled: field.disabled || isLoading }) })));
|
|
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))));
|
|
591
706
|
default:
|
|
592
|
-
// text, email, number, tel, date, file
|
|
593
|
-
return (react_1.default.createElement(
|
|
594
|
-
react_1.default.createElement(Input_1.default, { type: field.type, value: value, onChange: function (e) { return
|
|
595
|
-
}
|
|
596
|
-
}, [formValues, errors, touched, showPassword, isLoading, getFieldStatus, getColumnClass, handleFieldChange, handleFieldBlur, togglePasswordVisibility]);
|
|
597
|
-
// Check if form is valid
|
|
598
|
-
var isFormValid = (0, react_1.useMemo)(function () {
|
|
599
|
-
return Object.keys(errors).length === 0;
|
|
600
|
-
}, [errors]);
|
|
601
|
-
// Check if form has empty required fields
|
|
602
|
-
var hasEmptyRequiredFields = (0, react_1.useMemo)(function () {
|
|
603
|
-
return fields.some(function (field) {
|
|
604
|
-
if (!field.required)
|
|
605
|
-
return false;
|
|
606
|
-
var value = formValues[field.name];
|
|
607
|
-
if (field.type === 'checkbox' && field.multiple) {
|
|
608
|
-
return !Array.isArray(value) || value.length === 0;
|
|
609
|
-
}
|
|
610
|
-
if (field.type === 'checkbox' && !field.multiple) {
|
|
611
|
-
return value === false;
|
|
612
|
-
}
|
|
613
|
-
return value === undefined || value === null || value === '';
|
|
614
|
-
});
|
|
615
|
-
}, [fields, formValues]);
|
|
616
|
-
// Submit button disabled state
|
|
617
|
-
var isSubmitDisabled = isSubmitting || isLoading || (!isFormValid && hasEmptyRequiredFields);
|
|
618
|
-
// WhatsApp button disabled state
|
|
619
|
-
var isWhatsAppDisabled = isSubmitDisabled || !whatsappPhone;
|
|
620
|
-
// Layout container
|
|
621
|
-
var LayoutContainer = (0, react_1.useMemo)(function () {
|
|
622
|
-
if (layout === 'grid') {
|
|
623
|
-
return function (_a) {
|
|
624
|
-
var children = _a.children;
|
|
625
|
-
return (react_1.default.createElement("div", { className: "funui_form-grid", style: { display: 'grid', gap: gap, gridTemplateColumns: 'repeat(auto-fit, minmax(250px, 1fr))' } }, children));
|
|
626
|
-
};
|
|
627
|
-
}
|
|
628
|
-
else if (layout === 'horizontal') {
|
|
629
|
-
return function (_a) {
|
|
630
|
-
var children = _a.children;
|
|
631
|
-
return (react_1.default.createElement(Flex_1.default, { gap: gap, wrap: "wrap" }, children));
|
|
632
|
-
};
|
|
633
|
-
}
|
|
634
|
-
else {
|
|
635
|
-
// vertical layout (default)
|
|
636
|
-
return function (_a) {
|
|
637
|
-
var children = _a.children;
|
|
638
|
-
return (react_1.default.createElement(Flex_1.default, { direction: "column", gap: gap }, children));
|
|
639
|
-
};
|
|
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))));
|
|
640
710
|
}
|
|
641
|
-
}, [
|
|
642
|
-
return (react_1.default.createElement("
|
|
643
|
-
|
|
644
|
-
react_1.default.createElement(
|
|
645
|
-
|
|
646
|
-
react_1.default.createElement(
|
|
647
|
-
|
|
648
|
-
react_1.default.createElement(Flex_1.default, { gap:
|
|
649
|
-
|
|
650
|
-
react_1.default.createElement(
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
react_1.default.createElement(Flex_1.default, { gap: "1rem", alignItems: "center", justify: "space-between", wrap: "wrap" },
|
|
654
|
-
showReset && (react_1.default.createElement(Button_1.default, { type: "reset", text: resetText, bg: "light", color: "text", disabled: isSubmitting || isLoading, funcss: "funui_form-reset-btn" })),
|
|
655
|
-
react_1.default.createElement(Button_1.default, { type: "submit", text: submitText, bg: "primary", color: "white", raised: true, startIcon: react_1.default.createElement(pi_1.PiPaperPlaneTilt, null), disabled: isSubmitDisabled, isLoading: isSubmitting || isLoading, funcss: "funui_form-submit-btn" })),
|
|
656
|
-
(whatsappIntegration === null || whatsappIntegration === void 0 ? void 0 : whatsappIntegration.enabled) && whatsappPhone && (react_1.default.createElement(WhatsAppButton, { onClick: handleWhatsAppSubmit, disabled: isWhatsAppDisabled, text: "Send via WhatsApp" })))));
|
|
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 })))));
|
|
657
723
|
};
|
|
658
724
|
exports.default = Form;
|