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