@itcase/forms 1.0.59 → 1.0.61

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,50 +569,63 @@ 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]),
499
625
  messageType: PropTypes.string,
500
626
  name: PropTypes.string,
501
- options: Choice.propTypes.options,
502
627
  placeholder: PropTypes.string,
628
+ showMessage: PropTypes.bool,
503
629
  onChange: PropTypes.func
504
630
  };
505
631
 
@@ -515,45 +641,68 @@ const CustomField = /*#__PURE__*/React.memo(function CustomField(props) {
515
641
  showMessage
516
642
  } = props;
517
643
  return /*#__PURE__*/React.createElement(Field, {
518
- name: name,
519
- initialValue: initialValue
520
- }, ({
644
+ initialValue: initialValue,
645
+ name: name
646
+ }, function Render({
521
647
  input,
522
648
  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
- }))));
649
+ }) {
650
+ /** Note:
651
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
652
+ * React Hooks cannot be called inside a callback.
653
+ * React Hooks must be called in a React function component or a
654
+ * custom React Hook function.
655
+ */
656
+
657
+ const {
658
+ isErrorState,
659
+ isValidState,
660
+ errorKey,
661
+ errorMessage
662
+ } = useFieldValidationState({
663
+ fieldProps: fieldProps,
664
+ input: input,
665
+ meta: meta
666
+ });
667
+ const updatedInputProps = useValidationAppearanceInputProps({
668
+ validationStateKey: isErrorState ? errorKey : 'success',
669
+ // For "Custom" field we pass all props. Can contain some special props, we don't known.
670
+ inputProps: props
671
+ });
672
+ return /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
673
+ className: clsx('form-field_type_custom', 'form__item_type_custom', classNameGroupItem),
674
+ errorKey: errorKey,
675
+ errorMessage: errorMessage,
676
+ fieldClassName: 'form-custom',
677
+ inputName: input.name,
678
+ inputValue: input.value,
679
+ isDisabled: isDisabled,
680
+ isErrorState: isErrorState,
681
+ isRequired: isRequired,
682
+ isValidState: isValidState,
683
+ metaActive: meta.active,
684
+ metaError: meta.error,
685
+ showMessage: showMessage
686
+ }, fieldProps), /*#__PURE__*/React.createElement(Component, Object.assign({}, updatedInputProps, {
687
+ input: input,
688
+ isDisabled: isDisabled,
689
+ meta: meta
690
+ })));
691
+ });
543
692
  });
544
693
  CustomField.defaultProps = {
545
694
  inputProps: {},
546
695
  fieldProps: {}
547
696
  };
548
697
  CustomField.propTypes = {
549
- Component: PropTypes.element,
698
+ name: PropTypes.string.isRequired,
550
699
  classNameGroupItem: PropTypes.string,
700
+ Component: PropTypes.element,
551
701
  fieldProps: PropTypes.object,
552
702
  initialValue: PropTypes.any,
553
703
  inputProps: PropTypes.object,
554
704
  isDisabled: PropTypes.bool,
555
705
  isRequired: PropTypes.bool,
556
- name: PropTypes.string.isRequired,
557
706
  showMessage: PropTypes.bool
558
707
  };
559
708
 
@@ -571,33 +720,55 @@ const CodeField = /*#__PURE__*/React.memo(function CodeField(props) {
571
720
  return /*#__PURE__*/React.createElement(Field, {
572
721
  name: name,
573
722
  initialValue: initialValue
574
- }, ({
723
+ }, function Render({
575
724
  input,
576
725
  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))));
726
+ }) {
727
+ /** Note:
728
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
729
+ * React Hooks cannot be called inside a callback.
730
+ * React Hooks must be called in a React function component or a
731
+ * custom React Hook function.
732
+ */
733
+
734
+ const {
735
+ isErrorState,
736
+ isValidState,
737
+ errorKey,
738
+ errorMessage
739
+ } = useFieldValidationState({
740
+ fieldProps: fieldProps,
741
+ input: input,
742
+ meta: meta
743
+ });
744
+ const updatedInputProps = useValidationAppearanceInputProps({
745
+ validationStateKey: isErrorState ? errorKey : 'success',
746
+ inputProps: inputProps
747
+ });
748
+ return /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
749
+ className: clsx('form-field_type_code', 'form__item_type_code', classNameGroupItem),
750
+ fieldClassName: 'form-code',
751
+ inputName: input.name,
752
+ inputValue: input.value,
753
+ isRequired: isRequired,
754
+ isDisabled: isDisabled,
755
+ metaActive: meta.active,
756
+ metaError: meta.error,
757
+ showMessage: showMessage,
758
+ isErrorState: isErrorState,
759
+ isValidState: isValidState,
760
+ errorKey: errorKey,
761
+ errorMessage: errorMessage
762
+ }, fieldProps), /*#__PURE__*/React.createElement(Code, Object.assign({
763
+ autoComplete: "nope",
764
+ name: input.name,
765
+ isDisabled: isDisabled,
766
+ value: input.value,
767
+ onBlur: input.onBlur,
768
+ onChange: input.onChange,
769
+ onFocus: input.onFocus
770
+ }, updatedInputProps)));
771
+ });
601
772
  });
602
773
  CodeField.defaultProps = {
603
774
  inputProps: {},
@@ -616,60 +787,72 @@ CodeField.propTypes = {
616
787
 
617
788
  function DatePickerField(props) {
618
789
  const {
619
- isRequired,
790
+ classNameGroupItem,
791
+ datePickerProps,
620
792
  fieldProps,
621
793
  inputProps,
622
- datePickerProps,
623
- name,
624
- iconSize,
625
- iconBorder,
626
- iconBorderHover,
627
- iconFill,
628
- iconFillHover,
629
794
  isDisabled,
630
- iconRevealableShow,
631
- iconRevealableHide,
632
- iconShape,
795
+ isRequired,
796
+ name,
633
797
  showMessage,
634
- onChange,
635
- classNameGroupItem
798
+ onChange
636
799
  } = props;
637
800
  return /*#__PURE__*/React.createElement(Field, {
638
801
  name: name
639
- }, ({
802
+ }, function Render({
640
803
  input,
641
804
  meta
642
- }) => {
805
+ }) {
806
+ /** Note:
807
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
808
+ * React Hooks cannot be called inside a callback.
809
+ * React Hooks must be called in a React function component or a
810
+ * custom React Hook function.
811
+ */
812
+
643
813
  const onChangeField = useCallback(value => {
644
814
  input.onChange(value);
645
815
  if (onChange) {
646
816
  onChange(value, input.name);
647
817
  }
648
- }, [onChange]);
818
+ }, [onChange, input.onChange]);
819
+ const {
820
+ isErrorState,
821
+ isValidState,
822
+ errorKey,
823
+ errorMessage
824
+ } = useFieldValidationState({
825
+ fieldProps: fieldProps,
826
+ input: input,
827
+ meta: meta
828
+ });
829
+ const updatedInputProps = useValidationAppearanceInputProps({
830
+ validationStateKey: isErrorState ? errorKey : 'success',
831
+ inputProps: inputProps
832
+ });
649
833
  return /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
650
834
  className: clsx('form-field_type_datepicker', 'form__item_type_datepicker', classNameGroupItem),
835
+ errorKey: errorKey,
836
+ errorMessage: errorMessage,
651
837
  fieldClassName: "form-datepicker",
652
838
  inputName: input.name,
653
839
  inputValue: input.value || '',
654
- isRequired: isRequired,
655
840
  isDisabled: isDisabled,
841
+ isErrorState: isErrorState,
842
+ isRequired: isRequired,
843
+ isValidState: isValidState,
656
844
  metaActive: meta.active,
657
845
  metaError: meta.error,
658
- metaModifiedSinceLastSubmit: meta.modifiedSinceLastSubmit,
659
- metaSubmitError: meta.submitError,
660
- metaSubmitFailed: meta.submitFailed,
661
- metaTouched: meta.touched,
662
- metaValid: meta.valid,
663
846
  showMessage: showMessage
664
847
  }, fieldProps), /*#__PURE__*/React.createElement(DatePickerInput, {
848
+ datePickerProps: datePickerProps,
849
+ inputProps: updatedInputProps,
850
+ isDisabled: isDisabled,
665
851
  name: input.name,
666
852
  value: input.value || '',
667
853
  onBlur: input.onBlur,
668
- isDisabled: isDisabled,
669
854
  onChange: onChangeField,
670
- onFocus: input.onFocus,
671
- inputProps: inputProps,
672
- datePickerProps: datePickerProps
855
+ onFocus: input.onFocus
673
856
  }));
674
857
  });
675
858
  }
@@ -678,10 +861,14 @@ DatePickerField.defaultProps = {
678
861
  fieldProps: {}
679
862
  };
680
863
  DatePickerField.propTypes = {
864
+ name: PropTypes.string.isRequired,
865
+ classNameGroupItem: PropTypes.string,
866
+ datePickerProps: PropTypes.object,
681
867
  fieldProps: PropTypes.object,
682
868
  inputProps: PropTypes.object,
869
+ isDisabled: PropTypes.bool,
683
870
  isRequired: PropTypes.bool,
684
- name: PropTypes.string.isRequired,
871
+ showMessage: PropTypes.bool,
685
872
  onChange: PropTypes.func
686
873
  };
687
874
 
@@ -1072,7 +1259,6 @@ const FileInput = /*#__PURE__*/React.memo(function FileInput(props) {
1072
1259
  shape,
1073
1260
  size,
1074
1261
  borderWidth,
1075
- borderColor,
1076
1262
  borderColorHover,
1077
1263
  borderType,
1078
1264
  label,
@@ -1124,77 +1310,104 @@ const FileInput = /*#__PURE__*/React.memo(function FileInput(props) {
1124
1310
  } = props;
1125
1311
  return /*#__PURE__*/React.createElement(Field, {
1126
1312
  name: name
1127
- }, ({
1313
+ }, function Render({
1128
1314
  input,
1129
1315
  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
- })));
1316
+ }) {
1317
+ /** Note:
1318
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
1319
+ * React Hooks cannot be called inside a callback.
1320
+ * React Hooks must be called in a React function component or a
1321
+ * custom React Hook function.
1322
+ */
1323
+
1324
+ const {
1325
+ isErrorState,
1326
+ isValidState,
1327
+ errorKey,
1328
+ errorMessage
1329
+ } = useFieldValidationState({
1330
+ fieldProps: fieldProps,
1331
+ input: input,
1332
+ meta: meta
1333
+ });
1334
+ const updatedInputProps = useValidationAppearanceInputProps({
1335
+ validationStateKey: isErrorState ? errorKey : 'success',
1336
+ inputProps: props
1337
+ });
1338
+
1339
+ /** TODO:
1340
+ * REFACTOR PROPERTIES
1341
+ */
1342
+ return /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
1343
+ className: clsx('form-field_type_dropzone', 'form__item_type_dropzone', classNameGroupItem),
1344
+ fieldClassName: "form-dropzone",
1345
+ inputName: input.name,
1346
+ inputValue: input.value,
1347
+ isRequired: isRequired,
1348
+ label: label,
1349
+ labelTextColor: labelTextColor,
1350
+ metaActive: meta.active,
1351
+ metaError: meta.error,
1352
+ metaTouched: meta.touched,
1353
+ showMessage: showMessage,
1354
+ width: width,
1355
+ isErrorState: isErrorState,
1356
+ isValidState: isValidState,
1357
+ errorKey: errorKey,
1358
+ errorMessage: errorMessage
1359
+ }, fieldProps), /*#__PURE__*/React.createElement(FileInputDropzone, {
1360
+ dropzoneProps: dropzoneProps,
1361
+ hintDescription: hintDescription,
1362
+ hintTitle: hintTitle,
1363
+ borderWidth: borderWidth,
1364
+ borderColor: updatedInputProps.borderColor,
1365
+ borderColorHover: borderColorHover,
1366
+ borderType: borderType,
1367
+ thumbBorderWidth: thumbBorderWidth,
1368
+ thumbBorderColor: thumbBorderColor,
1369
+ thumbBorderColorHover: thumbBorderColorHover,
1370
+ thumbBorderType: thumbBorderType,
1371
+ fileErrorText: fileErrorText,
1372
+ fill: fill,
1373
+ size: size,
1374
+ maxFiles: maxFiles,
1375
+ maxSize: maxSize,
1376
+ removeThumbTextHoverColor: removeThumbTextHoverColor,
1377
+ fillHover: fillHover,
1378
+ className: className,
1379
+ thumbColumn: thumbColumn,
1380
+ thumbDirection: thumbDirection,
1381
+ inputName: input.name,
1382
+ inputValue: input.value,
1383
+ thumbNameTextSize: thumbNameTextSize,
1384
+ thumbNameTextColor: thumbNameTextColor,
1385
+ thumbNameTextWrap: thumbNameTextWrap,
1386
+ thumbNameTextWeight: thumbNameTextWeight,
1387
+ hintTitleTextSize: hintTitleTextSize,
1388
+ hintTitleTextColor: hintTitleTextColor,
1389
+ hintTitleTextWrap: hintTitleTextWrap,
1390
+ hintTitleTextWeight: hintTitleTextWeight,
1391
+ removeThumbTextSize: removeThumbTextSize,
1392
+ removeThumbTextColor: removeThumbTextColor,
1393
+ removeThumbTextWeight: removeThumbTextWeight,
1394
+ hintDescriptionTextSize: hintDescriptionTextSize,
1395
+ hintDescriptionTextColor: hintDescriptionTextColor,
1396
+ hintDescriptionTextWrap: hintDescriptionTextWrap,
1397
+ hintDescriptionTextWeight: hintDescriptionTextWeight,
1398
+ errorMessageTextSize: errorMessageTextSize,
1399
+ errorMessageWeight: errorMessageTextWeight,
1400
+ errorMessageTextColor: errorMessageTextColor,
1401
+ isPreviews: isPreviews,
1402
+ shape: shape,
1403
+ showFilename: showFilename,
1404
+ metaError: meta.error,
1405
+ metaTouched: meta.touched,
1406
+ removeThumbText: removeThumbText,
1407
+ onAddFiles: onAddFiles,
1408
+ onDeleteFile: onDeleteFile
1409
+ }));
1410
+ });
1198
1411
  });
1199
1412
  FileInput.defaultProps = {
1200
1413
  errorMessageTextSize: 's',
@@ -1231,32 +1444,41 @@ const Group = /*#__PURE__*/React.memo(function Group(props) {
1231
1444
  labelTextSize,
1232
1445
  labelTextWeight,
1233
1446
  message,
1234
- errorMessageTextSize,
1235
- errorMessageTextWeight,
1236
- errorMessageTextColor,
1237
1447
  messageTextSize,
1238
1448
  messageTextWeight,
1239
1449
  messageTextColor,
1240
1450
  children,
1241
1451
  dataTour,
1242
1452
  showGroupMessage,
1243
- name,
1244
- showErrorsOnSubmit
1453
+ name
1245
1454
  } = props;
1246
1455
  return /*#__PURE__*/React.createElement(Field, {
1247
1456
  name: name
1248
- }, ({
1457
+ }, function Render({
1249
1458
  input,
1250
1459
  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]);
1460
+ }) {
1461
+ /** Note:
1462
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
1463
+ * React Hooks cannot be called inside a callback.
1464
+ * React Hooks must be called in a React function component or a
1465
+ * custom React Hook function.
1466
+ */
1467
+ const {
1468
+ isErrorState,
1469
+ isValidState,
1470
+ errorKey,
1471
+ errorMessage
1472
+ } = useFieldValidationState({
1473
+ fieldProps: props,
1474
+ // or fieldProps?
1475
+ input: input,
1476
+ meta: meta
1477
+ });
1478
+ const updatedProps = useValidationAppearanceInputProps({
1479
+ validationStateKey: isErrorState ? errorKey : 'success',
1480
+ inputProps: props
1481
+ });
1260
1482
  return /*#__PURE__*/React.createElement("div", {
1261
1483
  className: clsx('form__group', className),
1262
1484
  "data-tour": dataTour
@@ -1265,23 +1487,23 @@ const Group = /*#__PURE__*/React.memo(function Group(props) {
1265
1487
  }, before, /*#__PURE__*/React.createElement("div", {
1266
1488
  className: "form__group-label"
1267
1489
  }, /*#__PURE__*/React.createElement(Title, {
1268
- textColor: labelTextColor,
1269
1490
  size: labelTextSize,
1491
+ textColor: labelTextColor,
1270
1492
  textWeight: labelTextWeight
1271
1493
  }, label)), /*#__PURE__*/React.createElement("div", {
1272
1494
  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, {
1495
+ }, children), after), showGroupMessage && /*#__PURE__*/React.createElement(React.Fragment, null, isErrorState && errorMessage && /*#__PURE__*/React.createElement(Text, {
1496
+ className: `form__group-message form__group-message_type-${errorKey}`,
1497
+ id: `${name}-error`,
1498
+ size: updatedProps.messageTextSize,
1499
+ textColor: updatedProps.messageTextColor,
1500
+ textWeight: updatedProps.messageTextWeight
1501
+ }, errorMessage), Boolean(message) && (!isErrorState || !errorMessage) && /*#__PURE__*/React.createElement(Text, {
1280
1502
  className: "form__group-message",
1281
1503
  size: messageTextSize,
1282
- textWeight: messageTextWeight,
1283
- textColor: messageTextColor
1284
- }, message), Boolean(!showError) && Boolean(!message) && /*#__PURE__*/React.createElement(Text, {
1504
+ textColor: messageTextColor,
1505
+ textWeight: messageTextWeight
1506
+ }, message), !isErrorState && !message && /*#__PURE__*/React.createElement(Text, {
1285
1507
  className: "form__group-message",
1286
1508
  size: messageTextSize
1287
1509
  }, '\u00A0')));
@@ -1298,34 +1520,34 @@ Group.defaultProps = {
1298
1520
  };
1299
1521
  Group.propTypes = {
1300
1522
  name: PropTypes.string.isRequired,
1301
- isRequired: PropTypes.bool,
1302
1523
  fieldProps: PropTypes.object,
1303
- inputProps: PropTypes.object
1524
+ inputProps: PropTypes.object,
1525
+ isRequired: PropTypes.bool
1304
1526
  };
1305
1527
 
1306
1528
  const InputField = /*#__PURE__*/React.memo(function InputField(props) {
1307
1529
  const {
1308
- isPassword,
1309
- isRequired,
1530
+ classNameGroupItem,
1310
1531
  fieldProps,
1311
- inputProps,
1312
- isRevealable,
1313
- name,
1314
- parse,
1315
- dataTestId,
1316
- iconSize,
1317
- isDisabled,
1318
- iconBorder,
1319
- iconBorderHover,
1320
1532
  iconFill,
1321
1533
  iconFillHover,
1322
1534
  iconRevealableHide,
1323
1535
  iconRevealableShow,
1324
1536
  iconShape,
1537
+ iconSize,
1325
1538
  initialValue,
1539
+ inputProps,
1540
+ isDisabled,
1541
+ isPassword,
1542
+ isRequired,
1543
+ isRevealable,
1544
+ name,
1545
+ parse,
1326
1546
  showMessage,
1327
- onChange,
1328
- classNameGroupItem
1547
+ onChange
1548
+ // dataTestId,
1549
+ // iconBorder,
1550
+ // iconBorderHover,
1329
1551
  } = props;
1330
1552
  const [isRevealed, setIsRevealed] = useState(false);
1331
1553
  const inputType = useMemo(() => {
@@ -1335,59 +1557,79 @@ const InputField = /*#__PURE__*/React.memo(function InputField(props) {
1335
1557
  return 'text';
1336
1558
  }
1337
1559
  }, [isRevealed, isPassword]);
1338
- const revealeHandler = useCallback(e => {
1339
- e.preventDefault();
1560
+ const onClickIconReveal = useCallback(event => {
1561
+ event.preventDefault();
1340
1562
  setIsRevealed(prev => !prev);
1341
- }, [setIsRevealed]);
1563
+ }, []);
1342
1564
  return /*#__PURE__*/React.createElement(Field, {
1565
+ initialValue: initialValue,
1343
1566
  name: name,
1344
- parse: parse,
1345
- initialValue: initialValue
1346
- }, ({
1567
+ parse: parse
1568
+ }, function Render({
1347
1569
  input,
1348
1570
  meta
1349
- }) => {
1571
+ }) {
1572
+ /** Note:
1573
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
1574
+ * React Hooks cannot be called inside a callback.
1575
+ * React Hooks must be called in a React function component or a
1576
+ * custom React Hook function.
1577
+ */
1578
+
1350
1579
  const onChangeField = useCallback(event => {
1351
1580
  input.onChange(event);
1352
1581
  if (onChange) {
1353
1582
  onChange(event.target.value, input.name);
1354
1583
  }
1355
- }, [onChange]);
1584
+ }, [onChange, input.onChange]);
1585
+ const {
1586
+ isErrorState,
1587
+ isValidState,
1588
+ errorKey,
1589
+ errorMessage
1590
+ } = useFieldValidationState({
1591
+ fieldProps: fieldProps,
1592
+ input: input,
1593
+ meta: meta
1594
+ });
1595
+ const updatedInputProps = useValidationAppearanceInputProps({
1596
+ validationStateKey: isErrorState ? errorKey : 'success',
1597
+ inputProps: inputProps
1598
+ });
1356
1599
  return /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
1357
1600
  className: clsx('form-field_type_input', 'form__item_type_input', classNameGroupItem),
1601
+ errorKey: errorKey,
1602
+ errorMessage: errorMessage,
1358
1603
  fieldClassName: isRevealable ? 'form-password' : 'form-input',
1359
1604
  inputName: input.name,
1360
1605
  inputValue: input.value || '',
1361
- isRequired: isRequired,
1362
1606
  isDisabled: isDisabled,
1607
+ isErrorState: isErrorState,
1608
+ isRequired: isRequired,
1609
+ isValidState: isValidState,
1363
1610
  metaActive: meta.active,
1364
1611
  metaError: meta.error,
1365
- metaModifiedSinceLastSubmit: meta.modifiedSinceLastSubmit,
1366
- metaSubmitError: meta.submitError,
1367
- metaSubmitFailed: meta.submitFailed,
1368
- metaTouched: meta.touched,
1369
- metaValid: meta.valid,
1370
1612
  showMessage: showMessage
1371
1613
  }, fieldProps), /*#__PURE__*/React.createElement(Input, Object.assign({
1372
- className: clsx(meta.active && 'input_state_focus', meta.error && meta.touched && 'input_state_error'),
1373
1614
  autoComplete: "nope",
1615
+ className: clsx(meta.active && 'input_state_focus', meta.error && meta.touched && `input_state_${errorKey}`),
1616
+ dataTestId: `${input.name}FieldInput`,
1617
+ isDisabled: isDisabled,
1374
1618
  name: input.name,
1375
1619
  type: inputType,
1376
1620
  value: input.value || '',
1377
1621
  onBlur: input.onBlur,
1378
1622
  onChange: onChangeField,
1379
- onFocus: input.onFocus,
1380
- isDisabled: isDisabled,
1381
- dataTestId: `${input.name}FieldInput`
1382
- }, inputProps)), isRevealable && /*#__PURE__*/React.createElement(Icon, {
1623
+ onFocus: input.onFocus
1624
+ }, updatedInputProps)), isRevealable && /*#__PURE__*/React.createElement(Icon, {
1383
1625
  className: "form-field__icon",
1384
1626
  iconFill: iconFill,
1385
1627
  iconFillHover: iconFillHover,
1386
- SvgImage: isRevealed ? iconRevealableHide : iconRevealableShow,
1387
1628
  imageSrc: isRevealed ? iconRevealableHide : iconRevealableShow,
1388
1629
  shape: iconShape,
1389
1630
  size: iconSize,
1390
- onClick: revealeHandler
1631
+ SvgImage: isRevealed ? iconRevealableHide : iconRevealableShow,
1632
+ onClick: onClickIconReveal
1391
1633
  }));
1392
1634
  });
1393
1635
  });
@@ -1396,13 +1638,26 @@ InputField.defaultProps = {
1396
1638
  fieldProps: {}
1397
1639
  };
1398
1640
  InputField.propTypes = {
1641
+ name: PropTypes.string.isRequired,
1642
+ classNameGroupItem: PropTypes.string,
1643
+ dataTestId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
1399
1644
  fieldProps: PropTypes.object,
1645
+ iconBorder: PropTypes.string,
1646
+ iconBorderHover: PropTypes.string,
1647
+ iconFill: PropTypes.string,
1648
+ iconFillHover: PropTypes.string,
1649
+ iconRevealableHide: PropTypes.oneOfType([PropTypes.elementType, PropTypes.func, PropTypes.object]),
1650
+ iconRevealableShow: PropTypes.oneOfType([PropTypes.elementType, PropTypes.func, PropTypes.object]),
1651
+ iconShape: PropTypes.oneOf(shapeProps),
1652
+ iconSize: PropTypes.oneOf(iconSizeProps),
1400
1653
  initialValue: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
1401
1654
  inputProps: PropTypes.object,
1655
+ isDisabled: PropTypes.bool,
1402
1656
  isPassword: PropTypes.bool,
1403
1657
  isRequired: PropTypes.bool,
1404
1658
  isRevealable: PropTypes.bool,
1405
- name: PropTypes.string.isRequired,
1659
+ parse: PropTypes.func,
1660
+ showMessage: PropTypes.bool,
1406
1661
  onChange: PropTypes.func
1407
1662
  };
1408
1663
 
@@ -1559,32 +1814,54 @@ const RadioGroup = /*#__PURE__*/React.memo(function RadioGroup(props) {
1559
1814
  } = props;
1560
1815
  return /*#__PURE__*/React.createElement(Field, {
1561
1816
  name: name
1562
- }, ({
1817
+ }, function Render({
1563
1818
  input,
1564
1819
  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
- })));
1820
+ }) {
1821
+ /** Note:
1822
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
1823
+ * React Hooks cannot be called inside a callback.
1824
+ * React Hooks must be called in a React function component or a
1825
+ * custom React Hook function.
1826
+ */
1827
+
1828
+ const {
1829
+ isErrorState,
1830
+ isValidState,
1831
+ errorKey,
1832
+ errorMessage
1833
+ } = useFieldValidationState({
1834
+ fieldProps: fieldProps,
1835
+ input: input,
1836
+ meta: meta
1837
+ });
1838
+ const updatedInputProps = useValidationAppearanceInputProps({
1839
+ validationStateKey: isErrorState ? errorKey : 'success',
1840
+ inputProps: inputProps
1841
+ });
1842
+ return /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
1843
+ className: "form__item_type_radio",
1844
+ errorKey: errorKey,
1845
+ errorMessage: errorMessage,
1846
+ fieldClassName: 'form-radio',
1847
+ inputName: input.name,
1848
+ inputValue: input.value || '',
1849
+ isDisabled: isDisabled,
1850
+ isErrorState: isErrorState,
1851
+ isRequired: isRequired,
1852
+ isValidState: isValidState,
1853
+ metaActive: meta.active,
1854
+ metaError: meta.error,
1855
+ showMessage: showMessage
1856
+ }, fieldProps), /*#__PURE__*/React.createElement(RadioGroupList, {
1857
+ editableProps: editableProps,
1858
+ input: input,
1859
+ inputProps: updatedInputProps,
1860
+ isDisabled: isDisabled,
1861
+ options: options,
1862
+ onChange: onChange
1863
+ }));
1864
+ });
1588
1865
  });
1589
1866
  RadioGroup.defaultProps = {
1590
1867
  editableProps: {},
@@ -1593,12 +1870,12 @@ RadioGroup.defaultProps = {
1593
1870
  options: []
1594
1871
  };
1595
1872
  RadioGroup.propTypes = {
1873
+ name: PropTypes.string.isRequired,
1596
1874
  editableProps: PropTypes.object,
1597
1875
  fieldProps: PropTypes.object,
1598
1876
  inputProps: PropTypes.object,
1599
1877
  isDisabled: PropTypes.bool,
1600
1878
  isRequired: PropTypes.bool,
1601
- name: PropTypes.string.isRequired,
1602
1879
  options: PropTypes.array,
1603
1880
  showMessage: PropTypes.bool,
1604
1881
  onChange: PropTypes.func
@@ -1622,10 +1899,17 @@ function SegmentedField(props) {
1622
1899
  }, [change]);
1623
1900
  return /*#__PURE__*/React.createElement(Field, {
1624
1901
  name: name
1625
- }, ({
1902
+ }, function Render({
1626
1903
  input,
1627
1904
  meta
1628
- }) => {
1905
+ }) {
1906
+ /** Note:
1907
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
1908
+ * React Hooks cannot be called inside a callback.
1909
+ * React Hooks must be called in a React function component or a
1910
+ * custom React Hook function.
1911
+ */
1912
+
1629
1913
  const activeOption = useMemo(() => {
1630
1914
  const emptyOption = {
1631
1915
  value: null,
@@ -1637,30 +1921,45 @@ function SegmentedField(props) {
1637
1921
  }
1638
1922
  return emptyOption;
1639
1923
  }, [input.value]);
1924
+ const {
1925
+ isErrorState,
1926
+ isValidState,
1927
+ errorKey,
1928
+ errorMessage
1929
+ } = useFieldValidationState({
1930
+ fieldProps: fieldProps,
1931
+ input: input,
1932
+ meta: meta
1933
+ });
1934
+ const updatedInputProps = useValidationAppearanceInputProps({
1935
+ validationStateKey: isErrorState ? errorKey : 'success',
1936
+ inputProps: inputProps
1937
+ });
1640
1938
  return /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
1641
1939
  className: clsx('form-field_type_segmented', 'form__item_type_segmented'),
1940
+ errorKey: errorKey,
1941
+ errorMessage: errorMessage,
1642
1942
  fieldClassName: "form-segmented",
1643
1943
  inputName: input.name,
1644
1944
  inputValue: input.value || [],
1645
- isRequired: isRequired,
1646
1945
  isDisabled: isDisabled,
1946
+ isErrorState: isErrorState,
1947
+ isRequired: isRequired,
1948
+ isValidState: isValidState,
1647
1949
  metaActive: meta.active,
1648
1950
  metaError: meta.error,
1649
- metaModifiedSinceLastSubmit: meta.modifiedSinceLastSubmit,
1650
- metaSubmitError: meta.submitError,
1651
- metaSubmitFailed: meta.submitFailed,
1652
- metaTouched: meta.touched,
1653
- metaValid: meta.valid,
1654
1951
  showMessage: showMessage
1655
1952
  }, fieldProps), /*#__PURE__*/React.createElement(Segmented, Object.assign({
1656
- segments: options,
1953
+ activeSegment: activeOption,
1657
1954
  isDisabled: isDisabled,
1658
- setActiveSegment: setActiveSegment,
1659
- activeSegment: activeOption
1660
- }, inputProps)));
1955
+ segments: options,
1956
+ setActiveSegment: setActiveSegment
1957
+ }, updatedInputProps)));
1661
1958
  });
1662
1959
  }
1663
1960
  SegmentedField.propTypes = {
1961
+ name: PropTypes.string.isRequired,
1962
+ options: PropTypes.array.isRequired,
1664
1963
  className: PropTypes.string,
1665
1964
  fieldProps: PropTypes.object,
1666
1965
  inputClass: PropTypes.string,
@@ -1668,8 +1967,6 @@ SegmentedField.propTypes = {
1668
1967
  isDisabled: PropTypes.bool,
1669
1968
  isRequired: PropTypes.bool,
1670
1969
  label: PropTypes.string,
1671
- name: PropTypes.string.isRequired,
1672
- options: PropTypes.array.isRequired,
1673
1970
  placeholder: PropTypes.string,
1674
1971
  showMessage: PropTypes.bool
1675
1972
  };
@@ -1707,10 +2004,16 @@ const SelectField = /*#__PURE__*/React.memo(function SelectField(props) {
1707
2004
  } = props;
1708
2005
  return /*#__PURE__*/React.createElement(Field, {
1709
2006
  name: name
1710
- }, ({
2007
+ }, function Render({
1711
2008
  input,
1712
2009
  meta
1713
- }) => {
2010
+ }) {
2011
+ /** Note:
2012
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
2013
+ * React Hooks cannot be called inside a callback.
2014
+ * React Hooks must be called in a React function component or a
2015
+ * custom React Hook function.
2016
+ */
1714
2017
  const [selectedOptions, setSelectedOptions] = useState(null);
1715
2018
  const defaultValue = useMemo(() => {
1716
2019
  const optionsValues = getDefaultValue(options, input.value);
@@ -1727,47 +2030,60 @@ const SelectField = /*#__PURE__*/React.memo(function SelectField(props) {
1727
2030
  if (onChange) {
1728
2031
  onChange(value, input.name);
1729
2032
  }
1730
- }, [onChange]);
2033
+ }, [onChange, input.onChange]);
1731
2034
  const onChangeValue = useCallback((option, actionMeta) => {
1732
2035
  const value = Array.isArray(option) ? option.map(o => o.value) : option?.value || null;
1733
2036
  setSelectedOptions(option);
1734
2037
  onChangeField(value);
1735
2038
  }, [onChangeField]);
1736
2039
  useEffect(() => setSelectedOptions(defaultValue), [defaultValue]);
2040
+ const {
2041
+ isErrorState,
2042
+ isValidState,
2043
+ errorKey,
2044
+ errorMessage
2045
+ } = useFieldValidationState({
2046
+ fieldProps: fieldProps,
2047
+ input: input,
2048
+ meta: meta
2049
+ });
2050
+ const updatedSelectProps = useValidationAppearanceInputProps({
2051
+ validationStateKey: isErrorState ? errorKey : 'success',
2052
+ inputProps: selectProps
2053
+ });
1737
2054
  return /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
1738
2055
  className: clsx('form-field_type_select', 'form__item_type_select', classNameGroupItem),
2056
+ errorKey: errorKey,
2057
+ errorMessage: errorMessage,
1739
2058
  fieldClassName: 'form-select',
1740
2059
  inputName: input.name,
1741
2060
  inputValue: input.value,
1742
- isRequired: isRequired,
1743
2061
  isDisabled: isDisabled,
2062
+ isErrorState: isErrorState,
2063
+ isRequired: isRequired,
2064
+ isValidState: isValidState,
1744
2065
  metaActive: meta.active,
1745
2066
  metaError: meta.error,
1746
- metaModifiedSinceLastSubmit: meta.modifiedSinceLastSubmit,
1747
- metaSubmitError: meta.submitError,
1748
- metaSubmitFailed: meta.submitFailed,
1749
- metaTouched: meta.touched,
1750
- metaValid: meta.valid,
1751
2067
  showMessage: showMessage
1752
2068
  }, fieldProps), /*#__PURE__*/React.createElement(Select, Object.assign({
1753
2069
  className: "form-select-item",
1754
2070
  instanceId: `id_${input.name}`,
1755
- value: selectedOptions,
1756
- onChange: onChangeValue,
1757
2071
  isDisabled: isDisabled,
1758
2072
  options: options,
1759
- ref: selectRef
1760
- }, selectProps)));
2073
+ ref: selectRef,
2074
+ value: selectedOptions,
2075
+ onChange: onChangeValue
2076
+ }, updatedSelectProps)));
1761
2077
  });
1762
2078
  });
1763
2079
  SelectField.propTypes = {
2080
+ name: PropTypes.string.isRequired,
1764
2081
  classNameGroupItem: PropTypes.string,
1765
2082
  fieldProps: PropTypes.object,
1766
2083
  isDisabled: PropTypes.bool,
1767
2084
  isRequired: PropTypes.bool,
1768
2085
  label: PropTypes.any,
1769
2086
  messageType: PropTypes.string,
1770
- name: PropTypes.string.isRequired,
1771
2087
  options: PropTypes.array,
1772
2088
  selectProps: PropTypes.object,
1773
2089
  selectRef: PropTypes.any,
@@ -1789,42 +2105,62 @@ const SwitchField = /*#__PURE__*/React.memo(function SwitchField(props) {
1789
2105
  return /*#__PURE__*/React.createElement(Field, {
1790
2106
  name: name,
1791
2107
  type: "checkbox"
1792
- }, ({
2108
+ }, function Render({
1793
2109
  input,
1794
2110
  meta
1795
- }) => {
2111
+ }) {
2112
+ /** Note:
2113
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
2114
+ * React Hooks cannot be called inside a callback.
2115
+ * React Hooks must be called in a React function component or a
2116
+ * custom React Hook function.
2117
+ */
2118
+
1796
2119
  const onChangeField = useCallback(event => {
1797
2120
  input.onChange(event);
1798
2121
  if (onChange) {
1799
2122
  onChange(event.target.checked, input.name);
1800
2123
  }
1801
- }, [onChange]);
2124
+ }, [onChange, input.onChange]);
2125
+ const {
2126
+ isErrorState,
2127
+ isValidState,
2128
+ errorKey,
2129
+ errorMessage
2130
+ } = useFieldValidationState({
2131
+ fieldProps: fieldProps,
2132
+ input: input,
2133
+ meta: meta
2134
+ });
2135
+ const updatedInputProps = useValidationAppearanceInputProps({
2136
+ validationStateKey: isErrorState ? errorKey : 'success',
2137
+ inputProps: inputProps
2138
+ });
1802
2139
  return /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
1803
2140
  className: clsx('form-field_type_switch', 'form__item_type_switch', classNameGroupItem),
2141
+ errorKey: errorKey,
2142
+ errorMessage: errorMessage,
1804
2143
  fieldClassName: "form-switch",
1805
2144
  inputName: input.name,
1806
2145
  inputValue: input.checked,
1807
- isRequired: isRequired,
1808
2146
  isDisabled: isDisabled,
2147
+ isErrorState: isErrorState,
2148
+ isRequired: isRequired,
2149
+ isValidState: isValidState,
1809
2150
  metaActive: meta.active,
1810
2151
  metaError: meta.error,
1811
- metaModifiedSinceLastSubmit: meta.modifiedSinceLastSubmit,
1812
- metaSubmitError: meta.submitError,
1813
- metaSubmitFailed: meta.submitFailed,
1814
- metaTouched: meta.touched,
1815
- metaValid: meta.valid,
1816
2152
  showMessage: showMessage,
1817
2153
  tag: "label"
1818
2154
  }, fieldProps), /*#__PURE__*/React.createElement(Switch, Object.assign({
1819
2155
  autoComplete: "nope",
1820
- isDisabled: isDisabled,
1821
2156
  checked: input.checked,
2157
+ isDisabled: isDisabled,
1822
2158
  name: input.name,
1823
2159
  type: "checkbox",
1824
2160
  onBlur: input.onBlur,
1825
2161
  onChange: onChangeField,
1826
2162
  onFocus: input.onFocus
1827
- }, inputProps)));
2163
+ }, updatedInputProps)));
1828
2164
  });
1829
2165
  });
1830
2166
  SwitchField.defaultProps = {
@@ -1854,48 +2190,168 @@ const TextareaField = /*#__PURE__*/React.memo(function TextareaField(props) {
1854
2190
  } = props;
1855
2191
  return /*#__PURE__*/React.createElement(Field, {
1856
2192
  name: name
1857
- }, ({
2193
+ }, function Render({
1858
2194
  input,
1859
2195
  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))));
2196
+ }) {
2197
+ /** Note:
2198
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
2199
+ * React Hooks cannot be called inside a callback.
2200
+ * React Hooks must be called in a React function component or a
2201
+ * custom React Hook function.
2202
+ */
2203
+
2204
+ const {
2205
+ isErrorState,
2206
+ isValidState,
2207
+ errorKey,
2208
+ errorMessage
2209
+ } = useFieldValidationState({
2210
+ fieldProps: fieldProps,
2211
+ input: input,
2212
+ meta: meta
2213
+ });
2214
+ const updatedInputProps = useValidationAppearanceInputProps({
2215
+ validationStateKey: isErrorState ? errorKey : 'success',
2216
+ inputProps: inputProps
2217
+ });
2218
+ return /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
2219
+ className: clsx('form-field_type_textarea', 'form__item_type_textarea', classNameGroupItem),
2220
+ errorKey: errorKey,
2221
+ errorMessage: errorMessage,
2222
+ fieldClassName: 'form-textarea',
2223
+ inputName: input.name,
2224
+ inputValue: input.value,
2225
+ isDisabled: isDisabled,
2226
+ isErrorState: isErrorState,
2227
+ isRequired: isRequired,
2228
+ isValidState: isValidState,
2229
+ metaActive: meta.active,
2230
+ metaError: meta.error,
2231
+ showMessage: showMessage
2232
+ }, fieldProps), /*#__PURE__*/React.createElement(Textarea, Object.assign({
2233
+ autoComplete: "nope",
2234
+ isDisabled: isDisabled,
2235
+ name: input.name,
2236
+ value: input.value,
2237
+ onBlur: input.onBlur,
2238
+ onChange: input.onChange,
2239
+ onFocus: input.onFocus
2240
+ }, updatedInputProps)));
2241
+ });
1884
2242
  });
1885
2243
  TextareaField.defaultProps = {
1886
2244
  inputProps: {},
1887
2245
  fieldProps: {}
1888
2246
  };
1889
2247
  TextareaField.propTypes = {
2248
+ name: PropTypes.string.isRequired,
1890
2249
  classNameGroupItem: PropTypes.string,
1891
2250
  fieldProps: PropTypes.object,
1892
2251
  inputProps: PropTypes.object,
1893
2252
  isDisabled: PropTypes.bool,
1894
2253
  isRequired: PropTypes.bool,
1895
- name: PropTypes.string.isRequired,
1896
2254
  showMessage: PropTypes.bool
1897
2255
  };
1898
2256
 
2257
+ const MaskedInputField = /*#__PURE__*/React.memo(function MaskedInputField(props) {
2258
+ const {
2259
+ isDisabled,
2260
+ isRequired,
2261
+ name,
2262
+ initialValue,
2263
+ fieldProps,
2264
+ classNameGroupItem,
2265
+ showMessage,
2266
+ inputProps,
2267
+ optionsMask,
2268
+ unmasked
2269
+ } = props;
2270
+ return /*#__PURE__*/React.createElement(Field, {
2271
+ initialValue: initialValue,
2272
+ name: name
2273
+ }, function Render({
2274
+ input,
2275
+ meta
2276
+ }) {
2277
+ /** Note:
2278
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
2279
+ * React Hooks cannot be called inside a callback.
2280
+ * React Hooks must be called in a React function component or a
2281
+ * custom React Hook function.
2282
+ */
2283
+
2284
+ const {
2285
+ ref,
2286
+ value,
2287
+ unmaskedValue,
2288
+ setUnmaskedValue
2289
+ } = useIMask(optionsMask, {
2290
+ onAccept: (newValue, event, element) => {
2291
+ if (element) {
2292
+ input.onChange(event._unmaskedValue);
2293
+ }
2294
+ }
2295
+ });
2296
+ useEffect(() => {
2297
+ if (input.value !== unmaskedValue) {
2298
+ setUnmaskedValue(input.value.replace(unmasked, ''));
2299
+ }
2300
+ }, [input.value]);
2301
+ const {
2302
+ isErrorState,
2303
+ isValidState,
2304
+ errorKey,
2305
+ errorMessage
2306
+ } = useFieldValidationState({
2307
+ fieldProps: fieldProps,
2308
+ input: input,
2309
+ meta: meta
2310
+ });
2311
+ const updatedInputProps = useValidationAppearanceInputProps({
2312
+ validationStateKey: isErrorState ? errorKey : 'success',
2313
+ inputProps: inputProps
2314
+ });
2315
+ return /*#__PURE__*/React.createElement(FieldWrapper, Object.assign({
2316
+ className: clsx('form-field_type_maskedInput', 'form__item_type_maskedInput', classNameGroupItem),
2317
+ errorKey: errorKey,
2318
+ errorMessage: errorMessage,
2319
+ fieldClassName: 'form-maskedInput',
2320
+ inputName: input.name,
2321
+ inputValue: input.value,
2322
+ isDisabled: isDisabled,
2323
+ isErrorState: isErrorState,
2324
+ isRequired: isRequired,
2325
+ isValidState: isValidState,
2326
+ metaActive: meta.active,
2327
+ metaError: meta.error,
2328
+ showMessage: showMessage
2329
+ }, fieldProps), /*#__PURE__*/React.createElement(Input, Object.assign({
2330
+ className: clsx(meta.active && 'input_state_focus', meta.error && meta.touched && `input_state_${errorKey}`),
2331
+ ref: ref,
2332
+ value: value,
2333
+ onBlur: input.onBlur,
2334
+ onFocus: input.onFocus
2335
+ }, updatedInputProps)));
2336
+ });
2337
+ });
2338
+ MaskedInputField.defaultProps = {
2339
+ inputProps: {},
2340
+ fieldProps: {}
2341
+ };
2342
+ MaskedInputField.propTypes = {
2343
+ name: PropTypes.string.isRequired,
2344
+ classNameGroupItem: PropTypes.string,
2345
+ fieldProps: PropTypes.object,
2346
+ initialValue: PropTypes.any,
2347
+ inputProps: PropTypes.object,
2348
+ isDisabled: PropTypes.bool,
2349
+ isRequired: PropTypes.bool,
2350
+ optionsMask: PropTypes.object,
2351
+ showMessage: PropTypes.bool,
2352
+ unmasked: PropTypes.string
2353
+ };
2354
+
1899
2355
  const focusOnError = (formElementsList, errors) => {
1900
2356
  const selectsIds = Object.keys(errors).map(fieldName => {
1901
2357
  if (fieldName === FORM_ERROR) {
@@ -2020,7 +2476,8 @@ const formTypes = {
2020
2476
  select: 'select',
2021
2477
  switch: 'switch',
2022
2478
  text: 'text',
2023
- textarea: 'textarea'
2479
+ textarea: 'textarea',
2480
+ maskedInput: 'maskedInput'
2024
2481
  };
2025
2482
  function generateField(field, config, props) {
2026
2483
  switch (field.type) {
@@ -2090,6 +2547,12 @@ function generateField(field, config, props) {
2090
2547
  key: config.key
2091
2548
  }, field, props));
2092
2549
  }
2550
+ case formTypes.maskedInput:
2551
+ {
2552
+ return /*#__PURE__*/React.createElement(MaskedInputField, Object.assign({
2553
+ key: config.key
2554
+ }, field, props));
2555
+ }
2093
2556
  case formTypes.custom:
2094
2557
  {
2095
2558
  return /*#__PURE__*/React.createElement(CustomField, Object.assign({
@@ -2423,4 +2886,116 @@ FinalForm.defaultProps = {
2423
2886
  disableFieldsAutoComplete: false
2424
2887
  };
2425
2888
 
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 };
2889
+ const DEFAULT_MESSAGES_FIELDS = {
2890
+ /*
2891
+ !!! it also works without props simply based on the class and key as before `input_state_${meta.error.key}`
2892
+ the KEY is needed for example for border color
2893
+ 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
2894
+ ...example
2895
+ required - KEY for yellow color
2896
+ error - KEY for red color
2897
+ custom or blue - KEY blue or other color
2898
+ requiredBorderColor: 'warningBorderPrimary',
2899
+ errorBorderColor: 'errorBorderPrimary',
2900
+ customBorderColor: 'customBorderPrimary',
2901
+ blueBorderColor: 'blueBorderPrimary',
2902
+ const defaultFieldProps = {
2903
+ messageTextSize: 's',
2904
+ messageTextColor: 'surfaceTextSecondary',
2905
+ requiredMessageTextSize: 's',
2906
+ requiredMessageTextColor: 'warningTextPrimary',
2907
+ errorMessageTextSize: 's',
2908
+ errorMessageTextColor: 'errorTextPrimary',
2909
+ }
2910
+ // INPUT
2911
+ const defaultInputProps = {
2912
+ ... other
2913
+ stateBorderColor: 'surfaceBorderTertiary',
2914
+ requiredStateBorderColor: 'warningBorderPrimary',
2915
+ errorStateBorderColor: 'errorBorderPrimary',
2916
+ }
2917
+ // RADIO
2918
+ const defaultRadioProps = {
2919
+ ... other
2920
+ stateBorderColor: 'surfaceBorderTertiary',
2921
+ requiredStateBorderColor: 'warningBorderPrimary',
2922
+ errorStateBorderColor: 'errorBorderPrimary',
2923
+ }
2924
+ // SELECT
2925
+ const defaultSelectProps = {
2926
+ ... other
2927
+ borderColor: 'surfaceBorderTertiary',
2928
+ requiredBorderColor: 'warningBorderPrimary',
2929
+ errorBorderColor: 'errorBorderPrimary',
2930
+ inputBorderColor: 'surfaceBorderTertiary',
2931
+ requiredInputBorderColor: 'warningBorderPrimary',
2932
+ errorInputBorderColor: 'errorBorderPrimary',
2933
+ }
2934
+ ... etc
2935
+ */
2936
+
2937
+ // DEFAULT
2938
+ // required - KEY for yellow color
2939
+ // error - KEY for red color
2940
+
2941
+ // key: 'required'
2942
+ required: {
2943
+ key: 'required',
2944
+ message: 'Обязательное поле'
2945
+ },
2946
+ phone_required: {
2947
+ key: 'required',
2948
+ message: 'Укажите номер телефона'
2949
+ },
2950
+ email_required: {
2951
+ key: 'required',
2952
+ message: 'Укажите адрес электронной почты'
2953
+ },
2954
+ password_required: {
2955
+ key: 'required',
2956
+ message: 'Введите пароль'
2957
+ },
2958
+ phone_or_email_required: {
2959
+ key: 'required',
2960
+ message: 'Введите телефон или адрес эл. почты'
2961
+ },
2962
+ // key: 'error'
2963
+ matches: {
2964
+ key: 'error',
2965
+ message: 'Допускается ввод только цифр от 0 до 9'
2966
+ },
2967
+ min: {
2968
+ key: 'error',
2969
+ message: ({
2970
+ min
2971
+ }) => `Значение должно быть не менее ${min} символов`
2972
+ },
2973
+ max: {
2974
+ key: 'error',
2975
+ message: ({
2976
+ max
2977
+ }) => `Значение должно быть не менее ${max} символов`
2978
+ },
2979
+ url: {
2980
+ key: 'error',
2981
+ message: 'Введите корректный URL-адрес'
2982
+ },
2983
+ invalid_value: {
2984
+ key: 'error',
2985
+ message: 'Некорректное значение'
2986
+ },
2987
+ numeric_value: {
2988
+ key: 'error',
2989
+ message: 'Только числовое значение'
2990
+ },
2991
+ phone_error: {
2992
+ key: 'error',
2993
+ message: 'Введите корректный номер телефона'
2994
+ },
2995
+ email_error: {
2996
+ key: 'error',
2997
+ message: 'Введите корректный адрес электронной почты'
2998
+ }
2999
+ };
3000
+
3001
+ 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 };