@itcase/forms 1.1.39 → 1.1.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,13 +5,19 @@ var React = require('react');
5
5
  var finalForm = require('final-form');
6
6
  var reactFinalForm = require('react-final-form');
7
7
  var clsx = require('clsx');
8
- var useDevicePropsGenerator = require('@itcase/ui/hooks/useDevicePropsGenerator');
8
+ var Checkbox = require('@itcase/ui/components/Checkbox');
9
9
  var camelCase = require('lodash/camelCase');
10
10
  var snakeCase = require('lodash/snakeCase');
11
11
  var Divider = require('@itcase/ui/components/Divider');
12
12
  var Text = require('@itcase/ui/components/Text');
13
13
  var useDeviceTargetClass = require('@itcase/ui/hooks/useDeviceTargetClass');
14
14
  var useStyles = require('@itcase/ui/hooks/useStyles');
15
+ var Chips = require('@itcase/ui/components/Chips');
16
+ var Choice = require('@itcase/ui/components/Choice');
17
+ var Code = require('@itcase/ui/components/Code');
18
+ var Icon = require('@itcase/ui/components/Icon');
19
+ var DatePicker = require('@itcase/ui/components/DatePicker');
20
+ var useDevicePropsGenerator = require('@itcase/ui/hooks/useDevicePropsGenerator');
15
21
  var axios = require('axios');
16
22
  var fileSelector = require('file-selector');
17
23
  var castArray = require('lodash/castArray');
@@ -20,20 +26,14 @@ var common = require('@itcase/common');
20
26
  var Button = require('@itcase/ui/components/Button');
21
27
  var Loader = require('@itcase/ui/components/Loader');
22
28
  var Title = require('@itcase/ui/components/Title');
23
- var Checkbox = require('@itcase/ui/components/Checkbox');
24
- var Chips = require('@itcase/ui/components/Chips');
25
- var Choice = require('@itcase/ui/components/Choice');
26
- var Code = require('@itcase/ui/components/Code');
27
- var Icon = require('@itcase/ui/components/Icon');
28
- var DatePicker = require('@itcase/ui/components/DatePicker');
29
29
  var Input = require('@itcase/ui/components/Input');
30
- var _default = require('@itcase/icons/default');
30
+ var reactImask = require('react-imask');
31
+ var InputPassword = require('@itcase/ui/components/InputPassword');
32
+ var Radio = require('@itcase/ui/components/Radio');
31
33
  var Segmented = require('@itcase/ui/components/Segmented');
32
34
  var Select = require('@itcase/ui/components/Select');
33
35
  var Switch = require('@itcase/ui/components/Switch');
34
36
  var Textarea = require('@itcase/ui/components/Textarea');
35
- var reactImask = require('react-imask');
36
- var Radio = require('@itcase/ui/components/Radio');
37
37
  var Group = require('@itcase/ui/components/Group');
38
38
  var Notification = require('@itcase/ui/components/Notification');
39
39
  var createDecorator = require('final-form-focus');
@@ -128,6 +128,16 @@ function useYupValidationSchema(schema, language) {
128
128
  return validate;
129
129
  }
130
130
 
131
+ const defaultCheckboxProps = {
132
+ appearance: 'defaultPrimary sizeL solid',
133
+ width: 'fill',
134
+ // useValidationAppearanceInputProps
135
+ // Error
136
+ errorAppearance: 'errorPrimary sizeL solid',
137
+ // Required
138
+ requiredAppearance: 'requirePrimary sizeL solid'
139
+ };
140
+
131
141
  // Whether to display an error message based on "fieldProps" and meta-objects
132
142
  function useFieldValidationState(props) {
133
143
  const {
@@ -441,423 +451,477 @@ function FieldWrapper(props) {
441
451
  return /*#__PURE__*/React__default.default.createElement(FieldWrapperBase, props);
442
452
  }
443
453
 
444
- const defaultDropzoneProps = {
445
- fill: 'surfaceSecondary',
446
- fillHover: 'surfaceTertiary',
447
- // borderColor: 'surfaceBorderTertiary',
448
- // borderColorHover: 'surfaceBorderQuaternary',
449
- hintTitle: 'Перетащите изображение или выберите файл с компьютера',
450
- hintTitleTextColor: 'surfaceTextPrimary',
451
- hintTitleTextSize: 'm',
452
- removeThumbText: 'удалить',
453
- removeThumbTextColor: 'errorTextPrimary',
454
- removeThumbTextHoverColor: 'errorTextPrimaryHover',
455
- removeThumbTextSize: 's',
456
- shape: 'rounded',
457
- showFilename: true,
458
- thumbBorderColor: 'surfaceBorderTertiary',
459
- thumbBorderColorHover: 'surfaceBorderQuaternary',
460
- thumbBorderWidth: 1,
461
- thumbNameTextColor: 'surfaceTextPrimary',
462
- thumbNameTextSize: 's',
463
- isPreviews: true
454
+ const FormFieldCheckbox = /*#__PURE__*/React__default.default.memo(function FormFieldCheckbox(props) {
455
+ const {
456
+ name,
457
+ initialValue,
458
+ isDisabled,
459
+ classNameGroupItem,
460
+ fieldProps = {},
461
+ inputProps = {},
462
+ showMessage,
463
+ isRequired,
464
+ onChange
465
+ } = props;
466
+ return /*#__PURE__*/React__default.default.createElement(reactFinalForm.Field, {
467
+ type: "checkbox",
468
+ name: name,
469
+ initialValue: initialValue
470
+ }, function Render({
471
+ input,
472
+ meta
473
+ }) {
474
+ /** Note:
475
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
476
+ * React Hooks cannot be called inside a callback.
477
+ * React Hooks must be called in a React function component or a
478
+ * custom React Hook function.
479
+ */
480
+
481
+ const onChangeField = React.useCallback(event => {
482
+ input.onChange(event);
483
+ if (onChange) {
484
+ onChange(event.target.checked, input.name);
485
+ }
486
+ }, [onChange, input.onChange]);
487
+ const {
488
+ errorKey,
489
+ errorMessage,
490
+ isErrorState,
491
+ successKey,
492
+ isValidState
493
+ } = useFieldValidationState({
494
+ fieldProps: fieldProps,
495
+ input: input,
496
+ meta: meta
497
+ });
498
+ const updatedInputProps = useValidationAppearanceInputProps({
499
+ inputProps: inputProps,
500
+ validationStateKey: isErrorState ? errorKey : isValidState ? successKey : null
501
+ });
502
+ return /*#__PURE__*/React__default.default.createElement(FieldWrapper, Object.assign({
503
+ className: clsx__default.default('form-field-checkbox', 'form__item_checkbox', classNameGroupItem),
504
+ errorKey: errorKey,
505
+ errorMessage: errorMessage,
506
+ isErrorState: isErrorState,
507
+ metaError: meta.error,
508
+ isDisabled: isDisabled,
509
+ fieldClassName: "form-checkbox",
510
+ inputName: input.name,
511
+ inputValue: input.checked,
512
+ metaActive: meta.active,
513
+ showMessage: showMessage,
514
+ tag: "label",
515
+ isRequired: isRequired,
516
+ isValidState: isValidState
517
+ }, fieldProps), /*#__PURE__*/React__default.default.createElement(Checkbox.Checkbox, Object.assign({
518
+ type: "checkbox",
519
+ name: input.name,
520
+ isDisabled: isDisabled,
521
+ autoComplete: "nope",
522
+ checked: input.checked,
523
+ isActive: input.checked,
524
+ onBlur: input.onBlur,
525
+ onChange: onChangeField,
526
+ onFocus: input.onFocus
527
+ }, updatedInputProps)));
528
+ });
529
+ });
530
+
531
+ const defaultChipsProps = {
532
+ appearance: 'surfacePrimary sizeM rounded',
533
+ width: 'fill',
534
+ // useValidationAppearanceInputProps
535
+ // Error
536
+ errorAppearance: 'errorPrimary sizeM solid rounded',
537
+ // Required
538
+ requiredAppearance: 'requirePrimary sizeM solid rounded'
539
+ // Success
540
+ // successAppearance: 'successPrimary sizeM solid rounded',
464
541
  };
465
542
 
466
- const FileInputDropzone = /*#__PURE__*/React__default.default.memo(function FileInputDropzone(props) {
543
+ function FormFieldChips(props) {
467
544
  const {
468
- className,
469
- maxFiles,
470
- maxSize,
471
- size,
472
- fileErrorText,
473
- dropzoneProps = {},
474
- hintDescription,
475
- hintTitle,
476
- inputName,
477
- inputValue,
478
- showFilename,
479
- thumbColumn,
480
- isPreviews,
481
- onAddFiles,
482
- onDeleteFile
545
+ name,
546
+ initialValue,
547
+ isDisabled,
548
+ classNameGroupItem,
549
+ emptyMessage,
550
+ emptyMessageTextColor,
551
+ emptyMessageTextSize,
552
+ fieldProps,
553
+ inputProps,
554
+ options,
555
+ showMessage,
556
+ isRequired,
557
+ onChange
483
558
  } = props;
484
-
485
- // TODO: delete react-final-form things out of here?
486
559
  const {
487
560
  change
488
561
  } = reactFinalForm.useForm();
489
- const [fileError, setFileError] = React.useState('');
490
- const [fileIsLoading, setFileIsLoading] = React.useState(false);
491
- const filesList = React.useMemo(() => inputValue ? castArray__default.default(inputValue) : [], [inputValue]);
492
- const changeFormState = React.useCallback(newFiles => {
493
- // If max files in dropzone is 1 - return file as it self, else as array of files
494
- // ps: for old projects compatibility
495
- const toSave = dropzoneProps.maxFiles == 1 ? newFiles[0] : newFiles;
496
- change(inputName, toSave);
497
- return toSave;
498
- },
499
- // If "inputName" will be changes, then it should be a different field
500
- // eslint-disable-next-line react-hooks/exhaustive-deps
501
- [dropzoneProps, change]);
502
562
 
503
- //
504
- const convertFiledValueAndSaveAsFiles = React.useCallback(async currentFilesList => {
505
- setFileIsLoading(true);
506
- const newFiles = [];
507
- for (const fileItem of currentFilesList) {
508
- if (typeof fileItem === 'string') {
509
- const newFile = await convertToFile(fileItem, isPreviews);
510
- if (newFile) {
511
- newFiles.push(newFile);
512
- }
513
- } else {
514
- newFiles.push(fileItem);
563
+ // Callback for value changes
564
+ const onChangeSomeInput = React.useCallback((inputValue, newOptionValue) => {
565
+ const updatedValues = inputValue.includes(newOptionValue) ? inputValue.filter(selectedValue => selectedValue !== newOptionValue) : [...inputValue, newOptionValue];
566
+ change(name, updatedValues);
567
+ onChange && onChange(updatedValues);
568
+ }, [change, name, onChange]);
569
+ React.useEffect(() => {
570
+ initialValue && change(name, initialValue);
571
+ // update the form value only when the initialValue changes, so use disable eslint to ignore the warning
572
+ // eslint-disable-next-line react-hooks/exhaustive-deps
573
+ }, [initialValue]);
574
+ return /*#__PURE__*/React__default.default.createElement(reactFinalForm.Field, {
575
+ name: name,
576
+ initialValue: initialValue
577
+ }, function Render({
578
+ input,
579
+ meta
580
+ }) {
581
+ const {
582
+ errorKey,
583
+ errorMessage,
584
+ isErrorState,
585
+ successKey,
586
+ isValidState
587
+ } = useFieldValidationState({
588
+ fieldProps: fieldProps,
589
+ input: input,
590
+ meta: meta
591
+ });
592
+ const updatedInputProps = useValidationAppearanceInputProps({
593
+ inputProps: inputProps,
594
+ validationStateKey: isErrorState ? errorKey : isValidState ? successKey : null
595
+ });
596
+ const activeOptionsList = React.useMemo(() => {
597
+ const emptyOptionsList = [{
598
+ label: null,
599
+ value: null
600
+ }];
601
+ if (input?.value) {
602
+ const currentOptions = options.filter(option => input.value?.includes(option.value));
603
+ return currentOptions || emptyOptionsList;
515
604
  }
516
- }
517
- changeFormState(newFiles);
518
- setFileIsLoading(false);
519
- }, [isPreviews, changeFormState]);
520
-
521
- // Delete file from dropzone
522
- const removeFile = React.useCallback((event, index) => {
523
- event.stopPropagation();
524
- event.preventDefault();
525
- const newFiles = [...filesList];
526
- newFiles.splice(index, 1);
527
- if (onDeleteFile) {
528
- onDeleteFile(filesList[index], inputName);
529
- }
530
- changeFormState(newFiles);
531
- },
532
- // If "inputName" will be changes, then it should be a different field
533
- // eslint-disable-next-line react-hooks/exhaustive-deps
534
- [filesList, changeFormState, onDeleteFile]);
535
-
536
- // Create dropzone options
537
- const {
538
- getInputProps,
539
- getRootProps
540
- } = reactDropzone.useDropzone({
541
- maxFiles: maxFiles || 5,
542
- maxSize: maxSize || 10485760,
543
- // 10mb
544
- // accept: { 'image/*': [] },
545
- ...dropzoneProps,
546
- getFilesFromEvent: async event => {
547
- const result = await fileSelector.fromEvent(event);
548
- const newFiles = result.filter(item => item instanceof File);
549
- // Add exists and new files to accepted(or rejected)
550
- return [...filesList, ...newFiles];
551
- },
552
- onDropAccepted: acceptedFiles => {
553
- // If dropped files has accepted and we need a previews
554
- if (isPreviews) {
555
- // Add preview to every file
556
- acceptedFiles.forEach(file => {
557
- if (!file.error) {
558
- file.preview = URL.createObjectURL(file);
559
- }
560
- });
561
- }
562
- // Save to form data (including empty when files are not valid)
563
- const filesToSave = changeFormState(acceptedFiles);
564
- setFileError('');
565
-
566
- // Save DataURL for all files
567
- const readerPromisesList = acceptedFiles.map(file => {
568
- return new Promise(resolve => setFileDataURL(file, resolve));
569
- });
570
- // Save files to form values
571
- Promise.all(readerPromisesList).then(() => {
572
- if (onAddFiles) {
573
- onAddFiles(filesToSave, inputName);
574
- }
575
- });
576
- },
577
- onDropRejected: rejectedFiles => {
578
- // If dropped files has rejected
579
- if (rejectedFiles.length) {
580
- let fileErrorMessage = 'Ошибка при добавлении файла';
581
- const firstFileErrorItem = rejectedFiles[0].errors[0];
582
- if (firstFileErrorItem) {
583
- if (firstFileErrorItem.code === reactDropzone.ErrorCode.TooManyFiles) {
584
- fileErrorMessage = `Максимальное количество файлов: ${maxFiles}`;
585
- } else {
586
- fileErrorMessage = firstFileErrorItem.message;
587
- }
588
- }
589
- // Show error
590
- setFileError(fileErrorMessage);
591
- } else {
592
- // Else clean error
593
- setFileError('');
594
- }
595
- }
605
+ return emptyOptionsList;
606
+ }, [input.value]);
607
+ return /*#__PURE__*/React__default.default.createElement(FieldWrapper, Object.assign({
608
+ className: clsx__default.default('form-field_chips', 'form__item_chips', classNameGroupItem),
609
+ errorKey: errorKey,
610
+ errorMessage: errorMessage,
611
+ isErrorState: isErrorState,
612
+ metaError: meta.error,
613
+ isDisabled: isDisabled,
614
+ fieldClassName: "form-chips",
615
+ inputName: input.name,
616
+ inputValue: input.value,
617
+ metaActive: meta.active,
618
+ showMessage: showMessage,
619
+ isRequired: isRequired,
620
+ isValidState: isValidState
621
+ }, fieldProps), options.length ? /*#__PURE__*/React__default.default.createElement(Chips.ChipsGroup, {
622
+ direction: "horizontal",
623
+ gap: "1m",
624
+ wrap: "wrap"
625
+ }, options.map(option => /*#__PURE__*/React__default.default.createElement(Chips.Chips, Object.assign({
626
+ className: clsx__default.default(meta.active && 'form-chips_state_focus', meta.error && meta.touched && `form-chips_state_${errorKey}`),
627
+ key: option.value,
628
+ label: option.label,
629
+ isDisabled: option.isDisabled,
630
+ value: option.value,
631
+ isActive: activeOptionsList.some(activeOption => activeOption.value === option.value),
632
+ onClick: () => onChangeSomeInput(input.value, option.value)
633
+ }, updatedInputProps)))) : /*#__PURE__*/React__default.default.createElement(Text.Text, {
634
+ size: emptyMessageTextSize,
635
+ textColor: emptyMessageTextColor
636
+ }, emptyMessage));
596
637
  });
597
- React.useEffect(() => {
598
- const currentFilesList = castArray__default.default(inputValue);
599
- const isNeedToConvert = currentFilesList.some(fileItem => typeof fileItem === 'string');
600
- if (isNeedToConvert) {
601
- // First time convert value to Files and save to local and form state
602
- convertFiledValueAndSaveAsFiles(currentFilesList);
603
- }
638
+ }
604
639
 
605
- // Make sure to revoke the data uris to avoid memory leaks, will run on unmount
606
- return () => {
607
- filesList.forEach(file => {
608
- if (file?.preview) {
609
- URL.revokeObjectURL(file.preview);
610
- }
611
- });
612
- };
613
- // eslint-disable-next-line react-hooks/exhaustive-deps
614
- }, [inputValue]);
615
- const propsGenerator = useDevicePropsGenerator.useDevicePropsGenerator(props);
640
+ const defaultChoiceProps = {
641
+ appearance: 'defaultPrimary sizeM solid rounded',
642
+ width: 'fill',
643
+ // useValidationAppearanceInputProps
644
+ // Error
645
+ errorAppearance: 'errorPrimary sizeM solid rounded',
646
+ // Required
647
+ requiredAppearance: 'requirePrimary sizeM solid rounded'
648
+ };
649
+
650
+ const FormFieldChoice = /*#__PURE__*/React__default.default.memo(function FormFieldChoice(props) {
616
651
  const {
617
- fillClass,
618
- fillHoverClass,
619
- borderColorClass,
620
- borderColorHoverClass,
621
- borderTypeClass,
622
- borderWidthClass,
623
- errorMessageTextColor,
624
- errorMessageTextSize,
625
- errorMessageTextWeight,
626
- hintDescriptionTextColor,
627
- hintDescriptionTextSize,
628
- hintDescriptionTextWeight,
629
- hintDescriptionTextWrap,
630
- hintTitleTextColor,
631
- hintTitleTextSize,
632
- hintTitleTextWeight,
633
- hintTitleTextWrap,
634
- removeThumbAppearance,
635
- removeThumbShape,
636
- removeThumbText,
637
- removeThumbTextWeight,
638
- shapeClass,
639
- thumbBorderColorClass,
640
- thumbBorderColorHoverClass,
641
- thumbBorderTypeClass,
642
- thumbBorderWidthClass,
643
- thumbDirectionClass,
644
- thumbNameTextColor,
645
- thumbNameTextSize,
646
- thumbNameTextWeight,
647
- thumbNameTextWrap
648
- } = propsGenerator;
649
- return /*#__PURE__*/React__default.default.createElement(React__default.default.Fragment, null, /*#__PURE__*/React__default.default.createElement("div", getRootProps({
650
- // className: `form-dropzone__dropzone dropzone ${className} form-dropzone__dropzone_size_${size} ${shapeClass}`,
651
- className: `form-dropzone__dropzone dropzone`
652
- }), /*#__PURE__*/React__default.default.createElement("input", Object.assign({}, getInputProps(), {
653
- name: inputName
654
- })), /*#__PURE__*/React__default.default.createElement("div", {
655
- className: clsx__default.default('form-dropzone__dropzone-wrapper', thumbColumn && `form-dropzone__dropzone-wrapper_column_${thumbColumn}`, fillClass && `fill_${fillClass}`, fillHoverClass && `fill_hover_${fillHoverClass}`, borderWidthClass && `border-width_${borderWidthClass}`, borderColorClass && `border-color_${borderColorClass}`, borderColorHoverClass && `border-color_hover_${borderColorHoverClass}`, borderTypeClass && `border_type_${borderTypeClass}`, shapeClass && `shape_${shapeClass}`)
656
- }, filesList.map((file, index) => /*#__PURE__*/React__default.default.createElement("aside", {
657
- className: clsx__default.default('form-dropzone__thumb', fillClass, thumbDirectionClass, thumbBorderWidthClass, thumbBorderColorClass, thumbBorderColorHoverClass, thumbBorderTypeClass),
658
- key: file.id || `${file.name}_${index}`
659
- }, isPreviews && !file.error && /*#__PURE__*/React__default.default.createElement("div", {
660
- className: "form-dropzone__thumb-image"
661
- }, /*#__PURE__*/React__default.default.createElement("img", {
662
- className: "form-dropzone__thumb-image-inner",
663
- src: file.preview || file.image,
664
- onLoad: () => {
665
- // Revoke data uri after image is loaded
666
- URL.revokeObjectURL(file.preview);
652
+ name,
653
+ initialValue,
654
+ label,
655
+ messageType,
656
+ isDisabled,
657
+ classNameGroupItem,
658
+ fieldProps,
659
+ inputProps,
660
+ options,
661
+ placeholder,
662
+ showMessage,
663
+ isCheckbox,
664
+ isRequired,
665
+ onChange
666
+ } = props;
667
+ const {
668
+ change
669
+ } = reactFinalForm.useForm();
670
+ const setActiveSegment = React.useCallback((option, isChecked) => {
671
+ change(name, isChecked && option.value);
672
+ if (onChange) {
673
+ onChange(option.value, name, isChecked);
667
674
  }
668
- })), file.error && /*#__PURE__*/React__default.default.createElement("div", null, /*#__PURE__*/React__default.default.createElement(Text.Text, {
669
- size: thumbNameTextSize,
670
- textColor: thumbNameTextColor,
671
- textWeight: thumbNameTextWeight,
672
- textWrap: thumbNameTextWrap
673
- }, fileErrorText || file.error)), showFilename && /*#__PURE__*/React__default.default.createElement("div", {
674
- className: "form-dropzone__thumb-name"
675
- }, /*#__PURE__*/React__default.default.createElement(Text.Text, {
676
- className: "form-dropzone__thumb-name-inner",
677
- size: thumbNameTextSize,
678
- textColor: thumbNameTextColor,
679
- textWeight: thumbNameTextWeight,
680
- textWrap: thumbNameTextWrap
681
- }, file.name)), fileIsLoading && /*#__PURE__*/React__default.default.createElement("div", {
682
- className: "form-dropzone__thumb-loader"
683
- }, /*#__PURE__*/React__default.default.createElement(Loader.Loader, {
684
- width: "fill",
685
- height: "fill"
686
- })), /*#__PURE__*/React__default.default.createElement("div", {
687
- className: clsx__default.default('form-dropzone__thumb-remove')
688
- }, /*#__PURE__*/React__default.default.createElement(Button.Button, {
689
- className: "form-dropzone__thumb-remove-text",
690
- appearance: removeThumbAppearance,
691
- label: removeThumbText || 'Удалить',
692
- labelTextWeight: removeThumbTextWeight,
693
- shape: removeThumbShape,
694
- onClick: event => removeFile(event, index)
695
- })))), !filesList.length ? /*#__PURE__*/React__default.default.createElement("div", {
696
- className: "form-dropzone__hint"
697
- }, /*#__PURE__*/React__default.default.createElement(Text.Text, {
698
- className: "form-dropzone__hint-title",
699
- size: hintTitleTextSize,
700
- textColor: hintTitleTextColor,
701
- textWeight: hintTitleTextWeight,
702
- textWrap: hintTitleTextWrap
703
- }, hintTitle || 'Select a file or drag in form'), hintDescription && /*#__PURE__*/React__default.default.createElement(Text.Text, {
704
- className: "form-dropzone__hint-text",
705
- size: hintDescriptionTextSize,
706
- textColor: hintDescriptionTextColor,
707
- textWeight: hintDescriptionTextWeight,
708
- textWrap: hintDescriptionTextWrap
709
- }, hintDescription)) : /*#__PURE__*/React__default.default.createElement("div", {
710
- className: "form-dropzone__hint form-dropzone__hint_type_add-more"
711
- }, /*#__PURE__*/React__default.default.createElement(Text.Text, {
712
- className: "form-dropzone__hint-title",
713
- size: hintTitleTextSize,
714
- textColor: hintTitleTextColor,
715
- textWeight: hintTitleTextWeight,
716
- textWrap: hintTitleTextWrap
717
- }, hintTitle || 'Select a file or drag in form'), hintDescription && /*#__PURE__*/React__default.default.createElement(Text.Text, {
718
- className: "form-dropzone__hint-text",
719
- size: hintDescriptionTextSize,
720
- textColor: hintDescriptionTextColor,
721
- textWeight: hintDescriptionTextWeight,
722
- textWrap: hintDescriptionTextWrap
723
- }, hintDescription)))), fileError && /*#__PURE__*/React__default.default.createElement("div", {
724
- className: "form-field__message"
725
- }, /*#__PURE__*/React__default.default.createElement(Text.Text, {
726
- className: "form-field__message-item form-field__message-item_type_message",
727
- size: errorMessageTextSize,
728
- textColor: errorMessageTextColor,
729
- textWeight: errorMessageTextWeight
730
- }, fileError)));
675
+ }, [change, onChange]);
676
+ return /*#__PURE__*/React__default.default.createElement(reactFinalForm.Field, {
677
+ initialValue: initialValue,
678
+ name: name
679
+ }, function Render({
680
+ input,
681
+ meta
682
+ }) {
683
+ /** Note:
684
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
685
+ * React Hooks cannot be called inside a callback.
686
+ * React Hooks must be called in a React function component or a
687
+ * custom React Hook function.
688
+ */
689
+ const activeOption = React.useMemo(() => {
690
+ const emptyOption = {
691
+ value: null,
692
+ label: null
693
+ };
694
+ if (input.value) {
695
+ const currentOption = options.find(option => option.value === input.value);
696
+ return currentOption || emptyOption;
697
+ }
698
+ return emptyOption;
699
+ }, [input.value]);
700
+ const {
701
+ errorKey,
702
+ errorMessage,
703
+ isErrorState,
704
+ successKey,
705
+ isValidState
706
+ } = useFieldValidationState({
707
+ fieldProps: fieldProps,
708
+ input: input,
709
+ meta: meta
710
+ });
711
+ const updatedInputProps = useValidationAppearanceInputProps({
712
+ inputProps: inputProps,
713
+ validationStateKey: isErrorState ? errorKey : isValidState ? successKey : null
714
+ });
715
+ return /*#__PURE__*/React__default.default.createElement(FieldWrapper, Object.assign({
716
+ className: clsx__default.default('form-field_choice', 'form__item_choice', classNameGroupItem),
717
+ label: label,
718
+ messageType: messageType,
719
+ errorKey: errorKey,
720
+ errorMessage: errorMessage,
721
+ isErrorState: isErrorState,
722
+ metaError: meta.error,
723
+ isDisabled: isDisabled,
724
+ fieldClassName: "form-choice",
725
+ inputName: input.name,
726
+ inputValue: input.value || [],
727
+ metaActive: meta.active,
728
+ showMessage: showMessage,
729
+ isRequired: isRequired,
730
+ isValidState: isValidState
731
+ }, fieldProps), /*#__PURE__*/React__default.default.createElement(Choice.Choice, Object.assign({
732
+ className: clsx__default.default(meta.active && 'form-choice_state_focus', meta.error && meta.touched && `form-choice_state_${errorKey}`),
733
+ name: input.name,
734
+ isDisabled: isDisabled,
735
+ active: activeOption,
736
+ inputValue: input.value || [],
737
+ options: options,
738
+ placeholder: placeholder,
739
+ setActiveSegment: setActiveSegment,
740
+ isCheckbox: isCheckbox,
741
+ isRequired: isRequired
742
+ }, updatedInputProps)));
743
+ });
731
744
  });
732
- async function getFileByURL(url) {
733
- try {
734
- const response = await axios__default.default({
735
- url: url,
736
- responseType: 'blob'
745
+
746
+ const defaultCodeProps = {
747
+ appearance: 'defaultPrimary sizeL solid rounded',
748
+ // useValidationAppearanceInputProps
749
+ // Error
750
+ errorAppearance: 'errorPrimary sizeM solid rounded',
751
+ // Required
752
+ requiredAppearance: 'requirePrimary sizeM solid rounded'
753
+ };
754
+
755
+ const FormFieldCode = /*#__PURE__*/React__default.default.memo(function FormFieldCode(props) {
756
+ const {
757
+ name,
758
+ initialValue,
759
+ label,
760
+ messageType,
761
+ isDisabled,
762
+ classNameGroupItem,
763
+ fieldProps = {},
764
+ inputProps = {},
765
+ showMessage,
766
+ isRequired
767
+ } = props;
768
+ return /*#__PURE__*/React__default.default.createElement(reactFinalForm.Field, {
769
+ name: name,
770
+ initialValue: initialValue
771
+ }, function Render({
772
+ input,
773
+ meta
774
+ }) {
775
+ /** Note:
776
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
777
+ * React Hooks cannot be called inside a callback.
778
+ * React Hooks must be called in a React function component or a
779
+ * custom React Hook function.
780
+ */
781
+
782
+ const {
783
+ errorKey,
784
+ errorMessage,
785
+ isErrorState,
786
+ successKey,
787
+ isValidState
788
+ } = useFieldValidationState({
789
+ fieldProps: fieldProps,
790
+ input: input,
791
+ meta: meta
737
792
  });
738
- const blobObject = response.data;
739
- const dirtyFilename = response.headers['content-disposition']?.split('filename=')[1];
740
- // Remove double quotes
741
- let filename = dirtyFilename?.substring(1).slice(0, -1);
742
- if (!filename) {
743
- filename = url.split('/').at(-1);
744
- // const typeParts = blobObject.type.split('/')
745
- // const fileType = typeParts[typeParts.length - 1]
746
- // filename = `${new Date().getTime()}.${fileType}`
747
- }
748
- return new File([blobObject], filename, {
749
- type: blobObject.type
793
+ const updatedInputProps = useValidationAppearanceInputProps({
794
+ inputProps: inputProps,
795
+ validationStateKey: isErrorState ? errorKey : isValidState ? successKey : null
750
796
  });
751
- } catch (error) {
752
- console.log('error: ', error);
753
- return null;
754
- }
755
- }
756
- async function convertToFile(inputValue, isPreviews) {
757
- let newFile = null;
758
-
759
- // Download image by url and save as File instance
760
- const isURL = typeof inputValue === 'string' && inputValue.includes('/');
761
- if (inputValue.image || isURL) {
762
- newFile = await getFileByURL(inputValue.image || inputValue);
763
- if (newFile) {
764
- setFileDataURL(newFile);
765
- }
766
- }
797
+ return /*#__PURE__*/React__default.default.createElement(FieldWrapper, Object.assign({
798
+ className: clsx__default.default('form-field-code', 'form__item_code', classNameGroupItem),
799
+ label: label,
800
+ messageType: messageType,
801
+ errorKey: errorKey,
802
+ errorMessage: errorMessage,
803
+ isErrorState: isErrorState,
804
+ fieldClassName: 'form-code',
805
+ inputName: input.name,
806
+ inputValue: input.value,
807
+ metaActive: meta.active,
808
+ showMessage: showMessage,
809
+ isRequired: isRequired,
810
+ isValidState: isValidState
811
+ }, fieldProps), /*#__PURE__*/React__default.default.createElement(Code.Code, Object.assign({
812
+ name: input.name,
813
+ initialValue: input.value,
814
+ isDisabled: isDisabled,
815
+ autoComplete: "nope",
816
+ onBlur: input.onBlur,
817
+ onChange: input.onChange,
818
+ onFocus: input.onFocus
819
+ }, updatedInputProps)));
820
+ });
821
+ });
767
822
 
768
- // Convert dataURL to File instance
769
- if (inputValue.dataURL) {
770
- newFile = common.createFileFromDataURL(inputValue.name || inputValue.path, inputValue.dataURL);
771
- newFile.dataURL = inputValue.dataURL;
772
- }
823
+ const FormFieldCustom = /*#__PURE__*/React__default.default.memo(function FormFieldCustom(props) {
824
+ const {
825
+ Component,
826
+ isDisabled,
827
+ isRequired,
828
+ name,
829
+ initialValue,
830
+ fieldProps = {},
831
+ classNameGroupItem,
832
+ showMessage,
833
+ clearIcon,
834
+ clearIconFill,
835
+ clearIconFillHover,
836
+ clearIconShape,
837
+ clearIconSize,
838
+ onClickClearIcon
839
+ } = props;
840
+ return /*#__PURE__*/React__default.default.createElement(reactFinalForm.Field, {
841
+ initialValue: initialValue,
842
+ name: name
843
+ }, function Render({
844
+ input,
845
+ meta
846
+ }) {
847
+ /** Note:
848
+ * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
849
+ * React Hooks cannot be called inside a callback.
850
+ * React Hooks must be called in a React function component or a
851
+ * custom React Hook function.
852
+ */
773
853
 
774
- // Save new File to state
775
- if (newFile) {
776
- newFile.id = inputValue.id;
777
- if (isPreviews) {
778
- newFile.preview = URL.createObjectURL(newFile);
779
- }
780
- }
781
- return newFile;
782
- }
783
- function setFileDataURL(file, resolve) {
784
- resolve = resolve || (() => {});
785
- // Init reader and save his file
786
- const reader = new FileReader();
787
- reader._readedFile = file;
854
+ const {
855
+ isErrorState,
856
+ isValidState,
857
+ errorKey,
858
+ errorMessage
859
+ } = useFieldValidationState({
860
+ fieldProps: fieldProps,
861
+ input: input,
862
+ meta: meta
863
+ });
864
+ const updatedInputProps = useValidationAppearanceInputProps({
865
+ validationStateKey: isErrorState ? errorKey : 'success',
866
+ // For "Custom" field we pass all props. Can contain some special props, we don't known.
867
+ inputProps: props
868
+ });
869
+ return /*#__PURE__*/React__default.default.createElement(FieldWrapper, Object.assign({
870
+ className: clsx__default.default('form-field_custom', 'form__item_custom', classNameGroupItem),
871
+ errorKey: errorKey,
872
+ errorMessage: errorMessage,
873
+ fieldClassName: 'form-custom',
874
+ inputName: input.name,
875
+ inputValue: input.value,
876
+ isDisabled: isDisabled,
877
+ isErrorState: isErrorState,
878
+ isRequired: isRequired,
879
+ isValidState: isValidState,
880
+ metaActive: meta.active,
881
+ metaError: meta.error,
882
+ showMessage: showMessage
883
+ }, fieldProps), /*#__PURE__*/React__default.default.createElement(Component, Object.assign({}, updatedInputProps, {
884
+ input: input,
885
+ isDisabled: isDisabled,
886
+ meta: meta
887
+ })), clearIcon && /*#__PURE__*/React__default.default.createElement(Icon.Icon, {
888
+ className: "form-field__icon",
889
+ iconFill: clearIconFill,
890
+ iconFillHover: clearIconFillHover,
891
+ imageSrc: clearIcon,
892
+ shape: clearIconShape,
893
+ size: clearIconSize,
894
+ SvgImage: clearIcon,
895
+ onClick: onClickClearIcon
896
+ }));
897
+ });
898
+ });
788
899
 
789
- // Set handlers
790
- reader.onabort = () => resolve();
791
- reader.onerror = () => resolve();
792
- reader.onload = event => {
793
- event.target._readedFile.dataURL = reader.result;
794
- resolve();
795
- };
796
- // Run reader
797
- if (file instanceof File) {
798
- reader.readAsDataURL(file);
799
- } else {
800
- resolve();
801
- }
802
- }
900
+ const defaultDatepickerProps = {
901
+ appearance: 'surfacePrimary sizeS',
902
+ dateFormat: 'dd/MM/yyyy - HH:mm',
903
+ readOnly: false,
904
+ selectsRange: false,
905
+ showTimeSelect: true,
906
+ timeCaption: 'Время',
907
+ timeFormat: 'p',
908
+ timeIntervals: 60,
909
+ isClearable: true,
910
+ isStartDefaultNull: true
911
+ };
803
912
 
804
- const FileInput = /*#__PURE__*/React__default.default.memo(function FileInput(props) {
913
+ function FormFieldDatePicker(props) {
805
914
  const {
806
- className,
807
915
  name,
808
- width,
809
- maxFiles,
810
- maxSize,
811
- label,
812
- fileErrorText,
916
+ isDisabled,
813
917
  classNameGroupItem,
814
- dropzoneProps,
815
- fieldProps,
816
- hintDescription,
817
- hintTitle,
818
- showFilename,
918
+ datePickerProps,
919
+ fieldProps = {},
920
+ inputProps = {},
819
921
  showMessage,
820
- isPreviews,
821
922
  isRequired,
822
- onAddFiles,
823
- onDeleteFile
923
+ onChange
824
924
  } = props;
825
- const propsGenerator = useDevicePropsGenerator.useDevicePropsGenerator(props);
826
- const {
827
- size,
828
- fill,
829
- fillHover,
830
- labelTextColor,
831
- borderColorHover,
832
- borderType,
833
- borderWidth,
834
- errorMessageTextColor,
835
- errorMessageTextSize,
836
- errorMessageTextWeight,
837
- hintDescriptionTextColor,
838
- hintDescriptionTextSize,
839
- hintDescriptionTextWeight,
840
- hintDescriptionTextWrap,
841
- hintTitleTextColor,
842
- hintTitleTextSize,
843
- hintTitleTextWeight,
844
- hintTitleTextWrap,
845
- removeThumbAppearance,
846
- removeThumbShape,
847
- removeThumbText,
848
- removeThumbTextWeight,
849
- shape,
850
- thumbBorderColor,
851
- thumbBorderColorHover,
852
- thumbBorderType,
853
- thumbBorderWidth,
854
- thumbColumn = 1,
855
- thumbDirection = 'vertical',
856
- thumbNameTextColor,
857
- thumbNameTextSize,
858
- thumbNameTextWeight,
859
- thumbNameTextWrap
860
- } = propsGenerator;
861
925
  return /*#__PURE__*/React__default.default.createElement(reactFinalForm.Field, {
862
926
  name: name
863
927
  }, function Render({
@@ -871,10 +935,27 @@ const FileInput = /*#__PURE__*/React__default.default.memo(function FileInput(pr
871
935
  * custom React Hook function.
872
936
  */
873
937
 
938
+ const onChangeField = React.useCallback((startDate, endDate) => {
939
+ if (!datePickerProps.selectsRange) {
940
+ // When we need to save single date, value is date
941
+ // TODO: make object with one date? need to check all forms with FormFieldDatePicker
942
+ input.onChange(startDate);
943
+ } else {
944
+ // When we need to save range, value is object with two date
945
+ input.onChange({
946
+ endDate,
947
+ startDate
948
+ });
949
+ }
950
+ if (onChange) {
951
+ onChange(startDate, endDate);
952
+ }
953
+ }, [input.onChange, onChange]);
874
954
  const {
875
955
  errorKey,
876
956
  errorMessage,
877
957
  isErrorState,
958
+ successKey,
878
959
  isValidState
879
960
  } = useFieldValidationState({
880
961
  fieldProps: fieldProps,
@@ -882,422 +963,460 @@ const FileInput = /*#__PURE__*/React__default.default.memo(function FileInput(pr
882
963
  meta: meta
883
964
  });
884
965
  const updatedInputProps = useValidationAppearanceInputProps({
885
- inputProps: props,
886
- validationStateKey: isErrorState ? errorKey : 'success'
966
+ inputProps: inputProps,
967
+ validationStateKey: isErrorState ? errorKey : isValidState ? successKey : null
887
968
  });
888
-
889
- /** TODO:
890
- * REFACTOR PROPERTIES
891
- */
892
969
  return /*#__PURE__*/React__default.default.createElement(FieldWrapper, Object.assign({
893
- className: clsx__default.default('form-field_type_dropzone', 'form__item_type_dropzone', classNameGroupItem),
894
- width: width,
895
- label: label,
896
- labelTextColor: labelTextColor,
970
+ className: clsx__default.default('form-field_datepicker', 'form__item_datepicker', classNameGroupItem),
897
971
  errorKey: errorKey,
898
972
  errorMessage: errorMessage,
899
973
  isErrorState: isErrorState,
900
974
  metaError: meta.error,
901
- fieldClassName: "form-dropzone",
975
+ isDisabled: isDisabled,
976
+ fieldClassName: "form-datepicker",
902
977
  inputName: input.name,
903
- inputValue: input.value,
978
+ inputValue: input.value || '',
904
979
  metaActive: meta.active,
905
- metaTouched: meta.touched,
906
980
  showMessage: showMessage,
907
981
  isRequired: isRequired,
908
982
  isValidState: isValidState
909
- }, fieldProps), /*#__PURE__*/React__default.default.createElement(FileInputDropzone, {
910
- className: className,
911
- maxFiles: maxFiles,
912
- maxSize: maxSize,
913
- size: size,
914
- fill: fill,
915
- fillHover: fillHover,
916
- borderColor: updatedInputProps.borderColor,
917
- borderColorHover: borderColorHover,
918
- borderType: borderType,
919
- borderWidth: borderWidth,
920
- errorMessageTextColor: errorMessageTextColor,
921
- errorMessageTextSize: errorMessageTextSize,
922
- errorMessageWeight: errorMessageTextWeight,
923
- fileErrorText: fileErrorText,
924
- metaError: meta.error,
925
- dropzoneProps: dropzoneProps,
926
- hintDescription: hintDescription,
927
- hintDescriptionTextColor: hintDescriptionTextColor,
928
- hintDescriptionTextSize: hintDescriptionTextSize,
929
- hintDescriptionTextWeight: hintDescriptionTextWeight,
930
- hintDescriptionTextWrap: hintDescriptionTextWrap,
931
- hintTitle: hintTitle,
932
- hintTitleTextColor: hintTitleTextColor,
933
- hintTitleTextSize: hintTitleTextSize,
934
- hintTitleTextWeight: hintTitleTextWeight,
935
- hintTitleTextWrap: hintTitleTextWrap,
936
- inputName: input.name,
937
- inputValue: input.value,
938
- metaTouched: meta.touched,
939
- removeThumbAppearance: removeThumbAppearance,
940
- removeThumbShape: removeThumbShape,
941
- removeThumbText: removeThumbText,
942
- removeThumbTextWeight: removeThumbTextWeight,
943
- shape: shape,
944
- showFilename: showFilename,
945
- thumbBorderColor: thumbBorderColor,
946
- thumbBorderColorHover: thumbBorderColorHover,
947
- thumbBorderType: thumbBorderType,
948
- thumbBorderWidth: thumbBorderWidth,
949
- thumbColumn: thumbColumn,
950
- thumbDirection: thumbDirection,
951
- thumbNameTextColor: thumbNameTextColor,
952
- thumbNameTextSize: thumbNameTextSize,
953
- thumbNameTextWeight: thumbNameTextWeight,
954
- thumbNameTextWrap: thumbNameTextWrap,
955
- isPreviews: isPreviews,
956
- onAddFiles: onAddFiles,
957
- onDeleteFile: onDeleteFile
983
+ }, fieldProps), /*#__PURE__*/React__default.default.createElement(DatePicker.DatePickerInput, {
984
+ name: input.name,
985
+ isDisabled: isDisabled,
986
+ datePickerProps: datePickerProps,
987
+ endValue: datePickerProps.selectsRange ? input.value.endDate : null,
988
+ inputProps: updatedInputProps,
989
+ value: datePickerProps.selectsRange ? input.value.startDate : input.value,
990
+ onBlur: input.onBlur,
991
+ onChange: onChangeField,
992
+ onFocus: input.onFocus
958
993
  }));
959
994
  });
960
- });
995
+ }
961
996
 
962
- const defaultGroupProps = {
963
- width: 'fill',
964
- labelTextSize: 's',
965
- messageTextColor: 'surfaceTextPrimary',
966
- messageTextSize: 's',
967
- errorMessageTextSize: 's',
968
- errorMessageTextColor: 'errorTextSecondary',
969
- helpTextSize: 's',
970
- requiredMessageTextColor: 'warningTextSecondary',
971
- requiredMessageTextSize: 's'
997
+ const defaultDropzoneProps = {
998
+ fill: 'surfaceSecondary',
999
+ fillHover: 'surfaceTertiary',
1000
+ // borderColor: 'surfaceBorderTertiary',
1001
+ // borderColorHover: 'surfaceBorderQuaternary',
1002
+ hintTitle: 'Перетащите изображение или выберите файл с компьютера',
1003
+ hintTitleTextColor: 'surfaceTextPrimary',
1004
+ hintTitleTextSize: 'm',
1005
+ removeThumbText: 'удалить',
1006
+ removeThumbTextColor: 'errorTextPrimary',
1007
+ removeThumbTextHoverColor: 'errorTextPrimaryHover',
1008
+ removeThumbTextSize: 's',
1009
+ shape: 'rounded',
1010
+ showFilename: true,
1011
+ thumbBorderColor: 'surfaceBorderTertiary',
1012
+ thumbBorderColorHover: 'surfaceBorderQuaternary',
1013
+ thumbBorderWidth: 1,
1014
+ thumbNameTextColor: 'surfaceTextPrimary',
1015
+ thumbNameTextSize: 's',
1016
+ isPreviews: true
972
1017
  };
973
1018
 
974
- const FormBlockGroup = /*#__PURE__*/React__default.default.memo(function Group(props) {
1019
+ const FileInputDropzone = /*#__PURE__*/React__default.default.memo(function FileInputDropzone(props) {
975
1020
  const {
976
- dataTour,
977
1021
  className,
978
- name,
979
- title,
980
- titleTextColor,
981
- titleTextSize,
982
- titleTextWeight,
983
- label,
984
- labelTextColor,
985
- labelTextSize,
986
- labelTextWeight,
987
- message,
988
- messageTextColor,
989
- messageTextSize,
990
- messageTextWeight,
991
- column,
992
- showGroupMessage,
993
- before,
994
- after,
995
- isHidden,
996
- children
1022
+ maxFiles,
1023
+ maxSize,
1024
+ size,
1025
+ fileErrorText,
1026
+ dropzoneProps = {},
1027
+ hintDescription,
1028
+ hintTitle,
1029
+ inputName,
1030
+ inputValue,
1031
+ showFilename,
1032
+ thumbColumn,
1033
+ isPreviews,
1034
+ onAddFiles,
1035
+ onClickPreview,
1036
+ onDeleteFile
997
1037
  } = props;
998
1038
 
999
- // @ts-expect-error
1039
+ // TODO: delete react-final-form things out of here?
1000
1040
  const {
1001
- styles: styles
1002
- } = useStyles.useStyles(props);
1003
- return /*#__PURE__*/React__default.default.createElement(reactFinalForm.Field, {
1004
- name: name
1005
- }, function Render({
1006
- input,
1007
- meta
1008
- }) {
1009
- /** Note:
1010
- * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
1011
- * React Hooks cannot be called inside a callback.
1012
- * React Hooks must be called in a React function component or a
1013
- * custom React Hook function.
1014
- */
1015
- const {
1016
- errorKey,
1017
- errorMessage,
1018
- isErrorState
1019
- } = useFieldValidationState({
1020
- fieldProps: props,
1021
- // or fieldProps?
1022
- input: input,
1023
- meta: meta
1024
- });
1025
- const updatedProps = useValidationAppearanceInputProps({
1026
- inputProps: props,
1027
- validationStateKey: isErrorState ? errorKey : 'success'
1028
- });
1029
- return /*#__PURE__*/React__default.default.createElement("div", {
1030
- className: clsx__default.default('form__group', className, isHidden && 'form__group_hidden', column && `form__group_column_${column}`),
1031
- "data-tour": dataTour,
1032
- style: styles
1033
- }, /*#__PURE__*/React__default.default.createElement("div", {
1034
- className: "form__group-wrapper"
1035
- }, before, title && /*#__PURE__*/React__default.default.createElement("div", {
1036
- className: "form__group-title"
1037
- }, /*#__PURE__*/React__default.default.createElement(Title.Title, {
1038
- size: titleTextSize,
1039
- textColor: titleTextColor,
1040
- textWeight: titleTextWeight
1041
- }, title)), label && /*#__PURE__*/React__default.default.createElement("div", {
1042
- className: "form__group-label"
1043
- }, /*#__PURE__*/React__default.default.createElement(Text.Text, {
1044
- size: labelTextSize,
1045
- textColor: labelTextColor,
1046
- textWeight: labelTextWeight
1047
- }, label)), /*#__PURE__*/React__default.default.createElement("div", {
1048
- className: "form__group-items"
1049
- }, children), after), showGroupMessage && /*#__PURE__*/React__default.default.createElement(React__default.default.Fragment, null, isErrorState && errorMessage && /*#__PURE__*/React__default.default.createElement(Text.Text, {
1050
- id: `${name}-error`,
1051
- className: `form__group-message form__group-message_type-${errorKey}`,
1052
- size: updatedProps.messageTextSize,
1053
- textColor: updatedProps.messageTextColor,
1054
- textWeight: updatedProps.messageTextWeight
1055
- }, errorMessage), Boolean(message) && (!isErrorState || !errorMessage) && /*#__PURE__*/React__default.default.createElement(Text.Text, {
1056
- className: "form__group-message",
1057
- size: messageTextSize,
1058
- textColor: messageTextColor,
1059
- textWeight: messageTextWeight
1060
- }, message), !isErrorState && !message && /*#__PURE__*/React__default.default.createElement(Text.Text, {
1061
- className: "form__group-message",
1062
- size: messageTextSize
1063
- }, '\u00A0')));
1064
- });
1065
- });
1041
+ change
1042
+ } = reactFinalForm.useForm();
1043
+ const [fileError, setFileError] = React.useState('');
1044
+ const [fileIsLoading, setFileIsLoading] = React.useState(false);
1045
+ const filesList = React.useMemo(() => inputValue ? castArray__default.default(inputValue) : [], [inputValue]);
1046
+ const changeFormState = React.useCallback(newFiles => {
1047
+ // If max files in dropzone is 1 - return file as it self, else as array of files
1048
+ // ps: for old projects compatibility
1049
+ const toSave = dropzoneProps.maxFiles == 1 ? newFiles[0] : newFiles;
1050
+ change(inputName, toSave);
1051
+ return toSave;
1052
+ },
1053
+ // If "inputName" will be changes, then it should be a different field
1054
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1055
+ [dropzoneProps, change]);
1056
+
1057
+ //
1058
+ const convertFiledValueAndSaveAsFiles = React.useCallback(async currentFilesList => {
1059
+ setFileIsLoading(true);
1060
+ const newFiles = [];
1061
+ for (const fileItem of currentFilesList) {
1062
+ if (typeof fileItem === 'string') {
1063
+ const newFile = await convertToFile(fileItem, isPreviews);
1064
+ if (newFile) {
1065
+ newFiles.push(newFile);
1066
+ }
1067
+ } else {
1068
+ newFiles.push(fileItem);
1069
+ }
1070
+ }
1071
+ changeFormState(newFiles);
1072
+ setFileIsLoading(false);
1073
+ }, [isPreviews, changeFormState]);
1066
1074
 
1067
- const defaultCheckboxProps = {
1068
- appearance: 'defaultPrimary sizeL solid',
1069
- width: 'fill',
1070
- // useValidationAppearanceInputProps
1071
- // Error
1072
- errorAppearance: 'errorPrimary sizeL solid',
1073
- // Required
1074
- requiredAppearance: 'requirePrimary sizeL solid'
1075
- };
1075
+ // Delete file from dropzone
1076
+ const removeFile = React.useCallback((event, index) => {
1077
+ event.stopPropagation();
1078
+ event.preventDefault();
1079
+ const newFiles = [...filesList];
1080
+ newFiles.splice(index, 1);
1081
+ if (onDeleteFile) {
1082
+ onDeleteFile(filesList[index], inputName);
1083
+ }
1084
+ changeFormState(newFiles);
1085
+ },
1086
+ // If "inputName" will be changes, then it should be a different field
1087
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1088
+ [filesList, changeFormState, onDeleteFile]);
1076
1089
 
1077
- const FormFieldCheckbox = /*#__PURE__*/React__default.default.memo(function FormFieldCheckbox(props) {
1090
+ // Create dropzone options
1078
1091
  const {
1079
- name,
1080
- initialValue,
1081
- isDisabled,
1082
- classNameGroupItem,
1083
- fieldProps = {},
1084
- inputProps = {},
1085
- showMessage,
1086
- isRequired,
1087
- onChange
1088
- } = props;
1089
- return /*#__PURE__*/React__default.default.createElement(reactFinalForm.Field, {
1090
- type: "checkbox",
1091
- name: name,
1092
- initialValue: initialValue
1093
- }, function Render({
1094
- input,
1095
- meta
1096
- }) {
1097
- /** Note:
1098
- * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
1099
- * React Hooks cannot be called inside a callback.
1100
- * React Hooks must be called in a React function component or a
1101
- * custom React Hook function.
1102
- */
1092
+ getInputProps,
1093
+ getRootProps
1094
+ } = reactDropzone.useDropzone({
1095
+ maxFiles: maxFiles || 5,
1096
+ maxSize: maxSize || 10485760,
1097
+ // 10mb
1098
+ // accept: { 'image/*': [] },
1099
+ ...dropzoneProps,
1100
+ getFilesFromEvent: async event => {
1101
+ const result = await fileSelector.fromEvent(event);
1102
+ const newFiles = result.filter(item => item instanceof File);
1103
+ // Add exists and new files to accepted(or rejected)
1104
+ return [...filesList, ...newFiles];
1105
+ },
1106
+ onDropAccepted: acceptedFiles => {
1107
+ // If dropped files has accepted and we need a previews
1108
+ if (isPreviews) {
1109
+ // Add preview to every file
1110
+ acceptedFiles.forEach(file => {
1111
+ if (!file.error) {
1112
+ file.preview = URL.createObjectURL(file);
1113
+ }
1114
+ });
1115
+ }
1116
+ // Save to form data (including empty when files are not valid)
1117
+ const filesToSave = changeFormState(acceptedFiles);
1118
+ setFileError('');
1103
1119
 
1104
- const onChangeField = React.useCallback(event => {
1105
- input.onChange(event);
1106
- if (onChange) {
1107
- onChange(event.target.checked, input.name);
1120
+ // Save DataURL for all files
1121
+ const readerPromisesList = acceptedFiles.map(file => {
1122
+ return new Promise(resolve => setFileDataURL(file, resolve));
1123
+ });
1124
+ // Save files to form values
1125
+ Promise.all(readerPromisesList).then(() => {
1126
+ if (onAddFiles) {
1127
+ onAddFiles(filesToSave, inputName);
1128
+ }
1129
+ });
1130
+ },
1131
+ onDropRejected: rejectedFiles => {
1132
+ // If dropped files has rejected
1133
+ if (rejectedFiles.length) {
1134
+ let fileErrorMessage = 'Ошибка при добавлении файла';
1135
+ const firstFileErrorItem = rejectedFiles[0].errors[0];
1136
+ if (firstFileErrorItem) {
1137
+ if (firstFileErrorItem.code === reactDropzone.ErrorCode.TooManyFiles) {
1138
+ fileErrorMessage = `Максимальное количество файлов: ${maxFiles}`;
1139
+ } else {
1140
+ fileErrorMessage = firstFileErrorItem.message;
1141
+ }
1142
+ }
1143
+ // Show error
1144
+ setFileError(fileErrorMessage);
1145
+ } else {
1146
+ // Else clean error
1147
+ setFileError('');
1108
1148
  }
1109
- }, [onChange, input.onChange]);
1110
- const {
1111
- errorKey,
1112
- errorMessage,
1113
- isErrorState,
1114
- successKey,
1115
- isValidState
1116
- } = useFieldValidationState({
1117
- fieldProps: fieldProps,
1118
- input: input,
1119
- meta: meta
1149
+ }
1150
+ });
1151
+ React.useEffect(() => {
1152
+ const currentFilesList = castArray__default.default(inputValue);
1153
+ const isNeedToConvert = currentFilesList.some(fileItem => typeof fileItem === 'string');
1154
+ if (isNeedToConvert) {
1155
+ // First time convert value to Files and save to local and form state
1156
+ convertFiledValueAndSaveAsFiles(currentFilesList);
1157
+ }
1158
+
1159
+ // Make sure to revoke the data uris to avoid memory leaks, will run on unmount
1160
+ return () => {
1161
+ filesList.forEach(file => {
1162
+ if (file?.preview) {
1163
+ URL.revokeObjectURL(file.preview);
1164
+ }
1165
+ });
1166
+ };
1167
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1168
+ }, [inputValue]);
1169
+ const propsGenerator = useDevicePropsGenerator.useDevicePropsGenerator(props);
1170
+ const {
1171
+ fillClass,
1172
+ fillHoverClass,
1173
+ borderColorClass,
1174
+ borderColorHoverClass,
1175
+ borderTypeClass,
1176
+ borderWidthClass,
1177
+ errorMessageTextColor,
1178
+ errorMessageTextSize,
1179
+ errorMessageTextWeight,
1180
+ hintDescriptionTextColor,
1181
+ hintDescriptionTextSize,
1182
+ hintDescriptionTextWeight,
1183
+ hintDescriptionTextWrap,
1184
+ hintTitleTextColor,
1185
+ hintTitleTextSize,
1186
+ hintTitleTextWeight,
1187
+ hintTitleTextWrap,
1188
+ removeThumbAppearance,
1189
+ removeThumbShape,
1190
+ removeThumbText,
1191
+ removeThumbTextWeight,
1192
+ shapeClass,
1193
+ thumbBorderColorClass,
1194
+ thumbBorderColorHoverClass,
1195
+ thumbBorderTypeClass,
1196
+ thumbBorderWidthClass,
1197
+ thumbDirectionClass,
1198
+ thumbNameTextColor,
1199
+ thumbNameTextSize,
1200
+ thumbNameTextWeight,
1201
+ thumbNameTextWrap
1202
+ } = propsGenerator;
1203
+ return /*#__PURE__*/React__default.default.createElement(React__default.default.Fragment, null, /*#__PURE__*/React__default.default.createElement("div", getRootProps({
1204
+ // className: `form-dropzone__dropzone dropzone ${className} form-dropzone__dropzone_size_${size} ${shapeClass}`,
1205
+ className: `form-dropzone__dropzone dropzone`
1206
+ }), /*#__PURE__*/React__default.default.createElement("input", Object.assign({}, getInputProps(), {
1207
+ name: inputName
1208
+ })), /*#__PURE__*/React__default.default.createElement("div", {
1209
+ className: clsx__default.default('form-dropzone__dropzone-wrapper', thumbColumn && `form-dropzone__dropzone-wrapper_column_${thumbColumn}`, fillClass && `fill_${fillClass}`, fillHoverClass && `fill_hover_${fillHoverClass}`, borderWidthClass && `border-width_${borderWidthClass}`, borderColorClass && `border-color_${borderColorClass}`, borderColorHoverClass && `border-color_hover_${borderColorHoverClass}`, borderTypeClass && `border_type_${borderTypeClass}`, shapeClass && `shape_${shapeClass}`)
1210
+ }, filesList.map((file, index) => /*#__PURE__*/React__default.default.createElement("aside", {
1211
+ className: clsx__default.default('form-dropzone__thumb', fillClass, thumbDirectionClass, thumbBorderWidthClass, thumbBorderColorClass, thumbBorderColorHoverClass, thumbBorderTypeClass),
1212
+ key: file.id || `${file.name}_${index}`
1213
+ }, isPreviews && !file.error && /*#__PURE__*/React__default.default.createElement("div", {
1214
+ className: "form-dropzone__thumb-image"
1215
+ }, /*#__PURE__*/React__default.default.createElement("img", {
1216
+ className: "form-dropzone__thumb-image-inner",
1217
+ src: file.preview || file.image,
1218
+ onClick: event => {
1219
+ onClickPreview && onClickPreview(file, event);
1220
+ },
1221
+ onLoad: () => {
1222
+ // Revoke data uri after image is loaded
1223
+ URL.revokeObjectURL(file.preview);
1224
+ }
1225
+ })), file.error && /*#__PURE__*/React__default.default.createElement("div", null, /*#__PURE__*/React__default.default.createElement(Text.Text, {
1226
+ size: thumbNameTextSize,
1227
+ textColor: thumbNameTextColor,
1228
+ textWeight: thumbNameTextWeight,
1229
+ textWrap: thumbNameTextWrap
1230
+ }, fileErrorText || file.error)), showFilename && /*#__PURE__*/React__default.default.createElement("div", {
1231
+ className: "form-dropzone__thumb-name"
1232
+ }, /*#__PURE__*/React__default.default.createElement(Text.Text, {
1233
+ className: "form-dropzone__thumb-name-inner",
1234
+ size: thumbNameTextSize,
1235
+ textColor: thumbNameTextColor,
1236
+ textWeight: thumbNameTextWeight,
1237
+ textWrap: thumbNameTextWrap
1238
+ }, file.name)), fileIsLoading && /*#__PURE__*/React__default.default.createElement("div", {
1239
+ className: "form-dropzone__thumb-loader"
1240
+ }, /*#__PURE__*/React__default.default.createElement(Loader.Loader, {
1241
+ width: "fill",
1242
+ height: "fill"
1243
+ })), /*#__PURE__*/React__default.default.createElement("div", {
1244
+ className: clsx__default.default('form-dropzone__thumb-remove')
1245
+ }, /*#__PURE__*/React__default.default.createElement(Button.Button, {
1246
+ className: "form-dropzone__thumb-remove-text",
1247
+ appearance: removeThumbAppearance,
1248
+ label: removeThumbText || 'Удалить',
1249
+ labelTextWeight: removeThumbTextWeight,
1250
+ shape: removeThumbShape,
1251
+ onClick: event => removeFile(event, index)
1252
+ })))), !filesList.length ? /*#__PURE__*/React__default.default.createElement("div", {
1253
+ className: "form-dropzone__hint"
1254
+ }, /*#__PURE__*/React__default.default.createElement(Text.Text, {
1255
+ className: "form-dropzone__hint-title",
1256
+ size: hintTitleTextSize,
1257
+ textColor: hintTitleTextColor,
1258
+ textWeight: hintTitleTextWeight,
1259
+ textWrap: hintTitleTextWrap
1260
+ }, hintTitle || 'Select a file or drag in form'), hintDescription && /*#__PURE__*/React__default.default.createElement(Text.Text, {
1261
+ className: "form-dropzone__hint-text",
1262
+ size: hintDescriptionTextSize,
1263
+ textColor: hintDescriptionTextColor,
1264
+ textWeight: hintDescriptionTextWeight,
1265
+ textWrap: hintDescriptionTextWrap
1266
+ }, hintDescription)) : /*#__PURE__*/React__default.default.createElement("div", {
1267
+ className: "form-dropzone__hint form-dropzone__hint_type_add-more"
1268
+ }, /*#__PURE__*/React__default.default.createElement(Text.Text, {
1269
+ className: "form-dropzone__hint-title",
1270
+ size: hintTitleTextSize,
1271
+ textColor: hintTitleTextColor,
1272
+ textWeight: hintTitleTextWeight,
1273
+ textWrap: hintTitleTextWrap
1274
+ }, hintTitle || 'Select a file or drag in form'), hintDescription && /*#__PURE__*/React__default.default.createElement(Text.Text, {
1275
+ className: "form-dropzone__hint-text",
1276
+ size: hintDescriptionTextSize,
1277
+ textColor: hintDescriptionTextColor,
1278
+ textWeight: hintDescriptionTextWeight,
1279
+ textWrap: hintDescriptionTextWrap
1280
+ }, hintDescription)))), fileError && /*#__PURE__*/React__default.default.createElement("div", {
1281
+ className: "form-field__message"
1282
+ }, /*#__PURE__*/React__default.default.createElement(Text.Text, {
1283
+ className: "form-field__message-item form-field__message-item_type_message",
1284
+ size: errorMessageTextSize,
1285
+ textColor: errorMessageTextColor,
1286
+ textWeight: errorMessageTextWeight
1287
+ }, fileError)));
1288
+ });
1289
+ async function getFileByURL(url) {
1290
+ try {
1291
+ const response = await axios__default.default({
1292
+ url: url,
1293
+ responseType: 'blob'
1120
1294
  });
1121
- const updatedInputProps = useValidationAppearanceInputProps({
1122
- inputProps: inputProps,
1123
- validationStateKey: isErrorState ? errorKey : isValidState ? successKey : null
1295
+ const blobObject = response.data;
1296
+ const dirtyFilename = response.headers['content-disposition']?.split('filename=')[1];
1297
+ // Remove double quotes
1298
+ let filename = dirtyFilename?.substring(1).slice(0, -1);
1299
+ if (!filename) {
1300
+ filename = url.split('/').at(-1);
1301
+ // const typeParts = blobObject.type.split('/')
1302
+ // const fileType = typeParts[typeParts.length - 1]
1303
+ // filename = `${new Date().getTime()}.${fileType}`
1304
+ }
1305
+ return new File([blobObject], filename, {
1306
+ type: blobObject.type
1124
1307
  });
1125
- return /*#__PURE__*/React__default.default.createElement(FieldWrapper, Object.assign({
1126
- className: clsx__default.default('form-field-checkbox', 'form__item_checkbox', classNameGroupItem),
1127
- errorKey: errorKey,
1128
- errorMessage: errorMessage,
1129
- isErrorState: isErrorState,
1130
- metaError: meta.error,
1131
- isDisabled: isDisabled,
1132
- fieldClassName: "form-checkbox",
1133
- inputName: input.name,
1134
- inputValue: input.checked,
1135
- metaActive: meta.active,
1136
- showMessage: showMessage,
1137
- tag: "label",
1138
- isRequired: isRequired,
1139
- isValidState: isValidState
1140
- }, fieldProps), /*#__PURE__*/React__default.default.createElement(Checkbox.Checkbox, Object.assign({
1141
- type: "checkbox",
1142
- name: input.name,
1143
- isDisabled: isDisabled,
1144
- autoComplete: "nope",
1145
- checked: input.checked,
1146
- isActive: input.checked,
1147
- onBlur: input.onBlur,
1148
- onChange: onChangeField,
1149
- onFocus: input.onFocus
1150
- }, updatedInputProps)));
1151
- });
1152
- });
1308
+ } catch (error) {
1309
+ console.log('error: ', error);
1310
+ return null;
1311
+ }
1312
+ }
1313
+ async function convertToFile(inputValue, isPreviews) {
1314
+ let newFile = null;
1153
1315
 
1154
- const defaultChipsProps = {
1155
- appearance: 'surfacePrimary sizeM rounded',
1156
- width: 'fill',
1157
- // useValidationAppearanceInputProps
1158
- // Error
1159
- errorAppearance: 'errorPrimary sizeM solid rounded',
1160
- // Required
1161
- requiredAppearance: 'requirePrimary sizeM solid rounded'
1162
- // Success
1163
- // successAppearance: 'successPrimary sizeM solid rounded',
1164
- };
1316
+ // Download image by url and save as File instance
1317
+ const isURL = typeof inputValue === 'string' && inputValue.includes('/');
1318
+ if (inputValue.image || isURL) {
1319
+ newFile = await getFileByURL(inputValue.image || inputValue);
1320
+ if (newFile) {
1321
+ setFileDataURL(newFile);
1322
+ }
1323
+ }
1165
1324
 
1166
- function FormFieldChips(props) {
1167
- const {
1168
- name,
1169
- initialValue,
1170
- isDisabled,
1171
- classNameGroupItem,
1172
- emptyMessage,
1173
- emptyMessageTextColor,
1174
- emptyMessageTextSize,
1175
- fieldProps,
1176
- inputProps,
1177
- options,
1178
- showMessage,
1179
- isRequired,
1180
- onChange
1181
- } = props;
1182
- const {
1183
- change
1184
- } = reactFinalForm.useForm();
1325
+ // Convert dataURL to File instance
1326
+ if (inputValue.dataURL) {
1327
+ newFile = common.createFileFromDataURL(inputValue.name || inputValue.path, inputValue.dataURL);
1328
+ newFile.dataURL = inputValue.dataURL;
1329
+ }
1185
1330
 
1186
- // Callback for value changes
1187
- const onChangeSomeInput = React.useCallback((inputValue, newOptionValue) => {
1188
- const updatedValues = inputValue.includes(newOptionValue) ? inputValue.filter(selectedValue => selectedValue !== newOptionValue) : [...inputValue, newOptionValue];
1189
- change(name, updatedValues);
1190
- onChange && onChange(updatedValues);
1191
- }, [change, name, onChange]);
1192
- React.useEffect(() => {
1193
- initialValue && change(name, initialValue);
1194
- // update the form value only when the initialValue changes, so use disable eslint to ignore the warning
1195
- // eslint-disable-next-line react-hooks/exhaustive-deps
1196
- }, [initialValue]);
1197
- return /*#__PURE__*/React__default.default.createElement(reactFinalForm.Field, {
1198
- name: name,
1199
- initialValue: initialValue
1200
- }, function Render({
1201
- input,
1202
- meta
1203
- }) {
1204
- const {
1205
- errorKey,
1206
- errorMessage,
1207
- isErrorState,
1208
- successKey,
1209
- isValidState
1210
- } = useFieldValidationState({
1211
- fieldProps: fieldProps,
1212
- input: input,
1213
- meta: meta
1214
- });
1215
- const updatedInputProps = useValidationAppearanceInputProps({
1216
- inputProps: inputProps,
1217
- validationStateKey: isErrorState ? errorKey : isValidState ? successKey : null
1218
- });
1219
- const activeOptionsList = React.useMemo(() => {
1220
- const emptyOptionsList = [{
1221
- label: null,
1222
- value: null
1223
- }];
1224
- if (input?.value) {
1225
- const currentOptions = options.filter(option => input.value?.includes(option.value));
1226
- return currentOptions || emptyOptionsList;
1227
- }
1228
- return emptyOptionsList;
1229
- }, [input.value]);
1230
- return /*#__PURE__*/React__default.default.createElement(FieldWrapper, Object.assign({
1231
- className: clsx__default.default('form-field_chips', 'form__item_chips', classNameGroupItem),
1232
- errorKey: errorKey,
1233
- errorMessage: errorMessage,
1234
- isErrorState: isErrorState,
1235
- metaError: meta.error,
1236
- isDisabled: isDisabled,
1237
- fieldClassName: "form-chips",
1238
- inputName: input.name,
1239
- inputValue: input.value,
1240
- metaActive: meta.active,
1241
- showMessage: showMessage,
1242
- isRequired: isRequired,
1243
- isValidState: isValidState
1244
- }, fieldProps), options.length ? /*#__PURE__*/React__default.default.createElement(Chips.ChipsGroup, {
1245
- direction: "horizontal",
1246
- gap: "1m",
1247
- wrap: "wrap"
1248
- }, options.map(option => /*#__PURE__*/React__default.default.createElement(Chips.Chips, Object.assign({
1249
- className: clsx__default.default(meta.active && 'form-chips_state_focus', meta.error && meta.touched && `form-chips_state_${errorKey}`),
1250
- key: option.value,
1251
- label: option.label,
1252
- isDisabled: option.isDisabled,
1253
- value: option.value,
1254
- isActive: activeOptionsList.some(activeOption => activeOption.value === option.value),
1255
- onClick: () => onChangeSomeInput(input.value, option.value)
1256
- }, updatedInputProps)))) : /*#__PURE__*/React__default.default.createElement(Text.Text, {
1257
- size: emptyMessageTextSize,
1258
- textColor: emptyMessageTextColor
1259
- }, emptyMessage));
1260
- });
1331
+ // Save new File to state
1332
+ if (newFile) {
1333
+ newFile.id = inputValue.id;
1334
+ if (isPreviews) {
1335
+ newFile.preview = URL.createObjectURL(newFile);
1336
+ }
1337
+ }
1338
+ return newFile;
1261
1339
  }
1340
+ function setFileDataURL(file, resolve) {
1341
+ resolve = resolve || (() => {});
1342
+ // Init reader and save his file
1343
+ const reader = new FileReader();
1344
+ reader._readedFile = file;
1262
1345
 
1263
- const defaultChoiceProps = {
1264
- appearance: 'defaultPrimary sizeM solid rounded',
1265
- width: 'fill',
1266
- // useValidationAppearanceInputProps
1267
- // Error
1268
- errorAppearance: 'errorPrimary sizeM solid rounded',
1269
- // Required
1270
- requiredAppearance: 'requirePrimary sizeM solid rounded'
1271
- };
1346
+ // Set handlers
1347
+ reader.onabort = () => resolve();
1348
+ reader.onerror = () => resolve();
1349
+ reader.onload = event => {
1350
+ event.target._readedFile.dataURL = reader.result;
1351
+ resolve();
1352
+ };
1353
+ // Run reader
1354
+ if (file instanceof File) {
1355
+ reader.readAsDataURL(file);
1356
+ } else {
1357
+ resolve();
1358
+ }
1359
+ }
1272
1360
 
1273
- const FormFieldChoice = /*#__PURE__*/React__default.default.memo(function FormFieldChoice(props) {
1361
+ const FormFieldFileInput = /*#__PURE__*/React__default.default.memo(function FormFieldFileInput(props) {
1274
1362
  const {
1363
+ className,
1275
1364
  name,
1276
- initialValue,
1365
+ width,
1366
+ maxFiles,
1367
+ maxSize,
1277
1368
  label,
1278
- messageType,
1279
- isDisabled,
1369
+ fileErrorText,
1280
1370
  classNameGroupItem,
1371
+ dropzoneProps,
1281
1372
  fieldProps,
1282
- inputProps,
1283
- options,
1284
- placeholder,
1373
+ hintDescription,
1374
+ hintTitle,
1375
+ showFilename,
1285
1376
  showMessage,
1286
- isCheckbox,
1377
+ isPreviews,
1287
1378
  isRequired,
1288
- onChange
1379
+ onAddFiles,
1380
+ onClickPreview,
1381
+ onDeleteFile
1289
1382
  } = props;
1383
+ const propsGenerator = useDevicePropsGenerator.useDevicePropsGenerator(props);
1290
1384
  const {
1291
- change
1292
- } = reactFinalForm.useForm();
1293
- const setActiveSegment = React.useCallback((option, isChecked) => {
1294
- change(name, isChecked && option.value);
1295
- if (onChange) {
1296
- onChange(option.value, name, isChecked);
1297
- }
1298
- }, [change, onChange]);
1385
+ size,
1386
+ fill,
1387
+ fillHover,
1388
+ labelTextColor,
1389
+ borderColorHover,
1390
+ borderType,
1391
+ borderWidth,
1392
+ errorMessageTextColor,
1393
+ errorMessageTextSize,
1394
+ errorMessageTextWeight,
1395
+ hintDescriptionTextColor,
1396
+ hintDescriptionTextSize,
1397
+ hintDescriptionTextWeight,
1398
+ hintDescriptionTextWrap,
1399
+ hintTitleTextColor,
1400
+ hintTitleTextSize,
1401
+ hintTitleTextWeight,
1402
+ hintTitleTextWrap,
1403
+ removeThumbAppearance,
1404
+ removeThumbShape,
1405
+ removeThumbText,
1406
+ removeThumbTextWeight,
1407
+ shape,
1408
+ thumbBorderColor,
1409
+ thumbBorderColorHover,
1410
+ thumbBorderType,
1411
+ thumbBorderWidth,
1412
+ thumbColumn = 1,
1413
+ thumbDirection = 'vertical',
1414
+ thumbNameTextColor,
1415
+ thumbNameTextSize,
1416
+ thumbNameTextWeight,
1417
+ thumbNameTextWrap
1418
+ } = propsGenerator;
1299
1419
  return /*#__PURE__*/React__default.default.createElement(reactFinalForm.Field, {
1300
- initialValue: initialValue,
1301
1420
  name: name
1302
1421
  }, function Render({
1303
1422
  input,
@@ -1309,22 +1428,11 @@ const FormFieldChoice = /*#__PURE__*/React__default.default.memo(function FormFi
1309
1428
  * React Hooks must be called in a React function component or a
1310
1429
  * custom React Hook function.
1311
1430
  */
1312
- const activeOption = React.useMemo(() => {
1313
- const emptyOption = {
1314
- value: null,
1315
- label: null
1316
- };
1317
- if (input.value) {
1318
- const currentOption = options.find(option => option.value === input.value);
1319
- return currentOption || emptyOption;
1320
- }
1321
- return emptyOption;
1322
- }, [input.value]);
1431
+
1323
1432
  const {
1324
1433
  errorKey,
1325
1434
  errorMessage,
1326
1435
  isErrorState,
1327
- successKey,
1328
1436
  isValidState
1329
1437
  } = useFieldValidationState({
1330
1438
  fieldProps: fieldProps,
@@ -1332,65 +1440,127 @@ const FormFieldChoice = /*#__PURE__*/React__default.default.memo(function FormFi
1332
1440
  meta: meta
1333
1441
  });
1334
1442
  const updatedInputProps = useValidationAppearanceInputProps({
1335
- inputProps: inputProps,
1336
- validationStateKey: isErrorState ? errorKey : isValidState ? successKey : null
1443
+ inputProps: props,
1444
+ validationStateKey: isErrorState ? errorKey : 'success'
1337
1445
  });
1446
+
1447
+ /** TODO:
1448
+ * REFACTOR PROPERTIES
1449
+ */
1338
1450
  return /*#__PURE__*/React__default.default.createElement(FieldWrapper, Object.assign({
1339
- className: clsx__default.default('form-field_choice', 'form__item_choice', classNameGroupItem),
1451
+ className: clsx__default.default('form-field_type_dropzone', 'form__item_type_dropzone', classNameGroupItem),
1452
+ width: width,
1340
1453
  label: label,
1341
- messageType: messageType,
1454
+ labelTextColor: labelTextColor,
1342
1455
  errorKey: errorKey,
1343
1456
  errorMessage: errorMessage,
1344
1457
  isErrorState: isErrorState,
1345
1458
  metaError: meta.error,
1346
- isDisabled: isDisabled,
1347
- fieldClassName: "form-choice",
1459
+ fieldClassName: "form-dropzone",
1348
1460
  inputName: input.name,
1349
- inputValue: input.value || [],
1461
+ inputValue: input.value,
1350
1462
  metaActive: meta.active,
1463
+ metaTouched: meta.touched,
1351
1464
  showMessage: showMessage,
1352
1465
  isRequired: isRequired,
1353
1466
  isValidState: isValidState
1354
- }, fieldProps), /*#__PURE__*/React__default.default.createElement(Choice.Choice, Object.assign({
1355
- className: clsx__default.default(meta.active && 'form-choice_state_focus', meta.error && meta.touched && `form-choice_state_${errorKey}`),
1356
- name: input.name,
1357
- isDisabled: isDisabled,
1358
- active: activeOption,
1359
- inputValue: input.value || [],
1360
- options: options,
1361
- placeholder: placeholder,
1362
- setActiveSegment: setActiveSegment,
1363
- isCheckbox: isCheckbox,
1364
- isRequired: isRequired
1365
- }, updatedInputProps)));
1467
+ }, fieldProps), /*#__PURE__*/React__default.default.createElement(FileInputDropzone, {
1468
+ className: className,
1469
+ maxFiles: maxFiles,
1470
+ maxSize: maxSize,
1471
+ size: size,
1472
+ fill: fill,
1473
+ fillHover: fillHover,
1474
+ borderColor: updatedInputProps.borderColor,
1475
+ borderColorHover: borderColorHover,
1476
+ borderType: borderType,
1477
+ borderWidth: borderWidth,
1478
+ errorMessageTextColor: errorMessageTextColor,
1479
+ errorMessageTextSize: errorMessageTextSize,
1480
+ errorMessageWeight: errorMessageTextWeight,
1481
+ fileErrorText: fileErrorText,
1482
+ metaError: meta.error,
1483
+ dropzoneProps: dropzoneProps,
1484
+ hintDescription: hintDescription,
1485
+ hintDescriptionTextColor: hintDescriptionTextColor,
1486
+ hintDescriptionTextSize: hintDescriptionTextSize,
1487
+ hintDescriptionTextWeight: hintDescriptionTextWeight,
1488
+ hintDescriptionTextWrap: hintDescriptionTextWrap,
1489
+ hintTitle: hintTitle,
1490
+ hintTitleTextColor: hintTitleTextColor,
1491
+ hintTitleTextSize: hintTitleTextSize,
1492
+ hintTitleTextWeight: hintTitleTextWeight,
1493
+ hintTitleTextWrap: hintTitleTextWrap,
1494
+ inputName: input.name,
1495
+ inputValue: input.value,
1496
+ metaTouched: meta.touched,
1497
+ removeThumbAppearance: removeThumbAppearance,
1498
+ removeThumbShape: removeThumbShape,
1499
+ removeThumbText: removeThumbText,
1500
+ removeThumbTextWeight: removeThumbTextWeight,
1501
+ shape: shape,
1502
+ showFilename: showFilename,
1503
+ thumbBorderColor: thumbBorderColor,
1504
+ thumbBorderColorHover: thumbBorderColorHover,
1505
+ thumbBorderType: thumbBorderType,
1506
+ thumbBorderWidth: thumbBorderWidth,
1507
+ thumbColumn: thumbColumn,
1508
+ thumbDirection: thumbDirection,
1509
+ thumbNameTextColor: thumbNameTextColor,
1510
+ thumbNameTextSize: thumbNameTextSize,
1511
+ thumbNameTextWeight: thumbNameTextWeight,
1512
+ thumbNameTextWrap: thumbNameTextWrap,
1513
+ isPreviews: isPreviews,
1514
+ onAddFiles: onAddFiles,
1515
+ onClickPreview: onClickPreview,
1516
+ onDeleteFile: onDeleteFile
1517
+ }));
1366
1518
  });
1367
1519
  });
1368
1520
 
1369
- const defaultCodeProps = {
1370
- appearance: 'defaultPrimary sizeL solid rounded',
1371
- // useValidationAppearanceInputProps
1372
- // Error
1373
- errorAppearance: 'errorPrimary sizeM solid rounded',
1374
- // Required
1375
- requiredAppearance: 'requirePrimary sizeM solid rounded'
1521
+ const defaultGroupProps = {
1522
+ width: 'fill',
1523
+ labelTextSize: 's',
1524
+ messageTextColor: 'surfaceTextPrimary',
1525
+ messageTextSize: 's',
1526
+ errorMessageTextSize: 's',
1527
+ errorMessageTextColor: 'errorTextSecondary',
1528
+ helpTextSize: 's',
1529
+ requiredMessageTextColor: 'warningTextSecondary',
1530
+ requiredMessageTextSize: 's'
1376
1531
  };
1377
1532
 
1378
- const FormFieldCode = /*#__PURE__*/React__default.default.memo(function FormFieldCode(props) {
1533
+ const FormBlockGroup = /*#__PURE__*/React__default.default.memo(function Group(props) {
1379
1534
  const {
1535
+ dataTour,
1536
+ className,
1380
1537
  name,
1381
- initialValue,
1382
- messageType,
1538
+ title,
1539
+ titleTextColor,
1540
+ titleTextSize,
1541
+ titleTextWeight,
1383
1542
  label,
1384
- isDisabled,
1385
- classNameGroupItem,
1386
- fieldProps = {},
1387
- inputProps = {},
1388
- showMessage,
1389
- isRequired
1543
+ labelTextColor,
1544
+ labelTextSize,
1545
+ labelTextWeight,
1546
+ message,
1547
+ messageTextColor,
1548
+ messageTextSize,
1549
+ messageTextWeight,
1550
+ column,
1551
+ showGroupMessage,
1552
+ before,
1553
+ after,
1554
+ isHidden,
1555
+ children
1390
1556
  } = props;
1557
+
1558
+ // @ts-expect-error
1559
+ const {
1560
+ styles: styles
1561
+ } = useStyles.useStyles(props);
1391
1562
  return /*#__PURE__*/React__default.default.createElement(reactFinalForm.Field, {
1392
- name: name,
1393
- initialValue: initialValue
1563
+ name: name
1394
1564
  }, function Render({
1395
1565
  input,
1396
1566
  meta
@@ -1401,68 +1571,93 @@ const FormFieldCode = /*#__PURE__*/React__default.default.memo(function FormFiel
1401
1571
  * React Hooks must be called in a React function component or a
1402
1572
  * custom React Hook function.
1403
1573
  */
1404
-
1405
1574
  const {
1406
1575
  errorKey,
1407
1576
  errorMessage,
1408
- isErrorState,
1409
- successKey,
1410
- isValidState
1577
+ isErrorState
1411
1578
  } = useFieldValidationState({
1412
- fieldProps: fieldProps,
1579
+ fieldProps: props,
1580
+ // or fieldProps?
1413
1581
  input: input,
1414
1582
  meta: meta
1415
1583
  });
1416
- const updatedInputProps = useValidationAppearanceInputProps({
1417
- inputProps: inputProps,
1418
- validationStateKey: isErrorState ? errorKey : isValidState ? successKey : null
1584
+ const updatedProps = useValidationAppearanceInputProps({
1585
+ inputProps: props,
1586
+ validationStateKey: isErrorState ? errorKey : 'success'
1419
1587
  });
1420
- return /*#__PURE__*/React__default.default.createElement(FieldWrapper, Object.assign({
1421
- className: clsx__default.default('form-field-code', 'form__item_code', classNameGroupItem),
1422
- label: label,
1423
- messageType: messageType,
1424
- errorKey: errorKey,
1425
- errorMessage: errorMessage,
1426
- isErrorState: isErrorState,
1427
- fieldClassName: 'form-code',
1428
- inputName: input.name,
1429
- inputValue: input.value,
1430
- metaActive: meta.active,
1431
- showMessage: showMessage,
1432
- isRequired: isRequired,
1433
- isValidState: isValidState
1434
- }, fieldProps), /*#__PURE__*/React__default.default.createElement(Code.Code, Object.assign({
1435
- name: input.name,
1436
- isDisabled: isDisabled,
1437
- autoComplete: "nope",
1438
- value: input.value,
1439
- onBlur: input.onBlur,
1440
- onChange: input.onChange,
1441
- onFocus: input.onFocus
1442
- }, updatedInputProps)));
1588
+ return /*#__PURE__*/React__default.default.createElement("div", {
1589
+ className: clsx__default.default('form__group', className, isHidden && 'form__group_hidden', column && `form__group_column_${column}`),
1590
+ "data-tour": dataTour,
1591
+ style: styles
1592
+ }, /*#__PURE__*/React__default.default.createElement("div", {
1593
+ className: "form__group-wrapper"
1594
+ }, before, title && /*#__PURE__*/React__default.default.createElement("div", {
1595
+ className: "form__group-title"
1596
+ }, /*#__PURE__*/React__default.default.createElement(Title.Title, {
1597
+ size: titleTextSize,
1598
+ textColor: titleTextColor,
1599
+ textWeight: titleTextWeight
1600
+ }, title)), label && /*#__PURE__*/React__default.default.createElement("div", {
1601
+ className: "form__group-label"
1602
+ }, /*#__PURE__*/React__default.default.createElement(Text.Text, {
1603
+ size: labelTextSize,
1604
+ textColor: labelTextColor,
1605
+ textWeight: labelTextWeight
1606
+ }, label)), /*#__PURE__*/React__default.default.createElement("div", {
1607
+ className: "form__group-items"
1608
+ }, children), after), showGroupMessage && /*#__PURE__*/React__default.default.createElement(React__default.default.Fragment, null, isErrorState && errorMessage && /*#__PURE__*/React__default.default.createElement(Text.Text, {
1609
+ id: `${name}-error`,
1610
+ className: `form__group-message form__group-message_type-${errorKey}`,
1611
+ size: updatedProps.messageTextSize,
1612
+ textColor: updatedProps.messageTextColor,
1613
+ textWeight: updatedProps.messageTextWeight
1614
+ }, errorMessage), Boolean(message) && (!isErrorState || !errorMessage) && /*#__PURE__*/React__default.default.createElement(Text.Text, {
1615
+ className: "form__group-message",
1616
+ size: messageTextSize,
1617
+ textColor: messageTextColor,
1618
+ textWeight: messageTextWeight
1619
+ }, message), !isErrorState && !message && /*#__PURE__*/React__default.default.createElement(Text.Text, {
1620
+ className: "form__group-message",
1621
+ size: messageTextSize
1622
+ }, '\u00A0')));
1443
1623
  });
1444
1624
  });
1445
1625
 
1446
- const FormFieldCustom = /*#__PURE__*/React__default.default.memo(function FormFieldCustom(props) {
1626
+ const defaultInputProps = {
1627
+ appearance: 'defaultPrimary sizeM solid rounded',
1628
+ width: 'fill',
1629
+ // useValidationAppearanceInputProps
1630
+ // Error
1631
+ errorAppearance: 'errorPrimary sizeM solid rounded',
1632
+ // Required
1633
+ requiredAppearance: 'requirePrimary sizeM solid rounded',
1634
+ // Success
1635
+ successAppearance: 'successPrimary sizeM solid rounded'
1636
+ };
1637
+
1638
+ const FormFieldInput = /*#__PURE__*/React__default.default.memo(function FormFieldInput(props) {
1447
1639
  const {
1448
- Component,
1449
- isDisabled,
1450
- isRequired,
1451
1640
  name,
1452
1641
  initialValue,
1453
- fieldProps = {},
1454
1642
  classNameGroupItem,
1455
- showMessage,
1456
1643
  clearIcon,
1457
1644
  clearIconFill,
1458
1645
  clearIconFillHover,
1459
1646
  clearIconShape,
1460
1647
  clearIconSize,
1461
- onClickClearIcon
1648
+ fieldProps = {},
1649
+ inputProps = {},
1650
+ parse,
1651
+ showMessage,
1652
+ isDisabled,
1653
+ isRequired,
1654
+ onClickClearIcon,
1655
+ onChange
1462
1656
  } = props;
1463
1657
  return /*#__PURE__*/React__default.default.createElement(reactFinalForm.Field, {
1658
+ name: name,
1464
1659
  initialValue: initialValue,
1465
- name: name
1660
+ parse: parse
1466
1661
  }, function Render({
1467
1662
  input,
1468
1663
  meta
@@ -1474,79 +1669,87 @@ const FormFieldCustom = /*#__PURE__*/React__default.default.memo(function FormFi
1474
1669
  * custom React Hook function.
1475
1670
  */
1476
1671
 
1672
+ const onChangeField = React.useCallback(event => {
1673
+ input.onChange(event);
1674
+ if (onChange) {
1675
+ onChange(event.target.value, input.name);
1676
+ }
1677
+ }, [onChange, input.onChange]);
1477
1678
  const {
1478
- isErrorState,
1479
- isValidState,
1480
1679
  errorKey,
1481
- errorMessage
1680
+ errorMessage,
1681
+ successKey,
1682
+ isErrorState,
1683
+ isValidState
1482
1684
  } = useFieldValidationState({
1483
1685
  fieldProps: fieldProps,
1484
1686
  input: input,
1485
1687
  meta: meta
1486
1688
  });
1487
1689
  const updatedInputProps = useValidationAppearanceInputProps({
1488
- validationStateKey: isErrorState ? errorKey : 'success',
1489
- // For "Custom" field we pass all props. Can contain some special props, we don't known.
1490
- inputProps: props
1690
+ inputProps: inputProps,
1691
+ validationStateKey: isErrorState ? errorKey : isValidState ? successKey : null
1491
1692
  });
1492
1693
  return /*#__PURE__*/React__default.default.createElement(FieldWrapper, Object.assign({
1493
- className: clsx__default.default('form-field_custom', 'form__item_custom', classNameGroupItem),
1694
+ className: clsx__default.default('form-field_input', 'form__item_input', classNameGroupItem),
1494
1695
  errorKey: errorKey,
1495
1696
  errorMessage: errorMessage,
1496
- fieldClassName: 'form-custom',
1697
+ fieldClassName: "form-input",
1497
1698
  inputName: input.name,
1498
- inputValue: input.value,
1699
+ inputValue: input.value || '',
1700
+ metaActive: meta.active,
1701
+ metaError: meta.error,
1702
+ showMessage: showMessage,
1499
1703
  isDisabled: isDisabled,
1500
1704
  isErrorState: isErrorState,
1501
1705
  isRequired: isRequired,
1502
- isValidState: isValidState,
1503
- metaActive: meta.active,
1504
- metaError: meta.error,
1505
- showMessage: showMessage
1506
- }, fieldProps), /*#__PURE__*/React__default.default.createElement(Component, Object.assign({}, updatedInputProps, {
1507
- input: input,
1706
+ isValidState: isValidState
1707
+ }, fieldProps), /*#__PURE__*/React__default.default.createElement(Input.Input, Object.assign({
1708
+ className: clsx__default.default(meta.active && 'input_state_focus', meta.error && meta.touched && `input_state_${errorKey}`),
1709
+ dataTestId: `${input.name}FieldInput`,
1710
+ type: "text",
1711
+ name: input.name,
1712
+ autoComplete: "nope",
1713
+ value: input.value || '',
1508
1714
  isDisabled: isDisabled,
1509
- meta: meta
1510
- })), clearIcon && /*#__PURE__*/React__default.default.createElement(Icon.Icon, {
1715
+ onBlur: input.onBlur,
1716
+ onChange: onChangeField,
1717
+ onFocus: input.onFocus
1718
+ }, updatedInputProps)), clearIcon && /*#__PURE__*/React__default.default.createElement(Icon.Icon, {
1511
1719
  className: "form-field__icon",
1720
+ size: clearIconSize,
1512
1721
  iconFill: clearIconFill,
1513
1722
  iconFillHover: clearIconFillHover,
1514
- imageSrc: clearIcon,
1723
+ imageSrc: typeof clearIcon === 'string' && clearIcon,
1515
1724
  shape: clearIconShape,
1516
- size: clearIconSize,
1517
- SvgImage: clearIcon,
1725
+ SvgImage: typeof clearIcon !== 'string' && clearIcon,
1518
1726
  onClick: onClickClearIcon
1519
1727
  }));
1520
1728
  });
1521
1729
  });
1522
1730
 
1523
- const defaultDatepickerProps = {
1524
- appearance: 'surfacePrimary sizeS',
1525
- dateFormat: 'dd/MM/yyyy - HH:mm',
1526
- readOnly: false,
1527
- selectsRange: false,
1528
- showTimeSelect: true,
1529
- timeCaption: 'Время',
1530
- timeFormat: 'p',
1531
- timeIntervals: 60,
1532
- isClearable: true,
1533
- isStartDefaultNull: true
1534
- };
1535
-
1536
- function FormFieldDatePicker(props) {
1731
+ const FormFieldMaskedInput = /*#__PURE__*/React__default.default.memo(function FormFieldMaskedInput(props) {
1537
1732
  const {
1538
1733
  name,
1539
- isDisabled,
1734
+ initialValue,
1540
1735
  classNameGroupItem,
1541
- datePickerProps,
1736
+ clearIcon,
1737
+ clearIconFill,
1738
+ clearIconFillHover,
1739
+ clearIconShape,
1740
+ clearIconSize,
1542
1741
  fieldProps = {},
1543
1742
  inputProps = {},
1743
+ optionsMask,
1544
1744
  showMessage,
1745
+ unmasked,
1746
+ isDisabled,
1545
1747
  isRequired,
1546
- onChange
1748
+ onClickClearIcon
1547
1749
  } = props;
1548
1750
  return /*#__PURE__*/React__default.default.createElement(reactFinalForm.Field, {
1549
- name: name
1751
+ name: name,
1752
+ initialValue: initialValue
1550
1753
  }, function Render({
1551
1754
  input,
1552
1755
  meta
@@ -1558,27 +1761,35 @@ function FormFieldDatePicker(props) {
1558
1761
  * custom React Hook function.
1559
1762
  */
1560
1763
 
1561
- const onChangeField = React.useCallback((startDate, endDate) => {
1562
- if (!datePickerProps.selectsRange) {
1563
- // When we need to save single date, value is date
1564
- // TODO: make object with one date? need to check all forms with FormFieldDatePicker
1565
- input.onChange(startDate);
1566
- } else {
1567
- // When we need to save range, value is object with two date
1568
- input.onChange({
1569
- endDate,
1570
- startDate
1571
- });
1764
+ const {
1765
+ ref,
1766
+ unmaskedValue,
1767
+ value,
1768
+ setUnmaskedValue
1769
+ } = reactImask.useIMask(optionsMask, {
1770
+ onAccept: (newValue, event, element) => {
1771
+ if (element) {
1772
+ input.onChange(event._unmaskedValue);
1773
+ }
1572
1774
  }
1573
- if (onChange) {
1574
- onChange(startDate, endDate);
1775
+ });
1776
+ React.useEffect(() => {
1777
+ if (input.value !== unmaskedValue) {
1778
+ setUnmaskedValue(input.value.replace(unmasked, ''));
1575
1779
  }
1576
- }, [input.onChange, onChange]);
1780
+ }, [input.value]);
1781
+
1782
+ // useEffect(() => {
1783
+ // if (unmaskedValue !== input.value) {
1784
+ // input.onChange(unmaskedValue)
1785
+ // }
1786
+ // }, [unmaskedValue])
1787
+
1577
1788
  const {
1578
1789
  errorKey,
1579
1790
  errorMessage,
1580
- isErrorState,
1581
1791
  successKey,
1792
+ isErrorState,
1582
1793
  isValidState
1583
1794
  } = useFieldValidationState({
1584
1795
  fieldProps: fieldProps,
@@ -1590,36 +1801,40 @@ function FormFieldDatePicker(props) {
1590
1801
  validationStateKey: isErrorState ? errorKey : isValidState ? successKey : null
1591
1802
  });
1592
1803
  return /*#__PURE__*/React__default.default.createElement(FieldWrapper, Object.assign({
1593
- className: clsx__default.default('form-field_datepicker', 'form__item_datepicker', classNameGroupItem),
1804
+ className: clsx__default.default('form-field-masked-input', 'form__item_masked-input', classNameGroupItem),
1594
1805
  errorKey: errorKey,
1595
1806
  errorMessage: errorMessage,
1596
- isErrorState: isErrorState,
1597
- metaError: meta.error,
1598
- isDisabled: isDisabled,
1599
- fieldClassName: "form-datepicker",
1807
+ fieldClassName: 'form-maskedInput',
1600
1808
  inputName: input.name,
1601
- inputValue: input.value || '',
1809
+ inputValue: input.value,
1602
1810
  metaActive: meta.active,
1811
+ metaError: meta.error,
1603
1812
  showMessage: showMessage,
1813
+ isDisabled: isDisabled,
1814
+ isErrorState: isErrorState,
1604
1815
  isRequired: isRequired,
1605
1816
  isValidState: isValidState
1606
- }, fieldProps), /*#__PURE__*/React__default.default.createElement(DatePicker.DatePickerInput, {
1607
- name: input.name,
1608
- isDisabled: isDisabled,
1609
- datePickerProps: datePickerProps,
1610
- endValue: datePickerProps.selectsRange ? input.value.endDate : null,
1611
- inputProps: updatedInputProps,
1612
- value: datePickerProps.selectsRange ? input.value.startDate : input.value,
1817
+ }, fieldProps), /*#__PURE__*/React__default.default.createElement(Input.Input, Object.assign({
1818
+ className: clsx__default.default(meta.active && 'input_state_focus', meta.error && meta.touched && `input_state_${errorKey}`),
1819
+ ref: ref,
1820
+ value: value,
1613
1821
  onBlur: input.onBlur,
1614
- onChange: onChangeField,
1615
1822
  onFocus: input.onFocus
1823
+ }, updatedInputProps)), clearIcon && /*#__PURE__*/React__default.default.createElement(Icon.Icon, {
1824
+ className: "form-field__icon",
1825
+ size: clearIconSize,
1826
+ iconFill: clearIconFill,
1827
+ iconFillHover: clearIconFillHover,
1828
+ imageSrc: clearIcon,
1829
+ shape: clearIconShape,
1830
+ SvgImage: clearIcon,
1831
+ onClick: onClickClearIcon
1616
1832
  }));
1617
1833
  });
1618
- }
1834
+ });
1619
1835
 
1620
- const defaultInputProps = {
1836
+ const defaultPasswordProps = {
1621
1837
  appearance: 'defaultPrimary sizeM solid rounded',
1622
- width: 'fill',
1623
1838
  // useValidationAppearanceInputProps
1624
1839
  // Error
1625
1840
  errorAppearance: 'errorPrimary sizeM solid rounded',
@@ -1629,27 +1844,18 @@ const defaultInputProps = {
1629
1844
  successAppearance: 'successPrimary sizeM solid rounded'
1630
1845
  };
1631
1846
 
1632
- const FormFieldInput = /*#__PURE__*/React__default.default.memo(function FormFieldInput(props) {
1847
+ const FormFieldPassword = /*#__PURE__*/React__default.default.memo(function FormFieldPassword(props) {
1633
1848
  const {
1634
1849
  name,
1635
1850
  initialValue,
1636
- isDisabled,
1637
1851
  classNameGroupItem,
1638
- // dataTestId,
1639
- // iconBorder,
1640
- // iconBorderHover,
1641
- clearIcon,
1642
- clearIconFill,
1643
- clearIconFillHover,
1644
- clearIconShape,
1645
- clearIconSize,
1646
- fieldProps = {},
1647
- inputProps = {},
1852
+ fieldProps,
1853
+ inputProps,
1648
1854
  parse,
1649
1855
  showMessage,
1856
+ isDisabled,
1650
1857
  isRequired,
1651
- onChange,
1652
- onClickClearIcon
1858
+ onChange
1653
1859
  } = props;
1654
1860
  return /*#__PURE__*/React__default.default.createElement(reactFinalForm.Field, {
1655
1861
  name: name,
@@ -1675,8 +1881,8 @@ const FormFieldInput = /*#__PURE__*/React__default.default.memo(function FormFie
1675
1881
  const {
1676
1882
  errorKey,
1677
1883
  errorMessage,
1678
- isErrorState,
1679
1884
  successKey,
1885
+ isErrorState,
1680
1886
  isValidState
1681
1887
  } = useFieldValidationState({
1682
1888
  fieldProps: fieldProps,
@@ -1688,79 +1894,90 @@ const FormFieldInput = /*#__PURE__*/React__default.default.memo(function FormFie
1688
1894
  validationStateKey: isErrorState ? errorKey : isValidState ? successKey : null
1689
1895
  });
1690
1896
  return /*#__PURE__*/React__default.default.createElement(FieldWrapper, Object.assign({
1691
- className: clsx__default.default('form-field_input', 'form__item_input', classNameGroupItem),
1897
+ className: clsx__default.default('form-field_input-password', 'form__item_input-password', classNameGroupItem),
1692
1898
  errorKey: errorKey,
1693
1899
  errorMessage: errorMessage,
1694
- isErrorState: isErrorState,
1695
- metaError: meta.error,
1696
- isDisabled: isDisabled,
1697
- fieldClassName: "form-input",
1900
+ fieldClassName: "form-password",
1698
1901
  inputName: input.name,
1699
1902
  inputValue: input.value || '',
1700
1903
  metaActive: meta.active,
1904
+ metaError: meta.error,
1701
1905
  showMessage: showMessage,
1906
+ isDisabled: isDisabled,
1907
+ isErrorState: isErrorState,
1702
1908
  isRequired: isRequired,
1703
1909
  isValidState: isValidState
1704
- }, fieldProps), /*#__PURE__*/React__default.default.createElement(Input.Input, Object.assign({
1705
- dataTestId: `${input.name}FieldInput`,
1706
- className: clsx__default.default(meta.active && 'input_state_focus', meta.error && meta.touched && `input_state_${errorKey}`),
1707
- type: "text",
1910
+ }, fieldProps), /*#__PURE__*/React__default.default.createElement(InputPassword.InputPassword, Object.assign({
1911
+ className: clsx__default.default(meta.active && 'input-password_state_focus', meta.error && meta.touched && `input-password_state_${errorKey}`),
1912
+ dataTestId: `${input.name}FieldInputPassword`,
1708
1913
  name: input.name,
1709
- isDisabled: isDisabled,
1710
1914
  autoComplete: "nope",
1711
1915
  value: input.value || '',
1916
+ isDisabled: isDisabled,
1712
1917
  onBlur: input.onBlur,
1713
1918
  onChange: onChangeField,
1714
1919
  onFocus: input.onFocus
1715
- }, updatedInputProps)), clearIcon && /*#__PURE__*/React__default.default.createElement(Icon.Icon, {
1716
- className: "form-field__icon",
1717
- size: clearIconSize,
1718
- iconFill: clearIconFill,
1719
- iconFillHover: clearIconFillHover,
1720
- imageSrc: typeof clearIcon === 'string' && clearIcon,
1721
- shape: clearIconShape,
1722
- SvgImage: typeof clearIcon !== 'string' && clearIcon,
1723
- onClick: onClickClearIcon
1724
- }));
1920
+ }, updatedInputProps)));
1725
1921
  });
1726
1922
  });
1727
1923
 
1728
- const defaultPasswordProps = {
1729
- appearance: 'sizeM defaultSecondary solid rounded',
1730
- // useValidationAppearanceInputProps
1731
- // Error
1732
- errorAppearance: 'errorPrimary sizeM solid rounded',
1733
- // Required
1734
- iconRevealableHide: _default.icons24.View.HideValue,
1735
- iconRevealableShow: _default.icons24.View.ShowValue,
1736
- requiredAppearance: 'requirePrimary sizeM solid rounded'
1924
+ const defaultRadioProps = {
1925
+ appearance: 'defaultPrimary sizeM solid circular'
1737
1926
  };
1738
1927
 
1739
- const FormFieldPassword = /*#__PURE__*/React__default.default.memo(function FormFieldPassword(props) {
1928
+ function FormFieldRadioGroupList(props) {
1929
+ const {
1930
+ input,
1931
+ inputProps,
1932
+ options,
1933
+ onChange
1934
+ } = props;
1935
+
1936
+ // Callback for value changes
1937
+ const onChangeSomeInput = React.useCallback(value => {
1938
+ // Save to form values
1939
+ input.onChange(value);
1940
+ if (onChange) {
1941
+ // Pass to custom event
1942
+ onChange(value, input.name);
1943
+ }
1944
+ }, [input, onChange]);
1945
+
1946
+ // Handle for radio inputs
1947
+ const onChangeRadio = React.useCallback(event => {
1948
+ if (event.target.checked) {
1949
+ onChangeSomeInput(event.target.value);
1950
+ }
1951
+ }, [onChange]);
1952
+ return /*#__PURE__*/React__default.default.createElement(React__default.default.Fragment, null, options.map(option => /*#__PURE__*/React__default.default.createElement(Radio.Radio, Object.assign({
1953
+ className: "form-radio__item",
1954
+ key: option.value,
1955
+ type: "radio",
1956
+ name: input.name,
1957
+ label: option.label,
1958
+ checked: option.value === input.value,
1959
+ value: option.value,
1960
+ onBlur: input.onBlur,
1961
+ onChange: onChangeRadio,
1962
+ onFocus: input.onFocus
1963
+ }, inputProps))));
1964
+ }
1965
+
1966
+ const FormFieldRadioGroup = /*#__PURE__*/React__default.default.memo(function FormFieldRadioGroup(props) {
1740
1967
  const {
1741
1968
  name,
1742
- initialValue,
1743
1969
  isDisabled,
1970
+ editableProps = {},
1971
+ fieldProps = {},
1972
+ inputProps = {},
1973
+ options = [],
1744
1974
  classNameGroupItem,
1745
- fieldProps,
1746
- inputProps,
1747
- parse,
1748
1975
  showMessage,
1749
1976
  isRequired,
1750
1977
  onChange
1751
1978
  } = props;
1752
- const [isRevealed, setIsRevealed] = React.useState(false);
1753
- const inputType = React.useMemo(() => {
1754
- return isRevealed ? 'text' : 'password';
1755
- }, [isRevealed]);
1756
- const onClickIconReveal = React.useCallback(event => {
1757
- event.preventDefault();
1758
- setIsRevealed(prev => !prev);
1759
- }, []);
1760
1979
  return /*#__PURE__*/React__default.default.createElement(reactFinalForm.Field, {
1761
- name: name,
1762
- initialValue: initialValue,
1763
- parse: parse
1980
+ name: name
1764
1981
  }, function Render({
1765
1982
  input,
1766
1983
  meta
@@ -1772,17 +1989,10 @@ const FormFieldPassword = /*#__PURE__*/React__default.default.memo(function Form
1772
1989
  * custom React Hook function.
1773
1990
  */
1774
1991
 
1775
- const onChangeField = React.useCallback(event => {
1776
- input.onChange(event);
1777
- if (onChange) {
1778
- onChange(event.target.value, input.name);
1779
- }
1780
- }, [onChange, input.onChange]);
1781
1992
  const {
1782
1993
  errorKey,
1783
1994
  errorMessage,
1784
1995
  isErrorState,
1785
- successKey,
1786
1996
  isValidState
1787
1997
  } = useFieldValidationState({
1788
1998
  fieldProps: fieldProps,
@@ -1791,39 +2001,29 @@ const FormFieldPassword = /*#__PURE__*/React__default.default.memo(function Form
1791
2001
  });
1792
2002
  const updatedInputProps = useValidationAppearanceInputProps({
1793
2003
  inputProps: inputProps,
1794
- validationStateKey: isErrorState ? errorKey : isValidState ? successKey : null
2004
+ validationStateKey: isErrorState ? errorKey : 'success'
1795
2005
  });
1796
2006
  return /*#__PURE__*/React__default.default.createElement(FieldWrapper, Object.assign({
1797
- className: clsx__default.default('form-field_input', 'form__item_input', classNameGroupItem),
2007
+ className: clsx__default.default('form-field_radio', 'form__item_radio', classNameGroupItem),
1798
2008
  errorKey: errorKey,
1799
2009
  errorMessage: errorMessage,
1800
2010
  isErrorState: isErrorState,
1801
2011
  metaError: meta.error,
1802
2012
  isDisabled: isDisabled,
1803
- fieldClassName: "form-password",
2013
+ fieldClassName: 'form-radio',
1804
2014
  inputName: input.name,
1805
2015
  inputValue: input.value || '',
1806
2016
  metaActive: meta.active,
1807
2017
  showMessage: showMessage,
1808
2018
  isRequired: isRequired,
1809
2019
  isValidState: isValidState
1810
- }, fieldProps), /*#__PURE__*/React__default.default.createElement(Input.Input, Object.assign({
1811
- dataTestId: `${input.name}FieldInputPassword`,
1812
- className: clsx__default.default(meta.active && 'input_state_focus', meta.error && meta.touched && `input_state_${errorKey}`),
1813
- type: inputType,
1814
- name: input.name,
2020
+ }, fieldProps), /*#__PURE__*/React__default.default.createElement(FormFieldRadioGroupList, {
1815
2021
  isDisabled: isDisabled,
1816
- autoComplete: "nope",
1817
- value: input.value || '',
1818
- onBlur: input.onBlur,
1819
- onChange: onChangeField,
1820
- onFocus: input.onFocus
1821
- }, updatedInputProps)), /*#__PURE__*/React__default.default.createElement(Icon.Icon, {
1822
- className: "form-field__icon",
1823
- size: inputProps?.iconSize,
1824
- iconFill: inputProps?.iconFill,
1825
- SvgImage: isRevealed ? inputProps?.iconRevealableHide : inputProps?.iconRevealableShow,
1826
- onClick: onClickIconReveal
2022
+ editableProps: editableProps,
2023
+ input: input,
2024
+ inputProps: updatedInputProps,
2025
+ options: options,
2026
+ onChange: onChange
1827
2027
  }));
1828
2028
  });
1829
2029
  });
@@ -2042,12 +2242,8 @@ const FormFieldSelect = /*#__PURE__*/React__default.default.memo(function FormFi
2042
2242
 
2043
2243
  const defaultSwitchProps = {
2044
2244
  appearance: 'defaultPrimary sizeL solid rounded',
2045
- // useValidationAppearanceInputProps
2046
- // Error
2047
2245
  errorAppearance: 'errorPrimary sizeL solid rounded',
2048
- // Success
2049
2246
  successAppearance: 'successPrimary sizeL solid rounded',
2050
- // Required
2051
2247
  requiredAppearance: 'requirePrimary sizeL solid rounded'
2052
2248
  };
2053
2249
 
@@ -2202,211 +2398,6 @@ const FormFieldTextarea = /*#__PURE__*/React__default.default.memo(function Form
2202
2398
  });
2203
2399
  });
2204
2400
 
2205
- const FormFieldMaskedInput = /*#__PURE__*/React__default.default.memo(function FormFieldMaskedInput(props) {
2206
- const {
2207
- name,
2208
- initialValue,
2209
- isDisabled,
2210
- classNameGroupItem,
2211
- clearIcon,
2212
- clearIconFill,
2213
- clearIconFillHover,
2214
- clearIconShape,
2215
- clearIconSize,
2216
- fieldProps = {},
2217
- inputProps = {},
2218
- optionsMask,
2219
- showMessage,
2220
- unmasked,
2221
- isRequired,
2222
- onClickClearIcon
2223
- } = props;
2224
- return /*#__PURE__*/React__default.default.createElement(reactFinalForm.Field, {
2225
- name: name,
2226
- initialValue: initialValue
2227
- }, function Render({
2228
- input,
2229
- meta
2230
- }) {
2231
- /** Note:
2232
- * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
2233
- * React Hooks cannot be called inside a callback.
2234
- * React Hooks must be called in a React function component or a
2235
- * custom React Hook function.
2236
- */
2237
-
2238
- const {
2239
- ref,
2240
- unmaskedValue,
2241
- value,
2242
- setUnmaskedValue
2243
- } = reactImask.useIMask(optionsMask, {
2244
- onAccept: (newValue, event, element) => {
2245
- if (element) {
2246
- input.onChange(event._unmaskedValue);
2247
- }
2248
- }
2249
- });
2250
- React.useEffect(() => {
2251
- if (input.value !== unmaskedValue) {
2252
- setUnmaskedValue(input.value.replace(unmasked, ''));
2253
- }
2254
- }, [input.value]);
2255
- const {
2256
- errorKey,
2257
- errorMessage,
2258
- isErrorState,
2259
- successKey,
2260
- isValidState
2261
- } = useFieldValidationState({
2262
- fieldProps: fieldProps,
2263
- input: input,
2264
- meta: meta
2265
- });
2266
- const updatedInputProps = useValidationAppearanceInputProps({
2267
- inputProps: inputProps,
2268
- validationStateKey: isErrorState ? errorKey : isValidState ? successKey : null
2269
- });
2270
- return /*#__PURE__*/React__default.default.createElement(FieldWrapper, Object.assign({
2271
- className: clsx__default.default('form-field-masked-input', 'form__item_masked-input', classNameGroupItem),
2272
- errorKey: errorKey,
2273
- errorMessage: errorMessage,
2274
- isErrorState: isErrorState,
2275
- metaError: meta.error,
2276
- isDisabled: isDisabled,
2277
- fieldClassName: 'form-maskedInput',
2278
- inputName: input.name,
2279
- inputValue: input.value,
2280
- metaActive: meta.active,
2281
- showMessage: showMessage,
2282
- isRequired: isRequired,
2283
- isValidState: isValidState
2284
- }, fieldProps), /*#__PURE__*/React__default.default.createElement(Input.Input, Object.assign({
2285
- className: clsx__default.default(meta.active && 'input_state_focus', meta.error && meta.touched && `input_state_${errorKey}`),
2286
- ref: ref,
2287
- value: value,
2288
- onBlur: input.onBlur,
2289
- onFocus: input.onFocus
2290
- }, updatedInputProps)), clearIcon && /*#__PURE__*/React__default.default.createElement(Icon.Icon, {
2291
- className: "form-field__icon",
2292
- size: clearIconSize,
2293
- iconFill: clearIconFill,
2294
- iconFillHover: clearIconFillHover,
2295
- imageSrc: clearIcon,
2296
- shape: clearIconShape,
2297
- SvgImage: clearIcon,
2298
- onClick: onClickClearIcon
2299
- }));
2300
- });
2301
- });
2302
-
2303
- const defaultRadioProps = {
2304
- appearance: 'defaultPrimary sizeM solid circular'
2305
- };
2306
-
2307
- function RadioGroupList(props) {
2308
- const {
2309
- input,
2310
- inputProps,
2311
- options,
2312
- onChange
2313
- } = props;
2314
-
2315
- // Callback for value changes
2316
- const onChangeSomeInput = React.useCallback(value => {
2317
- // Save to form values
2318
- input.onChange(value);
2319
- if (onChange) {
2320
- // Pass to custom event
2321
- onChange(value, input.name);
2322
- }
2323
- }, [input, onChange]);
2324
-
2325
- // Handle for radio inputs
2326
- const onChangeRadio = React.useCallback(event => {
2327
- if (event.target.checked) {
2328
- onChangeSomeInput(event.target.value);
2329
- }
2330
- }, [onChange]);
2331
- return /*#__PURE__*/React__default.default.createElement(React__default.default.Fragment, null, options.map(option => /*#__PURE__*/React__default.default.createElement(Radio.Radio, Object.assign({
2332
- className: "form-radio__item",
2333
- key: option.value,
2334
- type: "radio",
2335
- name: input.name,
2336
- label: option.label,
2337
- checked: option.value === input.value,
2338
- value: option.value,
2339
- onBlur: input.onBlur,
2340
- onChange: onChangeRadio,
2341
- onFocus: input.onFocus
2342
- }, inputProps))));
2343
- }
2344
-
2345
- const RadioGroup = /*#__PURE__*/React__default.default.memo(function RadioGroup(props) {
2346
- const {
2347
- name,
2348
- isDisabled,
2349
- editableProps = {},
2350
- fieldProps = {},
2351
- inputProps = {},
2352
- options = [],
2353
- classNameGroupItem,
2354
- showMessage,
2355
- isRequired,
2356
- onChange
2357
- } = props;
2358
- return /*#__PURE__*/React__default.default.createElement(reactFinalForm.Field, {
2359
- name: name
2360
- }, function Render({
2361
- input,
2362
- meta
2363
- }) {
2364
- /** Note:
2365
- * Create "Render" function by "eslint-react-hooks/rules-of-hooks":
2366
- * React Hooks cannot be called inside a callback.
2367
- * React Hooks must be called in a React function component or a
2368
- * custom React Hook function.
2369
- */
2370
-
2371
- const {
2372
- errorKey,
2373
- errorMessage,
2374
- isErrorState,
2375
- isValidState
2376
- } = useFieldValidationState({
2377
- fieldProps: fieldProps,
2378
- input: input,
2379
- meta: meta
2380
- });
2381
- const updatedInputProps = useValidationAppearanceInputProps({
2382
- inputProps: inputProps,
2383
- validationStateKey: isErrorState ? errorKey : 'success'
2384
- });
2385
- return /*#__PURE__*/React__default.default.createElement(FieldWrapper, Object.assign({
2386
- className: clsx__default.default('form-field_radio', 'form__item_radio', classNameGroupItem),
2387
- errorKey: errorKey,
2388
- errorMessage: errorMessage,
2389
- isErrorState: isErrorState,
2390
- metaError: meta.error,
2391
- isDisabled: isDisabled,
2392
- fieldClassName: 'form-radio',
2393
- inputName: input.name,
2394
- inputValue: input.value || '',
2395
- metaActive: meta.active,
2396
- showMessage: showMessage,
2397
- isRequired: isRequired,
2398
- isValidState: isValidState
2399
- }, fieldProps), /*#__PURE__*/React__default.default.createElement(RadioGroupList, {
2400
- isDisabled: isDisabled,
2401
- editableProps: editableProps,
2402
- input: input,
2403
- inputProps: updatedInputProps,
2404
- options: options,
2405
- onChange: onChange
2406
- }));
2407
- });
2408
- });
2409
-
2410
2401
  const formTypes = {
2411
2402
  password: 'password',
2412
2403
  code: 'code',
@@ -2478,13 +2469,13 @@ function generateField(field, config, props) {
2478
2469
  }
2479
2470
  case formTypes.fileInput:
2480
2471
  {
2481
- return /*#__PURE__*/React__default.default.createElement(FileInput, Object.assign({
2472
+ return /*#__PURE__*/React__default.default.createElement(FormFieldFileInput, Object.assign({
2482
2473
  key: config.key
2483
2474
  }, field, props));
2484
2475
  }
2485
2476
  case formTypes.radioGroup:
2486
2477
  {
2487
- return /*#__PURE__*/React__default.default.createElement(RadioGroup, Object.assign({
2478
+ return /*#__PURE__*/React__default.default.createElement(FormFieldRadioGroup, Object.assign({
2488
2479
  key: config.key
2489
2480
  }, field, props));
2490
2481
  }
@@ -3152,7 +3143,6 @@ Object.defineProperty(exports, "useFormState", {
3152
3143
  exports.DEFAULT_MESSAGES_FIELDS = DEFAULT_MESSAGES_FIELDS;
3153
3144
  exports.FieldWrapper = FieldWrapper;
3154
3145
  exports.FieldWrapperBase = FieldWrapperBase;
3155
- exports.FileInput = FileInput;
3156
3146
  exports.FinalForm = FinalForm;
3157
3147
  exports.FormBlockGroup = FormBlockGroup;
3158
3148
  exports.FormFieldCheckbox = FormFieldCheckbox;
@@ -3161,14 +3151,15 @@ exports.FormFieldChoice = FormFieldChoice;
3161
3151
  exports.FormFieldCode = FormFieldCode;
3162
3152
  exports.FormFieldCustom = FormFieldCustom;
3163
3153
  exports.FormFieldDatePicker = FormFieldDatePicker;
3154
+ exports.FormFieldFileInput = FormFieldFileInput;
3164
3155
  exports.FormFieldInput = FormFieldInput;
3165
3156
  exports.FormFieldMaskedInput = FormFieldMaskedInput;
3166
3157
  exports.FormFieldPassword = FormFieldPassword;
3158
+ exports.FormFieldRadioGroup = FormFieldRadioGroup;
3167
3159
  exports.FormFieldSegmented = FormFieldSegmented;
3168
3160
  exports.FormFieldSelect = FormFieldSelect;
3169
3161
  exports.FormFieldSwitch = FormFieldSwitch;
3170
3162
  exports.FormFieldTextarea = FormFieldTextarea;
3171
- exports.RadioGroup = RadioGroup;
3172
3163
  exports.addRequiredFieldsParamToSchema = addRequiredFieldsParamToSchema;
3173
3164
  exports.dateValidation = dateValidation;
3174
3165
  exports.defaultCheckboxProps = defaultCheckboxProps;