@itcase/forms 1.0.58 → 1.0.60

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.
@@ -10,6 +10,8 @@ import { Divider } from '@itcase/ui/components/Divider';
10
10
  import { Text } from '@itcase/ui/components/Text';
11
11
  import { useDeviceTargetClass } from '@itcase/ui/hooks/useDeviceTargetClass';
12
12
  import { useStyles } from '@itcase/ui/hooks/useStyles';
13
+ import camelCase from 'lodash/camelCase';
14
+ import snakeCase from 'lodash/snakeCase';
13
15
  import { Choice } from '@itcase/ui/components/Choice';
14
16
  import { Code } from '@itcase/ui/components/Code';
15
17
  import { DatePickerInput } from '@itcase/ui/components/DatePicker';
@@ -20,13 +22,16 @@ import castArray from 'lodash/castArray';
20
22
  import { createFileFromDataURL } from '@itcase/common';
21
23
  import { Loader } from '@itcase/ui/components/Loader';
22
24
  import { Title } from '@itcase/ui/components/Title';
23
- import { Input } from '@itcase/ui/components/Input';
24
25
  import { Icon } from '@itcase/ui/components/Icon';
26
+ import { Input } from '@itcase/ui/components/Input';
27
+ import iconSizeProps from '@itcase/ui/constants/componentProps/iconSize';
28
+ import shapeProps from '@itcase/ui/constants/componentProps/shape';
25
29
  import { Radio } from '@itcase/ui/components/Radio';
26
30
  import { Segmented } from '@itcase/ui/components/Segmented';
27
31
  import { Select } from '@itcase/ui/components/Select';
28
32
  import { Switch } from '@itcase/ui/components/Switch';
29
33
  import { Textarea } from '@itcase/ui/components/Textarea';
34
+ import { useIMask } from 'react-imask';
30
35
  import { Button } from '@itcase/ui/components/Button';
31
36
  import { Group as Group$1 } from '@itcase/ui/components/Group';
32
37
  import { NotificationItem } from '@itcase/ui/components/Notification';
@@ -124,9 +129,6 @@ function FieldWrapperBase(props) {
124
129
  dividerFill,
125
130
  dividerSize,
126
131
  dividerWidth,
127
- errorMessageTextColor,
128
- errorMessageTextSize,
129
- errorMessageTextWeight,
130
132
  fieldClassName,
131
133
  id,
132
134
  inputName,
@@ -143,42 +145,28 @@ function FieldWrapperBase(props) {
143
145
  helpTextSize,
144
146
  helpTextWeight,
145
147
  helpTextColor,
146
- errorBorderWidth,
147
- errorBorderColor,
148
- errorFill,
149
- message,
150
- messageTextColor,
148
+ isErrorState,
149
+ isValidState,
150
+ errorMessage,
151
151
  messageTextSize,
152
- messageTextWeight,
153
152
  metaActive,
154
153
  metaError,
155
- metaModifiedSinceLastSubmit,
156
- metaSubmitError,
157
- metaSubmitFailed,
158
- metaTouched,
159
- metaValid,
160
154
  set,
161
155
  showDivider,
162
- showErrorsOnSubmit,
163
156
  showMessage,
157
+ errorKey,
164
158
  tag: Tag,
165
159
  type
166
160
  } = props;
167
- const error = metaError || !metaModifiedSinceLastSubmit && metaSubmitError || false;
168
- const showError = useMemo(() => {
169
- if (showErrorsOnSubmit) {
170
- return metaSubmitFailed && metaTouched && error;
171
- } else {
172
- return metaTouched && error;
173
- }
174
- }, [showErrorsOnSubmit, metaSubmitFailed, metaTouched, error]);
175
- const showValid = useMemo(() => {
176
- const hasValue = Array.isArray(inputValue) ? inputValue.length : inputValue;
177
- const isModifiedAfterSubmit = !metaError && metaSubmitError && metaModifiedSinceLastSubmit;
178
- return hasValue && (metaValid || isModifiedAfterSubmit);
179
- }, [inputValue, metaValid, metaError, metaSubmitError, metaModifiedSinceLastSubmit]);
180
- const formFieldClass = useMemo(() => clsx(className, showError && 'form__item_state_error', showValid && 'form__item_state_success', isRequired && 'form__item_state_required', isDisabled && 'form__item_state_disabled', metaActive && 'form__item_state_focus', inputValue && 'form__item_state_filled'), [className, showError, showValid, isRequired, metaActive, inputValue, isDisabled]);
181
- const fieldClass = useMemo(() => clsx(fieldClassName, showError && `${fieldClassName}_state_error`, showValid && `${fieldClassName}_state_success`, metaActive && `${fieldClassName}_state_focus`, inputValue && `${fieldClassName}_state_filled`, isDisabled && `${fieldClassName}_state_disabled`), [fieldClassName, showError, showValid, metaActive, inputValue, isDisabled]);
161
+ const formFieldClass = useMemo(() => clsx(className, isValidState && 'form__item_state_success', isRequired && 'form__item_state_required', isDisabled && 'form__item_state_disabled', metaActive && 'form__item_state_focus', inputValue && 'form__item_state_filled', isErrorState && `form__item_state_${errorKey}`), [className, isErrorState, isValidState, isRequired, metaActive, inputValue, isDisabled, metaError]);
162
+ const fieldClass = useMemo(() => clsx(fieldClassName, isValidState && `${fieldClassName}_state_success`, metaActive && `${fieldClassName}_state_focus`, inputValue && `${fieldClassName}_state_filled`, isDisabled && `${fieldClassName}_state_disabled`, isErrorState && `${fieldClassName}_state_${errorKey}`), [fieldClassName, isErrorState, isValidState, metaActive, inputValue, isDisabled, metaError]);
163
+ const validationAppearance = useMemo(() => {
164
+ return {
165
+ textColor: props[`${errorKey}MessageTextColor`],
166
+ textSize: props[`${errorKey}MessageTextSize`],
167
+ textWeight: props[`${errorKey}MessageTextWeight`]
168
+ };
169
+ }, [errorKey, isErrorState]);
182
170
  const sizeClass = useDeviceTargetClass(props, {
183
171
  prefix: 'form-field_size_',
184
172
  propsKey: 'size'
@@ -212,59 +200,61 @@ function FieldWrapperBase(props) {
212
200
  } = useStyles(props);
213
201
  return /*#__PURE__*/React.createElement(Tag, {
214
202
  className: clsx(formFieldClass, 'form__item', 'form-field', type && `form-field_type_${type}`, set && `form-field_set_${set}`, sizeClass, fillClass, shapeClass, isDisabled && `form-field_state_disabled`, isHidden && `form-field_state_hidden`, directionClass, widthClass),
215
- "data-tour": dataTour,
216
203
  "data-test-id": `${inputName}Field`,
204
+ "data-tour": dataTour,
217
205
  style: formFieldStyles
218
206
  }, before, (label || labelHidden) && /*#__PURE__*/React.createElement("div", {
219
- htmlFor: id,
220
207
  className: clsx('form-field__label'),
221
- "data-test-id": `${inputName}FieldLabel`
208
+ "data-test-id": `${inputName}FieldLabel`,
209
+ htmlFor: id
222
210
  }, /*#__PURE__*/React.createElement(Text, {
223
211
  size: labelTextSize,
224
- textWeight: labelTextWidth,
225
- textColor: labelTextColor
212
+ textColor: labelTextColor,
213
+ textWeight: labelTextWidth
226
214
  }, label, labelHidden && '\u00A0')), desc && /*#__PURE__*/React.createElement("div", {
227
215
  className: "form-field__desc",
228
216
  "data-test-id": `${inputName}FieldDesc`
229
217
  }, /*#__PURE__*/React.createElement(Text, {
230
218
  size: descTextSize,
231
- textWeight: descTextWidth,
232
- textColor: descTextColor
219
+ textColor: descTextColor,
220
+ textWeight: descTextWidth
233
221
  }, desc)), /*#__PURE__*/React.createElement("div", {
234
222
  className: clsx('form-field__content', inputFillClass, inputShapeClass)
235
223
  }, /*#__PURE__*/React.createElement("div", {
236
224
  className: clsx('form-field__content-inner', fieldClass)
237
225
  }, beforeItem, children, afterItem), showDivider && /*#__PURE__*/React.createElement(Divider, {
238
226
  className: "form-field__item-divider",
239
- width: dividerWidth,
240
227
  direction: dividerDirection,
228
+ fill: dividerFill,
241
229
  size: dividerSize,
242
- fill: dividerFill
230
+ width: dividerWidth
243
231
  })), showMessage && /*#__PURE__*/React.createElement("div", {
244
232
  className: "form-field__message",
245
233
  "data-test-id": `${inputName}FieldMessage`
246
- }, Boolean(showError) && error && typeof error === 'string' && /*#__PURE__*/React.createElement(Text, {
234
+ }, isErrorState && errorMessage && /*#__PURE__*/React.createElement(Text, {
247
235
  className: "form-field__message-item form-field__message-item_type-error",
248
- size: errorMessageTextSize,
249
- textWeight: errorMessageTextWeight,
250
- textColor: errorMessageTextColor,
236
+ dataTestId: `${inputName}FieldMessageError`,
251
237
  id: `${inputName}-error`,
252
- dataTestId: `${inputName}FieldMessageError`
253
- }, error), Boolean(helpText) && Boolean(!showError) && /*#__PURE__*/React.createElement(Text, {
238
+ size: validationAppearance?.textSize,
239
+ textColor: validationAppearance?.textColor,
240
+ textWeight: validationAppearance?.textWeight
241
+ }, errorMessage), Boolean(helpText) && (!isErrorState || !errorMessage) && /*#__PURE__*/React.createElement(Text, {
254
242
  className: "form-field__message-item form-field__message-item_type_help-text",
243
+ dataTestId: `${inputName}FieldMessageHelpText`,
255
244
  size: helpTextSize,
256
- textWeight: helpTextWeight,
257
245
  textColor: helpTextColor,
258
- dataTestId: `${inputName}FieldMessageHelpText`
259
- }, helpText), (!showError && !helpText || showError && !helpText && (!error || typeof error !== 'string')) && /*#__PURE__*/React.createElement(Text, {
246
+ textWeight: helpTextWeight
247
+ }, helpText), (!isErrorState && !helpText || isErrorState && !helpText && !errorMessage) && /*#__PURE__*/React.createElement(Text, {
260
248
  className: "form-field__message-item form-field__message-item_type_help-text",
261
- size: messageTextSize,
262
- dataTestId: `${inputName}FieldMessageHelpText`
249
+ dataTestId: `${inputName}FieldMessageHelpText`,
250
+ size: messageTextSize
263
251
  }, '\u00A0')), after);
264
252
  }
265
253
  FieldWrapperBase.defaultProps = {
266
- errorMessageTextColor: 'errorTextSecondary',
254
+ requiredMessageTextSize: 's',
255
+ requiredMessageTextColor: 'warningTextPrimary',
267
256
  errorMessageTextSize: 's',
257
+ errorMessageTextColor: 'errorTextPrimary',
268
258
  tag: 'div',
269
259
  type: 'normal'
270
260
  };
@@ -285,10 +275,6 @@ FieldWrapperBase.propTypes = {
285
275
  dividerFill: PropTypes.string,
286
276
  dividerSize: PropTypes.string,
287
277
  dividerWidth: PropTypes.string,
288
- errorMessageTextColor: PropTypes.string,
289
- errorMessageTextSize: PropTypes.string,
290
- errorMessageTextWeight: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
291
- errorMessageTextWidth: PropTypes.string,
292
278
  fieldClassName: PropTypes.string,
293
279
  id: PropTypes.string,
294
280
  inputName: PropTypes.string,
@@ -313,14 +299,8 @@ FieldWrapperBase.propTypes = {
313
299
  messageTextWidth: PropTypes.string,
314
300
  metaActive: PropTypes.bool,
315
301
  metaError: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
316
- metaModifiedSinceLastSubmit: PropTypes.bool,
317
- metaSubmitError: PropTypes.string,
318
- metaSubmitFailed: PropTypes.bool,
319
- metaTouched: PropTypes.bool,
320
- metaValid: PropTypes.bool,
321
302
  set: PropTypes.string,
322
303
  showDivider: PropTypes.bool,
323
- showErrorsOnSubmit: PropTypes.bool,
324
304
  showMessage: PropTypes.bool,
325
305
  tag: PropTypes.oneOfType([PropTypes.elementType, PropTypes.string]),
326
306
  type: PropTypes.string
@@ -342,6 +322,113 @@ function FieldWrapper(props) {
342
322
  }
343
323
  FieldWrapper.propTypes = FieldWrapperBase.propTypes;
344
324
 
325
+ // Whether to display an error message based on "fieldProps" and meta-objects
326
+ function useFieldValidationState(props) {
327
+ const {
328
+ fieldProps,
329
+ meta,
330
+ input
331
+ } = props;
332
+ // Determines if there's a submission error that hasn't been rectified since the last submission.
333
+ const submitError = !meta.modifiedSinceLastSubmit && meta.submitError;
334
+
335
+ // Determines a key for the error, defaulting to 'error' if no specific key is found.
336
+ const errorKey = meta.error?.key || 'error';
337
+ const successKey = 'success';
338
+
339
+ // Determines if the field is in an error state based on various conditions.
340
+ const isErrorState = useMemo(() => {
341
+ if (fieldProps.showErrorsOnSubmit) {
342
+ return Boolean(meta.submitFailed && meta.touched && (meta.error || submitError));
343
+ } else {
344
+ return Boolean(meta.touched && (meta.error || submitError));
345
+ }
346
+ }, [fieldProps.showErrorsOnSubmit, meta.submitFailed, meta.touched, meta.error, submitError]);
347
+
348
+ // Determines if the field's input state is valid
349
+ const isValidState = useMemo(() => {
350
+ const hasValue = Array.isArray(input?.value) ? input?.value.length : input?.value;
351
+ const isModifiedAfterSubmit = meta.modifiedSinceLastSubmit && !meta.error && submitError;
352
+ return Boolean(hasValue && (meta.valid || isModifiedAfterSubmit));
353
+ }, [input?.value, meta.valid, meta.error, submitError, meta.modifiedSinceLastSubmit]);
354
+ const errorMessage = useMemo(() => {
355
+ // If final-form field has error in "meta" render-property.
356
+ // If field not modified after last form submit - use submit error
357
+ const error = meta.error || submitError || false;
358
+ if (error) {
359
+ // And error in "meta" is string
360
+ if (typeof error === 'string') {
361
+ // Return error as message
362
+ return error;
363
+ }
364
+ // Or if error in "meta" has "message" property(is object of error)
365
+ if (error.message) {
366
+ // Return message from error
367
+ return error.message;
368
+ }
369
+ }
370
+
371
+ // Field doesn't have error message
372
+ return '';
373
+ }, [meta.error, submitError]);
374
+ return {
375
+ errorKey,
376
+ successKey,
377
+ isErrorState,
378
+ isValidState,
379
+ errorMessage
380
+ };
381
+ }
382
+
383
+ // This hook changes the props of the child component depending on the type of error,
384
+ // looks at what props were in initialProps, if they are there then changes
385
+ function useValidationAppearanceInputProps(props) {
386
+ const {
387
+ validationStateKey,
388
+ inputProps
389
+ } = props;
390
+
391
+ // TODO: need to add props that can change during errors in this field
392
+ const validationAppearanceInputProps = useMemo(() => {
393
+ // const resultAppearanceProps = {
394
+ // messageTextColor: props.errorMessageTextColor,
395
+ // messageTextSize: props.errorMessageTextSize,
396
+ // messageTextWeight: props.errorMessageTextWeight,
397
+ // // Override appearance(styled) props for child input
398
+ // inputProps: {},
399
+ // }
400
+ const updatedInputProps = {};
401
+ if (validationStateKey) {
402
+ Object.entries(inputProps).forEach(([propKey, propValue]) => {
403
+ // Convert the input property key to "snake_case" format.
404
+ // e.g. "requiredBorderColor" -> "required_border_color".
405
+ const propKeySnake = snakeCase(propKey);
406
+ // Check if this property is for appearance.
407
+ // Key maybe starts with: "error", "required", "success", etc from validation config.
408
+ const isPropForValidationState = propKeySnake.startsWith(`${validationStateKey}_`);
409
+
410
+ // If property is for appearance
411
+ if (isPropForValidationState) {
412
+ // Remove validation state part from begin of property key, to make clean appearance property.
413
+ // e.g. "required_border_color" -> "border_color".
414
+ const stateTargetKeySnake = propKeySnake.replace(`${validationStateKey}_`, '');
415
+ // Convert clean appearance property key to "camelCase" format.
416
+ // e.g. "border_color" -> "borderColor"
417
+ const stateTargetKey = camelCase(stateTargetKeySnake);
418
+ // And save the value with a new clean property key
419
+ updatedInputProps[stateTargetKey] = propValue;
420
+ // Else if not already added earlier
421
+ } else if (!updatedInputProps[propKey]) {
422
+ // Just save original property
423
+ updatedInputProps[propKey] = propValue;
424
+ }
425
+ });
426
+ }
427
+ return updatedInputProps;
428
+ }, [validationStateKey, inputProps]);
429
+ return validationAppearanceInputProps;
430
+ }
431
+
345
432
  const CheckboxField = /*#__PURE__*/React.memo(function CheckboxField(props) {
346
433
  const {
347
434
  classNameGroupItem,
@@ -355,45 +442,65 @@ const CheckboxField = /*#__PURE__*/React.memo(function CheckboxField(props) {
355
442
  onChange
356
443
  } = props;
357
444
  return /*#__PURE__*/React.createElement(Field, {
445
+ initialValue: initialValue,
358
446
  name: name,
359
- type: "checkbox",
360
- initialValue: initialValue
361
- }, ({
447
+ type: "checkbox"
448
+ }, function Render({
362
449
  input,
363
450
  meta
364
- }) => {
451
+ }) {
452
+ /** Note:
453
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
454
+ * React Hooks cannot be called inside a callback.
455
+ * React Hooks must be called in a React function component or a
456
+ * custom React Hook function.
457
+ */
458
+
365
459
  const onChangeField = useCallback(event => {
366
460
  input.onChange(event);
367
461
  if (onChange) {
368
462
  onChange(event.target.checked, input.name);
369
463
  }
370
- }, [onChange]);
464
+ }, [onChange, input.onChange]);
465
+ const {
466
+ isErrorState,
467
+ isValidState,
468
+ errorKey,
469
+ errorMessage
470
+ } = useFieldValidationState({
471
+ fieldProps: fieldProps,
472
+ input: input,
473
+ meta: meta
474
+ });
475
+ const updatedInputProps = useValidationAppearanceInputProps({
476
+ validationStateKey: isErrorState ? errorKey : 'success',
477
+ inputProps: inputProps
478
+ });
371
479
  return /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
372
480
  className: clsx('form-field_type_checkbox', 'form__item_type_checkbox', classNameGroupItem),
481
+ errorKey: errorKey,
482
+ errorMessage: errorMessage,
373
483
  fieldClassName: "form-checkbox",
374
484
  inputName: input.name,
375
485
  inputValue: input.checked,
376
- isRequired: isRequired,
377
486
  isDisabled: isDisabled,
487
+ isErrorState: isErrorState,
488
+ isRequired: isRequired,
489
+ isValidState: isValidState,
378
490
  metaActive: meta.active,
379
491
  metaError: meta.error,
380
- metaModifiedSinceLastSubmit: meta.modifiedSinceLastSubmit,
381
- metaSubmitError: meta.submitError,
382
- metaSubmitFailed: meta.submitFailed,
383
- metaTouched: meta.touched,
384
- metaValid: meta.valid,
385
- tag: "label",
386
- showMessage: showMessage
492
+ showMessage: showMessage,
493
+ tag: "label"
387
494
  }, fieldProps), /*#__PURE__*/React.createElement(Checkbox, Object.assign({
388
495
  autoComplete: "nope",
389
496
  checked: input.checked,
390
- name: input.name,
391
497
  isDisabled: isDisabled,
498
+ name: input.name,
392
499
  type: "checkbox",
393
500
  onBlur: input.onBlur,
394
501
  onChange: onChangeField,
395
502
  onFocus: input.onFocus
396
- }, inputProps)));
503
+ }, updatedInputProps)));
397
504
  });
398
505
  });
399
506
  CheckboxField.defaultProps = {
@@ -401,9 +508,9 @@ CheckboxField.defaultProps = {
401
508
  inputProps: {}
402
509
  };
403
510
  CheckboxField.propTypes = {
404
- initialValue: PropTypes.bool,
405
511
  classNameGroupItem: PropTypes.string,
406
512
  fieldProps: PropTypes.object,
513
+ initialValue: PropTypes.bool,
407
514
  inputProps: PropTypes.object,
408
515
  isDisabled: PropTypes.bool,
409
516
  isRequired: PropTypes.bool,
@@ -416,17 +523,17 @@ const ChoiceField = /*#__PURE__*/React.memo(function ChoiceField(props) {
416
523
  const {
417
524
  classNameGroupItem,
418
525
  fieldProps,
419
- showMessage,
420
526
  initialValue,
421
527
  inputProps,
528
+ isDisabled,
422
529
  isMultiple,
423
530
  isRequired,
424
- isDisabled,
425
531
  label,
426
532
  messageType,
427
533
  name,
428
534
  options,
429
535
  placeholder,
536
+ showMessage,
430
537
  onChange
431
538
  } = props;
432
539
  const {
@@ -437,14 +544,20 @@ const ChoiceField = /*#__PURE__*/React.memo(function ChoiceField(props) {
437
544
  if (onChange) {
438
545
  onChange(option.value, name, isChecked);
439
546
  }
440
- }, [change]);
547
+ }, [change, onChange]);
441
548
  return /*#__PURE__*/React.createElement(Field, {
442
- name: name,
443
- initialValue: initialValue
444
- }, ({
549
+ initialValue: initialValue,
550
+ name: name
551
+ }, function Render({
445
552
  input,
446
553
  meta
447
- }) => {
554
+ }) {
555
+ /** Note:
556
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
557
+ * React Hooks cannot be called inside a callback.
558
+ * React Hooks must be called in a React function component or a
559
+ * custom React Hook function.
560
+ */
448
561
  const activeOption = useMemo(() => {
449
562
  const emptyOption = {
450
563
  value: null,
@@ -456,43 +569,56 @@ const ChoiceField = /*#__PURE__*/React.memo(function ChoiceField(props) {
456
569
  }
457
570
  return emptyOption;
458
571
  }, [input.value]);
572
+ const {
573
+ isErrorState,
574
+ isValidState,
575
+ errorKey,
576
+ errorMessage
577
+ } = useFieldValidationState({
578
+ fieldProps: fieldProps,
579
+ input: input,
580
+ meta: meta
581
+ });
582
+ const updatedInputProps = useValidationAppearanceInputProps({
583
+ validationStateKey: isErrorState ? errorKey : 'success',
584
+ inputProps: inputProps
585
+ });
459
586
  return /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
460
587
  className: clsx('form-field_type_choice', 'form__item_type_choice', classNameGroupItem),
588
+ errorKey: errorKey,
589
+ errorMessage: errorMessage,
461
590
  fieldClassName: "form-choice",
462
591
  inputName: input.name,
463
592
  inputValue: input.value || [],
464
- isRequired: isRequired,
465
593
  isDisabled: isDisabled,
594
+ isErrorState: isErrorState,
595
+ isRequired: isRequired,
596
+ isValidState: isValidState,
466
597
  label: label,
467
598
  messageType: messageType,
468
599
  metaActive: meta.active,
469
600
  metaError: meta.error,
470
- metaModifiedSinceLastSubmit: meta.modifiedSinceLastSubmit,
471
- metaSubmitError: meta.submitError,
472
- metaSubmitFailed: meta.submitFailed,
473
- metaTouched: meta.touched,
474
- metaValid: meta.valid,
475
601
  showMessage: showMessage
476
602
  }, fieldProps), /*#__PURE__*/React.createElement(Choice, Object.assign({
477
- className: clsx(meta.active && 'form-choice_state_focus', meta.error && meta.touched && 'form-choice_state_error'),
478
- options: options,
479
- name: input.name,
603
+ active: activeOption,
604
+ className: clsx(meta.active && 'form-choice_state_focus', meta.error && meta.touched && `form-choice_state_${errorKey}`),
480
605
  inputValue: input.value || [],
606
+ isDisabled: isDisabled,
481
607
  isMultiple: isMultiple,
482
608
  isRequired: isRequired,
609
+ name: input.name,
610
+ options: options,
483
611
  placeholder: placeholder,
484
- active: activeOption,
485
- setActiveSegment: setActiveSegment,
486
- isDisabled: isDisabled
487
- }, inputProps)));
612
+ setActiveSegment: setActiveSegment
613
+ }, updatedInputProps)));
488
614
  });
489
615
  });
490
616
  ChoiceField.propTypes = {
491
617
  classNameGroupItem: PropTypes.string,
492
618
  fieldProps: PropTypes.object,
493
- showMessage: PropTypes.bool,
494
619
  initialValue: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.bool]),
495
620
  inputProps: PropTypes.object,
621
+ isDisabled: PropTypes.bool,
496
622
  isMultiple: PropTypes.bool,
497
623
  isRequired: PropTypes.bool,
498
624
  label: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
@@ -500,6 +626,7 @@ ChoiceField.propTypes = {
500
626
  name: PropTypes.string,
501
627
  options: Choice.propTypes.options,
502
628
  placeholder: PropTypes.string,
629
+ showMessage: PropTypes.bool,
503
630
  onChange: PropTypes.func
504
631
  };
505
632
 
@@ -515,45 +642,68 @@ const CustomField = /*#__PURE__*/React.memo(function CustomField(props) {
515
642
  showMessage
516
643
  } = props;
517
644
  return /*#__PURE__*/React.createElement(Field, {
518
- name: name,
519
- initialValue: initialValue
520
- }, ({
645
+ initialValue: initialValue,
646
+ name: name
647
+ }, function Render({
521
648
  input,
522
649
  meta
523
- }) => /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
524
- className: clsx('form-field_type_custom', 'form__item_type_custom', classNameGroupItem),
525
- fieldClassName: 'form-custom',
526
- isDisabled: isDisabled,
527
- inputName: input.name,
528
- inputValue: input.value,
529
- isRequired: isRequired,
530
- metaActive: meta.active,
531
- metaError: meta.error,
532
- metaModifiedSinceLastSubmit: meta.modifiedSinceLastSubmit,
533
- metaSubmitError: meta.submitError,
534
- metaSubmitFailed: meta.submitFailed,
535
- metaTouched: meta.touched,
536
- metaValid: meta.valid,
537
- showMessage: showMessage
538
- }, fieldProps), /*#__PURE__*/React.createElement(Component, Object.assign({}, props, {
539
- isDisabled: isDisabled,
540
- input: input,
541
- meta: meta
542
- }))));
650
+ }) {
651
+ /** Note:
652
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
653
+ * React Hooks cannot be called inside a callback.
654
+ * React Hooks must be called in a React function component or a
655
+ * custom React Hook function.
656
+ */
657
+
658
+ const {
659
+ isErrorState,
660
+ isValidState,
661
+ errorKey,
662
+ errorMessage
663
+ } = useFieldValidationState({
664
+ fieldProps: fieldProps,
665
+ input: input,
666
+ meta: meta
667
+ });
668
+ const updatedInputProps = useValidationAppearanceInputProps({
669
+ validationStateKey: isErrorState ? errorKey : 'success',
670
+ // For "Custom" field we pass all props. Can contain some special props, we don't known.
671
+ inputProps: props
672
+ });
673
+ return /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
674
+ className: clsx('form-field_type_custom', 'form__item_type_custom', classNameGroupItem),
675
+ errorKey: errorKey,
676
+ errorMessage: errorMessage,
677
+ fieldClassName: 'form-custom',
678
+ inputName: input.name,
679
+ inputValue: input.value,
680
+ isDisabled: isDisabled,
681
+ isErrorState: isErrorState,
682
+ isRequired: isRequired,
683
+ isValidState: isValidState,
684
+ metaActive: meta.active,
685
+ metaError: meta.error,
686
+ showMessage: showMessage
687
+ }, fieldProps), /*#__PURE__*/React.createElement(Component, Object.assign({}, updatedInputProps, {
688
+ input: input,
689
+ isDisabled: isDisabled,
690
+ meta: meta
691
+ })));
692
+ });
543
693
  });
544
694
  CustomField.defaultProps = {
545
695
  inputProps: {},
546
696
  fieldProps: {}
547
697
  };
548
698
  CustomField.propTypes = {
549
- Component: PropTypes.element,
699
+ name: PropTypes.string.isRequired,
550
700
  classNameGroupItem: PropTypes.string,
701
+ Component: PropTypes.element,
551
702
  fieldProps: PropTypes.object,
552
703
  initialValue: PropTypes.any,
553
704
  inputProps: PropTypes.object,
554
705
  isDisabled: PropTypes.bool,
555
706
  isRequired: PropTypes.bool,
556
- name: PropTypes.string.isRequired,
557
707
  showMessage: PropTypes.bool
558
708
  };
559
709
 
@@ -571,33 +721,55 @@ const CodeField = /*#__PURE__*/React.memo(function CodeField(props) {
571
721
  return /*#__PURE__*/React.createElement(Field, {
572
722
  name: name,
573
723
  initialValue: initialValue
574
- }, ({
724
+ }, function Render({
575
725
  input,
576
726
  meta
577
- }) => /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
578
- className: clsx('form-field_type_code', 'form__item_type_code', classNameGroupItem),
579
- fieldClassName: 'form-code',
580
- inputName: input.name,
581
- inputValue: input.value,
582
- isRequired: isRequired,
583
- isDisabled: isDisabled,
584
- metaActive: meta.active,
585
- metaError: meta.error,
586
- metaModifiedSinceLastSubmit: meta.modifiedSinceLastSubmit,
587
- metaSubmitError: meta.submitError,
588
- metaSubmitFailed: meta.submitFailed,
589
- metaTouched: meta.touched,
590
- metaValid: meta.valid,
591
- showMessage: showMessage
592
- }, fieldProps), /*#__PURE__*/React.createElement(Code, Object.assign({
593
- autoComplete: "nope",
594
- name: input.name,
595
- isDisabled: isDisabled,
596
- value: input.value,
597
- onBlur: input.onBlur,
598
- onChange: input.onChange,
599
- onFocus: input.onFocus
600
- }, inputProps))));
727
+ }) {
728
+ /** Note:
729
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
730
+ * React Hooks cannot be called inside a callback.
731
+ * React Hooks must be called in a React function component or a
732
+ * custom React Hook function.
733
+ */
734
+
735
+ const {
736
+ isErrorState,
737
+ isValidState,
738
+ errorKey,
739
+ errorMessage
740
+ } = useFieldValidationState({
741
+ fieldProps: fieldProps,
742
+ input: input,
743
+ meta: meta
744
+ });
745
+ const updatedInputProps = useValidationAppearanceInputProps({
746
+ validationStateKey: isErrorState ? errorKey : 'success',
747
+ inputProps: inputProps
748
+ });
749
+ return /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
750
+ className: clsx('form-field_type_code', 'form__item_type_code', classNameGroupItem),
751
+ fieldClassName: 'form-code',
752
+ inputName: input.name,
753
+ inputValue: input.value,
754
+ isRequired: isRequired,
755
+ isDisabled: isDisabled,
756
+ metaActive: meta.active,
757
+ metaError: meta.error,
758
+ showMessage: showMessage,
759
+ isErrorState: isErrorState,
760
+ isValidState: isValidState,
761
+ errorKey: errorKey,
762
+ errorMessage: errorMessage
763
+ }, fieldProps), /*#__PURE__*/React.createElement(Code, Object.assign({
764
+ autoComplete: "nope",
765
+ name: input.name,
766
+ isDisabled: isDisabled,
767
+ value: input.value,
768
+ onBlur: input.onBlur,
769
+ onChange: input.onChange,
770
+ onFocus: input.onFocus
771
+ }, updatedInputProps)));
772
+ });
601
773
  });
602
774
  CodeField.defaultProps = {
603
775
  inputProps: {},
@@ -616,60 +788,72 @@ CodeField.propTypes = {
616
788
 
617
789
  function DatePickerField(props) {
618
790
  const {
619
- isRequired,
791
+ classNameGroupItem,
792
+ datePickerProps,
620
793
  fieldProps,
621
794
  inputProps,
622
- datePickerProps,
623
- name,
624
- iconSize,
625
- iconBorder,
626
- iconBorderHover,
627
- iconFill,
628
- iconFillHover,
629
795
  isDisabled,
630
- iconRevealableShow,
631
- iconRevealableHide,
632
- iconShape,
796
+ isRequired,
797
+ name,
633
798
  showMessage,
634
- onChange,
635
- classNameGroupItem
799
+ onChange
636
800
  } = props;
637
801
  return /*#__PURE__*/React.createElement(Field, {
638
802
  name: name
639
- }, ({
803
+ }, function Render({
640
804
  input,
641
805
  meta
642
- }) => {
806
+ }) {
807
+ /** Note:
808
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
809
+ * React Hooks cannot be called inside a callback.
810
+ * React Hooks must be called in a React function component or a
811
+ * custom React Hook function.
812
+ */
813
+
643
814
  const onChangeField = useCallback(value => {
644
815
  input.onChange(value);
645
816
  if (onChange) {
646
817
  onChange(value, input.name);
647
818
  }
648
- }, [onChange]);
819
+ }, [onChange, input.onChange]);
820
+ const {
821
+ isErrorState,
822
+ isValidState,
823
+ errorKey,
824
+ errorMessage
825
+ } = useFieldValidationState({
826
+ fieldProps: fieldProps,
827
+ input: input,
828
+ meta: meta
829
+ });
830
+ const updatedInputProps = useValidationAppearanceInputProps({
831
+ validationStateKey: isErrorState ? errorKey : 'success',
832
+ inputProps: inputProps
833
+ });
649
834
  return /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
650
835
  className: clsx('form-field_type_datepicker', 'form__item_type_datepicker', classNameGroupItem),
836
+ errorKey: errorKey,
837
+ errorMessage: errorMessage,
651
838
  fieldClassName: "form-datepicker",
652
839
  inputName: input.name,
653
840
  inputValue: input.value || '',
654
- isRequired: isRequired,
655
841
  isDisabled: isDisabled,
842
+ isErrorState: isErrorState,
843
+ isRequired: isRequired,
844
+ isValidState: isValidState,
656
845
  metaActive: meta.active,
657
846
  metaError: meta.error,
658
- metaModifiedSinceLastSubmit: meta.modifiedSinceLastSubmit,
659
- metaSubmitError: meta.submitError,
660
- metaSubmitFailed: meta.submitFailed,
661
- metaTouched: meta.touched,
662
- metaValid: meta.valid,
663
847
  showMessage: showMessage
664
848
  }, fieldProps), /*#__PURE__*/React.createElement(DatePickerInput, {
849
+ datePickerProps: datePickerProps,
850
+ inputProps: updatedInputProps,
851
+ isDisabled: isDisabled,
665
852
  name: input.name,
666
853
  value: input.value || '',
667
854
  onBlur: input.onBlur,
668
- isDisabled: isDisabled,
669
855
  onChange: onChangeField,
670
- onFocus: input.onFocus,
671
- inputProps: inputProps,
672
- datePickerProps: datePickerProps
856
+ onFocus: input.onFocus
673
857
  }));
674
858
  });
675
859
  }
@@ -678,10 +862,14 @@ DatePickerField.defaultProps = {
678
862
  fieldProps: {}
679
863
  };
680
864
  DatePickerField.propTypes = {
865
+ name: PropTypes.string.isRequired,
866
+ classNameGroupItem: PropTypes.string,
867
+ datePickerProps: PropTypes.object,
681
868
  fieldProps: PropTypes.object,
682
869
  inputProps: PropTypes.object,
870
+ isDisabled: PropTypes.bool,
683
871
  isRequired: PropTypes.bool,
684
- name: PropTypes.string.isRequired,
872
+ showMessage: PropTypes.bool,
685
873
  onChange: PropTypes.func
686
874
  };
687
875
 
@@ -1072,7 +1260,6 @@ const FileInput = /*#__PURE__*/React.memo(function FileInput(props) {
1072
1260
  shape,
1073
1261
  size,
1074
1262
  borderWidth,
1075
- borderColor,
1076
1263
  borderColorHover,
1077
1264
  borderType,
1078
1265
  label,
@@ -1124,77 +1311,104 @@ const FileInput = /*#__PURE__*/React.memo(function FileInput(props) {
1124
1311
  } = props;
1125
1312
  return /*#__PURE__*/React.createElement(Field, {
1126
1313
  name: name
1127
- }, ({
1314
+ }, function Render({
1128
1315
  input,
1129
1316
  meta
1130
- }) => /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
1131
- className: clsx('form-field_type_dropzone', 'form__item_type_dropzone', classNameGroupItem),
1132
- fieldClassName: "form-dropzone",
1133
- inputName: input.name,
1134
- inputValue: input.value,
1135
- isRequired: isRequired,
1136
- label: label,
1137
- labelTextColor: labelTextColor,
1138
- metaActive: meta.active,
1139
- metaError: meta.error,
1140
- metaModifiedSinceLastSubmit: meta.modifiedSinceLastSubmit,
1141
- metaSubmitError: meta.submitError,
1142
- metaSubmitFailed: meta.submitFailed,
1143
- metaTouched: meta.touched,
1144
- metaValid: meta.valid,
1145
- showMessage: showMessage,
1146
- width: width
1147
- }, fieldProps), /*#__PURE__*/React.createElement(FileInputDropzone, {
1148
- dropzoneProps: dropzoneProps,
1149
- hintDescription: hintDescription,
1150
- hintTitle: hintTitle,
1151
- borderWidth: borderWidth,
1152
- borderColor: borderColor,
1153
- borderColorHover: borderColorHover,
1154
- borderType: borderType,
1155
- thumbBorderWidth: thumbBorderWidth,
1156
- thumbBorderColor: thumbBorderColor,
1157
- thumbBorderColorHover: thumbBorderColorHover,
1158
- thumbBorderType: thumbBorderType,
1159
- fileErrorText: fileErrorText,
1160
- fill: fill,
1161
- size: size,
1162
- maxFiles: maxFiles,
1163
- maxSize: maxSize,
1164
- removeThumbTextHoverColor: removeThumbTextHoverColor,
1165
- fillHover: fillHover,
1166
- className: className,
1167
- thumbColumn: thumbColumn,
1168
- thumbDirection: thumbDirection,
1169
- inputName: input.name,
1170
- inputValue: input.value,
1171
- thumbNameTextSize: thumbNameTextSize,
1172
- thumbNameTextColor: thumbNameTextColor,
1173
- thumbNameTextWrap: thumbNameTextWrap,
1174
- thumbNameTextWeight: thumbNameTextWeight,
1175
- hintTitleTextSize: hintTitleTextSize,
1176
- hintTitleTextColor: hintTitleTextColor,
1177
- hintTitleTextWrap: hintTitleTextWrap,
1178
- hintTitleTextWeight: hintTitleTextWeight,
1179
- removeThumbTextSize: removeThumbTextSize,
1180
- removeThumbTextColor: removeThumbTextColor,
1181
- removeThumbTextWeight: removeThumbTextWeight,
1182
- hintDescriptionTextSize: hintDescriptionTextSize,
1183
- hintDescriptionTextColor: hintDescriptionTextColor,
1184
- hintDescriptionTextWrap: hintDescriptionTextWrap,
1185
- hintDescriptionTextWeight: hintDescriptionTextWeight,
1186
- errorMessageTextSize: errorMessageTextSize,
1187
- errorMessageWeight: errorMessageTextWeight,
1188
- errorMessageTextColor: errorMessageTextColor,
1189
- isPreviews: isPreviews,
1190
- shape: shape,
1191
- showFilename: showFilename,
1192
- metaError: meta.error,
1193
- metaTouched: meta.touched,
1194
- removeThumbText: removeThumbText,
1195
- onAddFiles: onAddFiles,
1196
- onDeleteFile: onDeleteFile
1197
- })));
1317
+ }) {
1318
+ /** Note:
1319
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
1320
+ * React Hooks cannot be called inside a callback.
1321
+ * React Hooks must be called in a React function component or a
1322
+ * custom React Hook function.
1323
+ */
1324
+
1325
+ const {
1326
+ isErrorState,
1327
+ isValidState,
1328
+ errorKey,
1329
+ errorMessage
1330
+ } = useFieldValidationState({
1331
+ fieldProps: fieldProps,
1332
+ input: input,
1333
+ meta: meta
1334
+ });
1335
+ const updatedInputProps = useValidationAppearanceInputProps({
1336
+ validationStateKey: isErrorState ? errorKey : 'success',
1337
+ inputProps: props
1338
+ });
1339
+
1340
+ /** TODO:
1341
+ * REFACTOR PROPERTIES
1342
+ */
1343
+ return /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
1344
+ className: clsx('form-field_type_dropzone', 'form__item_type_dropzone', classNameGroupItem),
1345
+ fieldClassName: "form-dropzone",
1346
+ inputName: input.name,
1347
+ inputValue: input.value,
1348
+ isRequired: isRequired,
1349
+ label: label,
1350
+ labelTextColor: labelTextColor,
1351
+ metaActive: meta.active,
1352
+ metaError: meta.error,
1353
+ metaTouched: meta.touched,
1354
+ showMessage: showMessage,
1355
+ width: width,
1356
+ isErrorState: isErrorState,
1357
+ isValidState: isValidState,
1358
+ errorKey: errorKey,
1359
+ errorMessage: errorMessage
1360
+ }, fieldProps), /*#__PURE__*/React.createElement(FileInputDropzone, {
1361
+ dropzoneProps: dropzoneProps,
1362
+ hintDescription: hintDescription,
1363
+ hintTitle: hintTitle,
1364
+ borderWidth: borderWidth,
1365
+ borderColor: updatedInputProps.borderColor,
1366
+ borderColorHover: borderColorHover,
1367
+ borderType: borderType,
1368
+ thumbBorderWidth: thumbBorderWidth,
1369
+ thumbBorderColor: thumbBorderColor,
1370
+ thumbBorderColorHover: thumbBorderColorHover,
1371
+ thumbBorderType: thumbBorderType,
1372
+ fileErrorText: fileErrorText,
1373
+ fill: fill,
1374
+ size: size,
1375
+ maxFiles: maxFiles,
1376
+ maxSize: maxSize,
1377
+ removeThumbTextHoverColor: removeThumbTextHoverColor,
1378
+ fillHover: fillHover,
1379
+ className: className,
1380
+ thumbColumn: thumbColumn,
1381
+ thumbDirection: thumbDirection,
1382
+ inputName: input.name,
1383
+ inputValue: input.value,
1384
+ thumbNameTextSize: thumbNameTextSize,
1385
+ thumbNameTextColor: thumbNameTextColor,
1386
+ thumbNameTextWrap: thumbNameTextWrap,
1387
+ thumbNameTextWeight: thumbNameTextWeight,
1388
+ hintTitleTextSize: hintTitleTextSize,
1389
+ hintTitleTextColor: hintTitleTextColor,
1390
+ hintTitleTextWrap: hintTitleTextWrap,
1391
+ hintTitleTextWeight: hintTitleTextWeight,
1392
+ removeThumbTextSize: removeThumbTextSize,
1393
+ removeThumbTextColor: removeThumbTextColor,
1394
+ removeThumbTextWeight: removeThumbTextWeight,
1395
+ hintDescriptionTextSize: hintDescriptionTextSize,
1396
+ hintDescriptionTextColor: hintDescriptionTextColor,
1397
+ hintDescriptionTextWrap: hintDescriptionTextWrap,
1398
+ hintDescriptionTextWeight: hintDescriptionTextWeight,
1399
+ errorMessageTextSize: errorMessageTextSize,
1400
+ errorMessageWeight: errorMessageTextWeight,
1401
+ errorMessageTextColor: errorMessageTextColor,
1402
+ isPreviews: isPreviews,
1403
+ shape: shape,
1404
+ showFilename: showFilename,
1405
+ metaError: meta.error,
1406
+ metaTouched: meta.touched,
1407
+ removeThumbText: removeThumbText,
1408
+ onAddFiles: onAddFiles,
1409
+ onDeleteFile: onDeleteFile
1410
+ }));
1411
+ });
1198
1412
  });
1199
1413
  FileInput.defaultProps = {
1200
1414
  errorMessageTextSize: 's',
@@ -1231,32 +1445,41 @@ const Group = /*#__PURE__*/React.memo(function Group(props) {
1231
1445
  labelTextSize,
1232
1446
  labelTextWeight,
1233
1447
  message,
1234
- errorMessageTextSize,
1235
- errorMessageTextWeight,
1236
- errorMessageTextColor,
1237
1448
  messageTextSize,
1238
1449
  messageTextWeight,
1239
1450
  messageTextColor,
1240
1451
  children,
1241
1452
  dataTour,
1242
1453
  showGroupMessage,
1243
- name,
1244
- showErrorsOnSubmit
1454
+ name
1245
1455
  } = props;
1246
1456
  return /*#__PURE__*/React.createElement(Field, {
1247
1457
  name: name
1248
- }, ({
1458
+ }, function Render({
1249
1459
  input,
1250
1460
  meta
1251
- }) => {
1252
- const error = meta.error || !meta.modifiedSinceLastSubmit && meta.submitError || false;
1253
- const showError = useMemo(() => {
1254
- if (showErrorsOnSubmit) {
1255
- return meta.submitFailed && meta.touched && error;
1256
- } else {
1257
- return meta.touched && error;
1258
- }
1259
- }, [showErrorsOnSubmit, meta.submitFailed, meta.touched, error]);
1461
+ }) {
1462
+ /** Note:
1463
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
1464
+ * React Hooks cannot be called inside a callback.
1465
+ * React Hooks must be called in a React function component or a
1466
+ * custom React Hook function.
1467
+ */
1468
+ const {
1469
+ isErrorState,
1470
+ isValidState,
1471
+ errorKey,
1472
+ errorMessage
1473
+ } = useFieldValidationState({
1474
+ fieldProps: props,
1475
+ // or fieldProps?
1476
+ input: input,
1477
+ meta: meta
1478
+ });
1479
+ const updatedProps = useValidationAppearanceInputProps({
1480
+ validationStateKey: isErrorState ? errorKey : 'success',
1481
+ inputProps: props
1482
+ });
1260
1483
  return /*#__PURE__*/React.createElement("div", {
1261
1484
  className: clsx('form__group', className),
1262
1485
  "data-tour": dataTour
@@ -1265,23 +1488,23 @@ const Group = /*#__PURE__*/React.memo(function Group(props) {
1265
1488
  }, before, /*#__PURE__*/React.createElement("div", {
1266
1489
  className: "form__group-label"
1267
1490
  }, /*#__PURE__*/React.createElement(Title, {
1268
- textColor: labelTextColor,
1269
1491
  size: labelTextSize,
1492
+ textColor: labelTextColor,
1270
1493
  textWeight: labelTextWeight
1271
1494
  }, label)), /*#__PURE__*/React.createElement("div", {
1272
1495
  className: "form__group-items"
1273
- }, children), after), showGroupMessage && /*#__PURE__*/React.createElement(React.Fragment, null, Boolean(showError) && /*#__PURE__*/React.createElement(Text, {
1274
- className: "form__group-message form__group-message_type-error",
1275
- size: errorMessageTextSize,
1276
- textWeight: errorMessageTextWeight,
1277
- textColor: errorMessageTextColor,
1278
- id: `${name}-error`
1279
- }, error), Boolean(message) && (!error || typeof error !== 'string') && /*#__PURE__*/React.createElement(Text, {
1496
+ }, children), after), showGroupMessage && /*#__PURE__*/React.createElement(React.Fragment, null, isErrorState && errorMessage && /*#__PURE__*/React.createElement(Text, {
1497
+ className: `form__group-message form__group-message_type-${errorKey}`,
1498
+ id: `${name}-error`,
1499
+ size: updatedProps.messageTextSize,
1500
+ textColor: updatedProps.messageTextColor,
1501
+ textWeight: updatedProps.messageTextWeight
1502
+ }, errorMessage), Boolean(message) && (!isErrorState || !errorMessage) && /*#__PURE__*/React.createElement(Text, {
1280
1503
  className: "form__group-message",
1281
1504
  size: messageTextSize,
1282
- textWeight: messageTextWeight,
1283
- textColor: messageTextColor
1284
- }, message), Boolean(!showError) && Boolean(!message) && /*#__PURE__*/React.createElement(Text, {
1505
+ textColor: messageTextColor,
1506
+ textWeight: messageTextWeight
1507
+ }, message), !isErrorState && !message && /*#__PURE__*/React.createElement(Text, {
1285
1508
  className: "form__group-message",
1286
1509
  size: messageTextSize
1287
1510
  }, '\u00A0')));
@@ -1298,34 +1521,34 @@ Group.defaultProps = {
1298
1521
  };
1299
1522
  Group.propTypes = {
1300
1523
  name: PropTypes.string.isRequired,
1301
- isRequired: PropTypes.bool,
1302
1524
  fieldProps: PropTypes.object,
1303
- inputProps: PropTypes.object
1525
+ inputProps: PropTypes.object,
1526
+ isRequired: PropTypes.bool
1304
1527
  };
1305
1528
 
1306
1529
  const InputField = /*#__PURE__*/React.memo(function InputField(props) {
1307
1530
  const {
1308
- isPassword,
1309
- isRequired,
1531
+ classNameGroupItem,
1310
1532
  fieldProps,
1311
- inputProps,
1312
- isRevealable,
1313
- name,
1314
- parse,
1315
- dataTestId,
1316
- iconSize,
1317
- isDisabled,
1318
- iconBorder,
1319
- iconBorderHover,
1320
1533
  iconFill,
1321
1534
  iconFillHover,
1322
1535
  iconRevealableHide,
1323
1536
  iconRevealableShow,
1324
1537
  iconShape,
1538
+ iconSize,
1325
1539
  initialValue,
1540
+ inputProps,
1541
+ isDisabled,
1542
+ isPassword,
1543
+ isRequired,
1544
+ isRevealable,
1545
+ name,
1546
+ parse,
1326
1547
  showMessage,
1327
- onChange,
1328
- classNameGroupItem
1548
+ onChange
1549
+ // dataTestId,
1550
+ // iconBorder,
1551
+ // iconBorderHover,
1329
1552
  } = props;
1330
1553
  const [isRevealed, setIsRevealed] = useState(false);
1331
1554
  const inputType = useMemo(() => {
@@ -1335,59 +1558,79 @@ const InputField = /*#__PURE__*/React.memo(function InputField(props) {
1335
1558
  return 'text';
1336
1559
  }
1337
1560
  }, [isRevealed, isPassword]);
1338
- const revealeHandler = useCallback(e => {
1339
- e.preventDefault();
1561
+ const onClickIconReveal = useCallback(event => {
1562
+ event.preventDefault();
1340
1563
  setIsRevealed(prev => !prev);
1341
- }, [setIsRevealed]);
1564
+ }, []);
1342
1565
  return /*#__PURE__*/React.createElement(Field, {
1566
+ initialValue: initialValue,
1343
1567
  name: name,
1344
- parse: parse,
1345
- initialValue: initialValue
1346
- }, ({
1568
+ parse: parse
1569
+ }, function Render({
1347
1570
  input,
1348
1571
  meta
1349
- }) => {
1572
+ }) {
1573
+ /** Note:
1574
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
1575
+ * React Hooks cannot be called inside a callback.
1576
+ * React Hooks must be called in a React function component or a
1577
+ * custom React Hook function.
1578
+ */
1579
+
1350
1580
  const onChangeField = useCallback(event => {
1351
1581
  input.onChange(event);
1352
1582
  if (onChange) {
1353
1583
  onChange(event.target.value, input.name);
1354
1584
  }
1355
- }, [onChange]);
1585
+ }, [onChange, input.onChange]);
1586
+ const {
1587
+ isErrorState,
1588
+ isValidState,
1589
+ errorKey,
1590
+ errorMessage
1591
+ } = useFieldValidationState({
1592
+ fieldProps: fieldProps,
1593
+ input: input,
1594
+ meta: meta
1595
+ });
1596
+ const updatedInputProps = useValidationAppearanceInputProps({
1597
+ validationStateKey: isErrorState ? errorKey : 'success',
1598
+ inputProps: inputProps
1599
+ });
1356
1600
  return /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
1357
1601
  className: clsx('form-field_type_input', 'form__item_type_input', classNameGroupItem),
1602
+ errorKey: errorKey,
1603
+ errorMessage: errorMessage,
1358
1604
  fieldClassName: isRevealable ? 'form-password' : 'form-input',
1359
1605
  inputName: input.name,
1360
1606
  inputValue: input.value || '',
1361
- isRequired: isRequired,
1362
1607
  isDisabled: isDisabled,
1608
+ isErrorState: isErrorState,
1609
+ isRequired: isRequired,
1610
+ isValidState: isValidState,
1363
1611
  metaActive: meta.active,
1364
1612
  metaError: meta.error,
1365
- metaModifiedSinceLastSubmit: meta.modifiedSinceLastSubmit,
1366
- metaSubmitError: meta.submitError,
1367
- metaSubmitFailed: meta.submitFailed,
1368
- metaTouched: meta.touched,
1369
- metaValid: meta.valid,
1370
1613
  showMessage: showMessage
1371
1614
  }, fieldProps), /*#__PURE__*/React.createElement(Input, Object.assign({
1372
- className: clsx(meta.active && 'input_state_focus', meta.error && meta.touched && 'input_state_error'),
1373
1615
  autoComplete: "nope",
1616
+ className: clsx(meta.active && 'input_state_focus', meta.error && meta.touched && `input_state_${errorKey}`),
1617
+ dataTestId: `${input.name}FieldInput`,
1618
+ isDisabled: isDisabled,
1374
1619
  name: input.name,
1375
1620
  type: inputType,
1376
1621
  value: input.value || '',
1377
1622
  onBlur: input.onBlur,
1378
1623
  onChange: onChangeField,
1379
- onFocus: input.onFocus,
1380
- isDisabled: isDisabled,
1381
- dataTestId: `${input.name}FieldInput`
1382
- }, inputProps)), isRevealable && /*#__PURE__*/React.createElement(Icon, {
1624
+ onFocus: input.onFocus
1625
+ }, updatedInputProps)), isRevealable && /*#__PURE__*/React.createElement(Icon, {
1383
1626
  className: "form-field__icon",
1384
1627
  iconFill: iconFill,
1385
1628
  iconFillHover: iconFillHover,
1386
- SvgImage: isRevealed ? iconRevealableHide : iconRevealableShow,
1387
1629
  imageSrc: isRevealed ? iconRevealableHide : iconRevealableShow,
1388
1630
  shape: iconShape,
1389
1631
  size: iconSize,
1390
- onClick: revealeHandler
1632
+ SvgImage: isRevealed ? iconRevealableHide : iconRevealableShow,
1633
+ onClick: onClickIconReveal
1391
1634
  }));
1392
1635
  });
1393
1636
  });
@@ -1396,13 +1639,26 @@ InputField.defaultProps = {
1396
1639
  fieldProps: {}
1397
1640
  };
1398
1641
  InputField.propTypes = {
1642
+ name: PropTypes.string.isRequired,
1643
+ classNameGroupItem: PropTypes.string,
1644
+ dataTestId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
1399
1645
  fieldProps: PropTypes.object,
1646
+ iconBorder: PropTypes.string,
1647
+ iconBorderHover: PropTypes.string,
1648
+ iconFill: PropTypes.string,
1649
+ iconFillHover: PropTypes.string,
1650
+ iconRevealableHide: PropTypes.oneOfType([PropTypes.elementType, PropTypes.func, PropTypes.object]),
1651
+ iconRevealableShow: PropTypes.oneOfType([PropTypes.elementType, PropTypes.func, PropTypes.object]),
1652
+ iconShape: PropTypes.oneOf(shapeProps),
1653
+ iconSize: PropTypes.oneOf(iconSizeProps),
1400
1654
  initialValue: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
1401
1655
  inputProps: PropTypes.object,
1656
+ isDisabled: PropTypes.bool,
1402
1657
  isPassword: PropTypes.bool,
1403
1658
  isRequired: PropTypes.bool,
1404
1659
  isRevealable: PropTypes.bool,
1405
- name: PropTypes.string.isRequired,
1660
+ parse: PropTypes.func,
1661
+ showMessage: PropTypes.bool,
1406
1662
  onChange: PropTypes.func
1407
1663
  };
1408
1664
 
@@ -1559,32 +1815,54 @@ const RadioGroup = /*#__PURE__*/React.memo(function RadioGroup(props) {
1559
1815
  } = props;
1560
1816
  return /*#__PURE__*/React.createElement(Field, {
1561
1817
  name: name
1562
- }, ({
1818
+ }, function Render({
1563
1819
  input,
1564
1820
  meta
1565
- }) => /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
1566
- className: "form__item_type_radio",
1567
- fieldClassName: 'form-radio',
1568
- inputName: input.name,
1569
- inputValue: input.value || '',
1570
- isRequired: isRequired,
1571
- isDisabled: isDisabled,
1572
- metaActive: meta.active,
1573
- metaError: meta.error,
1574
- metaModifiedSinceLastSubmit: meta.modifiedSinceLastSubmit,
1575
- metaSubmitError: meta.submitError,
1576
- metaSubmitFailed: meta.submitFailed,
1577
- metaTouched: meta.touched,
1578
- metaValid: meta.valid,
1579
- showMessage: showMessage
1580
- }, fieldProps), /*#__PURE__*/React.createElement(RadioGroupList, {
1581
- input: input,
1582
- options: options,
1583
- isDisabled: isDisabled,
1584
- onChange: onChange,
1585
- editableProps: editableProps,
1586
- inputProps: inputProps
1587
- })));
1821
+ }) {
1822
+ /** Note:
1823
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
1824
+ * React Hooks cannot be called inside a callback.
1825
+ * React Hooks must be called in a React function component or a
1826
+ * custom React Hook function.
1827
+ */
1828
+
1829
+ const {
1830
+ isErrorState,
1831
+ isValidState,
1832
+ errorKey,
1833
+ errorMessage
1834
+ } = useFieldValidationState({
1835
+ fieldProps: fieldProps,
1836
+ input: input,
1837
+ meta: meta
1838
+ });
1839
+ const updatedInputProps = useValidationAppearanceInputProps({
1840
+ validationStateKey: isErrorState ? errorKey : 'success',
1841
+ inputProps: inputProps
1842
+ });
1843
+ return /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
1844
+ className: "form__item_type_radio",
1845
+ errorKey: errorKey,
1846
+ errorMessage: errorMessage,
1847
+ fieldClassName: 'form-radio',
1848
+ inputName: input.name,
1849
+ inputValue: input.value || '',
1850
+ isDisabled: isDisabled,
1851
+ isErrorState: isErrorState,
1852
+ isRequired: isRequired,
1853
+ isValidState: isValidState,
1854
+ metaActive: meta.active,
1855
+ metaError: meta.error,
1856
+ showMessage: showMessage
1857
+ }, fieldProps), /*#__PURE__*/React.createElement(RadioGroupList, {
1858
+ editableProps: editableProps,
1859
+ input: input,
1860
+ inputProps: updatedInputProps,
1861
+ isDisabled: isDisabled,
1862
+ options: options,
1863
+ onChange: onChange
1864
+ }));
1865
+ });
1588
1866
  });
1589
1867
  RadioGroup.defaultProps = {
1590
1868
  editableProps: {},
@@ -1593,12 +1871,12 @@ RadioGroup.defaultProps = {
1593
1871
  options: []
1594
1872
  };
1595
1873
  RadioGroup.propTypes = {
1874
+ name: PropTypes.string.isRequired,
1596
1875
  editableProps: PropTypes.object,
1597
1876
  fieldProps: PropTypes.object,
1598
1877
  inputProps: PropTypes.object,
1599
1878
  isDisabled: PropTypes.bool,
1600
1879
  isRequired: PropTypes.bool,
1601
- name: PropTypes.string.isRequired,
1602
1880
  options: PropTypes.array,
1603
1881
  showMessage: PropTypes.bool,
1604
1882
  onChange: PropTypes.func
@@ -1622,10 +1900,17 @@ function SegmentedField(props) {
1622
1900
  }, [change]);
1623
1901
  return /*#__PURE__*/React.createElement(Field, {
1624
1902
  name: name
1625
- }, ({
1903
+ }, function Render({
1626
1904
  input,
1627
1905
  meta
1628
- }) => {
1906
+ }) {
1907
+ /** Note:
1908
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
1909
+ * React Hooks cannot be called inside a callback.
1910
+ * React Hooks must be called in a React function component or a
1911
+ * custom React Hook function.
1912
+ */
1913
+
1629
1914
  const activeOption = useMemo(() => {
1630
1915
  const emptyOption = {
1631
1916
  value: null,
@@ -1637,30 +1922,45 @@ function SegmentedField(props) {
1637
1922
  }
1638
1923
  return emptyOption;
1639
1924
  }, [input.value]);
1925
+ const {
1926
+ isErrorState,
1927
+ isValidState,
1928
+ errorKey,
1929
+ errorMessage
1930
+ } = useFieldValidationState({
1931
+ fieldProps: fieldProps,
1932
+ input: input,
1933
+ meta: meta
1934
+ });
1935
+ const updatedInputProps = useValidationAppearanceInputProps({
1936
+ validationStateKey: isErrorState ? errorKey : 'success',
1937
+ inputProps: inputProps
1938
+ });
1640
1939
  return /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
1641
1940
  className: clsx('form-field_type_segmented', 'form__item_type_segmented'),
1941
+ errorKey: errorKey,
1942
+ errorMessage: errorMessage,
1642
1943
  fieldClassName: "form-segmented",
1643
1944
  inputName: input.name,
1644
1945
  inputValue: input.value || [],
1645
- isRequired: isRequired,
1646
1946
  isDisabled: isDisabled,
1947
+ isErrorState: isErrorState,
1948
+ isRequired: isRequired,
1949
+ isValidState: isValidState,
1647
1950
  metaActive: meta.active,
1648
1951
  metaError: meta.error,
1649
- metaModifiedSinceLastSubmit: meta.modifiedSinceLastSubmit,
1650
- metaSubmitError: meta.submitError,
1651
- metaSubmitFailed: meta.submitFailed,
1652
- metaTouched: meta.touched,
1653
- metaValid: meta.valid,
1654
1952
  showMessage: showMessage
1655
1953
  }, fieldProps), /*#__PURE__*/React.createElement(Segmented, Object.assign({
1656
- segments: options,
1954
+ activeSegment: activeOption,
1657
1955
  isDisabled: isDisabled,
1658
- setActiveSegment: setActiveSegment,
1659
- activeSegment: activeOption
1660
- }, inputProps)));
1956
+ segments: options,
1957
+ setActiveSegment: setActiveSegment
1958
+ }, updatedInputProps)));
1661
1959
  });
1662
1960
  }
1663
1961
  SegmentedField.propTypes = {
1962
+ name: PropTypes.string.isRequired,
1963
+ options: PropTypes.array.isRequired,
1664
1964
  className: PropTypes.string,
1665
1965
  fieldProps: PropTypes.object,
1666
1966
  inputClass: PropTypes.string,
@@ -1668,8 +1968,6 @@ SegmentedField.propTypes = {
1668
1968
  isDisabled: PropTypes.bool,
1669
1969
  isRequired: PropTypes.bool,
1670
1970
  label: PropTypes.string,
1671
- name: PropTypes.string.isRequired,
1672
- options: PropTypes.array.isRequired,
1673
1971
  placeholder: PropTypes.string,
1674
1972
  showMessage: PropTypes.bool
1675
1973
  };
@@ -1707,10 +2005,16 @@ const SelectField = /*#__PURE__*/React.memo(function SelectField(props) {
1707
2005
  } = props;
1708
2006
  return /*#__PURE__*/React.createElement(Field, {
1709
2007
  name: name
1710
- }, ({
2008
+ }, function Render({
1711
2009
  input,
1712
2010
  meta
1713
- }) => {
2011
+ }) {
2012
+ /** Note:
2013
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
2014
+ * React Hooks cannot be called inside a callback.
2015
+ * React Hooks must be called in a React function component or a
2016
+ * custom React Hook function.
2017
+ */
1714
2018
  const [selectedOptions, setSelectedOptions] = useState(null);
1715
2019
  const defaultValue = useMemo(() => {
1716
2020
  const optionsValues = getDefaultValue(options, input.value);
@@ -1727,47 +2031,60 @@ const SelectField = /*#__PURE__*/React.memo(function SelectField(props) {
1727
2031
  if (onChange) {
1728
2032
  onChange(value, input.name);
1729
2033
  }
1730
- }, [onChange]);
2034
+ }, [onChange, input.onChange]);
1731
2035
  const onChangeValue = useCallback((option, actionMeta) => {
1732
2036
  const value = Array.isArray(option) ? option.map(o => o.value) : option?.value || null;
1733
2037
  setSelectedOptions(option);
1734
2038
  onChangeField(value);
1735
2039
  }, [onChangeField]);
1736
2040
  useEffect(() => setSelectedOptions(defaultValue), [defaultValue]);
2041
+ const {
2042
+ isErrorState,
2043
+ isValidState,
2044
+ errorKey,
2045
+ errorMessage
2046
+ } = useFieldValidationState({
2047
+ fieldProps: fieldProps,
2048
+ input: input,
2049
+ meta: meta
2050
+ });
2051
+ const updatedSelectProps = useValidationAppearanceInputProps({
2052
+ validationStateKey: isErrorState ? errorKey : 'success',
2053
+ inputProps: selectProps
2054
+ });
1737
2055
  return /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
1738
2056
  className: clsx('form-field_type_select', 'form__item_type_select', classNameGroupItem),
2057
+ errorKey: errorKey,
2058
+ errorMessage: errorMessage,
1739
2059
  fieldClassName: 'form-select',
1740
2060
  inputName: input.name,
1741
2061
  inputValue: input.value,
1742
- isRequired: isRequired,
1743
2062
  isDisabled: isDisabled,
2063
+ isErrorState: isErrorState,
2064
+ isRequired: isRequired,
2065
+ isValidState: isValidState,
1744
2066
  metaActive: meta.active,
1745
2067
  metaError: meta.error,
1746
- metaModifiedSinceLastSubmit: meta.modifiedSinceLastSubmit,
1747
- metaSubmitError: meta.submitError,
1748
- metaSubmitFailed: meta.submitFailed,
1749
- metaTouched: meta.touched,
1750
- metaValid: meta.valid,
1751
2068
  showMessage: showMessage
1752
2069
  }, fieldProps), /*#__PURE__*/React.createElement(Select, Object.assign({
1753
2070
  className: "form-select-item",
1754
2071
  instanceId: `id_${input.name}`,
1755
- value: selectedOptions,
1756
- onChange: onChangeValue,
1757
2072
  isDisabled: isDisabled,
1758
2073
  options: options,
1759
- ref: selectRef
1760
- }, selectProps)));
2074
+ ref: selectRef,
2075
+ value: selectedOptions,
2076
+ onChange: onChangeValue
2077
+ }, updatedSelectProps)));
1761
2078
  });
1762
2079
  });
1763
2080
  SelectField.propTypes = {
2081
+ name: PropTypes.string.isRequired,
1764
2082
  classNameGroupItem: PropTypes.string,
1765
2083
  fieldProps: PropTypes.object,
1766
2084
  isDisabled: PropTypes.bool,
1767
2085
  isRequired: PropTypes.bool,
1768
2086
  label: PropTypes.any,
1769
2087
  messageType: PropTypes.string,
1770
- name: PropTypes.string.isRequired,
1771
2088
  options: PropTypes.array,
1772
2089
  selectProps: PropTypes.object,
1773
2090
  selectRef: PropTypes.any,
@@ -1789,42 +2106,62 @@ const SwitchField = /*#__PURE__*/React.memo(function SwitchField(props) {
1789
2106
  return /*#__PURE__*/React.createElement(Field, {
1790
2107
  name: name,
1791
2108
  type: "checkbox"
1792
- }, ({
2109
+ }, function Render({
1793
2110
  input,
1794
2111
  meta
1795
- }) => {
2112
+ }) {
2113
+ /** Note:
2114
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
2115
+ * React Hooks cannot be called inside a callback.
2116
+ * React Hooks must be called in a React function component or a
2117
+ * custom React Hook function.
2118
+ */
2119
+
1796
2120
  const onChangeField = useCallback(event => {
1797
2121
  input.onChange(event);
1798
2122
  if (onChange) {
1799
2123
  onChange(event.target.checked, input.name);
1800
2124
  }
1801
- }, [onChange]);
2125
+ }, [onChange, input.onChange]);
2126
+ const {
2127
+ isErrorState,
2128
+ isValidState,
2129
+ errorKey,
2130
+ errorMessage
2131
+ } = useFieldValidationState({
2132
+ fieldProps: fieldProps,
2133
+ input: input,
2134
+ meta: meta
2135
+ });
2136
+ const updatedInputProps = useValidationAppearanceInputProps({
2137
+ validationStateKey: isErrorState ? errorKey : 'success',
2138
+ inputProps: inputProps
2139
+ });
1802
2140
  return /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
1803
2141
  className: clsx('form-field_type_switch', 'form__item_type_switch', classNameGroupItem),
2142
+ errorKey: errorKey,
2143
+ errorMessage: errorMessage,
1804
2144
  fieldClassName: "form-switch",
1805
2145
  inputName: input.name,
1806
2146
  inputValue: input.checked,
1807
- isRequired: isRequired,
1808
2147
  isDisabled: isDisabled,
2148
+ isErrorState: isErrorState,
2149
+ isRequired: isRequired,
2150
+ isValidState: isValidState,
1809
2151
  metaActive: meta.active,
1810
2152
  metaError: meta.error,
1811
- metaModifiedSinceLastSubmit: meta.modifiedSinceLastSubmit,
1812
- metaSubmitError: meta.submitError,
1813
- metaSubmitFailed: meta.submitFailed,
1814
- metaTouched: meta.touched,
1815
- metaValid: meta.valid,
1816
2153
  showMessage: showMessage,
1817
2154
  tag: "label"
1818
2155
  }, fieldProps), /*#__PURE__*/React.createElement(Switch, Object.assign({
1819
2156
  autoComplete: "nope",
1820
- isDisabled: isDisabled,
1821
2157
  checked: input.checked,
2158
+ isDisabled: isDisabled,
1822
2159
  name: input.name,
1823
2160
  type: "checkbox",
1824
2161
  onBlur: input.onBlur,
1825
2162
  onChange: onChangeField,
1826
2163
  onFocus: input.onFocus
1827
- }, inputProps)));
2164
+ }, updatedInputProps)));
1828
2165
  });
1829
2166
  });
1830
2167
  SwitchField.defaultProps = {
@@ -1854,48 +2191,168 @@ const TextareaField = /*#__PURE__*/React.memo(function TextareaField(props) {
1854
2191
  } = props;
1855
2192
  return /*#__PURE__*/React.createElement(Field, {
1856
2193
  name: name
1857
- }, ({
2194
+ }, function Render({
1858
2195
  input,
1859
2196
  meta
1860
- }) => /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
1861
- className: clsx('form-field_type_textarea', 'form__item_type_textarea', classNameGroupItem),
1862
- fieldClassName: 'form-textarea',
1863
- inputName: input.name,
1864
- inputValue: input.value,
1865
- isRequired: isRequired,
1866
- isDisabled: isDisabled,
1867
- metaActive: meta.active,
1868
- metaError: meta.error,
1869
- metaModifiedSinceLastSubmit: meta.modifiedSinceLastSubmit,
1870
- metaSubmitError: meta.submitError,
1871
- metaSubmitFailed: meta.submitFailed,
1872
- metaTouched: meta.touched,
1873
- metaValid: meta.valid,
1874
- showMessage: showMessage
1875
- }, fieldProps), /*#__PURE__*/React.createElement(Textarea, Object.assign({
1876
- autoComplete: "nope",
1877
- name: input.name,
1878
- value: input.value,
1879
- isDisabled: isDisabled,
1880
- onBlur: input.onBlur,
1881
- onChange: input.onChange,
1882
- onFocus: input.onFocus
1883
- }, inputProps))));
2197
+ }) {
2198
+ /** Note:
2199
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
2200
+ * React Hooks cannot be called inside a callback.
2201
+ * React Hooks must be called in a React function component or a
2202
+ * custom React Hook function.
2203
+ */
2204
+
2205
+ const {
2206
+ isErrorState,
2207
+ isValidState,
2208
+ errorKey,
2209
+ errorMessage
2210
+ } = useFieldValidationState({
2211
+ fieldProps: fieldProps,
2212
+ input: input,
2213
+ meta: meta
2214
+ });
2215
+ const updatedInputProps = useValidationAppearanceInputProps({
2216
+ validationStateKey: isErrorState ? errorKey : 'success',
2217
+ inputProps: inputProps
2218
+ });
2219
+ return /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
2220
+ className: clsx('form-field_type_textarea', 'form__item_type_textarea', classNameGroupItem),
2221
+ errorKey: errorKey,
2222
+ errorMessage: errorMessage,
2223
+ fieldClassName: 'form-textarea',
2224
+ inputName: input.name,
2225
+ inputValue: input.value,
2226
+ isDisabled: isDisabled,
2227
+ isErrorState: isErrorState,
2228
+ isRequired: isRequired,
2229
+ isValidState: isValidState,
2230
+ metaActive: meta.active,
2231
+ metaError: meta.error,
2232
+ showMessage: showMessage
2233
+ }, fieldProps), /*#__PURE__*/React.createElement(Textarea, Object.assign({
2234
+ autoComplete: "nope",
2235
+ isDisabled: isDisabled,
2236
+ name: input.name,
2237
+ value: input.value,
2238
+ onBlur: input.onBlur,
2239
+ onChange: input.onChange,
2240
+ onFocus: input.onFocus
2241
+ }, updatedInputProps)));
2242
+ });
1884
2243
  });
1885
2244
  TextareaField.defaultProps = {
1886
2245
  inputProps: {},
1887
2246
  fieldProps: {}
1888
2247
  };
1889
2248
  TextareaField.propTypes = {
2249
+ name: PropTypes.string.isRequired,
1890
2250
  classNameGroupItem: PropTypes.string,
1891
2251
  fieldProps: PropTypes.object,
1892
2252
  inputProps: PropTypes.object,
1893
2253
  isDisabled: PropTypes.bool,
1894
2254
  isRequired: PropTypes.bool,
1895
- name: PropTypes.string.isRequired,
1896
2255
  showMessage: PropTypes.bool
1897
2256
  };
1898
2257
 
2258
+ const MaskedInputField = /*#__PURE__*/React.memo(function MaskedInputField(props) {
2259
+ const {
2260
+ isDisabled,
2261
+ isRequired,
2262
+ name,
2263
+ initialValue,
2264
+ fieldProps,
2265
+ classNameGroupItem,
2266
+ showMessage,
2267
+ inputProps,
2268
+ optionsMask,
2269
+ unmasked
2270
+ } = props;
2271
+ return /*#__PURE__*/React.createElement(Field, {
2272
+ initialValue: initialValue,
2273
+ name: name
2274
+ }, function Render({
2275
+ input,
2276
+ meta
2277
+ }) {
2278
+ /** Note:
2279
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
2280
+ * React Hooks cannot be called inside a callback.
2281
+ * React Hooks must be called in a React function component or a
2282
+ * custom React Hook function.
2283
+ */
2284
+
2285
+ const {
2286
+ ref,
2287
+ value,
2288
+ unmaskedValue,
2289
+ setUnmaskedValue
2290
+ } = useIMask(optionsMask, {
2291
+ onAccept: (newValue, event, element) => {
2292
+ if (element) {
2293
+ input.onChange(event._unmaskedValue);
2294
+ }
2295
+ }
2296
+ });
2297
+ useEffect(() => {
2298
+ if (input.value !== unmaskedValue) {
2299
+ setUnmaskedValue(input.value.replace(unmasked, ''));
2300
+ }
2301
+ }, [input.value]);
2302
+ const {
2303
+ isErrorState,
2304
+ isValidState,
2305
+ errorKey,
2306
+ errorMessage
2307
+ } = useFieldValidationState({
2308
+ fieldProps: fieldProps,
2309
+ input: input,
2310
+ meta: meta
2311
+ });
2312
+ const updatedInputProps = useValidationAppearanceInputProps({
2313
+ validationStateKey: isErrorState ? errorKey : 'success',
2314
+ inputProps: inputProps
2315
+ });
2316
+ return /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
2317
+ className: clsx('form-field_type_maskedInput', 'form__item_type_maskedInput', classNameGroupItem),
2318
+ errorKey: errorKey,
2319
+ errorMessage: errorMessage,
2320
+ fieldClassName: 'form-maskedInput',
2321
+ inputName: input.name,
2322
+ inputValue: input.value,
2323
+ isDisabled: isDisabled,
2324
+ isErrorState: isErrorState,
2325
+ isRequired: isRequired,
2326
+ isValidState: isValidState,
2327
+ metaActive: meta.active,
2328
+ metaError: meta.error,
2329
+ showMessage: showMessage
2330
+ }, fieldProps), /*#__PURE__*/React.createElement(Input, Object.assign({
2331
+ className: clsx(meta.active && 'input_state_focus', meta.error && meta.touched && `input_state_${errorKey}`),
2332
+ ref: ref,
2333
+ value: value,
2334
+ onBlur: input.onBlur,
2335
+ onFocus: input.onFocus
2336
+ }, updatedInputProps)));
2337
+ });
2338
+ });
2339
+ MaskedInputField.defaultProps = {
2340
+ inputProps: {},
2341
+ fieldProps: {}
2342
+ };
2343
+ MaskedInputField.propTypes = {
2344
+ name: PropTypes.string.isRequired,
2345
+ classNameGroupItem: PropTypes.string,
2346
+ fieldProps: PropTypes.object,
2347
+ initialValue: PropTypes.any,
2348
+ inputProps: PropTypes.object,
2349
+ isDisabled: PropTypes.bool,
2350
+ isRequired: PropTypes.bool,
2351
+ optionsMask: PropTypes.object,
2352
+ showMessage: PropTypes.bool,
2353
+ unmasked: PropTypes.string
2354
+ };
2355
+
1899
2356
  const focusOnError = (formElementsList, errors) => {
1900
2357
  const selectsIds = Object.keys(errors).map(fieldName => {
1901
2358
  if (fieldName === FORM_ERROR) {
@@ -2020,7 +2477,8 @@ const formTypes = {
2020
2477
  select: 'select',
2021
2478
  switch: 'switch',
2022
2479
  text: 'text',
2023
- textarea: 'textarea'
2480
+ textarea: 'textarea',
2481
+ maskedInput: 'maskedInput'
2024
2482
  };
2025
2483
  function generateField(field, config, props) {
2026
2484
  switch (field.type) {
@@ -2090,6 +2548,12 @@ function generateField(field, config, props) {
2090
2548
  key: config.key
2091
2549
  }, field, props));
2092
2550
  }
2551
+ case formTypes.maskedInput:
2552
+ {
2553
+ return /*#__PURE__*/React.createElement(MaskedInputField, Object.assign({
2554
+ key: config.key
2555
+ }, field, props));
2556
+ }
2093
2557
  case formTypes.custom:
2094
2558
  {
2095
2559
  return /*#__PURE__*/React.createElement(CustomField, Object.assign({
@@ -2423,4 +2887,116 @@ FinalForm.defaultProps = {
2423
2887
  disableFieldsAutoComplete: false
2424
2888
  };
2425
2889
 
2426
- export { CheckboxField as Checkbox, ChoiceField, CodeField, CustomField, DatePickerField, FieldWrapper, FieldWrapperBase, FileInput, FinalForm, Group, InputField, RadioGroup, SegmentedField, SelectField, SwitchField as Switch, TextareaField as Textarea, addRequiredFieldsParamToSchema, emailValidation, focusOnError, focusOnErrorDecorator, formTypes, generateField, phoneValidation, sendFormDataToServer, setErrorsMutator, useYupValidationSchema };
2890
+ const DEFAULT_MESSAGES_FIELDS = {
2891
+ /*
2892
+ !!! it also works without props simply based on the class and key as before `input_state_${meta.error.key}`
2893
+ the KEY is needed for example for border color
2894
+ the name of the key is anything you want, the main thing is that there is a props with the same KEY and color in FieldProps
2895
+ ...example
2896
+ required - KEY for yellow color
2897
+ error - KEY for red color
2898
+ custom or blue - KEY blue or other color
2899
+ requiredBorderColor: 'warningBorderPrimary',
2900
+ errorBorderColor: 'errorBorderPrimary',
2901
+ customBorderColor: 'customBorderPrimary',
2902
+ blueBorderColor: 'blueBorderPrimary',
2903
+ const defaultFieldProps = {
2904
+ messageTextSize: 's',
2905
+ messageTextColor: 'surfaceTextSecondary',
2906
+ requiredMessageTextSize: 's',
2907
+ requiredMessageTextColor: 'warningTextPrimary',
2908
+ errorMessageTextSize: 's',
2909
+ errorMessageTextColor: 'errorTextPrimary',
2910
+ }
2911
+ // INPUT
2912
+ const defaultInputProps = {
2913
+ ... other
2914
+ stateBorderColor: 'surfaceBorderTertiary',
2915
+ requiredStateBorderColor: 'warningBorderPrimary',
2916
+ errorStateBorderColor: 'errorBorderPrimary',
2917
+ }
2918
+ // RADIO
2919
+ const defaultRadioProps = {
2920
+ ... other
2921
+ stateBorderColor: 'surfaceBorderTertiary',
2922
+ requiredStateBorderColor: 'warningBorderPrimary',
2923
+ errorStateBorderColor: 'errorBorderPrimary',
2924
+ }
2925
+ // SELECT
2926
+ const defaultSelectProps = {
2927
+ ... other
2928
+ borderColor: 'surfaceBorderTertiary',
2929
+ requiredBorderColor: 'warningBorderPrimary',
2930
+ errorBorderColor: 'errorBorderPrimary',
2931
+ inputBorderColor: 'surfaceBorderTertiary',
2932
+ requiredInputBorderColor: 'warningBorderPrimary',
2933
+ errorInputBorderColor: 'errorBorderPrimary',
2934
+ }
2935
+ ... etc
2936
+ */
2937
+
2938
+ // DEFAULT
2939
+ // required - KEY for yellow color
2940
+ // error - KEY for red color
2941
+
2942
+ // key: 'required'
2943
+ required: {
2944
+ key: 'required',
2945
+ message: 'Обязательное поле'
2946
+ },
2947
+ phone_required: {
2948
+ key: 'required',
2949
+ message: 'Укажите номер телефона'
2950
+ },
2951
+ email_required: {
2952
+ key: 'required',
2953
+ message: 'Укажите адрес электронной почты'
2954
+ },
2955
+ password_required: {
2956
+ key: 'required',
2957
+ message: 'Введите пароль'
2958
+ },
2959
+ phone_or_email_required: {
2960
+ key: 'required',
2961
+ message: 'Введите телефон или адрес эл. почты'
2962
+ },
2963
+ // key: 'error'
2964
+ matches: {
2965
+ key: 'error',
2966
+ message: 'Допускается ввод только цифр от 0 до 9'
2967
+ },
2968
+ min: {
2969
+ key: 'error',
2970
+ message: ({
2971
+ min
2972
+ }) => `Значение должно быть не менее ${min} символов`
2973
+ },
2974
+ max: {
2975
+ key: 'error',
2976
+ message: ({
2977
+ max
2978
+ }) => `Значение должно быть не менее ${max} символов`
2979
+ },
2980
+ url: {
2981
+ key: 'error',
2982
+ message: 'Введите корректный URL-адрес'
2983
+ },
2984
+ invalid_value: {
2985
+ key: 'error',
2986
+ message: 'Некорректное значение'
2987
+ },
2988
+ numeric_value: {
2989
+ key: 'error',
2990
+ message: 'Только числовое значение'
2991
+ },
2992
+ phone_error: {
2993
+ key: 'error',
2994
+ message: 'Введите корректный номер телефона'
2995
+ },
2996
+ email_error: {
2997
+ key: 'error',
2998
+ message: 'Введите корректный адрес электронной почты'
2999
+ }
3000
+ };
3001
+
3002
+ export { CheckboxField as Checkbox, ChoiceField, CodeField, CustomField, DEFAULT_MESSAGES_FIELDS, DatePickerField, FieldWrapper, FieldWrapperBase, FileInput, FinalForm, Group, InputField, MaskedInputField, RadioGroup, SegmentedField, SelectField, SwitchField as Switch, TextareaField as Textarea, addRequiredFieldsParamToSchema, emailValidation, focusOnError, focusOnErrorDecorator, formTypes, generateField, phoneValidation, sendFormDataToServer, setErrorsMutator, useYupValidationSchema };