@fovestta2/web-react 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/components/AddUpdateForm.d.ts +64 -0
  2. package/dist/components/AddUpdateForm.js +244 -0
  3. package/dist/components/FvCheckbox.d.ts +12 -0
  4. package/dist/components/FvCheckbox.js +19 -0
  5. package/dist/components/FvDateField.d.ts +19 -0
  6. package/dist/components/FvDateField.js +123 -0
  7. package/dist/components/FvDocumentField.d.ts +22 -0
  8. package/dist/components/FvDocumentField.js +242 -0
  9. package/dist/components/FvDropdown.d.ts +33 -0
  10. package/dist/components/FvDropdown.js +346 -0
  11. package/dist/components/FvEmailField.d.ts +18 -0
  12. package/dist/components/FvEmailField.js +103 -0
  13. package/dist/components/FvEntryField.d.ts +21 -0
  14. package/dist/components/FvEntryField.js +101 -0
  15. package/dist/components/FvEsiField.d.ts +16 -0
  16. package/dist/components/FvEsiField.js +92 -0
  17. package/dist/components/FvFileSelector.d.ts +22 -0
  18. package/dist/components/FvFileSelector.js +153 -0
  19. package/dist/components/FvIbanField.d.ts +16 -0
  20. package/dist/components/FvIbanField.js +92 -0
  21. package/dist/components/FvIfscField.d.ts +16 -0
  22. package/dist/components/FvIfscField.js +92 -0
  23. package/dist/components/FvImageSelector.d.ts +22 -0
  24. package/dist/components/FvImageSelector.js +317 -0
  25. package/dist/components/FvMicrField.d.ts +16 -0
  26. package/dist/components/FvMicrField.js +92 -0
  27. package/dist/components/FvMonthYearField.d.ts +19 -0
  28. package/dist/components/FvMonthYearField.js +139 -0
  29. package/dist/components/FvNameCode.d.ts +23 -0
  30. package/dist/components/FvNameCode.js +239 -0
  31. package/dist/components/FvNumberField.d.ts +21 -0
  32. package/dist/components/FvNumberField.js +98 -0
  33. package/dist/components/FvPasswordField.d.ts +18 -0
  34. package/dist/components/FvPasswordField.js +114 -0
  35. package/dist/components/FvPfField.d.ts +16 -0
  36. package/dist/components/FvPfField.js +106 -0
  37. package/dist/components/FvPhoneField.d.ts +16 -0
  38. package/dist/components/FvPhoneField.js +95 -0
  39. package/dist/components/FvRadioGroup.d.ts +20 -0
  40. package/dist/components/FvRadioGroup.js +64 -0
  41. package/dist/components/FvRichTextEditor.d.ts +20 -0
  42. package/dist/components/FvRichTextEditor.js +199 -0
  43. package/dist/components/FvServicePeriod.d.ts +10 -0
  44. package/dist/components/FvServicePeriod.js +122 -0
  45. package/dist/components/FvTimeField.d.ts +17 -0
  46. package/dist/components/FvTimeField.js +190 -0
  47. package/dist/components/FvToggle.d.ts +12 -0
  48. package/dist/components/FvToggle.js +39 -0
  49. package/dist/components/FvUanField.d.ts +16 -0
  50. package/dist/components/FvUanField.js +92 -0
  51. package/dist/components/QueryForm.d.ts +31 -0
  52. package/dist/components/QueryForm.js +214 -0
  53. package/dist/index.d.ts +28 -0
  54. package/dist/index.js +47 -0
  55. package/package.json +39 -0
@@ -0,0 +1,64 @@
1
+ import React from 'react';
2
+ export type FieldType = 'text' | 'email' | 'number' | 'select' | 'name-code' | 'checkbox' | 'textarea' | 'date' | 'password' | 'radio' | 'file' | 'month-year' | 'phone' | 'uan' | 'pf' | 'esi' | 'ifsc' | 'micr' | 'iban' | 'service-period' | 'scan' | 'document' | 'time' | 'toggle';
3
+ export type ValidationType = 'required' | 'email' | 'minLength' | 'maxLength' | 'pattern' | 'min' | 'max' | 'custom' | 'duplicate' | 'passwordComplexity';
4
+ export interface FieldValidation {
5
+ type: ValidationType;
6
+ value?: any;
7
+ message?: string;
8
+ errorKey?: string;
9
+ params?: any;
10
+ }
11
+ export interface FormColumn {
12
+ name: string;
13
+ label: string;
14
+ type: FieldType;
15
+ placeholder?: string;
16
+ required?: boolean;
17
+ options?: {
18
+ label: string;
19
+ value: any;
20
+ }[];
21
+ validations?: FieldValidation[];
22
+ value?: any;
23
+ disabled?: boolean | ((formData: any) => boolean);
24
+ className?: string;
25
+ hidden?: boolean;
26
+ hint?: string;
27
+ colSpan?: number;
28
+ onChange?: (value: any, formData: any) => void;
29
+ accept?: string;
30
+ filePreview?: boolean;
31
+ showTimePicker?: boolean;
32
+ allowAlphabetsOnly?: boolean;
33
+ maxLength?: number;
34
+ layout?: 'vertical' | 'horizontal';
35
+ servicePeriodConfig?: {
36
+ startField: string;
37
+ endField: string;
38
+ };
39
+ }
40
+ export interface FormSection {
41
+ title?: string;
42
+ fields: FormColumn[];
43
+ isRepeatable?: boolean;
44
+ sectionKey?: string;
45
+ }
46
+ export interface FormConfig {
47
+ sections: FormSection[];
48
+ submitLabel?: string;
49
+ resetLabel?: string;
50
+ onSubmit: (data: any) => void;
51
+ onReset?: () => void;
52
+ onCancel: () => void;
53
+ cancelLabel?: string;
54
+ formTitle?: string;
55
+ maxColsPerRow?: number;
56
+ disableSubmit?: boolean;
57
+ disableCancel?: boolean;
58
+ hideSubmit?: boolean;
59
+ hideCancel?: boolean;
60
+ }
61
+ export interface AddUpdateFormProps {
62
+ config: FormConfig;
63
+ }
64
+ export declare const AddUpdateForm: React.FC<AddUpdateFormProps>;
@@ -0,0 +1,244 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.AddUpdateForm = void 0;
27
+ const react_1 = __importStar(require("react"));
28
+ // Import all Fv controls
29
+ const FvEntryField_1 = require("./FvEntryField");
30
+ const FvDropdown_1 = require("./FvDropdown");
31
+ const FvNumberField_1 = require("./FvNumberField");
32
+ const FvDateField_1 = require("./FvDateField");
33
+ const FvMonthYearField_1 = require("./FvMonthYearField");
34
+ const FvFileSelector_1 = require("./FvFileSelector");
35
+ const FvImageSelector_1 = require("./FvImageSelector");
36
+ const FvRichTextEditor_1 = require("./FvRichTextEditor");
37
+ const FvNameCode_1 = require("./FvNameCode");
38
+ const FvPhoneField_1 = require("./FvPhoneField");
39
+ const FvUanField_1 = require("./FvUanField");
40
+ const FvPfField_1 = require("./FvPfField");
41
+ const FvEsiField_1 = require("./FvEsiField");
42
+ const FvIfscField_1 = require("./FvIfscField");
43
+ const FvMicrField_1 = require("./FvMicrField");
44
+ const FvIbanField_1 = require("./FvIbanField");
45
+ const FvEmailField_1 = require("./FvEmailField");
46
+ const FvPasswordField_1 = require("./FvPasswordField");
47
+ const FvToggle_1 = require("./FvToggle");
48
+ const FvCheckbox_1 = require("./FvCheckbox");
49
+ const FvRadioGroup_1 = require("./FvRadioGroup");
50
+ const FvDocumentField_1 = require("./FvDocumentField");
51
+ const FvTimeField_1 = require("./FvTimeField");
52
+ const AddUpdateForm = ({ config }) => {
53
+ const [formData, setFormData] = (0, react_1.useState)({});
54
+ (0, react_1.useEffect)(() => {
55
+ // Initialize form structure
56
+ const initialData = {};
57
+ config.sections.forEach((section) => {
58
+ if (section.isRepeatable && section.sectionKey) {
59
+ // Init as array with one empty object
60
+ const groupObj = {};
61
+ section.fields.forEach((col) => {
62
+ groupObj[col.name] = col.value || '';
63
+ });
64
+ initialData[section.sectionKey] = [groupObj];
65
+ }
66
+ else {
67
+ section.fields.forEach((col) => {
68
+ initialData[col.name] = col.value || '';
69
+ });
70
+ }
71
+ });
72
+ setFormData(initialData);
73
+ }, [config]);
74
+ const handleFieldChange = (name, value, sectionKey, index) => {
75
+ setFormData((prev) => {
76
+ const copy = { ...prev };
77
+ if (sectionKey && index !== undefined) {
78
+ copy[sectionKey] = [...(copy[sectionKey] || [])];
79
+ copy[sectionKey][index] = { ...copy[sectionKey][index], [name]: value };
80
+ }
81
+ else {
82
+ copy[name] = value;
83
+ }
84
+ return copy;
85
+ });
86
+ // We do a delayed trigger to on change to simulate reactive form passing state
87
+ setTimeout(() => {
88
+ const col = findColumn(name, sectionKey);
89
+ if (col && col.onChange) {
90
+ // Needs recent state
91
+ setFormData((latestState) => {
92
+ col.onChange(value, latestState);
93
+ return latestState;
94
+ });
95
+ }
96
+ }, 0);
97
+ };
98
+ const findColumn = (name, sectionKey) => {
99
+ for (const section of config.sections) {
100
+ if (sectionKey && section.sectionKey !== sectionKey)
101
+ continue;
102
+ const col = section.fields.find(c => c.name === name);
103
+ if (col)
104
+ return col;
105
+ }
106
+ return undefined;
107
+ };
108
+ const addSectionItem = (sectionKey, fields) => {
109
+ setFormData((prev) => {
110
+ const copy = { ...prev };
111
+ const groupObj = {};
112
+ fields.forEach((col) => { groupObj[col.name] = col.value || ''; });
113
+ copy[sectionKey] = [...(copy[sectionKey] || []), groupObj];
114
+ return copy;
115
+ });
116
+ };
117
+ const removeSectionItem = (sectionKey, index) => {
118
+ setFormData((prev) => {
119
+ const copy = { ...prev };
120
+ if (copy[sectionKey] && copy[sectionKey].length > 1) {
121
+ const arr = [...copy[sectionKey]];
122
+ arr.splice(index, 1);
123
+ copy[sectionKey] = arr;
124
+ }
125
+ return copy;
126
+ });
127
+ };
128
+ const handleSubmit = (e) => {
129
+ e.preventDefault();
130
+ config.onSubmit(formData);
131
+ };
132
+ const getSchema = (column) => {
133
+ const rules = [];
134
+ const errorPriority = [];
135
+ if (column.validations) {
136
+ column.validations.forEach((v) => {
137
+ if (v.type === 'required') {
138
+ rules.push({ name: 'required', params: { enabled: true }, errorKey: 'ERR_REQUIRED', message: v.message });
139
+ errorPriority.push('required');
140
+ }
141
+ if (v.type === 'email') {
142
+ rules.push({ name: 'regex', params: { pattern: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$' }, errorKey: 'ERR_REGEX_MISMATCH', message: v.message });
143
+ errorPriority.push('regex');
144
+ }
145
+ if (v.type === 'minLength') {
146
+ rules.push({ name: 'minLength', params: { value: v.value }, errorKey: 'ERR_MIN_LENGTH', message: v.message });
147
+ errorPriority.push('minLength');
148
+ }
149
+ if (v.type === 'maxLength') {
150
+ rules.push({ name: 'maxLength', params: { value: v.value }, errorKey: 'ERR_MAX_LENGTH', message: v.message });
151
+ errorPriority.push('maxLength');
152
+ }
153
+ if (v.type === 'pattern') {
154
+ rules.push({ name: 'regex', params: { pattern: v.value }, errorKey: 'ERR_REGEX_MISMATCH', message: v.message });
155
+ errorPriority.push('regex');
156
+ }
157
+ });
158
+ }
159
+ return { controlType: 'EntryField', rules, errorPriority };
160
+ };
161
+ const isFieldDisabled = (column) => {
162
+ if (typeof column.disabled === 'function') {
163
+ return column.disabled(formData);
164
+ }
165
+ return column.disabled || false;
166
+ };
167
+ const renderField = (column, value, sectionKey, index) => {
168
+ var _a, _b;
169
+ const disabled = isFieldDisabled(column);
170
+ const schema = getSchema(column);
171
+ const onChange = (val) => handleFieldChange(column.name, val, sectionKey, index);
172
+ if (column.hidden)
173
+ return null;
174
+ switch (column.type) {
175
+ case 'text':
176
+ return react_1.default.createElement(FvEntryField_1.FvEntryField, { label: column.label, placeholder: column.placeholder, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
177
+ case 'email':
178
+ return react_1.default.createElement(FvEmailField_1.FvEmailField, { label: column.label, placeholder: column.placeholder, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
179
+ case 'password':
180
+ return react_1.default.createElement(FvPasswordField_1.FvPasswordField, { label: column.label, placeholder: column.placeholder, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
181
+ case 'number':
182
+ return react_1.default.createElement(FvNumberField_1.FvNumberField, { label: column.label, placeholder: column.placeholder, value: value || null, schema: schema, disabled: disabled, onChange: onChange });
183
+ case 'select':
184
+ return react_1.default.createElement(FvDropdown_1.FvDropdown, { label: column.label, placeholder: column.placeholder, options: column.options || [], value: value || '', schema: schema, disabled: disabled, onChange: onChange });
185
+ case 'checkbox':
186
+ return react_1.default.createElement(FvCheckbox_1.FvCheckbox, { label: column.label, value: value || false, disabled: disabled, onChange: onChange });
187
+ case 'toggle':
188
+ return react_1.default.createElement(FvToggle_1.FvToggle, { label: column.label, value: value || false, disabled: disabled, onChange: onChange });
189
+ case 'radio':
190
+ return react_1.default.createElement(FvRadioGroup_1.FvRadioGroup, { label: column.label, options: column.options || [], value: value || '', disabled: disabled, layout: column.layout, onChange: onChange });
191
+ case 'date':
192
+ return react_1.default.createElement(FvDateField_1.FvDateField, { label: column.label, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
193
+ case 'month-year':
194
+ return react_1.default.createElement(FvMonthYearField_1.FvMonthYearField, { label: column.label, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
195
+ case 'textarea':
196
+ return react_1.default.createElement(FvRichTextEditor_1.FvRichTextEditor, { label: column.label, placeholder: column.placeholder, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
197
+ case 'file':
198
+ if (((_a = column.accept) === null || _a === void 0 ? void 0 : _a.startsWith('image')) || column.filePreview) {
199
+ return react_1.default.createElement(FvImageSelector_1.FvImageSelector, { label: column.label, placeholder: column.placeholder, value: value || null, schema: schema, disabled: disabled, onChange: onChange });
200
+ }
201
+ return react_1.default.createElement(FvFileSelector_1.FvFileSelector, { label: column.label, placeholder: column.placeholder, accept: column.accept, value: value || null, schema: schema, disabled: disabled, onChange: onChange });
202
+ case 'name-code':
203
+ return react_1.default.createElement(FvNameCode_1.FvNameCode, { label: column.label, placeholder: column.placeholder, options: ((_b = column.options) === null || _b === void 0 ? void 0 : _b.map(o => ({ code: o.value, name: o.label, value: o.value }))) || [], value: value || '', schema: schema, disabled: disabled, onChange: onChange });
204
+ case 'phone':
205
+ return react_1.default.createElement(FvPhoneField_1.FvPhoneField, { label: column.label, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
206
+ case 'uan':
207
+ return react_1.default.createElement(FvUanField_1.FvUanField, { label: column.label, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
208
+ case 'pf':
209
+ return react_1.default.createElement(FvPfField_1.FvPfField, { label: column.label, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
210
+ case 'esi':
211
+ return react_1.default.createElement(FvEsiField_1.FvEsiField, { label: column.label, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
212
+ case 'ifsc':
213
+ return react_1.default.createElement(FvIfscField_1.FvIfscField, { label: column.label, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
214
+ case 'micr':
215
+ return react_1.default.createElement(FvMicrField_1.FvMicrField, { label: column.label, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
216
+ case 'iban':
217
+ return react_1.default.createElement(FvIbanField_1.FvIbanField, { label: column.label, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
218
+ case 'document':
219
+ return react_1.default.createElement(FvDocumentField_1.FvDocumentField, { label: column.label, placeholder: column.placeholder, accept: column.accept, value: value || null, schema: schema, disabled: disabled, onChange: onChange });
220
+ case 'time':
221
+ return react_1.default.createElement(FvTimeField_1.FvTimeField, { label: column.label, placeholder: column.placeholder, value: value || '', schema: schema, disabled: disabled, onChange: onChange });
222
+ case 'service-period':
223
+ // Not perfectly mapped due to pure group dependency, simple implementation shown for continuity
224
+ return react_1.default.createElement(FvEntryField_1.FvEntryField, { label: column.label, value: value || '', disabled: true, onChange: onChange });
225
+ default:
226
+ return null; // unsupported
227
+ }
228
+ };
229
+ return (react_1.default.createElement("div", { style: { background: '#f5f5f5', padding: '15px 20px', borderRadius: '8px', maxWidth: '100%', boxSizing: 'border-box' } },
230
+ config.formTitle && (react_1.default.createElement("div", { style: { marginBottom: '15px' } },
231
+ react_1.default.createElement("h2", { style: { margin: 0, fontSize: '20px', fontWeight: 700, color: '#303030' } }, config.formTitle))),
232
+ react_1.default.createElement("form", { onSubmit: handleSubmit, style: { background: '#fff', padding: '15px', borderRadius: '6px', boxShadow: '0 1px 3px rgba(0,0,0,0.1)' } },
233
+ config.sections.map((section, sIdx) => (react_1.default.createElement("div", { key: sIdx, style: { marginBottom: '20px' } },
234
+ section.title && react_1.default.createElement("h3", { style: { fontSize: '16px', fontWeight: 700, color: '#303030', marginBottom: '16px', textTransform: 'uppercase' } }, section.title),
235
+ section.isRepeatable && section.sectionKey ? ((formData[section.sectionKey] || []).map((group, idx) => (react_1.default.createElement("div", { key: idx, style: { position: 'relative', border: '1px solid #eee', borderRadius: '8px', padding: '20px 80px 20px 20px', marginBottom: '15px', background: '#fafafa' } },
236
+ react_1.default.createElement("div", { style: { position: 'absolute', top: '15px', right: '15px', display: 'flex', gap: '8px' } },
237
+ react_1.default.createElement("button", { type: "button", onClick: () => addSectionItem(section.sectionKey, section.fields), style: { background: 'none', border: 'none', cursor: 'pointer', fontSize: '20px', color: '#2ecc71' } }, "\u2295"),
238
+ (formData[section.sectionKey] || []).length > 1 && (react_1.default.createElement("button", { type: "button", onClick: () => removeSectionItem(section.sectionKey, idx), style: { background: 'none', border: 'none', cursor: 'pointer', fontSize: '20px', color: '#e74c3c' } }, "\u2297"))),
239
+ react_1.default.createElement("div", { style: { display: 'grid', gridTemplateColumns: `repeat(auto-fit, minmax(200px, 1fr))`, gap: '16px' } }, section.fields.map((col, cIdx) => (react_1.default.createElement("div", { key: cIdx, style: { gridColumn: `span ${col.colSpan || 1}` } }, renderField(col, group[col.name], section.sectionKey, idx))))))))) : (react_1.default.createElement("div", { style: { display: 'grid', gridTemplateColumns: `repeat(auto-fit, minmax(200px, 1fr))`, gap: '16px' } }, section.fields.map((col, cIdx) => (react_1.default.createElement("div", { key: cIdx, style: { gridColumn: `span ${col.colSpan || 1}` } }, renderField(col, formData[col.name]))))))))),
240
+ react_1.default.createElement("div", { style: { display: 'flex', justifyContent: 'space-between', gap: '12px', marginTop: '20px' } },
241
+ !config.hideSubmit && (react_1.default.createElement("button", { type: "submit", disabled: config.disableSubmit, style: { padding: '8px 24px', background: config.disableSubmit ? '#bdc3c7' : '#006aff', color: '#fff', border: 'none', borderRadius: '7px', fontWeight: 600, cursor: config.disableSubmit ? 'not-allowed' : 'pointer' } }, config.submitLabel || 'Save')),
242
+ !config.hideCancel && (react_1.default.createElement("button", { type: "button", disabled: config.disableCancel, onClick: config.onCancel, style: { padding: '8px 24px', background: '#303030', color: '#fff', border: 'none', borderRadius: '7px', fontWeight: 600, cursor: config.disableCancel ? 'not-allowed' : 'pointer' } }, config.cancelLabel || 'Cancel'))))));
243
+ };
244
+ exports.AddUpdateForm = AddUpdateForm;
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ export interface FvCheckboxProps {
3
+ label?: string;
4
+ value: boolean;
5
+ disabled?: boolean;
6
+ required?: boolean;
7
+ className?: string;
8
+ labelClassName?: string;
9
+ checkboxClassName?: string;
10
+ onChange: (value: boolean) => void;
11
+ }
12
+ export declare const FvCheckbox: React.FC<FvCheckboxProps>;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.FvCheckbox = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const FvCheckbox = ({ label = '', value, disabled = false, required = false, className = '', labelClassName = '', checkboxClassName = '', onChange, }) => {
9
+ const handleChange = (e) => {
10
+ onChange(e.target.checked);
11
+ };
12
+ return (react_1.default.createElement("div", { className: `fv-checkbox-container ${className}`, style: { marginBottom: '16px', display: 'flex', alignItems: 'center' } },
13
+ react_1.default.createElement("label", { className: `fv-checkbox-label ${labelClassName}`, style: { display: 'flex', alignItems: 'center', cursor: disabled ? 'not-allowed' : 'pointer', fontSize: '14px', color: disabled ? '#999' : '#333' } },
14
+ react_1.default.createElement("input", { type: "checkbox", checked: value, onChange: handleChange, disabled: disabled, className: `fv-checkbox-input ${checkboxClassName}`, style: { marginRight: '8px', cursor: disabled ? 'not-allowed' : 'pointer' } }),
15
+ react_1.default.createElement("span", { className: "fv-checkbox-text" },
16
+ label,
17
+ required && react_1.default.createElement("span", { className: "fv-required-asterisk", style: { color: '#dc3545', fontWeight: 'bold' } }, " *")))));
18
+ };
19
+ exports.FvCheckbox = FvCheckbox;
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import { ValidationSchema } from '@fovestta2/validation-engine';
3
+ export interface FvDateFieldProps {
4
+ label?: string;
5
+ value: string;
6
+ schema?: ValidationSchema;
7
+ disabled?: boolean;
8
+ readonly?: boolean;
9
+ min?: string;
10
+ max?: string;
11
+ className?: string;
12
+ inputClassName?: string;
13
+ labelClassName?: string;
14
+ errorClassName?: string;
15
+ onChange: (value: string) => void;
16
+ onBlur?: () => void;
17
+ onFocus?: () => void;
18
+ }
19
+ export declare const FvDateField: React.FC<FvDateFieldProps>;
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.FvDateField = void 0;
27
+ const react_1 = __importStar(require("react"));
28
+ const validation_engine_1 = require("@fovestta2/validation-engine");
29
+ const FvDateField = ({ label = '', value, schema, disabled = false, readonly = false, min, max, className = '', inputClassName = '', labelClassName = '', errorClassName = '', onChange, onBlur, onFocus, }) => {
30
+ const [errorMessage, setErrorMessage] = (0, react_1.useState)(null);
31
+ const [derivedMin, setDerivedMin] = (0, react_1.useState)(min);
32
+ const [derivedMax, setDerivedMax] = (0, react_1.useState)(max);
33
+ (0, react_1.useEffect)(() => {
34
+ extractConstraintsFromSchema();
35
+ }, [schema, min, max]);
36
+ (0, react_1.useEffect)(() => {
37
+ validateValue(value);
38
+ }, [value, schema]);
39
+ const formatDate = (date) => {
40
+ if (!date)
41
+ return undefined;
42
+ const d = new Date(date);
43
+ if (isNaN(d.getTime()))
44
+ return undefined;
45
+ return d.toISOString().split('T')[0];
46
+ };
47
+ const extractConstraintsFromSchema = () => {
48
+ var _a, _b;
49
+ let newMin = min;
50
+ let newMax = max;
51
+ if (schema === null || schema === void 0 ? void 0 : schema.rules) {
52
+ for (const rule of schema.rules) {
53
+ if (rule.name === 'minDate' && !newMin) {
54
+ newMin = formatDate((_a = rule.params) === null || _a === void 0 ? void 0 : _a['value']);
55
+ }
56
+ if (rule.name === 'maxDate' && !newMax) {
57
+ newMax = formatDate((_b = rule.params) === null || _b === void 0 ? void 0 : _b['value']);
58
+ }
59
+ }
60
+ }
61
+ setDerivedMin(newMin);
62
+ setDerivedMax(newMax);
63
+ };
64
+ const validateValue = (val) => {
65
+ if (!schema)
66
+ return;
67
+ const result = validation_engine_1.Validator.validate(val, schema);
68
+ if (!result.isValid && result.errorKey) {
69
+ setErrorMessage(result.errorKey);
70
+ }
71
+ else {
72
+ setErrorMessage(null);
73
+ }
74
+ };
75
+ const handleInput = (e) => {
76
+ onChange(e.target.value);
77
+ };
78
+ const handleBlur = (e) => {
79
+ validateValue(value);
80
+ if (onBlur)
81
+ onBlur();
82
+ };
83
+ const handleFocus = (e) => {
84
+ if (onFocus)
85
+ onFocus();
86
+ };
87
+ const isRequired = () => {
88
+ var _a;
89
+ return ((_a = schema === null || schema === void 0 ? void 0 : schema.rules) === null || _a === void 0 ? void 0 : _a.some((r) => { var _a; return r.name === 'required' && ((_a = r.params) === null || _a === void 0 ? void 0 : _a['enabled']); })) || false;
90
+ };
91
+ const getErrorMessage = () => {
92
+ if (!errorMessage)
93
+ return '';
94
+ const errorMessages = {
95
+ ERR_REQUIRED: 'Date is required',
96
+ ERR_MIN_DATE: `Date must be after ${derivedMin}`,
97
+ ERR_MAX_DATE: `Date must be before ${derivedMax}`,
98
+ ERR_MIN_AGE: 'Age requirement not met (too young)',
99
+ ERR_MAX_AGE: 'Age requirement not met (too old)',
100
+ };
101
+ return errorMessages[errorMessage] || errorMessage;
102
+ };
103
+ return (react_1.default.createElement("div", { className: `fv-field-container ${className}`, style: { marginBottom: '16px', display: 'flex', flexDirection: 'column' } },
104
+ label && (react_1.default.createElement("label", { className: `fv-label ${labelClassName}`, style: { marginBottom: '6px', fontSize: '14px', fontWeight: 500, color: disabled ? '#999' : '#333' } },
105
+ label,
106
+ isRequired() && react_1.default.createElement("span", { className: "fv-required", style: { color: '#dc3545', fontWeight: 'bold' } }, " *"))),
107
+ react_1.default.createElement("input", { type: "date", value: value, onChange: handleInput, onBlur: handleBlur, onFocus: handleFocus, disabled: disabled, readOnly: readonly, min: derivedMin, max: derivedMax, className: `fv-input ${errorMessage ? 'fv-input-error' : ''} ${inputClassName}`, style: {
108
+ padding: '10px',
109
+ border: errorMessage ? '1px solid #dc3545' : '1px solid #ccc',
110
+ borderRadius: '4px',
111
+ fontSize: '14px',
112
+ backgroundColor: disabled ? '#f5f5f5' : '#fff',
113
+ cursor: disabled ? 'not-allowed' : 'text',
114
+ outline: 'none',
115
+ boxSizing: 'border-box',
116
+ width: '100%',
117
+ ...((disabled || readonly) ? { opacity: 0.6 } : {})
118
+ } }),
119
+ errorMessage && (react_1.default.createElement("span", { className: `fv-error-text ${errorClassName}`, style: { marginTop: '4px', fontSize: '12px', color: '#dc3545' } },
120
+ "\u26A0 ",
121
+ getErrorMessage()))));
122
+ };
123
+ exports.FvDateField = FvDateField;
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import { ValidationSchema } from '@fovestta2/validation-engine';
3
+ export interface FileInfo {
4
+ file: File | string;
5
+ name: string;
6
+ size?: number;
7
+ type: string;
8
+ }
9
+ export interface FvDocumentFieldProps {
10
+ label?: string;
11
+ placeholder?: string;
12
+ value: FileInfo | null;
13
+ schema?: ValidationSchema;
14
+ disabled?: boolean;
15
+ accept?: string;
16
+ maxSize?: number;
17
+ className?: string;
18
+ errorClassName?: string;
19
+ onChange: (value: FileInfo | null) => void;
20
+ onBlur?: () => void;
21
+ }
22
+ export declare const FvDocumentField: React.FC<FvDocumentFieldProps>;