@syncfusion/ej2-react-form-builder 0.1.0-beta → 35.1.42

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 (160) hide show
  1. package/README.md +81 -36
  2. package/diConfig.json +148 -0
  3. package/dist/ej2-react-form-builder.min.js +10 -0
  4. package/dist/ej2-react-form-builder.umd.min.js +11 -0
  5. package/dist/ej2-react-form-builder.umd.min.js.map +1 -0
  6. package/dist/es6/ej2-react-form-builder.es2015.js +60 -0
  7. package/dist/es6/ej2-react-form-builder.es2015.js.map +1 -0
  8. package/form-builder.d.ts +4 -0
  9. package/form-builder.js +4 -0
  10. package/index.d.ts +2 -4
  11. package/index.js +2 -4
  12. package/license +6 -13
  13. package/package.json +19 -43
  14. package/src/form-builder/formbuilder.component.d.ts +37 -0
  15. package/src/form-builder/formbuilder.component.js +50 -0
  16. package/src/form-builder/index.d.ts +2 -0
  17. package/src/form-builder/index.js +2 -0
  18. package/src/form-builder/toolboxitems-directive.d.ts +28 -0
  19. package/src/form-builder/toolboxitems-directive.js +47 -0
  20. package/src/global.js +1 -0
  21. package/src/index.d.ts +2 -16
  22. package/src/index.js +2 -6
  23. package/Common/CheckboxGroup.d.ts +0 -13
  24. package/Common/CheckboxGroup.js +0 -50
  25. package/Common/ConditionalRuleEngine.d.ts +0 -296
  26. package/Common/ConditionalRuleEngine.js +0 -566
  27. package/Common/CustomTabComponent.d.ts +0 -17
  28. package/Common/CustomTabComponent.js +0 -30
  29. package/Common/CustomValidationEngine.d.ts +0 -58
  30. package/Common/CustomValidationEngine.js +0 -146
  31. package/Common/DataGridComponent.d.ts +0 -20
  32. package/Common/DataGridComponent.js +0 -273
  33. package/Common/FormValidator.d.ts +0 -485
  34. package/Common/FormValidator.js +0 -575
  35. package/Common/MinMaxRuleEngine.d.ts +0 -105
  36. package/Common/MinMaxRuleEngine.js +0 -365
  37. package/Common/StaticHtmlRenderer.d.ts +0 -14
  38. package/Common/StaticHtmlRenderer.js +0 -24
  39. package/Common/expressions/DependencyTracker.d.ts +0 -30
  40. package/Common/expressions/DependencyTracker.js +0 -128
  41. package/Common/expressions/ExpressionEngine.d.ts +0 -95
  42. package/Common/expressions/ExpressionEngine.js +0 -506
  43. package/Common/expressions/ExpressionParser.d.ts +0 -41
  44. package/Common/expressions/ExpressionParser.js +0 -269
  45. package/Common/expressions/useGridExpressions.d.ts +0 -12
  46. package/Common/expressions/useGridExpressions.js +0 -71
  47. package/Common/globalFormId.d.ts +0 -26
  48. package/Common/globalFormId.js +0 -45
  49. package/Common/json-converter.d.ts +0 -444
  50. package/Common/json-converter.js +0 -1184
  51. package/Common/parser.d.ts +0 -98
  52. package/Common/parser.js +0 -753
  53. package/Common/utils.d.ts +0 -130
  54. package/Common/utils.js +0 -574
  55. package/src/FormBuilder.d.ts +0 -211
  56. package/src/FormBuilder.js +0 -1299
  57. package/src/components/Database/ConnectionForm.d.ts +0 -8
  58. package/src/components/Database/ConnectionForm.js +0 -28
  59. package/src/components/TopBar.d.ts +0 -10
  60. package/src/components/TopBar.js +0 -7
  61. package/src/components/icons/ComponentIcons.d.ts +0 -44
  62. package/src/components/icons/ComponentIcons.js +0 -40
  63. package/src/components/layout/FormFieldWrapper.d.ts +0 -41
  64. package/src/components/layout/FormFieldWrapper.js +0 -112
  65. package/src/components/layout/LeftPane.d.ts +0 -23
  66. package/src/components/layout/LeftPane.js +0 -310
  67. package/src/components/layout/ListBoxPane.d.ts +0 -24
  68. package/src/components/layout/ListBoxPane.js +0 -94
  69. package/src/components/layout/MainSection.d.ts +0 -39
  70. package/src/components/layout/MainSection.js +0 -1766
  71. package/src/components/layout/Preview.d.ts +0 -12
  72. package/src/components/layout/Preview.js +0 -337
  73. package/src/components/layout/RightPane.d.ts +0 -22
  74. package/src/components/layout/RightPane.js +0 -370
  75. package/src/components/theme/ThemeSwitcher.d.ts +0 -14
  76. package/src/components/theme/ThemeSwitcher.js +0 -24
  77. package/src/components/theme/theme-constant.d.ts +0 -37
  78. package/src/components/theme/theme-constant.js +0 -23
  79. package/src/config/component-properties.json +0 -4929
  80. package/src/config/form-setting.json +0 -56
  81. package/src/config/locale.d.ts +0 -449
  82. package/src/config/locale.js +0 -449
  83. package/src/context/FormSchemaContext.d.ts +0 -32
  84. package/src/context/FormSchemaContext.js +0 -155
  85. package/src/context/LocalizationContext.d.ts +0 -27
  86. package/src/context/LocalizationContext.js +0 -43
  87. package/src/context/ThemeContext.d.ts +0 -23
  88. package/src/context/ThemeContext.js +0 -161
  89. package/src/context/contexts.d.ts +0 -6
  90. package/src/context/contexts.js +0 -6
  91. package/src/context/defaultFormSchema.d.ts +0 -6
  92. package/src/context/defaultFormSchema.js +0 -20
  93. package/src/defaultPalette.d.ts +0 -9
  94. package/src/defaultPalette.js +0 -45
  95. package/src/defaultTemplate.d.ts +0 -3
  96. package/src/defaultTemplate.js +0 -185
  97. package/src/import/schemaImportUtils.d.ts +0 -24
  98. package/src/import/schemaImportUtils.js +0 -121
  99. package/src/types/ActionButtons.d.ts +0 -44
  100. package/src/types/ActionButtons.js +0 -27
  101. package/src/types/ComponentProperties.d.ts +0 -33
  102. package/src/types/ComponentProperties.js +0 -2
  103. package/src/types/FormSchema.d.ts +0 -585
  104. package/src/types/FormSchema.js +0 -147
  105. package/src/types/connection.d.ts +0 -19
  106. package/src/types/connection.js +0 -9
  107. package/src/utils/AttributesEditor.d.ts +0 -13
  108. package/src/utils/AttributesEditor.js +0 -117
  109. package/src/utils/ButtonGroupEditor.d.ts +0 -15
  110. package/src/utils/ButtonGroupEditor.js +0 -141
  111. package/src/utils/ChoiceBasedFieldEditor.d.ts +0 -16
  112. package/src/utils/ChoiceBasedFieldEditor.js +0 -87
  113. package/src/utils/ClipboardHelper.d.ts +0 -26
  114. package/src/utils/ClipboardHelper.js +0 -83
  115. package/src/utils/ColumnBuilder.d.ts +0 -11
  116. package/src/utils/ColumnBuilder.js +0 -153
  117. package/src/utils/ColumnSpanEditor.d.ts +0 -8
  118. package/src/utils/ColumnSpanEditor.js +0 -98
  119. package/src/utils/ConditionDataEditor.d.ts +0 -29
  120. package/src/utils/ConditionDataEditor.js +0 -177
  121. package/src/utils/ConditionalEditorUtils.d.ts +0 -27
  122. package/src/utils/ConditionalEditorUtils.js +0 -310
  123. package/src/utils/ConditionsEditor.d.ts +0 -20
  124. package/src/utils/ConditionsEditor.js +0 -571
  125. package/src/utils/CustomAccordion.d.ts +0 -13
  126. package/src/utils/CustomAccordion.js +0 -38
  127. package/src/utils/CustomValidationEditor.d.ts +0 -11
  128. package/src/utils/CustomValidationEditor.js +0 -208
  129. package/src/utils/DataSourceCollector.d.ts +0 -3
  130. package/src/utils/DataSourceCollector.js +0 -252
  131. package/src/utils/ExpressionEditor.d.ts +0 -13
  132. package/src/utils/ExpressionEditor.js +0 -99
  133. package/src/utils/FormSettingsPanel.d.ts +0 -9
  134. package/src/utils/FormSettingsPanel.js +0 -60
  135. package/src/utils/LookupConfig.d.ts +0 -11
  136. package/src/utils/LookupConfig.js +0 -159
  137. package/src/utils/MinMaxValueEditor.d.ts +0 -25
  138. package/src/utils/MinMaxValueEditor.js +0 -188
  139. package/src/utils/OptionsEditor.d.ts +0 -8
  140. package/src/utils/OptionsEditor.js +0 -79
  141. package/src/utils/PropertyRenderer.d.ts +0 -22
  142. package/src/utils/PropertyRenderer.js +0 -210
  143. package/src/utils/ValueRenderer.d.ts +0 -2
  144. package/src/utils/ValueRenderer.js +0 -91
  145. package/src/utils/ej2DbAdaptor.d.ts +0 -6
  146. package/src/utils/ej2DbAdaptor.js +0 -38
  147. package/src/utils/mappingHeuristics.d.ts +0 -10
  148. package/src/utils/mappingHeuristics.js +0 -33
  149. package/src/utils/renderComponent.d.ts +0 -18
  150. package/src/utils/renderComponent.js +0 -300
  151. package/styles/tailwind3.css +0 -67
  152. package/styles/themes/action-buttons.css +0 -110
  153. package/styles/themes/datagrid.css +0 -380
  154. package/styles/themes/drag-reorder.css +0 -248
  155. package/styles/themes/import-dialog.css +0 -292
  156. package/styles/themes/index.css +0 -658
  157. package/styles/themes/left-pane.css +0 -253
  158. package/styles/themes/options-editor.css +0 -63
  159. package/styles/themes/preview.css +0 -702
  160. package/styles/themes/property-dialog.css +0 -371
@@ -1,575 +0,0 @@
1
- import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
- import * as React from 'react';
3
- import { forwardRef, useEffect, useCallback, useRef, useImperativeHandle, createContext } from 'react';
4
- import { L10n } from '@syncfusion/ej2-base';
5
- import { VALIDATION_REGEX } from './utils';
6
- const FormContext = createContext(null);
7
- const FormProvider = FormContext.Provider;
8
- /**
9
- * Provides a form component with built-in validation functionality. Manages form state tracking,
10
- * field validation, and submission handling.
11
- *
12
- * ```typescript
13
- * import { Form, FormField, FormState } from '@syncfusion/react-inputs';
14
- *
15
- * const [formState, setFormState] = useState<FormState>();
16
- *
17
- * <Form
18
- * rules={{ username: { required: [true, 'Username is required'] } }}
19
- * onSubmit={data => console.log(data)}
20
- * onFormStateChange={setFormState} >
21
- * <FormField name="username">
22
- * <input
23
- * name="username"
24
- * value={(formState?.values.username || '') as string}
25
- * onChange={(e) => formState?.onChange('username', { value: e.target.value })}
26
- * onBlur={() => formState?.onBlur('username')}
27
- * onFocus={() => formState?.onFocus('username')}
28
- * />
29
- * {formState?.errors?.username && (<div className="error">{formState.errors.username}</div>)}
30
- * </FormField>
31
- * <button type="submit">Submit</button>
32
- * </Form>
33
- * ```
34
- * @private
35
- */
36
- export const Form = forwardRef((props, ref) => {
37
- const { rules, onSubmit, onReset, children, onFormStateChange, initialValues = {}, validateOnChange = false, className = '', ...otherProps } = props;
38
- const formRef = useRef(null);
39
- const stateRef = useRef({
40
- values: { ...initialValues },
41
- errors: {},
42
- touched: {},
43
- visited: {},
44
- modified: {},
45
- submitted: false,
46
- validated: {}
47
- });
48
- const notifyStateChange = useCallback(() => {
49
- if (onFormStateChange) {
50
- formStateRef.current = getFormState();
51
- onFormStateChange(formStateRef.current);
52
- }
53
- }, [onFormStateChange]);
54
- const setFieldValue = useCallback((field, value) => {
55
- stateRef.current = {
56
- ...stateRef.current,
57
- values: {
58
- ...stateRef.current.values,
59
- [field]: value
60
- },
61
- modified: {
62
- ...stateRef.current.modified,
63
- [field]: true
64
- }
65
- };
66
- }, []);
67
- const setFieldTouched = useCallback((field) => {
68
- stateRef.current = {
69
- ...stateRef.current,
70
- touched: {
71
- ...stateRef.current.touched,
72
- [field]: true
73
- }
74
- };
75
- }, []);
76
- const setFieldVisited = useCallback((field) => {
77
- stateRef.current = {
78
- ...stateRef.current,
79
- visited: {
80
- ...stateRef.current.visited,
81
- [field]: true
82
- }
83
- };
84
- }, []);
85
- const setFieldError = useCallback((field, error) => {
86
- const errors = { ...stateRef.current.errors };
87
- if (error) {
88
- errors[field] = error;
89
- }
90
- else {
91
- delete errors[field];
92
- }
93
- stateRef.current = {
94
- ...stateRef.current,
95
- errors
96
- };
97
- }, []);
98
- const setSubmitted = useCallback((value) => {
99
- stateRef.current = {
100
- ...stateRef.current,
101
- submitted: value
102
- };
103
- }, []);
104
- const resetForm = useCallback((values) => {
105
- stateRef.current = {
106
- values,
107
- errors: {},
108
- touched: {},
109
- visited: {},
110
- modified: {},
111
- submitted: false,
112
- validated: {}
113
- };
114
- notifyStateChange();
115
- }, [notifyStateChange]);
116
- const touchAllFields = useCallback(() => {
117
- const allTouched = {};
118
- Object.keys(stateRef.current.values).forEach((field) => {
119
- allTouched[field] = true;
120
- });
121
- stateRef.current = {
122
- ...stateRef.current,
123
- touched: allTouched
124
- };
125
- }, []);
126
- const visitAllFields = useCallback(() => {
127
- const allVisited = {};
128
- Object.keys(stateRef.current.values).forEach((field) => {
129
- allVisited[field] = true;
130
- });
131
- stateRef.current = {
132
- ...stateRef.current,
133
- visited: allVisited
134
- };
135
- }, []);
136
- const setBulkErrors = useCallback((errors) => {
137
- const newErrors = { ...stateRef.current.errors };
138
- Object.entries(errors).forEach(([field, error]) => {
139
- if (error) {
140
- newErrors[field] = error;
141
- }
142
- else {
143
- delete newErrors[field];
144
- }
145
- });
146
- stateRef.current = {
147
- ...stateRef.current,
148
- errors: newErrors
149
- };
150
- notifyStateChange();
151
- }, [notifyStateChange]);
152
- const rulesRef = useRef(rules);
153
- const fieldLevelRulesRef = useRef({});
154
- const formStateRef = useRef(null);
155
- const l10nRef = useRef(null);
156
- const defaultErrorMessages = {
157
- required: 'This field is required.',
158
- email: 'Please enter a valid email address.',
159
- url: 'Please enter a valid URL.',
160
- date: 'Please enter a valid date.',
161
- dateIso: 'Please enter a valid date (ISO).',
162
- creditCard: 'Please enter valid card number.',
163
- number: 'Please enter a valid number.',
164
- digits: 'Please enter only digits.',
165
- maxLength: 'Please enter no more than {0} characters.',
166
- minLength: 'Please enter at least {0} characters.',
167
- rangeLength: 'Please enter a value between {0} and {1} characters long.',
168
- range: 'Please enter a value between {0} and {1}.',
169
- max: 'Please enter a value less than or equal to {0}.',
170
- min: 'Please enter a value greater than or equal to {0}.',
171
- regex: 'Please enter a correct value.',
172
- tel: 'Please enter a valid phone number.',
173
- equalTo: 'Please enter the same value again.'
174
- };
175
- const registeredFields = useRef({});
176
- const registerField = (fieldName, rules) => {
177
- registeredFields.current[fieldName] = true;
178
- if (rules) {
179
- fieldLevelRulesRef.current[fieldName] = rules;
180
- }
181
- };
182
- const getMergedRulesForField = (fieldName) => {
183
- const formLevelRules = rulesRef.current[fieldName];
184
- const fieldLevelRules = fieldLevelRulesRef.current[fieldName];
185
- if (!formLevelRules && !fieldLevelRules) {
186
- return undefined;
187
- }
188
- return {
189
- ...formLevelRules,
190
- ...fieldLevelRules
191
- };
192
- };
193
- const getAllFieldNames = () => {
194
- const names = new Set([
195
- ...Object.keys(rulesRef.current || {}),
196
- ...Object.keys(fieldLevelRulesRef.current || {})
197
- ]);
198
- return Array.from(names);
199
- };
200
- useEffect(() => {
201
- l10nRef.current = new L10n('formValidator', defaultErrorMessages);
202
- return () => {
203
- l10nRef.current = null;
204
- };
205
- }, []);
206
- useEffect(() => {
207
- notifyStateChange();
208
- validateInitialValues();
209
- return () => {
210
- l10nRef.current = null;
211
- rulesRef.current = {};
212
- fieldLevelRulesRef.current = {};
213
- registeredFields.current = {};
214
- if (formRef.current) {
215
- formRef.current = null;
216
- }
217
- formStateRef.current = null;
218
- };
219
- }, []);
220
- useEffect(() => {
221
- rulesRef.current = rules;
222
- }, [rules]);
223
- const validateInitialValues = () => {
224
- if (Object.keys(initialValues).length > 0) {
225
- const errors = {};
226
- for (const fieldName in initialValues) {
227
- if (Object.prototype.hasOwnProperty.call(initialValues, fieldName) &&
228
- Object.prototype.hasOwnProperty.call(rulesRef.current, fieldName)) {
229
- const error = validateFieldValue(fieldName, initialValues[fieldName]);
230
- if (error) {
231
- errors[fieldName] = error;
232
- }
233
- else {
234
- errors[fieldName] = null;
235
- }
236
- }
237
- }
238
- if (Object.keys(errors).length > 0) {
239
- setBulkErrors(errors);
240
- }
241
- }
242
- };
243
- const formatErrorMessage = (ruleName, params) => {
244
- let formattedMessage = l10nRef.current?.getConstant(ruleName);
245
- if (Array.isArray(params)) {
246
- params.forEach((value, index) => {
247
- const placeholder = `{${index}}`;
248
- if (formattedMessage.includes(placeholder)) {
249
- formattedMessage = formattedMessage.replace(placeholder, String(value));
250
- }
251
- });
252
- }
253
- else {
254
- formattedMessage = formattedMessage.replace('{0}', String(params));
255
- }
256
- return formattedMessage;
257
- };
258
- const validateCreditCard = (value) => {
259
- if (!VALIDATION_REGEX.CREDIT_CARD.test(value)) {
260
- return false;
261
- }
262
- const cardNumber = value.replace(/[\s-]/g, '');
263
- let sum = 0;
264
- let shouldDouble = false;
265
- for (let i = cardNumber.length - 1; i >= 0; i--) {
266
- let digit = parseInt(cardNumber.charAt(i), 10);
267
- if (shouldDouble) {
268
- digit *= 2;
269
- if (digit > 9) {
270
- digit -= 9;
271
- }
272
- }
273
- sum += digit;
274
- shouldDouble = !shouldDouble;
275
- }
276
- return (sum % 10) === 0;
277
- };
278
- const validateFieldValue = (fieldName, value) => {
279
- const fieldRules = getMergedRulesForField(fieldName);
280
- if (!fieldRules || !registeredFields.current[fieldName]) {
281
- return null;
282
- }
283
- const isValueEmpty = value === undefined || value === null || value.toString().trim() === '';
284
- const isRequired = fieldRules.required != null && fieldRules.required[0] !== false;
285
- if (isValueEmpty && !isRequired) {
286
- return null;
287
- }
288
- for (const ruleName in fieldRules) {
289
- if (Object.prototype.hasOwnProperty.call(fieldRules, ruleName)) {
290
- const ruleValue = fieldRules[ruleName];
291
- if (!ruleValue) {
292
- continue;
293
- }
294
- let isValid = true;
295
- let param = null;
296
- let errorMessage;
297
- if (ruleName === 'customValidator' && typeof ruleValue === 'function') {
298
- const customError = ruleValue(value);
299
- if (customError) {
300
- return customError;
301
- }
302
- continue;
303
- }
304
- if (Array.isArray(ruleValue)) {
305
- param = ruleValue[0];
306
- errorMessage = ruleValue[1];
307
- if (ruleName === 'required' && param === false) {
308
- continue;
309
- }
310
- }
311
- if (ruleName !== 'required' && (value === '' || value === null || value === undefined)) {
312
- continue;
313
- }
314
- switch (ruleName) {
315
- case 'required':
316
- isValid = !isValueEmpty;
317
- break;
318
- case 'email':
319
- isValid = VALIDATION_REGEX.EMAIL.test(value);
320
- break;
321
- case 'url':
322
- isValid = VALIDATION_REGEX.URL.test(value);
323
- break;
324
- case 'date':
325
- isValid = !isNaN(Date.parse(value));
326
- break;
327
- case 'dateIso':
328
- isValid = VALIDATION_REGEX.DATE_ISO.test(value);
329
- break;
330
- case 'number':
331
- isValid = !isNaN(Number(value)) && String(value).indexOf(' ') === -1;
332
- break;
333
- case 'digits':
334
- isValid = VALIDATION_REGEX.DIGITS.test(value);
335
- break;
336
- case 'creditCard':
337
- isValid = validateCreditCard(value);
338
- break;
339
- case 'minLength':
340
- isValid = String(value).length >= Number(param);
341
- break;
342
- case 'maxLength':
343
- isValid = String(value).length <= Number(param);
344
- break;
345
- case 'rangeLength':
346
- if (Array.isArray(param)) {
347
- isValid = String(value).length >= param[0] && String(value).length <= param[1];
348
- }
349
- break;
350
- case 'min':
351
- isValid = Number(value) >= Number(param);
352
- break;
353
- case 'max':
354
- isValid = Number(value) <= Number(param);
355
- break;
356
- case 'range':
357
- if (Array.isArray(param)) {
358
- isValid = Number(value) >= param[0] && Number(value) <= param[1];
359
- }
360
- break;
361
- case 'regex':
362
- if (param instanceof RegExp) {
363
- isValid = param.test(value);
364
- }
365
- else if (typeof param === 'string') {
366
- // eslint-disable-next-line security/detect-non-literal-regexp
367
- isValid = new RegExp(param).test(value);
368
- }
369
- break;
370
- case 'tel':
371
- isValid = VALIDATION_REGEX.PHONE.test(value);
372
- break;
373
- case 'equalTo':
374
- if (typeof param === 'string') {
375
- isValid = value === stateRef.current.values[param];
376
- }
377
- break;
378
- }
379
- if (!isValid) {
380
- if (errorMessage) {
381
- return errorMessage;
382
- }
383
- else {
384
- return formatErrorMessage(ruleName, param);
385
- }
386
- }
387
- }
388
- }
389
- return null;
390
- };
391
- const validateForm = () => {
392
- const errors = {};
393
- const fields = getAllFieldNames();
394
- for (const field of fields) {
395
- const error = validateFieldValue(field, stateRef.current.values[field]);
396
- if (!stateRef.current.values[field]) {
397
- setFieldValue(field, stateRef.current.values[field]);
398
- }
399
- if (error) {
400
- errors[field] = error;
401
- }
402
- }
403
- return errors;
404
- };
405
- const validate = () => {
406
- const formErrors = validateForm();
407
- for (const field in formErrors) {
408
- if (Object.prototype.hasOwnProperty.call(formErrors, field)) {
409
- setFieldError(field, formErrors[field]);
410
- }
411
- }
412
- const fields = getAllFieldNames();
413
- for (const field of fields) {
414
- if (!formErrors[field]) {
415
- setFieldError(field, null);
416
- }
417
- }
418
- if (Object.keys(formErrors).length === 0) {
419
- stateRef.current = {
420
- ...stateRef.current,
421
- errors: {},
422
- touched: {},
423
- visited: {},
424
- modified: {},
425
- submitted: false,
426
- validated: {}
427
- };
428
- }
429
- notifyStateChange();
430
- return Object.keys(formErrors).length === 0;
431
- };
432
- const handleSubmit = (event) => {
433
- event?.preventDefault();
434
- const isValid = validate();
435
- touchAllFields();
436
- visitAllFields();
437
- setSubmitted(true);
438
- notifyStateChange();
439
- if (isValid && !event.nativeEvent.submitter.parentNode.classList.contains('e-toolbar-item')) {
440
- onSubmit?.(stateRef.current.values);
441
- }
442
- };
443
- const handleChange = (name, { value }) => {
444
- setFieldValue(name, value);
445
- if (validateOnChange) {
446
- const error = validateFieldValue(name, value);
447
- setFieldError(name, error);
448
- }
449
- notifyStateChange();
450
- };
451
- const handleBlur = (fieldName) => {
452
- setFieldTouched(fieldName);
453
- const error = validateFieldValue(fieldName, stateRef.current.values[fieldName]);
454
- setFieldError(fieldName, error);
455
- notifyStateChange();
456
- };
457
- const handleFormReset = (args) => {
458
- resetForm({ ...initialValues });
459
- onReset?.(args);
460
- };
461
- const reset = () => {
462
- handleFormReset();
463
- };
464
- const getFormState = () => {
465
- const state = stateRef.current;
466
- const fields = getAllFieldNames();
467
- return {
468
- values: state.values,
469
- errors: state.errors,
470
- submitted: state.submitted,
471
- touched: state.touched,
472
- visited: state.visited,
473
- modified: state.modified,
474
- valid: fields.reduce((acc, fieldName) => {
475
- acc[fieldName] = !state.errors[fieldName];
476
- return acc;
477
- }, {}),
478
- allowSubmit: Object.keys(state.errors).length === 0,
479
- onChange: handleChange,
480
- onBlur: handleBlur,
481
- onFocus: handleFocus,
482
- onFormReset: handleFormReset,
483
- onSubmit: handleSubmit,
484
- fieldNames: Object.keys(registeredFields.current).reduce((acc, fieldName) => {
485
- acc[fieldName] = fieldName;
486
- return acc;
487
- }, {})
488
- };
489
- };
490
- const validateField = (fieldName) => {
491
- const error = validateFieldValue(fieldName, stateRef.current.values[fieldName]);
492
- setFieldError(fieldName, error);
493
- notifyStateChange();
494
- return !error;
495
- };
496
- const publicAPI = React.useMemo(() => ({
497
- rules,
498
- initialValues,
499
- validateOnChange
500
- }), [rules, initialValues, validateOnChange]);
501
- useImperativeHandle(ref, () => ({
502
- ...publicAPI,
503
- validate,
504
- reset,
505
- validateField,
506
- element: formRef.current
507
- }), [publicAPI]);
508
- const formClassName = React.useMemo(() => {
509
- return [
510
- 'sf-control sf-form-validator',
511
- className
512
- ].filter(Boolean).join(' ');
513
- }, [className]);
514
- const handleFocus = (fieldName) => {
515
- setFieldVisited(fieldName);
516
- notifyStateChange();
517
- };
518
- const formContextValue = {
519
- registerField: registerField
520
- };
521
- return (_jsx(FormProvider, { value: formContextValue, children: _jsx("form", { ref: formRef, className: formClassName, onSubmit: handleSubmit, onReset: handleFormReset, noValidate: true, ...otherProps, children: children }) }));
522
- });
523
- Form.displayName = 'Form';
524
- /**
525
- * Specifies a component that connects form inputs with validation rules. The FormField component provides
526
- * an easy way to integrate form controls with the Form validation system, handling state management and
527
- * validation automatically.
528
- *
529
- * ```typescript
530
- * const [formState, setFormState] = useState<FormState>();
531
- *
532
- * <Form
533
- * rules={{
534
- * username: { required: [true, 'Username is required'] }
535
- * }}
536
- * onSubmit={data => console.log(data)}
537
- * onFormStateChange={setFormState}
538
- * >
539
- * <FormField name="username">
540
- * <input
541
- * name="username"
542
- * value={formState?.values.username || ''}
543
- * onChange={(e) => formState?.onChange('username', { value: e.target.value })}
544
- * onBlur={() => formState?.onBlur('username')}
545
- * onFocus={() => formState?.onFocus('username')}
546
- * />
547
- * {formState?.touched?.username && formState?.errors?.username && (
548
- * <div className="error">{formState.errors.username}</div>
549
- * )}
550
- * </FormField>
551
- * <button type="submit">Submit</button>
552
- * </Form>
553
- * ```
554
- *
555
- * @param {IFormFieldProps} props - Specifies the form field configuration properties
556
- * @returns {React.ReactNode} - Returns the children with access to form validation context
557
- * @private
558
- */
559
- export const FormField = (props) => {
560
- const { name, children, rules } = props;
561
- if (!name) {
562
- return null;
563
- }
564
- // eslint-disable-next-line react-hooks/rules-of-hooks
565
- const formContext = React.useContext(FormContext);
566
- if (!formContext) {
567
- return null;
568
- }
569
- // eslint-disable-next-line react-hooks/rules-of-hooks
570
- React.useEffect(() => {
571
- formContext?.registerField?.(name, rules);
572
- }, [name, rules, formContext]);
573
- return _jsx(_Fragment, { children: children });
574
- };
575
- FormField.displayName = 'FormField';
@@ -1,105 +0,0 @@
1
- /**
2
- * @private
3
- */
4
- export interface MinMaxRangeItem {
5
- enabled: boolean;
6
- minValue?: number | string | {
7
- field: string;
8
- };
9
- maxValue?: number | string | {
10
- field: string;
11
- };
12
- }
13
- /**
14
- * @private
15
- */
16
- export interface MinMaxConstraints {
17
- minValue?: number | string;
18
- maxValue?: number | string;
19
- minDate?: string;
20
- maxDate?: string;
21
- minTime?: string;
22
- maxTime?: string;
23
- }
24
- /**
25
- * Extract min/max constraints from minMaxRange array
26
- * @private
27
- */
28
- export declare class MinMaxRuleEngine {
29
- /**
30
- * Extract min/max constraints from minMaxRange array
31
- * Handles three cases:
32
- * 1. Direct values (enabled: false)
33
- * 2. Single field reference (enabled: true, 1 range)
34
- * 3. Multiple ranges (enabled: true, 2+ ranges) - takes UTMOST
35
- * @private
36
- * @param minMaxRange - Array of range configurations
37
- * @param formValues - Current form state values (id → value)
38
- * @param componentType - 'number' | 'date' | 'dateRange'
39
- * @returns Constraints object with appropriate keys
40
- */
41
- static getConstraints(minMaxRange: MinMaxRangeItem[] | undefined, formValues: Record<string, any>, componentType?: string): MinMaxConstraints;
42
- /**
43
- * Resolve a single value - either direct or field reference
44
- *
45
- * @param value - Direct value or field reference object
46
- * @param formValues - Form state values for field lookup
47
- * @returns Resolved value or undefined
48
- */
49
- private static resolveValue;
50
- /**
51
- * Get the most permissive (widest) minimum value
52
- * For numbers: MIN of all mins
53
- * For dates: earliest date (MIN string comparison on ISO format)
54
- * For times: earliest time (MIN string comparison on 24-hour format)
55
- *
56
- * @param ranges - Array of {min, max} values
57
- * @param componentType - Type of component
58
- * @returns Most permissive minimum value
59
- */
60
- private static getPermissiveMin;
61
- /**
62
- * Get the most permissive (widest) maximum value
63
- * For numbers: MAX of all maxs
64
- * For dates: latest date (MAX string comparison on ISO format)
65
- * For times: latest time (MAX string comparison on 24-hour format)
66
- *
67
- * @param ranges - Array of {min, max} values
68
- * @param componentType - Type of component
69
- * @returns Most permissive maximum value
70
- */
71
- private static getPermissiveMax;
72
- /**
73
- * Convert MM/DD/YYYY date format to ISO (YYYY-MM-DD) for comparison
74
- * Handles both formats gracefully
75
- *
76
- * @param dateString - Date in MM/DD/YYYY or ISO format
77
- * @returns ISO date string (YYYY-MM-DD)
78
- */
79
- private static convertToISO;
80
- /**
81
- * Convert 12-hour time format to 24-hour format for comparison
82
- * Handles both 12-hour (hh:mm a) and 24-hour (HH:mm) formats
83
- *
84
- * @param timeString - Time in 12-hour (hh:mm a/p) or 24-hour (HH:mm) format
85
- * @returns 24-hour format time string (HH:mm)
86
- */
87
- private static convertTimeTo24Hour;
88
- /**
89
- * Get empty constraints object based on component type
90
- */
91
- private static getEmptyConstraints;
92
- /**
93
- * Validate if a value passes all min/max constraints (optional)
94
- * Can be used for client-side validation before submission
95
- *
96
- * @param value - Value to validate
97
- * @param constraints - Constraints to check against
98
- * @param componentType - Type of component
99
- * @returns Validation result with error message if invalid
100
- */
101
- static validateValue(value: any, constraints: MinMaxConstraints, componentType: string): {
102
- isValid: boolean;
103
- error?: string;
104
- };
105
- }