@itcase/forms 1.1.23 → 1.1.26
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/README.md +4 -4
- package/dist/css/form/FormField/FormField.css +0 -26
- package/dist/itcase-forms.cjs.js +1238 -1330
- package/dist/itcase-forms.esm.js +1225 -1319
- package/package.json +8 -9
- /package/dist/css/form/Field/Checkbox/{Checkbox.css → FormFieldCheckbox.css} +0 -0
- /package/dist/css/form/Field/Chips/{Chips.css → FormFieldChips.css} +0 -0
- /package/dist/css/form/Field/Choice/{Choice.css → FormFieldChoice.css} +0 -0
- /package/dist/css/form/Field/Code/{Code.css → FormFieldCode.css} +0 -0
- /package/dist/css/form/Field/Custom/{Custom.css → FormFieldCustom.css} +0 -0
- /package/dist/css/form/Field/DatePicker/{DatePicker.css → FormFieldDatePicker.css} +0 -0
- /package/dist/css/form/Field/Group/{Group.css → FormBlockGroup.css} +0 -0
- /package/dist/css/form/Field/Input/{Input.css → FormFieldInput.css} +0 -0
- /package/dist/css/form/Field/MaskedInput/{MaskedInput.css → FormFieldMaskedInput.css} +0 -0
- /package/dist/css/form/Field/Password/{Password.css → FormFieldPassword.css} +0 -0
- /package/dist/css/form/Field/Segmented/{Segmented.css → FormFieldSegmented.css} +0 -0
- /package/dist/css/form/Field/Select/{Select.css → FormFieldSelect.css} +0 -0
- /package/dist/css/form/Field/Switch/{Switch.css → FormFieldSwitch.css} +0 -0
- /package/dist/css/form/Field/Textarea/{Textarea.css → FormFieldTextarea.css} +0 -0
package/dist/itcase-forms.esm.js
CHANGED
|
@@ -1,21 +1,16 @@
|
|
|
1
1
|
import { isPossiblePhoneNumber } from 'libphonenumber-js';
|
|
2
|
-
import React$1, { useMemo, useEffect,
|
|
2
|
+
import React$1, { useMemo, useEffect, useState, useCallback } 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 { useDevicePropsGenerator } from '@itcase/ui/hooks/useDevicePropsGenerator';
|
|
8
|
+
import camelCase from 'lodash/camelCase';
|
|
9
|
+
import snakeCase from 'lodash/snakeCase';
|
|
8
10
|
import { Divider } from '@itcase/ui/components/Divider';
|
|
9
11
|
import { Text } from '@itcase/ui/components/Text';
|
|
10
12
|
import { useDeviceTargetClass } from '@itcase/ui/hooks/useDeviceTargetClass';
|
|
11
13
|
import { useStyles } from '@itcase/ui/hooks/useStyles';
|
|
12
|
-
import camelCase from 'lodash/camelCase';
|
|
13
|
-
import snakeCase from 'lodash/snakeCase';
|
|
14
|
-
import { Choice } from '@itcase/ui/components/Choice';
|
|
15
|
-
import { Icon } from '@itcase/ui/components/Icon';
|
|
16
|
-
import { Code } from '@itcase/ui/components/Code';
|
|
17
|
-
import { DatePickerInput } from '@itcase/ui/components/DatePicker';
|
|
18
|
-
import { useDevicePropsGenerator } from '@itcase/ui/hooks/useDevicePropsGenerator';
|
|
19
14
|
import axios from 'axios';
|
|
20
15
|
import { fromEvent } from 'file-selector';
|
|
21
16
|
import castArray from 'lodash/castArray';
|
|
@@ -24,15 +19,20 @@ import { createFileFromDataURL } from '@itcase/common';
|
|
|
24
19
|
import { Button } from '@itcase/ui/components/Button';
|
|
25
20
|
import { Loader } from '@itcase/ui/components/Loader';
|
|
26
21
|
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';
|
|
27
28
|
import { Input } from '@itcase/ui/components/Input';
|
|
28
|
-
import { Radio } from '@itcase/ui/components/Radio';
|
|
29
29
|
import { Segmented } from '@itcase/ui/components/Segmented';
|
|
30
30
|
import { Select } from '@itcase/ui/components/Select';
|
|
31
31
|
import { Switch } from '@itcase/ui/components/Switch';
|
|
32
32
|
import { Textarea } from '@itcase/ui/components/Textarea';
|
|
33
33
|
import { useIMask } from 'react-imask';
|
|
34
|
-
import {
|
|
35
|
-
import { Group
|
|
34
|
+
import { Radio } from '@itcase/ui/components/Radio';
|
|
35
|
+
import { Group } from '@itcase/ui/components/Group';
|
|
36
36
|
import { Notification } from '@itcase/ui/components/Notification';
|
|
37
37
|
import createDecorator from 'final-form-focus';
|
|
38
38
|
|
|
@@ -116,29 +116,149 @@ function useYupValidationSchema(schema, language) {
|
|
|
116
116
|
return validate;
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
// Whether to display an error message based on "fieldProps" and meta-objects
|
|
120
|
+
function useFieldValidationState(props) {
|
|
121
|
+
const {
|
|
122
|
+
fieldProps = {},
|
|
123
|
+
meta = {},
|
|
124
|
+
input = {}
|
|
125
|
+
} = props;
|
|
126
|
+
// Determines if there's a submission error that hasn't been rectified since the last submission.
|
|
127
|
+
const submitError = !meta.modifiedSinceLastSubmit && meta.submitError;
|
|
128
|
+
|
|
129
|
+
// Determines a key for the error, defaulting to 'error' if no specific key is found.
|
|
130
|
+
const errorKey = meta.error?.key || 'error';
|
|
131
|
+
const successKey = 'success';
|
|
132
|
+
|
|
133
|
+
// Determines if the field is in an error state based on various conditions.
|
|
134
|
+
const isErrorState = useMemo(() => {
|
|
135
|
+
if (fieldProps.showErrorsOnSubmit) {
|
|
136
|
+
return Boolean(meta.submitFailed && meta.touched && (meta.error || submitError));
|
|
137
|
+
} else {
|
|
138
|
+
return Boolean(meta.touched && (meta.error || submitError));
|
|
139
|
+
}
|
|
140
|
+
}, [fieldProps.showErrorsOnSubmit, meta.submitFailed, meta.touched, meta.error, submitError]);
|
|
141
|
+
|
|
142
|
+
// Determines if the field's input state is valid
|
|
143
|
+
const isValidState = useMemo(() => {
|
|
144
|
+
const hasValue = Array.isArray(input?.value) ? input?.value.length : input?.value;
|
|
145
|
+
const isModifiedAfterSubmit = meta.modifiedSinceLastSubmit && !meta.error && submitError;
|
|
146
|
+
return Boolean(hasValue && (meta.valid || isModifiedAfterSubmit));
|
|
147
|
+
}, [input?.value, meta.valid, meta.error, submitError, meta.modifiedSinceLastSubmit]);
|
|
148
|
+
const errorMessage = useMemo(() => {
|
|
149
|
+
// If final-form field has error in "meta" render-property.
|
|
150
|
+
// If field not modified after last form submit - use submit error
|
|
151
|
+
const error = meta.error || submitError || false;
|
|
152
|
+
if (error) {
|
|
153
|
+
// And error in "meta" is string
|
|
154
|
+
if (typeof error === 'string') {
|
|
155
|
+
// Return error as message
|
|
156
|
+
return error;
|
|
157
|
+
}
|
|
158
|
+
// Or if error in "meta" has "message" property(is object of error)
|
|
159
|
+
if (error.message) {
|
|
160
|
+
// Return message from error
|
|
161
|
+
return error.message;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Field doesn't have error message
|
|
166
|
+
return '';
|
|
167
|
+
}, [meta.error, submitError]);
|
|
168
|
+
return {
|
|
169
|
+
errorKey,
|
|
170
|
+
successKey,
|
|
171
|
+
isErrorState,
|
|
172
|
+
isValidState,
|
|
173
|
+
errorMessage
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// This hook changes the props of the child component depending on the type of error,
|
|
178
|
+
// looks at what props were in initialProps, if they are there then changes
|
|
179
|
+
function useValidationAppearanceInputProps(props) {
|
|
180
|
+
const {
|
|
181
|
+
validationStateKey,
|
|
182
|
+
inputProps
|
|
183
|
+
} = props;
|
|
184
|
+
|
|
185
|
+
// TODO: need to add props that can change during errors in this field
|
|
186
|
+
const validationAppearanceInputProps = useMemo(() => {
|
|
187
|
+
// const resultAppearanceProps = {
|
|
188
|
+
// messageTextColor: props.errorMessageTextColor,
|
|
189
|
+
// messageTextSize: props.errorMessageTextSize,
|
|
190
|
+
// messageTextWeight: props.errorMessageTextWeight,
|
|
191
|
+
// // Override appearance(styled) props for child input
|
|
192
|
+
// inputProps: {},
|
|
193
|
+
// }
|
|
194
|
+
const updatedInputProps = {};
|
|
195
|
+
if (validationStateKey) {
|
|
196
|
+
Object.entries(inputProps).forEach(([propKey, propValue]) => {
|
|
197
|
+
// Convert the input property key to "snake_case" format.
|
|
198
|
+
// e.g. "requiredBorderColor" -> "required_border_color".
|
|
199
|
+
const propKeySnake = snakeCase(propKey);
|
|
200
|
+
// Check if this property is for appearance.
|
|
201
|
+
// Key maybe starts with: "error", "required", "success", etc from validation config.
|
|
202
|
+
const isPropForValidationState = propKeySnake.startsWith(`${validationStateKey}_`);
|
|
203
|
+
|
|
204
|
+
// If property is for appearance
|
|
205
|
+
if (isPropForValidationState) {
|
|
206
|
+
// Remove validation state part from begin of property key, to make clean appearance property.
|
|
207
|
+
// e.g. "required_border_color" -> "border_color".
|
|
208
|
+
const stateTargetKeySnake = propKeySnake.replace(`${validationStateKey}_`, '');
|
|
209
|
+
// Convert clean appearance property key to "camelCase" format.
|
|
210
|
+
// e.g. "border_color" -> "borderColor"
|
|
211
|
+
const stateTargetKey = camelCase(stateTargetKeySnake);
|
|
212
|
+
// And save the value with a new clean property key
|
|
213
|
+
updatedInputProps[stateTargetKey] = propValue;
|
|
214
|
+
// Else if not already added earlier
|
|
215
|
+
} else if (!updatedInputProps[propKey]) {
|
|
216
|
+
// Just save original property
|
|
217
|
+
updatedInputProps[propKey] = propValue;
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
return updatedInputProps;
|
|
222
|
+
}, [validationStateKey, inputProps]);
|
|
223
|
+
return validationAppearanceInputProps;
|
|
224
|
+
}
|
|
225
|
+
|
|
119
226
|
const defaultFieldProps = {
|
|
120
227
|
width: 'fill',
|
|
121
228
|
direction: 'vertical',
|
|
122
|
-
size: 'm',
|
|
123
229
|
labelTextColor: 'surfaceTextPrimary',
|
|
124
|
-
labelTextSize: 's',
|
|
125
230
|
messageTextColor: 'surfaceTextSecondary',
|
|
126
|
-
messageTextSize: 's',
|
|
127
231
|
errorMessageTextColor: 'errorTextSecondary',
|
|
128
|
-
errorMessageTextSize: 's',
|
|
129
232
|
dividerFill: 'errorPrimary',
|
|
130
233
|
helpTextColor: 'surfaceTextQuaternary',
|
|
131
|
-
helpTextSize: 's',
|
|
132
234
|
requiredMessageTextColor: 'warningTextSecondary',
|
|
133
|
-
requiredMessageTextSize: 's',
|
|
134
235
|
showMessage: true
|
|
135
236
|
};
|
|
237
|
+
const defaultFieldSizeM = {
|
|
238
|
+
size: 'm',
|
|
239
|
+
labelTextSize: 's',
|
|
240
|
+
messageTextSize: 's',
|
|
241
|
+
errorMessageTextSize: 's',
|
|
242
|
+
helpTextSize: 's',
|
|
243
|
+
requiredMessageTextSize: 's',
|
|
244
|
+
...defaultFieldProps
|
|
245
|
+
};
|
|
246
|
+
const defaultFieldSizeXL = {
|
|
247
|
+
size: 'xl',
|
|
248
|
+
labelTextSize: 's',
|
|
249
|
+
messageTextSize: 's',
|
|
250
|
+
errorMessageTextSize: 's',
|
|
251
|
+
helpTextSize: 's',
|
|
252
|
+
requiredMessageTextSize: 's',
|
|
253
|
+
...defaultFieldProps
|
|
254
|
+
};
|
|
136
255
|
|
|
137
256
|
function FieldWrapperBase(props) {
|
|
138
257
|
const {
|
|
139
258
|
id,
|
|
259
|
+
dataTour,
|
|
140
260
|
className,
|
|
141
|
-
type
|
|
261
|
+
type,
|
|
142
262
|
label,
|
|
143
263
|
labelHidden,
|
|
144
264
|
labelTextColor,
|
|
@@ -146,6 +266,7 @@ function FieldWrapperBase(props) {
|
|
|
146
266
|
labelTextSizeMobile,
|
|
147
267
|
labelTextSizeTablet,
|
|
148
268
|
labelTextWeight,
|
|
269
|
+
messageTextSize,
|
|
149
270
|
desc,
|
|
150
271
|
descTextColor,
|
|
151
272
|
descTextSize,
|
|
@@ -158,7 +279,6 @@ function FieldWrapperBase(props) {
|
|
|
158
279
|
isDisabled,
|
|
159
280
|
afterItem,
|
|
160
281
|
beforeItem,
|
|
161
|
-
dataTour,
|
|
162
282
|
dividerDirection,
|
|
163
283
|
dividerFill,
|
|
164
284
|
dividerSize,
|
|
@@ -171,7 +291,6 @@ function FieldWrapperBase(props) {
|
|
|
171
291
|
helpTextWeight,
|
|
172
292
|
inputName,
|
|
173
293
|
inputValue,
|
|
174
|
-
messageTextSize,
|
|
175
294
|
metaActive,
|
|
176
295
|
showDivider,
|
|
177
296
|
showMessage,
|
|
@@ -220,13 +339,13 @@ function FieldWrapperBase(props) {
|
|
|
220
339
|
const errorTextColor = props[`${errorKey}MessageTextColor`];
|
|
221
340
|
const errorTextWeight = props[`${errorKey}MessageTextWeight`];
|
|
222
341
|
return /*#__PURE__*/React$1.createElement(Tag, {
|
|
342
|
+
dataTestId: `${inputName}Field`,
|
|
343
|
+
dataTour: dataTour,
|
|
223
344
|
className: clsx(formFieldClass, 'form__item', 'form-field', type && `form-field_type_${type}`, sizeClass, fillClass, shapeClass, isDisabled && `form-field_state_disabled`, isHidden && `form-field_state_hidden`, directionClass, widthClass),
|
|
224
|
-
"data-test-id": `${inputName}Field`,
|
|
225
|
-
"data-tour": dataTour,
|
|
226
345
|
style: formFieldStyles
|
|
227
346
|
}, before, (label || labelHidden) && /*#__PURE__*/React$1.createElement("div", {
|
|
347
|
+
dataTestId: `${inputName}FieldLabel`,
|
|
228
348
|
className: clsx('form-field__label'),
|
|
229
|
-
"data-test-id": `${inputName}FieldLabel`,
|
|
230
349
|
htmlFor: id
|
|
231
350
|
}, /*#__PURE__*/React$1.createElement(Text, {
|
|
232
351
|
size: labelTextSize,
|
|
@@ -236,7 +355,7 @@ function FieldWrapperBase(props) {
|
|
|
236
355
|
sizeTablet: labelTextSizeTablet
|
|
237
356
|
}, label, labelHidden && '\u00A0')), desc && /*#__PURE__*/React$1.createElement("div", {
|
|
238
357
|
className: "form-field__desc",
|
|
239
|
-
|
|
358
|
+
dataTestId: `${inputName}FieldDesc`
|
|
240
359
|
}, /*#__PURE__*/React$1.createElement(Text, {
|
|
241
360
|
size: descTextSize,
|
|
242
361
|
textColor: descTextColor,
|
|
@@ -252,26 +371,26 @@ function FieldWrapperBase(props) {
|
|
|
252
371
|
size: dividerSize,
|
|
253
372
|
fill: dividerFill
|
|
254
373
|
})), showMessage && /*#__PURE__*/React$1.createElement("div", {
|
|
255
|
-
|
|
256
|
-
"
|
|
374
|
+
dataTestId: `${inputName}FieldMessage`,
|
|
375
|
+
className: "form-field__message"
|
|
257
376
|
}, isErrorState && errorMessage && /*#__PURE__*/React$1.createElement(Text, {
|
|
258
377
|
id: `${inputName}-error`,
|
|
378
|
+
dataTestId: `${inputName}FieldMessageError`,
|
|
259
379
|
className: "form-field__message-item form-field__message-item_type-error",
|
|
260
380
|
size: errorTextSize,
|
|
261
381
|
textColor: errorTextColor,
|
|
262
|
-
textWeight: errorTextWeight
|
|
263
|
-
dataTestId: `${inputName}FieldMessageError`
|
|
382
|
+
textWeight: errorTextWeight
|
|
264
383
|
}, errorMessage), Boolean(helpText) && (!isErrorState || !errorMessage) && /*#__PURE__*/React$1.createElement(Text, {
|
|
384
|
+
dataTestId: `${inputName}FieldMessageHelpText`,
|
|
265
385
|
className: "form-field__message-item form-field__message-item_type_help-text",
|
|
266
386
|
size: helpTextSize,
|
|
267
387
|
textColor: isValidState ? helpTextColorSuccess : helpTextColor,
|
|
268
388
|
textWeight: helpTextWeight,
|
|
269
|
-
dataTestId: `${inputName}FieldMessageHelpText`,
|
|
270
389
|
sizeMobile: helpTextSizeMobile
|
|
271
390
|
}, helpText), (!isErrorState && !helpText || isErrorState && !helpText && !errorMessage) && /*#__PURE__*/React$1.createElement(Text, {
|
|
391
|
+
dataTestId: `${inputName}FieldMessageHelpText`,
|
|
272
392
|
className: "form-field__message-item form-field__message-item_type_help-text",
|
|
273
|
-
size: messageTextSize
|
|
274
|
-
dataTestId: `${inputName}FieldMessageHelpText`
|
|
393
|
+
size: messageTextSize
|
|
275
394
|
}, '\u00A0')), after);
|
|
276
395
|
}
|
|
277
396
|
function FieldWrapper(props) {
|
|
@@ -290,242 +409,425 @@ function FieldWrapper(props) {
|
|
|
290
409
|
return /*#__PURE__*/React$1.createElement(FieldWrapperBase, props);
|
|
291
410
|
}
|
|
292
411
|
|
|
293
|
-
|
|
294
|
-
|
|
412
|
+
const defaultDropzoneProps = {
|
|
413
|
+
fill: 'surfacePrimary',
|
|
414
|
+
borderColor: 'surfaceBorderTertiary',
|
|
415
|
+
borderColorHover: 'surfaceBorderQuaternary',
|
|
416
|
+
hintTitle: 'Перетащите изображение или выберите файл с компьютера',
|
|
417
|
+
hintTitleTextColor: 'surfaceTextPrimary',
|
|
418
|
+
hintTitleTextSize: 'm',
|
|
419
|
+
removeThumbText: 'удалить',
|
|
420
|
+
removeThumbTextColor: 'errorTextPrimary',
|
|
421
|
+
removeThumbTextHoverColor: 'errorTextPrimaryHover',
|
|
422
|
+
removeThumbTextSize: 's',
|
|
423
|
+
shape: 'rounded',
|
|
424
|
+
showFilename: true,
|
|
425
|
+
thumbBorderColor: 'surfaceBorderTertiary',
|
|
426
|
+
thumbBorderColorHover: 'surfaceBorderQuaternary',
|
|
427
|
+
thumbBorderWidth: 1,
|
|
428
|
+
thumbNameTextColor: 'surfaceTextPrimary',
|
|
429
|
+
thumbNameTextSize: 's',
|
|
430
|
+
isPreviews: true
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
const FileInputDropzone = /*#__PURE__*/React$1.memo(function FileInputDropzone(props) {
|
|
295
434
|
const {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
435
|
+
className,
|
|
436
|
+
maxFiles,
|
|
437
|
+
maxSize,
|
|
438
|
+
size,
|
|
439
|
+
fileErrorText,
|
|
440
|
+
dropzoneProps = {},
|
|
441
|
+
hintDescription,
|
|
442
|
+
hintTitle,
|
|
443
|
+
inputName,
|
|
444
|
+
inputValue,
|
|
445
|
+
showFilename,
|
|
446
|
+
thumbColumn,
|
|
447
|
+
isPreviews,
|
|
448
|
+
onAddFiles,
|
|
449
|
+
onDeleteFile
|
|
299
450
|
} = props;
|
|
300
|
-
// Determines if there's a submission error that hasn't been rectified since the last submission.
|
|
301
|
-
const submitError = !meta.modifiedSinceLastSubmit && meta.submitError;
|
|
302
451
|
|
|
303
|
-
//
|
|
304
|
-
const
|
|
305
|
-
|
|
452
|
+
// TODO: delete react-final-form things out of here?
|
|
453
|
+
const {
|
|
454
|
+
change
|
|
455
|
+
} = useForm();
|
|
456
|
+
const [fileError, setFileError] = useState('');
|
|
457
|
+
const [fileIsLoading, setFileIsLoading] = useState(false);
|
|
458
|
+
const filesList = useMemo(() => inputValue ? castArray(inputValue) : [], [inputValue]);
|
|
459
|
+
const changeFormState = useCallback(newFiles => {
|
|
460
|
+
// If max files in dropzone is 1 - return file as it self, else as array of files
|
|
461
|
+
// ps: for old projects compatibility
|
|
462
|
+
const toSave = dropzoneProps.maxFiles == 1 ? newFiles[0] : newFiles;
|
|
463
|
+
change(inputName, toSave);
|
|
464
|
+
return toSave;
|
|
465
|
+
},
|
|
466
|
+
// If "inputName" will be changes, then it should be a different field
|
|
467
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
468
|
+
[dropzoneProps, change]);
|
|
306
469
|
|
|
307
|
-
//
|
|
308
|
-
const
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
470
|
+
//
|
|
471
|
+
const convertFiledValueAndSaveAsFiles = useCallback(async currentFilesList => {
|
|
472
|
+
setFileIsLoading(true);
|
|
473
|
+
const newFiles = [];
|
|
474
|
+
for (const fileItem of currentFilesList) {
|
|
475
|
+
if (typeof fileItem === 'string') {
|
|
476
|
+
const newFile = await convertToFile(fileItem, isPreviews);
|
|
477
|
+
if (newFile) {
|
|
478
|
+
newFiles.push(newFile);
|
|
479
|
+
}
|
|
480
|
+
} else {
|
|
481
|
+
newFiles.push(fileItem);
|
|
482
|
+
}
|
|
313
483
|
}
|
|
314
|
-
|
|
484
|
+
changeFormState(newFiles);
|
|
485
|
+
setFileIsLoading(false);
|
|
486
|
+
}, [isPreviews, changeFormState]);
|
|
315
487
|
|
|
316
|
-
//
|
|
317
|
-
const
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
// If field not modified after last form submit - use submit error
|
|
325
|
-
const error = meta.error || submitError || false;
|
|
326
|
-
if (error) {
|
|
327
|
-
// And error in "meta" is string
|
|
328
|
-
if (typeof error === 'string') {
|
|
329
|
-
// Return error as message
|
|
330
|
-
return error;
|
|
331
|
-
}
|
|
332
|
-
// Or if error in "meta" has "message" property(is object of error)
|
|
333
|
-
if (error.message) {
|
|
334
|
-
// Return message from error
|
|
335
|
-
return error.message;
|
|
336
|
-
}
|
|
488
|
+
// Delete file from dropzone
|
|
489
|
+
const removeFile = useCallback((event, index) => {
|
|
490
|
+
event.stopPropagation();
|
|
491
|
+
event.preventDefault();
|
|
492
|
+
const newFiles = [...filesList];
|
|
493
|
+
newFiles.splice(index, 1);
|
|
494
|
+
if (onDeleteFile) {
|
|
495
|
+
onDeleteFile(filesList[index], inputName);
|
|
337
496
|
}
|
|
497
|
+
changeFormState(newFiles);
|
|
498
|
+
},
|
|
499
|
+
// If "inputName" will be changes, then it should be a different field
|
|
500
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
501
|
+
[filesList, changeFormState, onDeleteFile]);
|
|
338
502
|
|
|
339
|
-
|
|
340
|
-
return '';
|
|
341
|
-
}, [meta.error, submitError]);
|
|
342
|
-
return {
|
|
343
|
-
errorKey,
|
|
344
|
-
successKey,
|
|
345
|
-
isErrorState,
|
|
346
|
-
isValidState,
|
|
347
|
-
errorMessage
|
|
348
|
-
};
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
// This hook changes the props of the child component depending on the type of error,
|
|
352
|
-
// looks at what props were in initialProps, if they are there then changes
|
|
353
|
-
function useValidationAppearanceInputProps(props) {
|
|
503
|
+
// Create dropzone options
|
|
354
504
|
const {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
} =
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
//
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
//
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
505
|
+
getInputProps,
|
|
506
|
+
getRootProps
|
|
507
|
+
} = useDropzone({
|
|
508
|
+
maxFiles: maxFiles || 5,
|
|
509
|
+
maxSize: maxSize || 10485760,
|
|
510
|
+
// 10mb
|
|
511
|
+
// accept: { 'image/*': [] },
|
|
512
|
+
...dropzoneProps,
|
|
513
|
+
getFilesFromEvent: async event => {
|
|
514
|
+
const result = await fromEvent(event);
|
|
515
|
+
const newFiles = result.filter(item => item instanceof File);
|
|
516
|
+
// Add exists and new files to accepted(or rejected)
|
|
517
|
+
return [...filesList, ...newFiles];
|
|
518
|
+
},
|
|
519
|
+
onDropAccepted: acceptedFiles => {
|
|
520
|
+
// If dropped files has accepted and we need a previews
|
|
521
|
+
if (isPreviews) {
|
|
522
|
+
// Add preview to every file
|
|
523
|
+
acceptedFiles.forEach(file => {
|
|
524
|
+
if (!file.error) {
|
|
525
|
+
file.preview = URL.createObjectURL(file);
|
|
526
|
+
}
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
// Save to form data (including empty when files are not valid)
|
|
530
|
+
const filesToSave = changeFormState(acceptedFiles);
|
|
531
|
+
setFileError('');
|
|
377
532
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
// And save the value with a new clean property key
|
|
387
|
-
updatedInputProps[stateTargetKey] = propValue;
|
|
388
|
-
// Else if not already added earlier
|
|
389
|
-
} else if (!updatedInputProps[propKey]) {
|
|
390
|
-
// Just save original property
|
|
391
|
-
updatedInputProps[propKey] = propValue;
|
|
533
|
+
// Save DataURL for all files
|
|
534
|
+
const readerPromisesList = acceptedFiles.map(file => {
|
|
535
|
+
return new Promise(resolve => setFileDataURL(file, resolve));
|
|
536
|
+
});
|
|
537
|
+
// Save files to form values
|
|
538
|
+
Promise.all(readerPromisesList).then(() => {
|
|
539
|
+
if (onAddFiles) {
|
|
540
|
+
onAddFiles(filesToSave, inputName);
|
|
392
541
|
}
|
|
393
542
|
});
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
classNameGroupItem,
|
|
413
|
-
fieldProps = {},
|
|
414
|
-
inputProps = {},
|
|
415
|
-
showMessage,
|
|
416
|
-
isRequired,
|
|
417
|
-
onChange
|
|
418
|
-
} = props;
|
|
419
|
-
return /*#__PURE__*/React$1.createElement(Field, {
|
|
420
|
-
type: "checkbox",
|
|
421
|
-
name: name,
|
|
422
|
-
initialValue: initialValue
|
|
423
|
-
}, function Render({
|
|
424
|
-
input,
|
|
425
|
-
meta
|
|
426
|
-
}) {
|
|
427
|
-
/** Note:
|
|
428
|
-
* Create "Render" function by "eslint-react-hooks/rules-of-hooks":
|
|
429
|
-
* React Hooks cannot be called inside a callback.
|
|
430
|
-
* React Hooks must be called in a React function component or a
|
|
431
|
-
* custom React Hook function.
|
|
432
|
-
*/
|
|
433
|
-
|
|
434
|
-
const onChangeField = useCallback(event => {
|
|
435
|
-
input.onChange(event);
|
|
436
|
-
if (onChange) {
|
|
437
|
-
onChange(event.target.checked, input.name);
|
|
543
|
+
},
|
|
544
|
+
onDropRejected: rejectedFiles => {
|
|
545
|
+
// If dropped files has rejected
|
|
546
|
+
if (rejectedFiles.length) {
|
|
547
|
+
let fileErrorMessage = 'Ошибка при добавлении файла';
|
|
548
|
+
const firstFileErrorItem = rejectedFiles[0].errors[0];
|
|
549
|
+
if (firstFileErrorItem) {
|
|
550
|
+
if (firstFileErrorItem.code === ErrorCode.TooManyFiles) {
|
|
551
|
+
fileErrorMessage = `Максимальное количество файлов: ${maxFiles}`;
|
|
552
|
+
} else {
|
|
553
|
+
fileErrorMessage = firstFileErrorItem.message;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
// Show error
|
|
557
|
+
setFileError(fileErrorMessage);
|
|
558
|
+
} else {
|
|
559
|
+
// Else clean error
|
|
560
|
+
setFileError('');
|
|
438
561
|
}
|
|
439
|
-
}
|
|
440
|
-
const {
|
|
441
|
-
errorKey,
|
|
442
|
-
errorMessage,
|
|
443
|
-
isErrorState,
|
|
444
|
-
isValidState
|
|
445
|
-
} = useFieldValidationState({
|
|
446
|
-
fieldProps: fieldProps,
|
|
447
|
-
input: input,
|
|
448
|
-
meta: meta
|
|
449
|
-
});
|
|
450
|
-
const updatedInputProps = useValidationAppearanceInputProps({
|
|
451
|
-
inputProps: inputProps,
|
|
452
|
-
validationStateKey: isErrorState ? errorKey : 'success'
|
|
453
|
-
});
|
|
454
|
-
return /*#__PURE__*/React$1.createElement(FieldWrapper, Object.assign({
|
|
455
|
-
className: clsx('form-field_type_checkbox', 'form__item_type_checkbox', classNameGroupItem),
|
|
456
|
-
errorKey: errorKey,
|
|
457
|
-
errorMessage: errorMessage,
|
|
458
|
-
isErrorState: isErrorState,
|
|
459
|
-
metaError: meta.error,
|
|
460
|
-
isDisabled: isDisabled,
|
|
461
|
-
fieldClassName: "form-checkbox",
|
|
462
|
-
inputName: input.name,
|
|
463
|
-
inputValue: input.checked,
|
|
464
|
-
metaActive: meta.active,
|
|
465
|
-
showMessage: showMessage,
|
|
466
|
-
tag: "label",
|
|
467
|
-
isRequired: isRequired,
|
|
468
|
-
isValidState: isValidState
|
|
469
|
-
}, fieldProps), /*#__PURE__*/React$1.createElement(Checkbox, Object.assign({
|
|
470
|
-
type: "checkbox",
|
|
471
|
-
name: input.name,
|
|
472
|
-
isDisabled: isDisabled,
|
|
473
|
-
autoComplete: "nope",
|
|
474
|
-
checked: input.checked,
|
|
475
|
-
onBlur: input.onBlur,
|
|
476
|
-
onChange: onChangeField,
|
|
477
|
-
onFocus: input.onFocus
|
|
478
|
-
}, updatedInputProps)));
|
|
562
|
+
}
|
|
479
563
|
});
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
const
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
fill: 'surfaceSecondary',
|
|
488
|
-
fillActive: 'accentPrimary',
|
|
489
|
-
fillActiveDisabled: 'surfaceTertiary',
|
|
490
|
-
fillHover: 'surfacePrimaryHover',
|
|
491
|
-
indicatorFill: 'accentPrimary',
|
|
492
|
-
labelTextActiveColor: 'accentTextPrimary',
|
|
493
|
-
labelTextActiveColorDisabled: 'surfaceTextDisabled',
|
|
494
|
-
labelTextColor: 'surfaceTextPrimary',
|
|
495
|
-
labelTextColorDisabled: 'surfaceTextDisabled',
|
|
496
|
-
labelTextSize: 'm',
|
|
497
|
-
requiredBorderColor: 'warningBorderPrimary',
|
|
498
|
-
shape: 'rounded'
|
|
499
|
-
};
|
|
564
|
+
useEffect(() => {
|
|
565
|
+
const currentFilesList = castArray(inputValue);
|
|
566
|
+
const isNeedToConvert = currentFilesList.some(fileItem => typeof fileItem === 'string');
|
|
567
|
+
if (isNeedToConvert) {
|
|
568
|
+
// First time convert value to Files and save to local and form state
|
|
569
|
+
convertFiledValueAndSaveAsFiles(currentFilesList);
|
|
570
|
+
}
|
|
500
571
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
placeholder,
|
|
513
|
-
showMessage,
|
|
514
|
-
isCheckbox,
|
|
515
|
-
isRequired,
|
|
516
|
-
onChange
|
|
517
|
-
} = props;
|
|
572
|
+
// Make sure to revoke the data uris to avoid memory leaks, will run on unmount
|
|
573
|
+
return () => {
|
|
574
|
+
filesList.forEach(file => {
|
|
575
|
+
if (file?.preview) {
|
|
576
|
+
URL.revokeObjectURL(file.preview);
|
|
577
|
+
}
|
|
578
|
+
});
|
|
579
|
+
};
|
|
580
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
581
|
+
}, [inputValue]);
|
|
582
|
+
const propsGenerator = useDevicePropsGenerator(props);
|
|
518
583
|
const {
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
584
|
+
fillClass,
|
|
585
|
+
fillHoverClass,
|
|
586
|
+
borderColorClass,
|
|
587
|
+
borderColorHoverClass,
|
|
588
|
+
borderTypeClass,
|
|
589
|
+
borderWidthClass,
|
|
590
|
+
errorMessageTextColor,
|
|
591
|
+
errorMessageTextSize,
|
|
592
|
+
errorMessageTextWeight,
|
|
593
|
+
hintDescriptionTextColor,
|
|
594
|
+
hintDescriptionTextSize,
|
|
595
|
+
hintDescriptionTextWeight,
|
|
596
|
+
hintDescriptionTextWrap,
|
|
597
|
+
hintTitleTextColor,
|
|
598
|
+
hintTitleTextSize,
|
|
599
|
+
hintTitleTextWeight,
|
|
600
|
+
hintTitleTextWrap,
|
|
601
|
+
removeThumbAppearance,
|
|
602
|
+
removeThumbShape,
|
|
603
|
+
removeThumbText,
|
|
604
|
+
removeThumbTextWeight,
|
|
605
|
+
shapeClass,
|
|
606
|
+
thumbBorderColorClass,
|
|
607
|
+
thumbBorderColorHoverClass,
|
|
608
|
+
thumbBorderTypeClass,
|
|
609
|
+
thumbBorderWidthClass,
|
|
610
|
+
thumbDirectionClass,
|
|
611
|
+
thumbNameTextColor,
|
|
612
|
+
thumbNameTextSize,
|
|
613
|
+
thumbNameTextWeight,
|
|
614
|
+
thumbNameTextWrap
|
|
615
|
+
} = propsGenerator;
|
|
616
|
+
return /*#__PURE__*/React$1.createElement(React$1.Fragment, null, /*#__PURE__*/React$1.createElement("div", getRootProps({
|
|
617
|
+
className: `form-dropzone__dropzone dropzone ${className} form-dropzone__dropzone_size_${size} ${shapeClass}`
|
|
618
|
+
}), /*#__PURE__*/React$1.createElement("input", Object.assign({}, getInputProps(), {
|
|
619
|
+
name: inputName
|
|
620
|
+
})), /*#__PURE__*/React$1.createElement("div", {
|
|
621
|
+
className: clsx('form-dropzone__dropzone-wrapper', thumbColumn && `form-dropzone__dropzone-wrapper_column_${thumbColumn}`, fillClass, fillHoverClass, borderWidthClass, borderColorClass, borderColorHoverClass, borderTypeClass)
|
|
622
|
+
}, filesList.map((file, index) => /*#__PURE__*/React$1.createElement("aside", {
|
|
623
|
+
className: clsx('form-dropzone__thumb', fillClass, thumbDirectionClass, thumbBorderWidthClass, thumbBorderColorClass, thumbBorderColorHoverClass, thumbBorderTypeClass),
|
|
624
|
+
key: file.id || `${file.name}_${index}`
|
|
625
|
+
}, isPreviews && !file.error && /*#__PURE__*/React$1.createElement("div", {
|
|
626
|
+
className: "form-dropzone__thumb-image"
|
|
627
|
+
}, /*#__PURE__*/React$1.createElement("img", {
|
|
628
|
+
className: "form-dropzone__thumb-image-inner",
|
|
629
|
+
src: file.preview || file.image,
|
|
630
|
+
onLoad: () => {
|
|
631
|
+
// Revoke data uri after image is loaded
|
|
632
|
+
URL.revokeObjectURL(file.preview);
|
|
525
633
|
}
|
|
526
|
-
},
|
|
634
|
+
})), file.error && /*#__PURE__*/React$1.createElement("div", null, /*#__PURE__*/React$1.createElement(Text, {
|
|
635
|
+
size: thumbNameTextSize,
|
|
636
|
+
textColor: thumbNameTextColor,
|
|
637
|
+
textWeight: thumbNameTextWeight,
|
|
638
|
+
textWrap: thumbNameTextWrap
|
|
639
|
+
}, fileErrorText || file.error)), showFilename && /*#__PURE__*/React$1.createElement("div", {
|
|
640
|
+
className: "form-dropzone__thumb-name"
|
|
641
|
+
}, /*#__PURE__*/React$1.createElement(Text, {
|
|
642
|
+
className: "form-dropzone__thumb-name-inner",
|
|
643
|
+
size: thumbNameTextSize,
|
|
644
|
+
textColor: thumbNameTextColor,
|
|
645
|
+
textWeight: thumbNameTextWeight,
|
|
646
|
+
textWrap: thumbNameTextWrap
|
|
647
|
+
}, file.name)), fileIsLoading && /*#__PURE__*/React$1.createElement("div", {
|
|
648
|
+
className: "form-dropzone__thumb-loader"
|
|
649
|
+
}, /*#__PURE__*/React$1.createElement(Loader, {
|
|
650
|
+
width: "fill",
|
|
651
|
+
height: "fill",
|
|
652
|
+
fill: "surfacePrimary",
|
|
653
|
+
itemFill: "surfaceItemAccent",
|
|
654
|
+
set: "simple"
|
|
655
|
+
})), /*#__PURE__*/React$1.createElement("div", {
|
|
656
|
+
className: clsx('form-dropzone__thumb-remove')
|
|
657
|
+
}, /*#__PURE__*/React$1.createElement(Button, {
|
|
658
|
+
className: "form-dropzone__thumb-remove-text",
|
|
659
|
+
appearance: removeThumbAppearance,
|
|
660
|
+
label: removeThumbText || 'Удалить',
|
|
661
|
+
labelTextWeight: removeThumbTextWeight,
|
|
662
|
+
shape: removeThumbShape,
|
|
663
|
+
onClick: event => removeFile(event, index)
|
|
664
|
+
})))), !filesList.length ? /*#__PURE__*/React$1.createElement("div", {
|
|
665
|
+
className: "form-dropzone__hint"
|
|
666
|
+
}, /*#__PURE__*/React$1.createElement(Text, {
|
|
667
|
+
className: "form-dropzone__hint-title",
|
|
668
|
+
size: hintTitleTextSize,
|
|
669
|
+
textColor: hintTitleTextColor,
|
|
670
|
+
textWeight: hintTitleTextWeight,
|
|
671
|
+
textWrap: hintTitleTextWrap
|
|
672
|
+
}, hintTitle || 'Select a file or drag in form'), hintDescription && /*#__PURE__*/React$1.createElement(Text, {
|
|
673
|
+
className: "form-dropzone__hint-text",
|
|
674
|
+
size: hintDescriptionTextSize,
|
|
675
|
+
textColor: hintDescriptionTextColor,
|
|
676
|
+
textWeight: hintDescriptionTextWeight,
|
|
677
|
+
textWrap: hintDescriptionTextWrap
|
|
678
|
+
}, hintDescription)) : /*#__PURE__*/React$1.createElement("div", {
|
|
679
|
+
className: "form-dropzone__hint form-dropzone__hint_type_add-more"
|
|
680
|
+
}, /*#__PURE__*/React$1.createElement(Text, {
|
|
681
|
+
className: "form-dropzone__hint-title",
|
|
682
|
+
size: hintTitleTextSize,
|
|
683
|
+
textColor: hintTitleTextColor,
|
|
684
|
+
textWeight: hintTitleTextWeight,
|
|
685
|
+
textWrap: hintTitleTextWrap
|
|
686
|
+
}, hintTitle || 'Select a file or drag in form'), hintDescription && /*#__PURE__*/React$1.createElement(Text, {
|
|
687
|
+
className: "form-dropzone__hint-text",
|
|
688
|
+
size: hintDescriptionTextSize,
|
|
689
|
+
textColor: hintDescriptionTextColor,
|
|
690
|
+
textWeight: hintDescriptionTextWeight,
|
|
691
|
+
textWrap: hintDescriptionTextWrap
|
|
692
|
+
}, hintDescription)))), fileError && /*#__PURE__*/React$1.createElement("div", {
|
|
693
|
+
className: "form-field__message"
|
|
694
|
+
}, /*#__PURE__*/React$1.createElement(Text, {
|
|
695
|
+
className: "form-field__message-item form-field__message-item_type_message",
|
|
696
|
+
size: errorMessageTextSize,
|
|
697
|
+
textColor: errorMessageTextColor,
|
|
698
|
+
textWeight: errorMessageTextWeight
|
|
699
|
+
}, fileError)));
|
|
700
|
+
});
|
|
701
|
+
async function getFileByURL(url) {
|
|
702
|
+
try {
|
|
703
|
+
const response = await axios({
|
|
704
|
+
url: url,
|
|
705
|
+
responseType: 'blob'
|
|
706
|
+
});
|
|
707
|
+
const blobObject = response.data;
|
|
708
|
+
const dirtyFilename = response.headers['content-disposition']?.split('filename=')[1];
|
|
709
|
+
// Remove double quotes
|
|
710
|
+
let filename = dirtyFilename?.substring(1).slice(0, -1);
|
|
711
|
+
if (!filename) {
|
|
712
|
+
filename = url.split('/').at(-1);
|
|
713
|
+
// const typeParts = blobObject.type.split('/')
|
|
714
|
+
// const fileType = typeParts[typeParts.length - 1]
|
|
715
|
+
// filename = `${new Date().getTime()}.${fileType}`
|
|
716
|
+
}
|
|
717
|
+
return new File([blobObject], filename, {
|
|
718
|
+
type: blobObject.type
|
|
719
|
+
});
|
|
720
|
+
} catch (error) {
|
|
721
|
+
console.log('error: ', error);
|
|
722
|
+
return null;
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
async function convertToFile(inputValue, isPreviews) {
|
|
726
|
+
let newFile = null;
|
|
727
|
+
|
|
728
|
+
// Download image by url and save as File instance
|
|
729
|
+
const isURL = typeof inputValue === 'string' && inputValue.includes('/');
|
|
730
|
+
if (inputValue.image || isURL) {
|
|
731
|
+
newFile = await getFileByURL(inputValue.image || inputValue);
|
|
732
|
+
if (newFile) {
|
|
733
|
+
setFileDataURL(newFile);
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
// Convert dataURL to File instance
|
|
738
|
+
if (inputValue.dataURL) {
|
|
739
|
+
newFile = createFileFromDataURL(inputValue.name || inputValue.path, inputValue.dataURL);
|
|
740
|
+
newFile.dataURL = inputValue.dataURL;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
// Save new File to state
|
|
744
|
+
if (newFile) {
|
|
745
|
+
newFile.id = inputValue.id;
|
|
746
|
+
if (isPreviews) {
|
|
747
|
+
newFile.preview = URL.createObjectURL(newFile);
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
return newFile;
|
|
751
|
+
}
|
|
752
|
+
function setFileDataURL(file, resolve) {
|
|
753
|
+
resolve = resolve || (() => {});
|
|
754
|
+
// Init reader and save his file
|
|
755
|
+
const reader = new FileReader();
|
|
756
|
+
reader._readedFile = file;
|
|
757
|
+
|
|
758
|
+
// Set handlers
|
|
759
|
+
reader.onabort = () => resolve();
|
|
760
|
+
reader.onerror = () => resolve();
|
|
761
|
+
reader.onload = event => {
|
|
762
|
+
event.target._readedFile.dataURL = reader.result;
|
|
763
|
+
resolve();
|
|
764
|
+
};
|
|
765
|
+
// Run reader
|
|
766
|
+
if (file instanceof File) {
|
|
767
|
+
reader.readAsDataURL(file);
|
|
768
|
+
} else {
|
|
769
|
+
resolve();
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
const FileInput = /*#__PURE__*/React$1.memo(function FileInput(props) {
|
|
774
|
+
const {
|
|
775
|
+
className,
|
|
776
|
+
name,
|
|
777
|
+
width,
|
|
778
|
+
maxFiles,
|
|
779
|
+
maxSize,
|
|
780
|
+
label,
|
|
781
|
+
fileErrorText,
|
|
782
|
+
classNameGroupItem,
|
|
783
|
+
dropzoneProps,
|
|
784
|
+
fieldProps,
|
|
785
|
+
hintDescription,
|
|
786
|
+
hintTitle,
|
|
787
|
+
showFilename,
|
|
788
|
+
showMessage,
|
|
789
|
+
isPreviews,
|
|
790
|
+
isRequired,
|
|
791
|
+
onAddFiles,
|
|
792
|
+
onDeleteFile
|
|
793
|
+
} = props;
|
|
794
|
+
const propsGenerator = useDevicePropsGenerator(props);
|
|
795
|
+
const {
|
|
796
|
+
size,
|
|
797
|
+
fill,
|
|
798
|
+
fillHover,
|
|
799
|
+
labelTextColor,
|
|
800
|
+
borderColorHover,
|
|
801
|
+
borderType,
|
|
802
|
+
borderWidth,
|
|
803
|
+
errorMessageTextColor,
|
|
804
|
+
errorMessageTextSize,
|
|
805
|
+
errorMessageTextWeight,
|
|
806
|
+
hintDescriptionTextColor,
|
|
807
|
+
hintDescriptionTextSize,
|
|
808
|
+
hintDescriptionTextWeight,
|
|
809
|
+
hintDescriptionTextWrap,
|
|
810
|
+
hintTitleTextColor,
|
|
811
|
+
hintTitleTextSize,
|
|
812
|
+
hintTitleTextWeight,
|
|
813
|
+
hintTitleTextWrap,
|
|
814
|
+
removeThumbAppearance,
|
|
815
|
+
removeThumbText,
|
|
816
|
+
removeThumbTextWeight,
|
|
817
|
+
removeThumbShape,
|
|
818
|
+
shape,
|
|
819
|
+
thumbBorderColor,
|
|
820
|
+
thumbBorderColorHover,
|
|
821
|
+
thumbBorderType,
|
|
822
|
+
thumbBorderWidth,
|
|
823
|
+
thumbColumn = 1,
|
|
824
|
+
thumbDirection = 'vertical',
|
|
825
|
+
thumbNameTextColor,
|
|
826
|
+
thumbNameTextSize,
|
|
827
|
+
thumbNameTextWeight,
|
|
828
|
+
thumbNameTextWrap
|
|
829
|
+
} = propsGenerator;
|
|
527
830
|
return /*#__PURE__*/React$1.createElement(Field, {
|
|
528
|
-
initialValue: initialValue,
|
|
529
831
|
name: name
|
|
530
832
|
}, function Render({
|
|
531
833
|
input,
|
|
@@ -537,81 +839,127 @@ const ChoiceField = /*#__PURE__*/React$1.memo(function ChoiceField(props) {
|
|
|
537
839
|
* React Hooks must be called in a React function component or a
|
|
538
840
|
* custom React Hook function.
|
|
539
841
|
*/
|
|
540
|
-
|
|
541
|
-
const emptyOption = {
|
|
542
|
-
value: null,
|
|
543
|
-
label: null
|
|
544
|
-
};
|
|
545
|
-
if (input.value) {
|
|
546
|
-
const currentOption = options.find(option => option.value === input.value);
|
|
547
|
-
return currentOption || emptyOption;
|
|
548
|
-
}
|
|
549
|
-
return emptyOption;
|
|
550
|
-
}, [input.value]);
|
|
842
|
+
|
|
551
843
|
const {
|
|
552
|
-
isErrorState,
|
|
553
|
-
isValidState,
|
|
554
844
|
errorKey,
|
|
555
|
-
errorMessage
|
|
845
|
+
errorMessage,
|
|
846
|
+
isErrorState,
|
|
847
|
+
isValidState
|
|
556
848
|
} = useFieldValidationState({
|
|
557
849
|
fieldProps: fieldProps,
|
|
558
850
|
input: input,
|
|
559
851
|
meta: meta
|
|
560
852
|
});
|
|
561
853
|
const updatedInputProps = useValidationAppearanceInputProps({
|
|
562
|
-
inputProps:
|
|
854
|
+
inputProps: props,
|
|
563
855
|
validationStateKey: isErrorState ? errorKey : 'success'
|
|
564
856
|
});
|
|
857
|
+
|
|
858
|
+
/** TODO:
|
|
859
|
+
* REFACTOR PROPERTIES
|
|
860
|
+
*/
|
|
565
861
|
return /*#__PURE__*/React$1.createElement(FieldWrapper, Object.assign({
|
|
566
|
-
className: clsx('form-
|
|
862
|
+
className: clsx('form-field_type_dropzone', 'form__item_type_dropzone', classNameGroupItem),
|
|
863
|
+
width: width,
|
|
567
864
|
label: label,
|
|
865
|
+
labelTextColor: labelTextColor,
|
|
568
866
|
errorKey: errorKey,
|
|
569
867
|
errorMessage: errorMessage,
|
|
570
868
|
isErrorState: isErrorState,
|
|
571
869
|
metaError: meta.error,
|
|
572
|
-
|
|
573
|
-
fieldClassName: "form-choice",
|
|
870
|
+
fieldClassName: "form-dropzone",
|
|
574
871
|
inputName: input.name,
|
|
575
|
-
inputValue: input.value
|
|
576
|
-
messageType: messageType,
|
|
872
|
+
inputValue: input.value,
|
|
577
873
|
metaActive: meta.active,
|
|
874
|
+
metaTouched: meta.touched,
|
|
578
875
|
showMessage: showMessage,
|
|
579
876
|
isRequired: isRequired,
|
|
580
877
|
isValidState: isValidState
|
|
581
|
-
}, fieldProps), /*#__PURE__*/React$1.createElement(
|
|
582
|
-
className:
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
878
|
+
}, fieldProps), /*#__PURE__*/React$1.createElement(FileInputDropzone, {
|
|
879
|
+
className: className,
|
|
880
|
+
maxFiles: maxFiles,
|
|
881
|
+
maxSize: maxSize,
|
|
882
|
+
size: size,
|
|
883
|
+
fill: fill,
|
|
884
|
+
fillHover: fillHover,
|
|
885
|
+
borderColor: updatedInputProps.borderColor,
|
|
886
|
+
borderColorHover: borderColorHover,
|
|
887
|
+
borderType: borderType,
|
|
888
|
+
borderWidth: borderWidth,
|
|
889
|
+
errorMessageTextColor: errorMessageTextColor,
|
|
890
|
+
errorMessageTextSize: errorMessageTextSize,
|
|
891
|
+
errorMessageWeight: errorMessageTextWeight,
|
|
892
|
+
fileErrorText: fileErrorText,
|
|
893
|
+
metaError: meta.error,
|
|
894
|
+
dropzoneProps: dropzoneProps,
|
|
895
|
+
hintDescription: hintDescription,
|
|
896
|
+
hintDescriptionTextColor: hintDescriptionTextColor,
|
|
897
|
+
hintDescriptionTextSize: hintDescriptionTextSize,
|
|
898
|
+
hintDescriptionTextWeight: hintDescriptionTextWeight,
|
|
899
|
+
hintDescriptionTextWrap: hintDescriptionTextWrap,
|
|
900
|
+
hintTitle: hintTitle,
|
|
901
|
+
hintTitleTextColor: hintTitleTextColor,
|
|
902
|
+
hintTitleTextSize: hintTitleTextSize,
|
|
903
|
+
hintTitleTextWeight: hintTitleTextWeight,
|
|
904
|
+
hintTitleTextWrap: hintTitleTextWrap,
|
|
905
|
+
inputName: input.name,
|
|
906
|
+
inputValue: input.value,
|
|
907
|
+
metaTouched: meta.touched,
|
|
908
|
+
removeThumbAppearance: removeThumbAppearance,
|
|
909
|
+
removeThumbText: removeThumbText,
|
|
910
|
+
removeThumbTextWeight: removeThumbTextWeight,
|
|
911
|
+
removeThumbShape: removeThumbShape,
|
|
912
|
+
shape: shape,
|
|
913
|
+
showFilename: showFilename,
|
|
914
|
+
thumbBorderColor: thumbBorderColor,
|
|
915
|
+
thumbBorderColorHover: thumbBorderColorHover,
|
|
916
|
+
thumbBorderType: thumbBorderType,
|
|
917
|
+
thumbBorderWidth: thumbBorderWidth,
|
|
918
|
+
thumbColumn: thumbColumn,
|
|
919
|
+
thumbDirection: thumbDirection,
|
|
920
|
+
thumbNameTextColor: thumbNameTextColor,
|
|
921
|
+
thumbNameTextSize: thumbNameTextSize,
|
|
922
|
+
thumbNameTextWeight: thumbNameTextWeight,
|
|
923
|
+
thumbNameTextWrap: thumbNameTextWrap,
|
|
924
|
+
isPreviews: isPreviews,
|
|
925
|
+
onAddFiles: onAddFiles,
|
|
926
|
+
onDeleteFile: onDeleteFile
|
|
927
|
+
}));
|
|
593
928
|
});
|
|
594
929
|
});
|
|
595
930
|
|
|
596
|
-
const
|
|
931
|
+
const defaultGroupProps = {
|
|
932
|
+
width: 'fill',
|
|
933
|
+
labelTextColor: 'surfaceTextPrimary',
|
|
934
|
+
labelTextSize: 'h5',
|
|
935
|
+
labelTextWeight: 500
|
|
936
|
+
};
|
|
937
|
+
|
|
938
|
+
const FormBlockGroup = /*#__PURE__*/React$1.memo(function Group(props) {
|
|
597
939
|
const {
|
|
598
|
-
|
|
599
|
-
isDisabled,
|
|
600
|
-
isRequired,
|
|
940
|
+
className,
|
|
601
941
|
name,
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
942
|
+
label,
|
|
943
|
+
labelTextColor,
|
|
944
|
+
labelTextSize,
|
|
945
|
+
labelTextWeight,
|
|
946
|
+
message,
|
|
947
|
+
column,
|
|
948
|
+
dataTour,
|
|
949
|
+
title,
|
|
950
|
+
titleTextSize,
|
|
951
|
+
titleTextColor,
|
|
952
|
+
titleTextWeight,
|
|
953
|
+
messageTextColor = 'surfaceTextTertiary',
|
|
954
|
+
messageTextSize = 's',
|
|
955
|
+
messageTextWeight,
|
|
956
|
+
showGroupMessage,
|
|
957
|
+
before,
|
|
958
|
+
after,
|
|
959
|
+
isHidden,
|
|
960
|
+
children
|
|
612
961
|
} = props;
|
|
613
962
|
return /*#__PURE__*/React$1.createElement(Field, {
|
|
614
|
-
initialValue: initialValue,
|
|
615
963
|
name: name
|
|
616
964
|
}, function Render({
|
|
617
965
|
input,
|
|
@@ -623,84 +971,70 @@ const CustomField = /*#__PURE__*/React$1.memo(function CustomField(props) {
|
|
|
623
971
|
* React Hooks must be called in a React function component or a
|
|
624
972
|
* custom React Hook function.
|
|
625
973
|
*/
|
|
626
|
-
|
|
627
974
|
const {
|
|
628
975
|
isErrorState,
|
|
629
|
-
isValidState,
|
|
630
976
|
errorKey,
|
|
631
977
|
errorMessage
|
|
632
978
|
} = useFieldValidationState({
|
|
633
|
-
fieldProps:
|
|
979
|
+
fieldProps: props,
|
|
980
|
+
// or fieldProps?
|
|
634
981
|
input: input,
|
|
635
982
|
meta: meta
|
|
636
983
|
});
|
|
637
|
-
const
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
inputProps: props
|
|
984
|
+
const updatedProps = useValidationAppearanceInputProps({
|
|
985
|
+
inputProps: props,
|
|
986
|
+
validationStateKey: isErrorState ? errorKey : 'success'
|
|
641
987
|
});
|
|
642
|
-
return /*#__PURE__*/React$1.createElement(
|
|
643
|
-
className: clsx('
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
988
|
+
return /*#__PURE__*/React$1.createElement("div", {
|
|
989
|
+
className: clsx('form__group', className, isHidden && 'form__group_hidden', column && `form__group_column_${column}`),
|
|
990
|
+
"data-tour": dataTour
|
|
991
|
+
}, /*#__PURE__*/React$1.createElement("div", {
|
|
992
|
+
className: "form__group-wrapper"
|
|
993
|
+
}, before, title && /*#__PURE__*/React$1.createElement("div", {
|
|
994
|
+
className: "form__group-title"
|
|
995
|
+
}, /*#__PURE__*/React$1.createElement(Title, {
|
|
996
|
+
size: titleTextSize,
|
|
997
|
+
textColor: titleTextColor,
|
|
998
|
+
textWeight: titleTextWeight
|
|
999
|
+
}, title)), label && /*#__PURE__*/React$1.createElement("div", {
|
|
1000
|
+
className: "form__group-label"
|
|
1001
|
+
}, /*#__PURE__*/React$1.createElement(Text, {
|
|
1002
|
+
size: labelTextSize,
|
|
1003
|
+
textColor: labelTextColor,
|
|
1004
|
+
textWeight: labelTextWeight
|
|
1005
|
+
}, label)), /*#__PURE__*/React$1.createElement("div", {
|
|
1006
|
+
className: "form__group-items"
|
|
1007
|
+
}, children), after), showGroupMessage && /*#__PURE__*/React$1.createElement(React$1.Fragment, null, isErrorState && errorMessage && /*#__PURE__*/React$1.createElement(Text, {
|
|
1008
|
+
className: `form__group-message form__group-message_type-${errorKey}`,
|
|
1009
|
+
id: `${name}-error`,
|
|
1010
|
+
size: updatedProps.messageTextSize,
|
|
1011
|
+
textColor: updatedProps.messageTextColor,
|
|
1012
|
+
textWeight: updatedProps.messageTextWeight
|
|
1013
|
+
}, errorMessage), Boolean(message) && (!isErrorState || !errorMessage) && /*#__PURE__*/React$1.createElement(Text, {
|
|
1014
|
+
className: "form__group-message",
|
|
1015
|
+
size: messageTextSize,
|
|
1016
|
+
textColor: messageTextColor,
|
|
1017
|
+
textWeight: messageTextWeight
|
|
1018
|
+
}, message), !isErrorState && !message && /*#__PURE__*/React$1.createElement(Text, {
|
|
1019
|
+
className: "form__group-message",
|
|
1020
|
+
size: messageTextSize
|
|
1021
|
+
}, '\u00A0')));
|
|
670
1022
|
});
|
|
671
1023
|
});
|
|
672
1024
|
|
|
673
|
-
const
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
showMessage: true
|
|
684
|
-
},
|
|
685
|
-
inputProps: {
|
|
686
|
-
width: 'fill',
|
|
687
|
-
size: 'l',
|
|
688
|
-
fill: 'surfaceSecondary',
|
|
689
|
-
inputBorderColor: 'surfaceBorderTertiary',
|
|
690
|
-
inputBorderColorHover: 'surfaceBorderQuaternary',
|
|
691
|
-
inputBorderFocusColor: 'surfaceBorderAccent',
|
|
692
|
-
inputCaretColor: 'surfaceItemAccent',
|
|
693
|
-
inputFill: 'surfacePrimary',
|
|
694
|
-
inputFillHover: 'surfaceSecondary',
|
|
695
|
-
inputPlaceholderTextColor: 'surfaceSecondary',
|
|
696
|
-
inputSize: 'l',
|
|
697
|
-
inputTextColor: 'surfaceSecondary',
|
|
698
|
-
inputTextSize: 'xxl',
|
|
699
|
-
inputTextWeight: 'normal'
|
|
700
|
-
}
|
|
1025
|
+
const defaultCheckboxProps = {
|
|
1026
|
+
appearance: 'defaultPrimary',
|
|
1027
|
+
width: 'fill',
|
|
1028
|
+
size: 'm',
|
|
1029
|
+
labelTextColor: 'surfaceTextPrimary',
|
|
1030
|
+
labelTextColorDisabled: 'surfaceTextDisabled',
|
|
1031
|
+
labelTextSize: 's',
|
|
1032
|
+
descTextSize: 's',
|
|
1033
|
+
errorBorderColor: 'errorBorderSecondary',
|
|
1034
|
+
requiredBorderColor: 'warningBorderSecondary'
|
|
701
1035
|
};
|
|
702
1036
|
|
|
703
|
-
const
|
|
1037
|
+
const FormFieldCheckbox = /*#__PURE__*/React$1.memo(function FormFieldCheckbox(props) {
|
|
704
1038
|
const {
|
|
705
1039
|
name,
|
|
706
1040
|
initialValue,
|
|
@@ -709,9 +1043,11 @@ const CodeField = /*#__PURE__*/React$1.memo(function CodeField(props) {
|
|
|
709
1043
|
fieldProps = {},
|
|
710
1044
|
inputProps = {},
|
|
711
1045
|
showMessage,
|
|
712
|
-
isRequired
|
|
1046
|
+
isRequired,
|
|
1047
|
+
onChange
|
|
713
1048
|
} = props;
|
|
714
1049
|
return /*#__PURE__*/React$1.createElement(Field, {
|
|
1050
|
+
type: "checkbox",
|
|
715
1051
|
name: name,
|
|
716
1052
|
initialValue: initialValue
|
|
717
1053
|
}, function Render({
|
|
@@ -725,10 +1061,18 @@ const CodeField = /*#__PURE__*/React$1.memo(function CodeField(props) {
|
|
|
725
1061
|
* custom React Hook function.
|
|
726
1062
|
*/
|
|
727
1063
|
|
|
1064
|
+
const onChangeField = useCallback(event => {
|
|
1065
|
+
input.onChange(event);
|
|
1066
|
+
if (onChange) {
|
|
1067
|
+
onChange(event.target.checked, input.name);
|
|
1068
|
+
}
|
|
1069
|
+
}, [onChange, input.onChange]);
|
|
728
1070
|
const {
|
|
1071
|
+
errorKey,
|
|
1072
|
+
errorMessage,
|
|
729
1073
|
isErrorState,
|
|
730
|
-
isValidState
|
|
731
|
-
|
|
1074
|
+
isValidState
|
|
1075
|
+
} = useFieldValidationState({
|
|
732
1076
|
fieldProps: fieldProps,
|
|
733
1077
|
input: input,
|
|
734
1078
|
meta: meta
|
|
@@ -738,79 +1082,78 @@ const CodeField = /*#__PURE__*/React$1.memo(function CodeField(props) {
|
|
|
738
1082
|
validationStateKey: isErrorState ? errorKey : 'success'
|
|
739
1083
|
});
|
|
740
1084
|
return /*#__PURE__*/React$1.createElement(FieldWrapper, Object.assign({
|
|
741
|
-
className: clsx('form-
|
|
742
|
-
|
|
1085
|
+
className: clsx('form-field_type_checkbox', 'form__item_type_checkbox', classNameGroupItem),
|
|
1086
|
+
errorKey: errorKey,
|
|
1087
|
+
errorMessage: errorMessage,
|
|
1088
|
+
isErrorState: isErrorState,
|
|
1089
|
+
metaError: meta.error,
|
|
1090
|
+
isDisabled: isDisabled,
|
|
1091
|
+
fieldClassName: "form-checkbox",
|
|
743
1092
|
inputName: input.name,
|
|
744
|
-
inputValue: input.
|
|
1093
|
+
inputValue: input.checked,
|
|
745
1094
|
metaActive: meta.active,
|
|
746
1095
|
showMessage: showMessage,
|
|
1096
|
+
tag: "label",
|
|
747
1097
|
isRequired: isRequired,
|
|
748
1098
|
isValidState: isValidState
|
|
749
|
-
}, fieldProps), /*#__PURE__*/React$1.createElement(
|
|
1099
|
+
}, fieldProps), /*#__PURE__*/React$1.createElement(Checkbox, Object.assign({
|
|
1100
|
+
type: "checkbox",
|
|
750
1101
|
name: input.name,
|
|
751
1102
|
isDisabled: isDisabled,
|
|
752
1103
|
autoComplete: "nope",
|
|
753
|
-
|
|
1104
|
+
checked: input.checked,
|
|
754
1105
|
onBlur: input.onBlur,
|
|
755
|
-
onChange:
|
|
1106
|
+
onChange: onChangeField,
|
|
756
1107
|
onFocus: input.onFocus
|
|
757
1108
|
}, updatedInputProps)));
|
|
758
1109
|
});
|
|
759
1110
|
});
|
|
760
1111
|
|
|
761
|
-
const
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
timeCaption: 'Время',
|
|
767
|
-
timeFormat: 'p',
|
|
768
|
-
timeIntervals: 60,
|
|
769
|
-
isClearable: true,
|
|
770
|
-
isStartDefaultNull: true
|
|
1112
|
+
const defaultChipsProps = {
|
|
1113
|
+
appearance: 'surfacePrimary sizeM rounded',
|
|
1114
|
+
width: 'fill',
|
|
1115
|
+
errorBorderColor: 'errorBorderSecondary',
|
|
1116
|
+
requiredBorderColor: 'warningBorderSecondary'
|
|
771
1117
|
};
|
|
772
1118
|
|
|
773
|
-
function
|
|
1119
|
+
function FormFieldChips(props) {
|
|
774
1120
|
const {
|
|
775
1121
|
name,
|
|
1122
|
+
initialValue,
|
|
776
1123
|
isDisabled,
|
|
777
1124
|
classNameGroupItem,
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
1125
|
+
emptyMessage,
|
|
1126
|
+
emptyMessageTextColor,
|
|
1127
|
+
emptyMessageTextSize,
|
|
1128
|
+
fieldProps,
|
|
1129
|
+
inputProps,
|
|
1130
|
+
options,
|
|
781
1131
|
showMessage,
|
|
782
1132
|
isRequired,
|
|
783
1133
|
onChange
|
|
784
1134
|
} = props;
|
|
1135
|
+
const {
|
|
1136
|
+
change
|
|
1137
|
+
} = useForm();
|
|
1138
|
+
|
|
1139
|
+
// Callback for value changes
|
|
1140
|
+
const onChangeSomeInput = useCallback((inputValue, newOptionValue) => {
|
|
1141
|
+
const updatedValues = inputValue.includes(newOptionValue) ? inputValue.filter(selectedValue => selectedValue !== newOptionValue) : [...inputValue, newOptionValue];
|
|
1142
|
+
change(name, updatedValues);
|
|
1143
|
+
onChange && onChange(updatedValues);
|
|
1144
|
+
}, [change, name, onChange]);
|
|
1145
|
+
useEffect(() => {
|
|
1146
|
+
initialValue && change(name, initialValue);
|
|
1147
|
+
// update the form value only when the initialValue changes, so use disable eslint to ignore the warning
|
|
1148
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1149
|
+
}, [initialValue]);
|
|
785
1150
|
return /*#__PURE__*/React$1.createElement(Field, {
|
|
786
|
-
name: name
|
|
1151
|
+
name: name,
|
|
1152
|
+
initialValue: initialValue
|
|
787
1153
|
}, function Render({
|
|
788
1154
|
input,
|
|
789
1155
|
meta
|
|
790
1156
|
}) {
|
|
791
|
-
/** Note:
|
|
792
|
-
* Create "Render" function by "eslint-react-hooks/rules-of-hooks":
|
|
793
|
-
* React Hooks cannot be called inside a callback.
|
|
794
|
-
* React Hooks must be called in a React function component or a
|
|
795
|
-
* custom React Hook function.
|
|
796
|
-
*/
|
|
797
|
-
|
|
798
|
-
const onChangeField = useCallback((startDate, endDate) => {
|
|
799
|
-
if (!datePickerProps.selectsRange) {
|
|
800
|
-
// When we need to save single date, value is date
|
|
801
|
-
// TODO: make object with one date? need to check all forms with DatePickerField
|
|
802
|
-
input.onChange(startDate);
|
|
803
|
-
} else {
|
|
804
|
-
// When we need to save range, value is object with two date
|
|
805
|
-
input.onChange({
|
|
806
|
-
endDate,
|
|
807
|
-
startDate
|
|
808
|
-
});
|
|
809
|
-
}
|
|
810
|
-
if (onChange) {
|
|
811
|
-
onChange(startDate, endDate);
|
|
812
|
-
}
|
|
813
|
-
}, [input.onChange, onChange]);
|
|
814
1157
|
const {
|
|
815
1158
|
errorKey,
|
|
816
1159
|
errorMessage,
|
|
@@ -825,454 +1168,170 @@ function DatePickerField(props) {
|
|
|
825
1168
|
inputProps: inputProps,
|
|
826
1169
|
validationStateKey: isErrorState ? errorKey : 'success'
|
|
827
1170
|
});
|
|
1171
|
+
const activeOptionsList = useMemo(() => {
|
|
1172
|
+
const emptyOptionsList = [{
|
|
1173
|
+
label: null,
|
|
1174
|
+
value: null
|
|
1175
|
+
}];
|
|
1176
|
+
if (input?.value) {
|
|
1177
|
+
const currentOptions = options.filter(option => input.value?.includes(option.value));
|
|
1178
|
+
return currentOptions || emptyOptionsList;
|
|
1179
|
+
}
|
|
1180
|
+
return emptyOptionsList;
|
|
1181
|
+
}, [input.value]);
|
|
828
1182
|
return /*#__PURE__*/React$1.createElement(FieldWrapper, Object.assign({
|
|
829
|
-
className: clsx('form-
|
|
1183
|
+
className: clsx('form-field_type_chips', 'form__item_type_chips', classNameGroupItem),
|
|
830
1184
|
errorKey: errorKey,
|
|
831
1185
|
errorMessage: errorMessage,
|
|
832
1186
|
isErrorState: isErrorState,
|
|
833
1187
|
metaError: meta.error,
|
|
834
1188
|
isDisabled: isDisabled,
|
|
835
|
-
fieldClassName: "form-
|
|
1189
|
+
fieldClassName: "form-chips",
|
|
836
1190
|
inputName: input.name,
|
|
837
|
-
inputValue: input.value
|
|
1191
|
+
inputValue: input.value,
|
|
838
1192
|
metaActive: meta.active,
|
|
839
1193
|
showMessage: showMessage,
|
|
840
1194
|
isRequired: isRequired,
|
|
841
1195
|
isValidState: isValidState
|
|
842
|
-
}, fieldProps), /*#__PURE__*/React$1.createElement(
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
1196
|
+
}, fieldProps), options.length ? /*#__PURE__*/React$1.createElement(ChipsGroup, {
|
|
1197
|
+
direction: "horizontal",
|
|
1198
|
+
gap: "1m",
|
|
1199
|
+
wrap: "wrap"
|
|
1200
|
+
}, options.map(option => /*#__PURE__*/React$1.createElement(Chips, Object.assign({
|
|
1201
|
+
className: clsx(meta.active && 'form-chips_state_focus', meta.error && meta.touched && `form-chips_state_${errorKey}`),
|
|
1202
|
+
key: option.value,
|
|
1203
|
+
label: option.label,
|
|
1204
|
+
isDisabled: option.isDisabled,
|
|
1205
|
+
value: option.value,
|
|
1206
|
+
isActive: activeOptionsList.some(activeOption => activeOption.value === option.value),
|
|
1207
|
+
onClick: () => onChangeSomeInput(input.value, option.value)
|
|
1208
|
+
}, updatedInputProps)))) : /*#__PURE__*/React$1.createElement(Text, {
|
|
1209
|
+
size: emptyMessageTextSize,
|
|
1210
|
+
textColor: emptyMessageTextColor
|
|
1211
|
+
}, emptyMessage));
|
|
853
1212
|
});
|
|
854
1213
|
}
|
|
855
1214
|
|
|
856
|
-
const
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
hintTitleTextColor: 'surfaceTextPrimary',
|
|
862
|
-
hintTitleTextSize: 'm',
|
|
863
|
-
removeThumbText: 'удалить',
|
|
864
|
-
removeThumbTextColor: 'errorTextPrimary',
|
|
865
|
-
removeThumbTextHoverColor: 'errorTextPrimaryHover',
|
|
866
|
-
removeThumbTextSize: 's',
|
|
867
|
-
shape: 'rounded',
|
|
868
|
-
showFilename: true,
|
|
869
|
-
thumbBorderColor: 'surfaceBorderTertiary',
|
|
870
|
-
thumbBorderColorHover: 'surfaceBorderQuaternary',
|
|
871
|
-
thumbBorderWidth: 1,
|
|
872
|
-
thumbNameTextColor: 'surfaceTextPrimary',
|
|
873
|
-
thumbNameTextSize: 's',
|
|
874
|
-
isPreviews: true
|
|
1215
|
+
const defaultChoiceProps = {
|
|
1216
|
+
appearance: 'defaultPrimary sizeM solid rounded',
|
|
1217
|
+
width: 'fill',
|
|
1218
|
+
errorBorderColor: 'errorBorderPrimary',
|
|
1219
|
+
requiredBorderColor: 'warningBorderPrimary'
|
|
875
1220
|
};
|
|
876
1221
|
|
|
877
|
-
const
|
|
1222
|
+
const FormFieldChoice = /*#__PURE__*/React$1.memo(function FormFieldChoice(props) {
|
|
878
1223
|
const {
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
onDeleteFile
|
|
1224
|
+
name,
|
|
1225
|
+
initialValue,
|
|
1226
|
+
label,
|
|
1227
|
+
isDisabled,
|
|
1228
|
+
classNameGroupItem,
|
|
1229
|
+
fieldProps,
|
|
1230
|
+
inputProps,
|
|
1231
|
+
messageType,
|
|
1232
|
+
options,
|
|
1233
|
+
placeholder,
|
|
1234
|
+
showMessage,
|
|
1235
|
+
isCheckbox,
|
|
1236
|
+
isRequired,
|
|
1237
|
+
onChange
|
|
894
1238
|
} = props;
|
|
895
|
-
|
|
896
|
-
// TODO: delete react-final-form things out of here?
|
|
897
1239
|
const {
|
|
898
1240
|
change
|
|
899
1241
|
} = useForm();
|
|
900
|
-
const
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
// If max files in dropzone is 1 - return file as it self, else as array of files
|
|
905
|
-
// ps: for old projects compatibility
|
|
906
|
-
const toSave = dropzoneProps.maxFiles == 1 ? newFiles[0] : newFiles;
|
|
907
|
-
change(inputName, toSave);
|
|
908
|
-
return toSave;
|
|
909
|
-
},
|
|
910
|
-
// If "inputName" will be changes, then it should be a different field
|
|
911
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
912
|
-
[dropzoneProps, change]);
|
|
913
|
-
|
|
914
|
-
//
|
|
915
|
-
const convertFiledValueAndSaveAsFiles = useCallback(async currentFilesList => {
|
|
916
|
-
setFileIsLoading(true);
|
|
917
|
-
const newFiles = [];
|
|
918
|
-
for (const fileItem of currentFilesList) {
|
|
919
|
-
if (typeof fileItem === 'string') {
|
|
920
|
-
const newFile = await convertToFile(fileItem, isPreviews);
|
|
921
|
-
if (newFile) {
|
|
922
|
-
newFiles.push(newFile);
|
|
923
|
-
}
|
|
924
|
-
} else {
|
|
925
|
-
newFiles.push(fileItem);
|
|
926
|
-
}
|
|
927
|
-
}
|
|
928
|
-
changeFormState(newFiles);
|
|
929
|
-
setFileIsLoading(false);
|
|
930
|
-
}, [isPreviews, changeFormState]);
|
|
931
|
-
|
|
932
|
-
// Delete file from dropzone
|
|
933
|
-
const removeFile = useCallback((event, index) => {
|
|
934
|
-
event.stopPropagation();
|
|
935
|
-
event.preventDefault();
|
|
936
|
-
const newFiles = [...filesList];
|
|
937
|
-
newFiles.splice(index, 1);
|
|
938
|
-
if (onDeleteFile) {
|
|
939
|
-
onDeleteFile(filesList[index], inputName);
|
|
1242
|
+
const setActiveSegment = useCallback((option, isChecked) => {
|
|
1243
|
+
change(name, isChecked && option.value);
|
|
1244
|
+
if (onChange) {
|
|
1245
|
+
onChange(option.value, name, isChecked);
|
|
940
1246
|
}
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
onDropAccepted: acceptedFiles => {
|
|
964
|
-
// If dropped files has accepted and we need a previews
|
|
965
|
-
if (isPreviews) {
|
|
966
|
-
// Add preview to every file
|
|
967
|
-
acceptedFiles.forEach(file => {
|
|
968
|
-
if (!file.error) {
|
|
969
|
-
file.preview = URL.createObjectURL(file);
|
|
970
|
-
}
|
|
971
|
-
});
|
|
1247
|
+
}, [change, onChange]);
|
|
1248
|
+
return /*#__PURE__*/React$1.createElement(Field, {
|
|
1249
|
+
initialValue: initialValue,
|
|
1250
|
+
name: name
|
|
1251
|
+
}, function Render({
|
|
1252
|
+
input,
|
|
1253
|
+
meta
|
|
1254
|
+
}) {
|
|
1255
|
+
/** Note:
|
|
1256
|
+
* Create "Render" function by "eslint-react-hooks/rules-of-hooks":
|
|
1257
|
+
* React Hooks cannot be called inside a callback.
|
|
1258
|
+
* React Hooks must be called in a React function component or a
|
|
1259
|
+
* custom React Hook function.
|
|
1260
|
+
*/
|
|
1261
|
+
const activeOption = useMemo(() => {
|
|
1262
|
+
const emptyOption = {
|
|
1263
|
+
value: null,
|
|
1264
|
+
label: null
|
|
1265
|
+
};
|
|
1266
|
+
if (input.value) {
|
|
1267
|
+
const currentOption = options.find(option => option.value === input.value);
|
|
1268
|
+
return currentOption || emptyOption;
|
|
972
1269
|
}
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
onAddFiles(filesToSave, inputName);
|
|
985
|
-
}
|
|
986
|
-
});
|
|
987
|
-
},
|
|
988
|
-
onDropRejected: rejectedFiles => {
|
|
989
|
-
// If dropped files has rejected
|
|
990
|
-
if (rejectedFiles.length) {
|
|
991
|
-
let fileErrorMessage = 'Ошибка при добавлении файла';
|
|
992
|
-
const firstFileErrorItem = rejectedFiles[0].errors[0];
|
|
993
|
-
if (firstFileErrorItem) {
|
|
994
|
-
if (firstFileErrorItem.code === ErrorCode.TooManyFiles) {
|
|
995
|
-
fileErrorMessage = `Максимальное количество файлов: ${maxFiles}`;
|
|
996
|
-
} else {
|
|
997
|
-
fileErrorMessage = firstFileErrorItem.message;
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
// Show error
|
|
1001
|
-
setFileError(fileErrorMessage);
|
|
1002
|
-
} else {
|
|
1003
|
-
// Else clean error
|
|
1004
|
-
setFileError('');
|
|
1005
|
-
}
|
|
1006
|
-
}
|
|
1007
|
-
});
|
|
1008
|
-
useEffect(() => {
|
|
1009
|
-
const currentFilesList = castArray(inputValue);
|
|
1010
|
-
const isNeedToConvert = currentFilesList.some(fileItem => typeof fileItem === 'string');
|
|
1011
|
-
if (isNeedToConvert) {
|
|
1012
|
-
// First time convert value to Files and save to local and form state
|
|
1013
|
-
convertFiledValueAndSaveAsFiles(currentFilesList);
|
|
1014
|
-
}
|
|
1015
|
-
|
|
1016
|
-
// Make sure to revoke the data uris to avoid memory leaks, will run on unmount
|
|
1017
|
-
return () => {
|
|
1018
|
-
filesList.forEach(file => {
|
|
1019
|
-
if (file?.preview) {
|
|
1020
|
-
URL.revokeObjectURL(file.preview);
|
|
1021
|
-
}
|
|
1022
|
-
});
|
|
1023
|
-
};
|
|
1024
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1025
|
-
}, [inputValue]);
|
|
1026
|
-
const propsGenerator = useDevicePropsGenerator(props);
|
|
1027
|
-
const {
|
|
1028
|
-
fillClass,
|
|
1029
|
-
fillHoverClass,
|
|
1030
|
-
borderColorClass,
|
|
1031
|
-
borderColorHoverClass,
|
|
1032
|
-
borderTypeClass,
|
|
1033
|
-
borderWidthClass,
|
|
1034
|
-
errorMessageTextColor,
|
|
1035
|
-
errorMessageTextSize,
|
|
1036
|
-
errorMessageTextWeight,
|
|
1037
|
-
hintDescriptionTextColor,
|
|
1038
|
-
hintDescriptionTextSize,
|
|
1039
|
-
hintDescriptionTextWeight,
|
|
1040
|
-
hintDescriptionTextWrap,
|
|
1041
|
-
hintTitleTextColor,
|
|
1042
|
-
hintTitleTextSize,
|
|
1043
|
-
hintTitleTextWeight,
|
|
1044
|
-
hintTitleTextWrap,
|
|
1045
|
-
removeThumbAppearance,
|
|
1046
|
-
removeThumbShape,
|
|
1047
|
-
removeThumbText,
|
|
1048
|
-
removeThumbTextWeight,
|
|
1049
|
-
shapeClass,
|
|
1050
|
-
thumbBorderColorClass,
|
|
1051
|
-
thumbBorderColorHoverClass,
|
|
1052
|
-
thumbBorderTypeClass,
|
|
1053
|
-
thumbBorderWidthClass,
|
|
1054
|
-
thumbDirectionClass,
|
|
1055
|
-
thumbNameTextColor,
|
|
1056
|
-
thumbNameTextSize,
|
|
1057
|
-
thumbNameTextWeight,
|
|
1058
|
-
thumbNameTextWrap
|
|
1059
|
-
} = propsGenerator;
|
|
1060
|
-
return /*#__PURE__*/React$1.createElement(React$1.Fragment, null, /*#__PURE__*/React$1.createElement("div", getRootProps({
|
|
1061
|
-
className: `form-dropzone__dropzone dropzone ${className} form-dropzone__dropzone_size_${size} ${shapeClass}`
|
|
1062
|
-
}), /*#__PURE__*/React$1.createElement("input", Object.assign({}, getInputProps(), {
|
|
1063
|
-
name: inputName
|
|
1064
|
-
})), /*#__PURE__*/React$1.createElement("div", {
|
|
1065
|
-
className: clsx('form-dropzone__dropzone-wrapper', thumbColumn && `form-dropzone__dropzone-wrapper_column_${thumbColumn}`, fillClass, fillHoverClass, borderWidthClass, borderColorClass, borderColorHoverClass, borderTypeClass)
|
|
1066
|
-
}, filesList.map((file, index) => /*#__PURE__*/React$1.createElement("aside", {
|
|
1067
|
-
className: clsx('form-dropzone__thumb', fillClass, thumbDirectionClass, thumbBorderWidthClass, thumbBorderColorClass, thumbBorderColorHoverClass, thumbBorderTypeClass),
|
|
1068
|
-
key: file.id || `${file.name}_${index}`
|
|
1069
|
-
}, isPreviews && !file.error && /*#__PURE__*/React$1.createElement("div", {
|
|
1070
|
-
className: "form-dropzone__thumb-image"
|
|
1071
|
-
}, /*#__PURE__*/React$1.createElement("img", {
|
|
1072
|
-
className: "form-dropzone__thumb-image-inner",
|
|
1073
|
-
src: file.preview || file.image,
|
|
1074
|
-
onLoad: () => {
|
|
1075
|
-
// Revoke data uri after image is loaded
|
|
1076
|
-
URL.revokeObjectURL(file.preview);
|
|
1077
|
-
}
|
|
1078
|
-
})), file.error && /*#__PURE__*/React$1.createElement("div", null, /*#__PURE__*/React$1.createElement(Text, {
|
|
1079
|
-
size: thumbNameTextSize,
|
|
1080
|
-
textColor: thumbNameTextColor,
|
|
1081
|
-
textWeight: thumbNameTextWeight,
|
|
1082
|
-
textWrap: thumbNameTextWrap
|
|
1083
|
-
}, fileErrorText || file.error)), showFilename && /*#__PURE__*/React$1.createElement("div", {
|
|
1084
|
-
className: "form-dropzone__thumb-name"
|
|
1085
|
-
}, /*#__PURE__*/React$1.createElement(Text, {
|
|
1086
|
-
className: "form-dropzone__thumb-name-inner",
|
|
1087
|
-
size: thumbNameTextSize,
|
|
1088
|
-
textColor: thumbNameTextColor,
|
|
1089
|
-
textWeight: thumbNameTextWeight,
|
|
1090
|
-
textWrap: thumbNameTextWrap
|
|
1091
|
-
}, file.name)), fileIsLoading && /*#__PURE__*/React$1.createElement("div", {
|
|
1092
|
-
className: "form-dropzone__thumb-loader"
|
|
1093
|
-
}, /*#__PURE__*/React$1.createElement(Loader, {
|
|
1094
|
-
width: "fill",
|
|
1095
|
-
height: "fill",
|
|
1096
|
-
fill: "surfacePrimary",
|
|
1097
|
-
itemFill: "surfaceItemAccent",
|
|
1098
|
-
set: "simple"
|
|
1099
|
-
})), /*#__PURE__*/React$1.createElement("div", {
|
|
1100
|
-
className: clsx('form-dropzone__thumb-remove')
|
|
1101
|
-
}, /*#__PURE__*/React$1.createElement(Button, {
|
|
1102
|
-
className: "form-dropzone__thumb-remove-text",
|
|
1103
|
-
appearance: removeThumbAppearance,
|
|
1104
|
-
label: removeThumbText || 'Удалить',
|
|
1105
|
-
labelTextWeight: removeThumbTextWeight,
|
|
1106
|
-
shape: removeThumbShape,
|
|
1107
|
-
onClick: event => removeFile(event, index)
|
|
1108
|
-
})))), !filesList.length ? /*#__PURE__*/React$1.createElement("div", {
|
|
1109
|
-
className: "form-dropzone__hint"
|
|
1110
|
-
}, /*#__PURE__*/React$1.createElement(Text, {
|
|
1111
|
-
className: "form-dropzone__hint-title",
|
|
1112
|
-
size: hintTitleTextSize,
|
|
1113
|
-
textColor: hintTitleTextColor,
|
|
1114
|
-
textWeight: hintTitleTextWeight,
|
|
1115
|
-
textWrap: hintTitleTextWrap
|
|
1116
|
-
}, hintTitle || 'Select a file or drag in form'), hintDescription && /*#__PURE__*/React$1.createElement(Text, {
|
|
1117
|
-
className: "form-dropzone__hint-text",
|
|
1118
|
-
size: hintDescriptionTextSize,
|
|
1119
|
-
textColor: hintDescriptionTextColor,
|
|
1120
|
-
textWeight: hintDescriptionTextWeight,
|
|
1121
|
-
textWrap: hintDescriptionTextWrap
|
|
1122
|
-
}, hintDescription)) : /*#__PURE__*/React$1.createElement("div", {
|
|
1123
|
-
className: "form-dropzone__hint form-dropzone__hint_type_add-more"
|
|
1124
|
-
}, /*#__PURE__*/React$1.createElement(Text, {
|
|
1125
|
-
className: "form-dropzone__hint-title",
|
|
1126
|
-
size: hintTitleTextSize,
|
|
1127
|
-
textColor: hintTitleTextColor,
|
|
1128
|
-
textWeight: hintTitleTextWeight,
|
|
1129
|
-
textWrap: hintTitleTextWrap
|
|
1130
|
-
}, hintTitle || 'Select a file or drag in form'), hintDescription && /*#__PURE__*/React$1.createElement(Text, {
|
|
1131
|
-
className: "form-dropzone__hint-text",
|
|
1132
|
-
size: hintDescriptionTextSize,
|
|
1133
|
-
textColor: hintDescriptionTextColor,
|
|
1134
|
-
textWeight: hintDescriptionTextWeight,
|
|
1135
|
-
textWrap: hintDescriptionTextWrap
|
|
1136
|
-
}, hintDescription)))), fileError && /*#__PURE__*/React$1.createElement("div", {
|
|
1137
|
-
className: "form-field__message"
|
|
1138
|
-
}, /*#__PURE__*/React$1.createElement(Text, {
|
|
1139
|
-
className: "form-field__message-item form-field__message-item_type_message",
|
|
1140
|
-
size: errorMessageTextSize,
|
|
1141
|
-
textColor: errorMessageTextColor,
|
|
1142
|
-
textWeight: errorMessageTextWeight
|
|
1143
|
-
}, fileError)));
|
|
1144
|
-
});
|
|
1145
|
-
async function getFileByURL(url) {
|
|
1146
|
-
try {
|
|
1147
|
-
const response = await axios({
|
|
1148
|
-
url: url,
|
|
1149
|
-
responseType: 'blob'
|
|
1270
|
+
return emptyOption;
|
|
1271
|
+
}, [input.value]);
|
|
1272
|
+
const {
|
|
1273
|
+
isErrorState,
|
|
1274
|
+
isValidState,
|
|
1275
|
+
errorKey,
|
|
1276
|
+
errorMessage
|
|
1277
|
+
} = useFieldValidationState({
|
|
1278
|
+
fieldProps: fieldProps,
|
|
1279
|
+
input: input,
|
|
1280
|
+
meta: meta
|
|
1150
1281
|
});
|
|
1151
|
-
const
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
let filename = dirtyFilename?.substring(1).slice(0, -1);
|
|
1155
|
-
if (!filename) {
|
|
1156
|
-
filename = url.split('/').at(-1);
|
|
1157
|
-
// const typeParts = blobObject.type.split('/')
|
|
1158
|
-
// const fileType = typeParts[typeParts.length - 1]
|
|
1159
|
-
// filename = `${new Date().getTime()}.${fileType}`
|
|
1160
|
-
}
|
|
1161
|
-
return new File([blobObject], filename, {
|
|
1162
|
-
type: blobObject.type
|
|
1282
|
+
const updatedInputProps = useValidationAppearanceInputProps({
|
|
1283
|
+
inputProps: inputProps,
|
|
1284
|
+
validationStateKey: isErrorState ? errorKey : 'success'
|
|
1163
1285
|
});
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
return newFile;
|
|
1195
|
-
}
|
|
1196
|
-
function setFileDataURL(file, resolve) {
|
|
1197
|
-
resolve = resolve || (() => {});
|
|
1198
|
-
// Init reader and save his file
|
|
1199
|
-
const reader = new FileReader();
|
|
1200
|
-
reader._readedFile = file;
|
|
1286
|
+
return /*#__PURE__*/React$1.createElement(FieldWrapper, Object.assign({
|
|
1287
|
+
className: clsx('form-field_type_choice', 'form__item_type_choice', classNameGroupItem),
|
|
1288
|
+
label: label,
|
|
1289
|
+
errorKey: errorKey,
|
|
1290
|
+
errorMessage: errorMessage,
|
|
1291
|
+
isErrorState: isErrorState,
|
|
1292
|
+
metaError: meta.error,
|
|
1293
|
+
isDisabled: isDisabled,
|
|
1294
|
+
fieldClassName: "form-choice",
|
|
1295
|
+
inputName: input.name,
|
|
1296
|
+
inputValue: input.value || [],
|
|
1297
|
+
messageType: messageType,
|
|
1298
|
+
metaActive: meta.active,
|
|
1299
|
+
showMessage: showMessage,
|
|
1300
|
+
isRequired: isRequired,
|
|
1301
|
+
isValidState: isValidState
|
|
1302
|
+
}, fieldProps), /*#__PURE__*/React$1.createElement(Choice, Object.assign({
|
|
1303
|
+
className: clsx(meta.active && 'form-choice_state_focus', meta.error && meta.touched && `form-choice_state_${errorKey}`),
|
|
1304
|
+
name: input.name,
|
|
1305
|
+
isDisabled: isDisabled,
|
|
1306
|
+
active: activeOption,
|
|
1307
|
+
inputValue: input.value || [],
|
|
1308
|
+
options: options,
|
|
1309
|
+
placeholder: placeholder,
|
|
1310
|
+
isCheckbox: isCheckbox,
|
|
1311
|
+
isRequired: isRequired,
|
|
1312
|
+
setActiveSegment: setActiveSegment
|
|
1313
|
+
}, updatedInputProps)));
|
|
1314
|
+
});
|
|
1315
|
+
});
|
|
1201
1316
|
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
reader.onload = event => {
|
|
1206
|
-
event.target._readedFile.dataURL = reader.result;
|
|
1207
|
-
resolve();
|
|
1208
|
-
};
|
|
1209
|
-
// Run reader
|
|
1210
|
-
if (file instanceof File) {
|
|
1211
|
-
reader.readAsDataURL(file);
|
|
1212
|
-
} else {
|
|
1213
|
-
resolve();
|
|
1214
|
-
}
|
|
1215
|
-
}
|
|
1317
|
+
const defaultCodeProps = {
|
|
1318
|
+
appearance: 'defaultPrimary sizeL solid rounded'
|
|
1319
|
+
};
|
|
1216
1320
|
|
|
1217
|
-
const
|
|
1321
|
+
const FormFieldCode = /*#__PURE__*/React$1.memo(function FormFieldCode(props) {
|
|
1218
1322
|
const {
|
|
1219
|
-
className,
|
|
1220
1323
|
name,
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
maxSize,
|
|
1224
|
-
label,
|
|
1225
|
-
fileErrorText,
|
|
1324
|
+
initialValue,
|
|
1325
|
+
isDisabled,
|
|
1226
1326
|
classNameGroupItem,
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
hintDescription,
|
|
1230
|
-
hintTitle,
|
|
1231
|
-
showFilename,
|
|
1327
|
+
fieldProps = {},
|
|
1328
|
+
inputProps = {},
|
|
1232
1329
|
showMessage,
|
|
1233
|
-
|
|
1234
|
-
isRequired,
|
|
1235
|
-
onAddFiles,
|
|
1236
|
-
onDeleteFile
|
|
1330
|
+
isRequired
|
|
1237
1331
|
} = props;
|
|
1238
|
-
const propsGenerator = useDevicePropsGenerator(props);
|
|
1239
|
-
const {
|
|
1240
|
-
size,
|
|
1241
|
-
fill,
|
|
1242
|
-
fillHover,
|
|
1243
|
-
labelTextColor,
|
|
1244
|
-
borderColorHover,
|
|
1245
|
-
borderType,
|
|
1246
|
-
borderWidth,
|
|
1247
|
-
errorMessageTextColor,
|
|
1248
|
-
errorMessageTextSize,
|
|
1249
|
-
errorMessageTextWeight,
|
|
1250
|
-
hintDescriptionTextColor,
|
|
1251
|
-
hintDescriptionTextSize,
|
|
1252
|
-
hintDescriptionTextWeight,
|
|
1253
|
-
hintDescriptionTextWrap,
|
|
1254
|
-
hintTitleTextColor,
|
|
1255
|
-
hintTitleTextSize,
|
|
1256
|
-
hintTitleTextWeight,
|
|
1257
|
-
hintTitleTextWrap,
|
|
1258
|
-
removeThumbAppearance,
|
|
1259
|
-
removeThumbText,
|
|
1260
|
-
removeThumbTextWeight,
|
|
1261
|
-
removeThumbShape,
|
|
1262
|
-
shape,
|
|
1263
|
-
thumbBorderColor,
|
|
1264
|
-
thumbBorderColorHover,
|
|
1265
|
-
thumbBorderType,
|
|
1266
|
-
thumbBorderWidth,
|
|
1267
|
-
thumbColumn = 1,
|
|
1268
|
-
thumbDirection = 'vertical',
|
|
1269
|
-
thumbNameTextColor,
|
|
1270
|
-
thumbNameTextSize,
|
|
1271
|
-
thumbNameTextWeight,
|
|
1272
|
-
thumbNameTextWrap
|
|
1273
|
-
} = propsGenerator;
|
|
1274
1332
|
return /*#__PURE__*/React$1.createElement(Field, {
|
|
1275
|
-
name: name
|
|
1333
|
+
name: name,
|
|
1334
|
+
initialValue: initialValue
|
|
1276
1335
|
}, function Render({
|
|
1277
1336
|
input,
|
|
1278
1337
|
meta
|
|
@@ -1285,125 +1344,57 @@ const FileInput = /*#__PURE__*/React$1.memo(function FileInput(props) {
|
|
|
1285
1344
|
*/
|
|
1286
1345
|
|
|
1287
1346
|
const {
|
|
1288
|
-
errorKey,
|
|
1289
|
-
errorMessage,
|
|
1290
1347
|
isErrorState,
|
|
1291
|
-
isValidState
|
|
1292
|
-
|
|
1348
|
+
isValidState,
|
|
1349
|
+
errorKey} = useFieldValidationState({
|
|
1293
1350
|
fieldProps: fieldProps,
|
|
1294
1351
|
input: input,
|
|
1295
1352
|
meta: meta
|
|
1296
1353
|
});
|
|
1297
1354
|
const updatedInputProps = useValidationAppearanceInputProps({
|
|
1298
|
-
inputProps:
|
|
1355
|
+
inputProps: inputProps,
|
|
1299
1356
|
validationStateKey: isErrorState ? errorKey : 'success'
|
|
1300
1357
|
});
|
|
1301
|
-
|
|
1302
|
-
/** TODO:
|
|
1303
|
-
* REFACTOR PROPERTIES
|
|
1304
|
-
*/
|
|
1305
1358
|
return /*#__PURE__*/React$1.createElement(FieldWrapper, Object.assign({
|
|
1306
|
-
className: clsx('form-
|
|
1307
|
-
|
|
1308
|
-
label: label,
|
|
1309
|
-
labelTextColor: labelTextColor,
|
|
1310
|
-
errorKey: errorKey,
|
|
1311
|
-
errorMessage: errorMessage,
|
|
1312
|
-
isErrorState: isErrorState,
|
|
1313
|
-
metaError: meta.error,
|
|
1314
|
-
fieldClassName: "form-dropzone",
|
|
1359
|
+
className: clsx('form-field_type_code', 'form__item_type_code', classNameGroupItem),
|
|
1360
|
+
fieldClassName: 'form-code',
|
|
1315
1361
|
inputName: input.name,
|
|
1316
1362
|
inputValue: input.value,
|
|
1317
1363
|
metaActive: meta.active,
|
|
1318
|
-
metaTouched: meta.touched,
|
|
1319
1364
|
showMessage: showMessage,
|
|
1320
1365
|
isRequired: isRequired,
|
|
1321
1366
|
isValidState: isValidState
|
|
1322
|
-
}, fieldProps), /*#__PURE__*/React$1.createElement(
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
borderType: borderType,
|
|
1332
|
-
borderWidth: borderWidth,
|
|
1333
|
-
errorMessageTextColor: errorMessageTextColor,
|
|
1334
|
-
errorMessageTextSize: errorMessageTextSize,
|
|
1335
|
-
errorMessageWeight: errorMessageTextWeight,
|
|
1336
|
-
fileErrorText: fileErrorText,
|
|
1337
|
-
metaError: meta.error,
|
|
1338
|
-
dropzoneProps: dropzoneProps,
|
|
1339
|
-
hintDescription: hintDescription,
|
|
1340
|
-
hintDescriptionTextColor: hintDescriptionTextColor,
|
|
1341
|
-
hintDescriptionTextSize: hintDescriptionTextSize,
|
|
1342
|
-
hintDescriptionTextWeight: hintDescriptionTextWeight,
|
|
1343
|
-
hintDescriptionTextWrap: hintDescriptionTextWrap,
|
|
1344
|
-
hintTitle: hintTitle,
|
|
1345
|
-
hintTitleTextColor: hintTitleTextColor,
|
|
1346
|
-
hintTitleTextSize: hintTitleTextSize,
|
|
1347
|
-
hintTitleTextWeight: hintTitleTextWeight,
|
|
1348
|
-
hintTitleTextWrap: hintTitleTextWrap,
|
|
1349
|
-
inputName: input.name,
|
|
1350
|
-
inputValue: input.value,
|
|
1351
|
-
metaTouched: meta.touched,
|
|
1352
|
-
removeThumbAppearance: removeThumbAppearance,
|
|
1353
|
-
removeThumbText: removeThumbText,
|
|
1354
|
-
removeThumbTextWeight: removeThumbTextWeight,
|
|
1355
|
-
removeThumbShape: removeThumbShape,
|
|
1356
|
-
shape: shape,
|
|
1357
|
-
showFilename: showFilename,
|
|
1358
|
-
thumbBorderColor: thumbBorderColor,
|
|
1359
|
-
thumbBorderColorHover: thumbBorderColorHover,
|
|
1360
|
-
thumbBorderType: thumbBorderType,
|
|
1361
|
-
thumbBorderWidth: thumbBorderWidth,
|
|
1362
|
-
thumbColumn: thumbColumn,
|
|
1363
|
-
thumbDirection: thumbDirection,
|
|
1364
|
-
thumbNameTextColor: thumbNameTextColor,
|
|
1365
|
-
thumbNameTextSize: thumbNameTextSize,
|
|
1366
|
-
thumbNameTextWeight: thumbNameTextWeight,
|
|
1367
|
-
thumbNameTextWrap: thumbNameTextWrap,
|
|
1368
|
-
isPreviews: isPreviews,
|
|
1369
|
-
onAddFiles: onAddFiles,
|
|
1370
|
-
onDeleteFile: onDeleteFile
|
|
1371
|
-
}));
|
|
1367
|
+
}, fieldProps), /*#__PURE__*/React$1.createElement(Code, Object.assign({
|
|
1368
|
+
name: input.name,
|
|
1369
|
+
isDisabled: isDisabled,
|
|
1370
|
+
autoComplete: "nope",
|
|
1371
|
+
value: input.value,
|
|
1372
|
+
onBlur: input.onBlur,
|
|
1373
|
+
onChange: input.onChange,
|
|
1374
|
+
onFocus: input.onFocus
|
|
1375
|
+
}, updatedInputProps)));
|
|
1372
1376
|
});
|
|
1373
1377
|
});
|
|
1374
1378
|
|
|
1375
|
-
const
|
|
1376
|
-
width: 'fill',
|
|
1377
|
-
labelTextColor: 'surfaceTextPrimary',
|
|
1378
|
-
labelTextSize: 'h5',
|
|
1379
|
-
labelTextWeight: 500
|
|
1380
|
-
};
|
|
1381
|
-
|
|
1382
|
-
const Group = /*#__PURE__*/React$1.memo(function Group(props) {
|
|
1379
|
+
const FormFieldCustom = /*#__PURE__*/React$1.memo(function FormFieldCustom(props) {
|
|
1383
1380
|
const {
|
|
1384
|
-
|
|
1381
|
+
Component,
|
|
1382
|
+
isDisabled,
|
|
1383
|
+
isRequired,
|
|
1385
1384
|
name,
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
titleTextWeight,
|
|
1397
|
-
messageTextColor = 'surfaceTextTertiary',
|
|
1398
|
-
messageTextSize = 's',
|
|
1399
|
-
messageTextWeight,
|
|
1400
|
-
showGroupMessage,
|
|
1401
|
-
before,
|
|
1402
|
-
after,
|
|
1403
|
-
isHidden,
|
|
1404
|
-
children
|
|
1385
|
+
initialValue,
|
|
1386
|
+
fieldProps = {},
|
|
1387
|
+
classNameGroupItem,
|
|
1388
|
+
showMessage,
|
|
1389
|
+
clearIcon,
|
|
1390
|
+
clearIconFill,
|
|
1391
|
+
clearIconFillHover,
|
|
1392
|
+
clearIconShape,
|
|
1393
|
+
clearIconSize,
|
|
1394
|
+
onClickClearIcon
|
|
1405
1395
|
} = props;
|
|
1406
1396
|
return /*#__PURE__*/React$1.createElement(Field, {
|
|
1397
|
+
initialValue: initialValue,
|
|
1407
1398
|
name: name
|
|
1408
1399
|
}, function Render({
|
|
1409
1400
|
input,
|
|
@@ -1415,111 +1406,80 @@ const Group = /*#__PURE__*/React$1.memo(function Group(props) {
|
|
|
1415
1406
|
* React Hooks must be called in a React function component or a
|
|
1416
1407
|
* custom React Hook function.
|
|
1417
1408
|
*/
|
|
1409
|
+
|
|
1418
1410
|
const {
|
|
1419
1411
|
isErrorState,
|
|
1412
|
+
isValidState,
|
|
1420
1413
|
errorKey,
|
|
1421
1414
|
errorMessage
|
|
1422
1415
|
} = useFieldValidationState({
|
|
1423
|
-
fieldProps:
|
|
1424
|
-
// or fieldProps?
|
|
1416
|
+
fieldProps: fieldProps,
|
|
1425
1417
|
input: input,
|
|
1426
1418
|
meta: meta
|
|
1427
1419
|
});
|
|
1428
|
-
const
|
|
1429
|
-
|
|
1430
|
-
|
|
1420
|
+
const updatedInputProps = useValidationAppearanceInputProps({
|
|
1421
|
+
validationStateKey: isErrorState ? errorKey : 'success',
|
|
1422
|
+
// For "Custom" field we pass all props. Can contain some special props, we don't known.
|
|
1423
|
+
inputProps: props
|
|
1431
1424
|
});
|
|
1432
|
-
return /*#__PURE__*/React$1.createElement(
|
|
1433
|
-
className: clsx('
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
textColor: messageTextColor,
|
|
1461
|
-
textWeight: messageTextWeight
|
|
1462
|
-
}, message), !isErrorState && !message && /*#__PURE__*/React$1.createElement(Text, {
|
|
1463
|
-
className: "form__group-message",
|
|
1464
|
-
size: messageTextSize
|
|
1465
|
-
}, '\u00A0')));
|
|
1425
|
+
return /*#__PURE__*/React$1.createElement(FieldWrapper, Object.assign({
|
|
1426
|
+
className: clsx('form-field_type_custom', 'form__item_type_custom', classNameGroupItem),
|
|
1427
|
+
errorKey: errorKey,
|
|
1428
|
+
errorMessage: errorMessage,
|
|
1429
|
+
fieldClassName: 'form-custom',
|
|
1430
|
+
inputName: input.name,
|
|
1431
|
+
inputValue: input.value,
|
|
1432
|
+
isDisabled: isDisabled,
|
|
1433
|
+
isErrorState: isErrorState,
|
|
1434
|
+
isRequired: isRequired,
|
|
1435
|
+
isValidState: isValidState,
|
|
1436
|
+
metaActive: meta.active,
|
|
1437
|
+
metaError: meta.error,
|
|
1438
|
+
showMessage: showMessage
|
|
1439
|
+
}, fieldProps), /*#__PURE__*/React$1.createElement(Component, Object.assign({}, updatedInputProps, {
|
|
1440
|
+
input: input,
|
|
1441
|
+
isDisabled: isDisabled,
|
|
1442
|
+
meta: meta
|
|
1443
|
+
})), clearIcon && /*#__PURE__*/React$1.createElement(Icon, {
|
|
1444
|
+
className: "form-field__icon",
|
|
1445
|
+
iconFill: clearIconFill,
|
|
1446
|
+
iconFillHover: clearIconFillHover,
|
|
1447
|
+
imageSrc: clearIcon,
|
|
1448
|
+
shape: clearIconShape,
|
|
1449
|
+
size: clearIconSize,
|
|
1450
|
+
SvgImage: clearIcon,
|
|
1451
|
+
onClick: onClickClearIcon
|
|
1452
|
+
}));
|
|
1466
1453
|
});
|
|
1467
1454
|
});
|
|
1468
1455
|
|
|
1469
|
-
const
|
|
1470
|
-
appearance: '
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1456
|
+
const defaultDatepickerProps = {
|
|
1457
|
+
appearance: 'surfacePrimary sizeS',
|
|
1458
|
+
dateFormat: 'dd/MM/yyyy - HH:mm',
|
|
1459
|
+
readOnly: false,
|
|
1460
|
+
selectsRange: false,
|
|
1461
|
+
showTimeSelect: true,
|
|
1462
|
+
timeCaption: 'Время',
|
|
1463
|
+
timeFormat: 'p',
|
|
1464
|
+
timeIntervals: 60,
|
|
1465
|
+
isClearable: true,
|
|
1466
|
+
isStartDefaultNull: true
|
|
1475
1467
|
};
|
|
1476
1468
|
|
|
1477
|
-
|
|
1469
|
+
function FormFieldDatePicker(props) {
|
|
1478
1470
|
const {
|
|
1479
1471
|
name,
|
|
1480
|
-
initialValue,
|
|
1481
1472
|
isDisabled,
|
|
1482
1473
|
classNameGroupItem,
|
|
1483
|
-
|
|
1484
|
-
// iconBorder,
|
|
1485
|
-
// iconBorderHover,
|
|
1486
|
-
clearIcon,
|
|
1487
|
-
clearIconFill,
|
|
1488
|
-
clearIconFillHover,
|
|
1489
|
-
clearIconShape,
|
|
1490
|
-
clearIconSize,
|
|
1474
|
+
datePickerProps,
|
|
1491
1475
|
fieldProps = {},
|
|
1492
|
-
iconFill,
|
|
1493
|
-
iconFillHover,
|
|
1494
|
-
iconRevealableHide,
|
|
1495
|
-
iconRevealableShow,
|
|
1496
|
-
iconShape,
|
|
1497
|
-
iconSize,
|
|
1498
1476
|
inputProps = {},
|
|
1499
|
-
parse,
|
|
1500
1477
|
showMessage,
|
|
1501
|
-
isPassword,
|
|
1502
1478
|
isRequired,
|
|
1503
|
-
|
|
1504
|
-
onChange,
|
|
1505
|
-
onClickClearIcon
|
|
1479
|
+
onChange
|
|
1506
1480
|
} = props;
|
|
1507
|
-
const [isRevealed, setIsRevealed] = useState(false);
|
|
1508
|
-
const inputType = useMemo(() => {
|
|
1509
|
-
if (isPassword) {
|
|
1510
|
-
return isRevealed ? 'text' : 'password';
|
|
1511
|
-
} else {
|
|
1512
|
-
return 'text';
|
|
1513
|
-
}
|
|
1514
|
-
}, [isRevealed, isPassword]);
|
|
1515
|
-
const onClickIconReveal = useCallback(event => {
|
|
1516
|
-
event.preventDefault();
|
|
1517
|
-
setIsRevealed(prev => !prev);
|
|
1518
|
-
}, []);
|
|
1519
1481
|
return /*#__PURE__*/React$1.createElement(Field, {
|
|
1520
|
-
name: name
|
|
1521
|
-
initialValue: initialValue,
|
|
1522
|
-
parse: parse
|
|
1482
|
+
name: name
|
|
1523
1483
|
}, function Render({
|
|
1524
1484
|
input,
|
|
1525
1485
|
meta
|
|
@@ -1531,12 +1491,22 @@ const InputField = /*#__PURE__*/React$1.memo(function InputField(props) {
|
|
|
1531
1491
|
* custom React Hook function.
|
|
1532
1492
|
*/
|
|
1533
1493
|
|
|
1534
|
-
const onChangeField = useCallback(
|
|
1535
|
-
|
|
1494
|
+
const onChangeField = useCallback((startDate, endDate) => {
|
|
1495
|
+
if (!datePickerProps.selectsRange) {
|
|
1496
|
+
// When we need to save single date, value is date
|
|
1497
|
+
// TODO: make object with one date? need to check all forms with FormFieldDatePicker
|
|
1498
|
+
input.onChange(startDate);
|
|
1499
|
+
} else {
|
|
1500
|
+
// When we need to save range, value is object with two date
|
|
1501
|
+
input.onChange({
|
|
1502
|
+
endDate,
|
|
1503
|
+
startDate
|
|
1504
|
+
});
|
|
1505
|
+
}
|
|
1536
1506
|
if (onChange) {
|
|
1537
|
-
onChange(
|
|
1507
|
+
onChange(startDate, endDate);
|
|
1538
1508
|
}
|
|
1539
|
-
}, [onChange,
|
|
1509
|
+
}, [input.onChange, onChange]);
|
|
1540
1510
|
const {
|
|
1541
1511
|
errorKey,
|
|
1542
1512
|
errorMessage,
|
|
@@ -1551,200 +1521,87 @@ const InputField = /*#__PURE__*/React$1.memo(function InputField(props) {
|
|
|
1551
1521
|
inputProps: inputProps,
|
|
1552
1522
|
validationStateKey: isErrorState ? errorKey : 'success'
|
|
1553
1523
|
});
|
|
1554
|
-
const isIconRevealableString = typeof iconRevealableHide === 'string' && typeof iconRevealableShow === 'string';
|
|
1555
1524
|
return /*#__PURE__*/React$1.createElement(FieldWrapper, Object.assign({
|
|
1556
|
-
className: clsx('form-
|
|
1525
|
+
className: clsx('form-field_type_datepicker', 'form__item_type_datepicker', classNameGroupItem),
|
|
1557
1526
|
errorKey: errorKey,
|
|
1558
1527
|
errorMessage: errorMessage,
|
|
1559
1528
|
isErrorState: isErrorState,
|
|
1560
1529
|
metaError: meta.error,
|
|
1561
1530
|
isDisabled: isDisabled,
|
|
1562
|
-
fieldClassName:
|
|
1531
|
+
fieldClassName: "form-datepicker",
|
|
1563
1532
|
inputName: input.name,
|
|
1564
1533
|
inputValue: input.value || '',
|
|
1565
1534
|
metaActive: meta.active,
|
|
1566
1535
|
showMessage: showMessage,
|
|
1567
1536
|
isRequired: isRequired,
|
|
1568
1537
|
isValidState: isValidState
|
|
1569
|
-
}, fieldProps), /*#__PURE__*/React$1.createElement(
|
|
1570
|
-
className: clsx(meta.active && 'input_state_focus', meta.error && meta.touched && `input_state_${errorKey}`),
|
|
1571
|
-
type: inputType,
|
|
1538
|
+
}, fieldProps), /*#__PURE__*/React$1.createElement(DatePickerInput, {
|
|
1572
1539
|
name: input.name,
|
|
1573
1540
|
isDisabled: isDisabled,
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1541
|
+
datePickerProps: datePickerProps,
|
|
1542
|
+
endValue: datePickerProps.selectsRange ? input.value.endDate : null,
|
|
1543
|
+
inputProps: updatedInputProps,
|
|
1544
|
+
value: datePickerProps.selectsRange ? input.value.startDate : input.value,
|
|
1577
1545
|
onBlur: input.onBlur,
|
|
1578
1546
|
onChange: onChangeField,
|
|
1579
1547
|
onFocus: input.onFocus
|
|
1580
|
-
}, updatedInputProps)), isRevealable && /*#__PURE__*/React$1.createElement(Icon, {
|
|
1581
|
-
className: "form-field__icon",
|
|
1582
|
-
size: iconSize,
|
|
1583
|
-
iconFill: iconFill,
|
|
1584
|
-
iconFillHover: iconFillHover,
|
|
1585
|
-
imageSrc: isRevealed && isIconRevealableString ? iconRevealableHide : iconRevealableShow,
|
|
1586
|
-
shape: iconShape,
|
|
1587
|
-
SvgImage: isRevealed && !isIconRevealableString ? iconRevealableHide : iconRevealableShow,
|
|
1588
|
-
onClick: onClickIconReveal
|
|
1589
|
-
}), clearIcon && /*#__PURE__*/React$1.createElement(Icon, {
|
|
1590
|
-
className: "form-field__icon",
|
|
1591
|
-
size: clearIconSize,
|
|
1592
|
-
iconFill: clearIconFill,
|
|
1593
|
-
iconFillHover: clearIconFillHover,
|
|
1594
|
-
imageSrc: typeof clearIcon === 'string' && clearIcon,
|
|
1595
|
-
shape: clearIconShape,
|
|
1596
|
-
SvgImage: typeof clearIcon !== 'string' && clearIcon,
|
|
1597
|
-
onClick: onClickClearIcon
|
|
1598
1548
|
}));
|
|
1599
1549
|
});
|
|
1600
|
-
});
|
|
1601
|
-
|
|
1602
|
-
const defaultRadioProps = {
|
|
1603
|
-
fieldProps: {
|
|
1604
|
-
width: 'fill',
|
|
1605
|
-
size: 'm',
|
|
1606
|
-
labelTextColor: 'surfaceTextPrimary',
|
|
1607
|
-
labelTextSize: 's',
|
|
1608
|
-
labelTextWeight: 'normal',
|
|
1609
|
-
textColor: 'surfaceTextPrimary',
|
|
1610
|
-
helpText: 'Supporting text',
|
|
1611
|
-
helpTextColor: 'surfaceTextPrimary',
|
|
1612
|
-
helpTextSize: 's',
|
|
1613
|
-
helpTextWeight: 'normal',
|
|
1614
|
-
showMessage: true
|
|
1615
|
-
},
|
|
1616
|
-
inputProps: {
|
|
1617
|
-
width: 'fill',
|
|
1618
|
-
size: 'm',
|
|
1619
|
-
labelTextColor: 'surfaceTextPrimary',
|
|
1620
|
-
labelTextSize: 's',
|
|
1621
|
-
descTextColor: 'surfaceTextPrimary',
|
|
1622
|
-
descTextSize: 's'
|
|
1623
|
-
}
|
|
1624
|
-
};
|
|
1625
|
-
|
|
1626
|
-
function RadioGroupInput(props) {
|
|
1627
|
-
const {
|
|
1628
|
-
input,
|
|
1629
|
-
value,
|
|
1630
|
-
onChange
|
|
1631
|
-
} = props;
|
|
1632
|
-
const onChangeField = useCallback(event => onChange(event.target.value), [onChange]);
|
|
1633
|
-
return /*#__PURE__*/React.createElement(Input, Object.assign({
|
|
1634
|
-
name: input.name,
|
|
1635
|
-
autoComplete: "nope",
|
|
1636
|
-
value: value,
|
|
1637
|
-
onBlur: input.onBlur,
|
|
1638
|
-
onChange: onChangeField,
|
|
1639
|
-
onFocus: input.onFocus
|
|
1640
|
-
}, props));
|
|
1641
|
-
}
|
|
1642
|
-
|
|
1643
|
-
function RadioGroupItem(props) {
|
|
1644
|
-
const {
|
|
1645
|
-
input,
|
|
1646
|
-
inputProps,
|
|
1647
|
-
option,
|
|
1648
|
-
onChange
|
|
1649
|
-
} = props;
|
|
1650
|
-
const onChangeField = useCallback(event => {
|
|
1651
|
-
if (event.target.checked) {
|
|
1652
|
-
onChange(option.value);
|
|
1653
|
-
}
|
|
1654
|
-
}, [onChange]);
|
|
1655
|
-
return /*#__PURE__*/React.createElement(Radio, Object.assign({
|
|
1656
|
-
className: "form-radio__item",
|
|
1657
|
-
type: "radio",
|
|
1658
|
-
name: input.name,
|
|
1659
|
-
label: option.label,
|
|
1660
|
-
checked: option.value === input.value,
|
|
1661
|
-
value: option.value,
|
|
1662
|
-
onBlur: input.onBlur,
|
|
1663
|
-
onChange: onChangeField,
|
|
1664
|
-
onFocus: input.onFocus
|
|
1665
|
-
}, inputProps));
|
|
1666
1550
|
}
|
|
1667
1551
|
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
onChange
|
|
1675
|
-
} = props;
|
|
1676
|
-
const [editableValue, setEditableValue] = useState(() => {
|
|
1677
|
-
const isRadioValue = options.find(option => option.value === input.value);
|
|
1678
|
-
if (!isRadioValue) {
|
|
1679
|
-
return input.value;
|
|
1680
|
-
}
|
|
1681
|
-
return '';
|
|
1682
|
-
});
|
|
1683
|
-
useEffect(() => {
|
|
1684
|
-
// When a new value from outside enters the form
|
|
1685
|
-
if (input.value) {
|
|
1686
|
-
// Check value for radio type
|
|
1687
|
-
const isRadioValue = options.find(option => option.value === input.value && !option.editable);
|
|
1688
|
-
// If new value not in radio list - set to editable input
|
|
1689
|
-
setEditableValue(isRadioValue ? '' : input.value);
|
|
1690
|
-
} else {
|
|
1691
|
-
// If new value is empty - clear editable input
|
|
1692
|
-
setEditableValue('');
|
|
1693
|
-
}
|
|
1694
|
-
}, [input.value]);
|
|
1695
|
-
|
|
1696
|
-
// Callback for value changes
|
|
1697
|
-
const onChangeSomeInput = useCallback(value => {
|
|
1698
|
-
// Save to form values
|
|
1699
|
-
input.onChange(value);
|
|
1700
|
-
if (onChange) {
|
|
1701
|
-
// Pass to custom event
|
|
1702
|
-
onChange(value, input.name);
|
|
1703
|
-
}
|
|
1704
|
-
}, [input, onChange]);
|
|
1705
|
-
|
|
1706
|
-
// Handle for radio inputs
|
|
1707
|
-
const onChangeRadio = useCallback(value => {
|
|
1708
|
-
setEditableValue('');
|
|
1709
|
-
onChangeSomeInput(value);
|
|
1710
|
-
}, [onChangeSomeInput]);
|
|
1711
|
-
|
|
1712
|
-
// Handle for text input
|
|
1713
|
-
const onChangeEditable = useCallback(value => {
|
|
1714
|
-
setEditableValue(value);
|
|
1715
|
-
onChangeSomeInput(value);
|
|
1716
|
-
}, [onChangeSomeInput]);
|
|
1717
|
-
return /*#__PURE__*/React$1.createElement(React$1.Fragment, null, options.map(option => option.editable ? /*#__PURE__*/React$1.createElement(RadioGroupInput, {
|
|
1718
|
-
key: option.label,
|
|
1719
|
-
editableProps: editableProps,
|
|
1720
|
-
input: input,
|
|
1721
|
-
inputProps: inputProps,
|
|
1722
|
-
option: option,
|
|
1723
|
-
value: editableValue,
|
|
1724
|
-
onChange: onChangeEditable
|
|
1725
|
-
}) : /*#__PURE__*/React$1.createElement(RadioGroupItem, {
|
|
1726
|
-
key: option.value,
|
|
1727
|
-
input: input,
|
|
1728
|
-
inputProps: inputProps,
|
|
1729
|
-
option: option,
|
|
1730
|
-
onChange: onChangeRadio
|
|
1731
|
-
})));
|
|
1732
|
-
}
|
|
1552
|
+
const defaultInputProps = {
|
|
1553
|
+
appearance: 'sizeM defaultSecondary solid rounded',
|
|
1554
|
+
width: 'fill',
|
|
1555
|
+
errorBorderColor: 'errorBorderSecondary',
|
|
1556
|
+
requiredBorderColor: 'warningBorderSecondary'
|
|
1557
|
+
};
|
|
1733
1558
|
|
|
1734
|
-
const
|
|
1559
|
+
const FormFieldInput = /*#__PURE__*/React$1.memo(function FormFieldInput(props) {
|
|
1735
1560
|
const {
|
|
1736
1561
|
name,
|
|
1562
|
+
initialValue,
|
|
1737
1563
|
isDisabled,
|
|
1738
|
-
|
|
1564
|
+
classNameGroupItem,
|
|
1565
|
+
// dataTestId,
|
|
1566
|
+
// iconBorder,
|
|
1567
|
+
// iconBorderHover,
|
|
1568
|
+
clearIcon,
|
|
1569
|
+
clearIconFill,
|
|
1570
|
+
clearIconFillHover,
|
|
1571
|
+
clearIconShape,
|
|
1572
|
+
clearIconSize,
|
|
1739
1573
|
fieldProps = {},
|
|
1574
|
+
iconFill,
|
|
1575
|
+
iconFillHover,
|
|
1576
|
+
iconRevealableHide,
|
|
1577
|
+
iconRevealableShow,
|
|
1578
|
+
iconShape,
|
|
1579
|
+
iconSize,
|
|
1740
1580
|
inputProps = {},
|
|
1741
|
-
|
|
1581
|
+
parse,
|
|
1742
1582
|
showMessage,
|
|
1583
|
+
isPassword,
|
|
1743
1584
|
isRequired,
|
|
1744
|
-
|
|
1585
|
+
isRevealable,
|
|
1586
|
+
onChange,
|
|
1587
|
+
onClickClearIcon
|
|
1745
1588
|
} = props;
|
|
1589
|
+
const [isRevealed, setIsRevealed] = useState(false);
|
|
1590
|
+
const inputType = useMemo(() => {
|
|
1591
|
+
if (isPassword) {
|
|
1592
|
+
return isRevealed ? 'text' : 'password';
|
|
1593
|
+
} else {
|
|
1594
|
+
return 'text';
|
|
1595
|
+
}
|
|
1596
|
+
}, [isRevealed, isPassword]);
|
|
1597
|
+
const onClickIconReveal = useCallback(event => {
|
|
1598
|
+
event.preventDefault();
|
|
1599
|
+
setIsRevealed(prev => !prev);
|
|
1600
|
+
}, []);
|
|
1746
1601
|
return /*#__PURE__*/React$1.createElement(Field, {
|
|
1747
|
-
name: name
|
|
1602
|
+
name: name,
|
|
1603
|
+
initialValue: initialValue,
|
|
1604
|
+
parse: parse
|
|
1748
1605
|
}, function Render({
|
|
1749
1606
|
input,
|
|
1750
1607
|
meta
|
|
@@ -1756,6 +1613,12 @@ const RadioGroup = /*#__PURE__*/React$1.memo(function RadioGroup(props) {
|
|
|
1756
1613
|
* custom React Hook function.
|
|
1757
1614
|
*/
|
|
1758
1615
|
|
|
1616
|
+
const onChangeField = useCallback(event => {
|
|
1617
|
+
input.onChange(event);
|
|
1618
|
+
if (onChange) {
|
|
1619
|
+
onChange(event.target.value, input.name);
|
|
1620
|
+
}
|
|
1621
|
+
}, [onChange, input.onChange]);
|
|
1759
1622
|
const {
|
|
1760
1623
|
errorKey,
|
|
1761
1624
|
errorMessage,
|
|
@@ -1770,40 +1633,62 @@ const RadioGroup = /*#__PURE__*/React$1.memo(function RadioGroup(props) {
|
|
|
1770
1633
|
inputProps: inputProps,
|
|
1771
1634
|
validationStateKey: isErrorState ? errorKey : 'success'
|
|
1772
1635
|
});
|
|
1636
|
+
const isIconRevealableString = typeof iconRevealableHide === 'string' && typeof iconRevealableShow === 'string';
|
|
1773
1637
|
return /*#__PURE__*/React$1.createElement(FieldWrapper, Object.assign({
|
|
1774
|
-
className: clsx('form-
|
|
1638
|
+
className: clsx('form-field_type_input', 'form__item_type_input', classNameGroupItem),
|
|
1775
1639
|
errorKey: errorKey,
|
|
1776
1640
|
errorMessage: errorMessage,
|
|
1777
1641
|
isErrorState: isErrorState,
|
|
1778
1642
|
metaError: meta.error,
|
|
1779
1643
|
isDisabled: isDisabled,
|
|
1780
|
-
fieldClassName: 'form-
|
|
1644
|
+
fieldClassName: isRevealable ? 'form-password' : 'form-input',
|
|
1781
1645
|
inputName: input.name,
|
|
1782
1646
|
inputValue: input.value || '',
|
|
1783
1647
|
metaActive: meta.active,
|
|
1784
1648
|
showMessage: showMessage,
|
|
1785
1649
|
isRequired: isRequired,
|
|
1786
1650
|
isValidState: isValidState
|
|
1787
|
-
}, fieldProps), /*#__PURE__*/React$1.createElement(
|
|
1651
|
+
}, fieldProps), /*#__PURE__*/React$1.createElement(Input, Object.assign({
|
|
1652
|
+
dataTestId: `${input.name}FieldInput`,
|
|
1653
|
+
className: clsx(meta.active && 'input_state_focus', meta.error && meta.touched && `input_state_${errorKey}`),
|
|
1654
|
+
type: inputType,
|
|
1655
|
+
name: input.name,
|
|
1788
1656
|
isDisabled: isDisabled,
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1657
|
+
autoComplete: "nope",
|
|
1658
|
+
value: input.value || '',
|
|
1659
|
+
onBlur: input.onBlur,
|
|
1660
|
+
onChange: onChangeField,
|
|
1661
|
+
onFocus: input.onFocus
|
|
1662
|
+
}, updatedInputProps)), isRevealable && /*#__PURE__*/React$1.createElement(Icon, {
|
|
1663
|
+
className: "form-field__icon",
|
|
1664
|
+
size: iconSize,
|
|
1665
|
+
iconFill: iconFill,
|
|
1666
|
+
iconFillHover: iconFillHover,
|
|
1667
|
+
imageSrc: isRevealed && isIconRevealableString ? iconRevealableHide : iconRevealableShow,
|
|
1668
|
+
shape: iconShape,
|
|
1669
|
+
SvgImage: isRevealed && !isIconRevealableString ? iconRevealableHide : iconRevealableShow,
|
|
1670
|
+
onClick: onClickIconReveal
|
|
1671
|
+
}), clearIcon && /*#__PURE__*/React$1.createElement(Icon, {
|
|
1672
|
+
className: "form-field__icon",
|
|
1673
|
+
size: clearIconSize,
|
|
1674
|
+
iconFill: clearIconFill,
|
|
1675
|
+
iconFillHover: clearIconFillHover,
|
|
1676
|
+
imageSrc: typeof clearIcon === 'string' && clearIcon,
|
|
1677
|
+
shape: clearIconShape,
|
|
1678
|
+
SvgImage: typeof clearIcon !== 'string' && clearIcon,
|
|
1679
|
+
onClick: onClickClearIcon
|
|
1794
1680
|
}));
|
|
1795
1681
|
});
|
|
1796
1682
|
});
|
|
1797
1683
|
|
|
1798
1684
|
const defaultSegmentedProps = {
|
|
1799
|
-
appearance: 'sizeM
|
|
1685
|
+
appearance: 'defaultPrimary sizeM solid rounded',
|
|
1800
1686
|
width: 'fill',
|
|
1801
1687
|
errorLabelTextColor: 'errorTextPrimary',
|
|
1802
|
-
requiredLabelTextColor: 'warningTextPrimary'
|
|
1803
|
-
shape: 'rounded'
|
|
1688
|
+
requiredLabelTextColor: 'warningTextPrimary'
|
|
1804
1689
|
};
|
|
1805
1690
|
|
|
1806
|
-
function
|
|
1691
|
+
function FormFieldSegmented(props) {
|
|
1807
1692
|
const {
|
|
1808
1693
|
name,
|
|
1809
1694
|
isDisabled,
|
|
@@ -1881,36 +1766,7 @@ function SegmentedField(props) {
|
|
|
1881
1766
|
}
|
|
1882
1767
|
|
|
1883
1768
|
const defaultSelectProps = {
|
|
1884
|
-
|
|
1885
|
-
isClearable: true,
|
|
1886
|
-
isSearchable: true,
|
|
1887
|
-
badgeAppearance: 'accent',
|
|
1888
|
-
badgeSize: 'm',
|
|
1889
|
-
badgeTextSize: 'm',
|
|
1890
|
-
// clearIcon: icon24.Clear,
|
|
1891
|
-
clearIconFill: 'surfaceItemPrimary',
|
|
1892
|
-
closeMenuOnSelect: true,
|
|
1893
|
-
// optionSelected: <Icon iconFill="surfaceItemAccent" SvgImage={icon24.Check} />,
|
|
1894
|
-
|
|
1895
|
-
dividerDirection: 'horizontal',
|
|
1896
|
-
dividerFill: 'surfaceTertiary',
|
|
1897
|
-
dividerSize: 'xxs',
|
|
1898
|
-
// dropdownIcon: icon24.ChevronDownSmall,
|
|
1899
|
-
dropdownIconFill: 'surfaceItemPrimary',
|
|
1900
|
-
// error
|
|
1901
|
-
errorInputBorderColor: 'errorBorderPrimary',
|
|
1902
|
-
headingFill: 'surfaceSecondary',
|
|
1903
|
-
loadingMessage: /*#__PURE__*/React$1.createElement(Loader, {
|
|
1904
|
-
width: "fill",
|
|
1905
|
-
height: "fill",
|
|
1906
|
-
fill: "surfacePrimary",
|
|
1907
|
-
position: "absolute",
|
|
1908
|
-
left: "0px",
|
|
1909
|
-
right: "0px",
|
|
1910
|
-
zIndex: "1",
|
|
1911
|
-
itemFill: "surfaceItemAccent",
|
|
1912
|
-
set: "simple"
|
|
1913
|
-
})
|
|
1769
|
+
appearance: 'defaultPrimary sizeM'
|
|
1914
1770
|
};
|
|
1915
1771
|
|
|
1916
1772
|
function getDefaultValue(options, selectValue) {
|
|
@@ -1931,7 +1787,7 @@ function getDefaultValue(options, selectValue) {
|
|
|
1931
1787
|
});
|
|
1932
1788
|
return result;
|
|
1933
1789
|
}
|
|
1934
|
-
const
|
|
1790
|
+
const FormFieldSelect = /*#__PURE__*/React$1.memo(function FormFieldSelect(props) {
|
|
1935
1791
|
const {
|
|
1936
1792
|
isDisabled,
|
|
1937
1793
|
isRequired,
|
|
@@ -2014,10 +1870,10 @@ const SelectField = /*#__PURE__*/React$1.memo(function SelectField(props) {
|
|
|
2014
1870
|
isValidState: isValidState
|
|
2015
1871
|
}, fieldProps), /*#__PURE__*/React$1.createElement(Select, Object.assign({
|
|
2016
1872
|
className: "form-select-item",
|
|
1873
|
+
ref: selectRef,
|
|
2017
1874
|
isDisabled: isDisabled,
|
|
2018
1875
|
instanceId: `id_${input.name}`,
|
|
2019
1876
|
options: options,
|
|
2020
|
-
ref: selectRef,
|
|
2021
1877
|
value: selectedOptions,
|
|
2022
1878
|
onChange: onChangeValue,
|
|
2023
1879
|
onInputChange: onInputChange
|
|
@@ -2026,32 +1882,10 @@ const SelectField = /*#__PURE__*/React$1.memo(function SelectField(props) {
|
|
|
2026
1882
|
});
|
|
2027
1883
|
|
|
2028
1884
|
const defaultSwitchProps = {
|
|
2029
|
-
|
|
2030
|
-
width: 'fill',
|
|
2031
|
-
size: 'xl',
|
|
2032
|
-
labelTextColor: 'surfaceTextPrimary',
|
|
2033
|
-
labelTextSize: 's',
|
|
2034
|
-
labelTextWeight: 'normal',
|
|
2035
|
-
textColor: 'surfaceTextPrimary',
|
|
2036
|
-
helpText: 'Supporting text',
|
|
2037
|
-
helpTextColor: 'surfaceTextPrimary',
|
|
2038
|
-
helpTextSize: 's',
|
|
2039
|
-
helpTextWeight: 'normal',
|
|
2040
|
-
showMessage: true
|
|
2041
|
-
},
|
|
2042
|
-
inputProps: {
|
|
2043
|
-
size: 'm',
|
|
2044
|
-
fill: 'surfaceSecondary',
|
|
2045
|
-
title: 'Switch',
|
|
2046
|
-
titleTextColor: 'surfaceTextPrimary',
|
|
2047
|
-
titleTextSize: 's',
|
|
2048
|
-
desc: 'Description',
|
|
2049
|
-
descTextColor: 'surfaceTextPrimary',
|
|
2050
|
-
descTextSize: 'xs'
|
|
2051
|
-
}
|
|
1885
|
+
appearance: 'defaultPrimary sizeL solid rounded'
|
|
2052
1886
|
};
|
|
2053
1887
|
|
|
2054
|
-
const
|
|
1888
|
+
const FormFieldSwitch = /*#__PURE__*/React$1.memo(function FormFieldSwitch(props) {
|
|
2055
1889
|
const {
|
|
2056
1890
|
name,
|
|
2057
1891
|
isDisabled,
|
|
@@ -2125,14 +1959,12 @@ const SwitchField = /*#__PURE__*/React$1.memo(function SwitchField(props) {
|
|
|
2125
1959
|
});
|
|
2126
1960
|
|
|
2127
1961
|
const defaultTextareaProps = {
|
|
2128
|
-
appearance: 'sizeM
|
|
2129
|
-
width: 'fill',
|
|
1962
|
+
appearance: 'defaultPrimary sizeM solid rounded',
|
|
2130
1963
|
errorBorderColor: 'errorBorderSecondary',
|
|
2131
|
-
requiredBorderColor: 'warningBorderSecondary'
|
|
2132
|
-
shape: 'rounded'
|
|
1964
|
+
requiredBorderColor: 'warningBorderSecondary'
|
|
2133
1965
|
};
|
|
2134
1966
|
|
|
2135
|
-
const
|
|
1967
|
+
const FormFieldTextarea = /*#__PURE__*/React$1.memo(function FormFieldTextarea(props) {
|
|
2136
1968
|
const {
|
|
2137
1969
|
name,
|
|
2138
1970
|
isDisabled,
|
|
@@ -2195,7 +2027,7 @@ const TextareaField = /*#__PURE__*/React$1.memo(function TextareaField(props) {
|
|
|
2195
2027
|
});
|
|
2196
2028
|
});
|
|
2197
2029
|
|
|
2198
|
-
const
|
|
2030
|
+
const FormFieldMaskedInput = /*#__PURE__*/React$1.memo(function FormFieldMaskedInput(props) {
|
|
2199
2031
|
const {
|
|
2200
2032
|
name,
|
|
2201
2033
|
initialValue,
|
|
@@ -2292,51 +2124,144 @@ const MaskedInputField = /*#__PURE__*/React$1.memo(function MaskedInputField(pro
|
|
|
2292
2124
|
});
|
|
2293
2125
|
});
|
|
2294
2126
|
|
|
2295
|
-
const
|
|
2296
|
-
appearance: '
|
|
2297
|
-
width: 'fill',
|
|
2298
|
-
errorBorderColor: 'errorBorderSecondary',
|
|
2299
|
-
requiredBorderColor: 'warningBorderSecondary'
|
|
2127
|
+
const defaultRadioProps = {
|
|
2128
|
+
appearance: 'defaultPrimary sizeM solid circular'
|
|
2300
2129
|
};
|
|
2301
2130
|
|
|
2302
|
-
function
|
|
2131
|
+
function RadioGroupInput(props) {
|
|
2132
|
+
const {
|
|
2133
|
+
input,
|
|
2134
|
+
value,
|
|
2135
|
+
onChange
|
|
2136
|
+
} = props;
|
|
2137
|
+
const onChangeField = useCallback(event => onChange(event.target.value), [onChange]);
|
|
2138
|
+
return /*#__PURE__*/React.createElement(Input, Object.assign({
|
|
2139
|
+
name: input.name,
|
|
2140
|
+
autoComplete: "nope",
|
|
2141
|
+
value: value,
|
|
2142
|
+
onBlur: input.onBlur,
|
|
2143
|
+
onChange: onChangeField,
|
|
2144
|
+
onFocus: input.onFocus
|
|
2145
|
+
}, props));
|
|
2146
|
+
}
|
|
2147
|
+
|
|
2148
|
+
function RadioGroupItem(props) {
|
|
2149
|
+
const {
|
|
2150
|
+
input,
|
|
2151
|
+
inputProps,
|
|
2152
|
+
option,
|
|
2153
|
+
onChange
|
|
2154
|
+
} = props;
|
|
2155
|
+
const onChangeField = useCallback(event => {
|
|
2156
|
+
if (event.target.checked) {
|
|
2157
|
+
onChange(option.value);
|
|
2158
|
+
}
|
|
2159
|
+
}, [onChange]);
|
|
2160
|
+
return /*#__PURE__*/React.createElement(Radio, Object.assign({
|
|
2161
|
+
className: "form-radio__item",
|
|
2162
|
+
type: "radio",
|
|
2163
|
+
name: input.name,
|
|
2164
|
+
label: option.label,
|
|
2165
|
+
checked: option.value === input.value,
|
|
2166
|
+
value: option.value,
|
|
2167
|
+
onBlur: input.onBlur,
|
|
2168
|
+
onChange: onChangeField,
|
|
2169
|
+
onFocus: input.onFocus
|
|
2170
|
+
}, inputProps));
|
|
2171
|
+
}
|
|
2172
|
+
|
|
2173
|
+
function RadioGroupList(props) {
|
|
2174
|
+
const {
|
|
2175
|
+
editableProps,
|
|
2176
|
+
input,
|
|
2177
|
+
inputProps,
|
|
2178
|
+
options,
|
|
2179
|
+
onChange
|
|
2180
|
+
} = props;
|
|
2181
|
+
const [editableValue, setEditableValue] = useState(() => {
|
|
2182
|
+
const isRadioValue = options.find(option => option.value === input.value);
|
|
2183
|
+
if (!isRadioValue) {
|
|
2184
|
+
return input.value;
|
|
2185
|
+
}
|
|
2186
|
+
return '';
|
|
2187
|
+
});
|
|
2188
|
+
useEffect(() => {
|
|
2189
|
+
// When a new value from outside enters the form
|
|
2190
|
+
if (input.value) {
|
|
2191
|
+
// Check value for radio type
|
|
2192
|
+
const isRadioValue = options.find(option => option.value === input.value && !option.editable);
|
|
2193
|
+
// If new value not in radio list - set to editable input
|
|
2194
|
+
setEditableValue(isRadioValue ? '' : input.value);
|
|
2195
|
+
} else {
|
|
2196
|
+
// If new value is empty - clear editable input
|
|
2197
|
+
setEditableValue('');
|
|
2198
|
+
}
|
|
2199
|
+
}, [input.value]);
|
|
2200
|
+
|
|
2201
|
+
// Callback for value changes
|
|
2202
|
+
const onChangeSomeInput = useCallback(value => {
|
|
2203
|
+
// Save to form values
|
|
2204
|
+
input.onChange(value);
|
|
2205
|
+
if (onChange) {
|
|
2206
|
+
// Pass to custom event
|
|
2207
|
+
onChange(value, input.name);
|
|
2208
|
+
}
|
|
2209
|
+
}, [input, onChange]);
|
|
2210
|
+
|
|
2211
|
+
// Handle for radio inputs
|
|
2212
|
+
const onChangeRadio = useCallback(value => {
|
|
2213
|
+
setEditableValue('');
|
|
2214
|
+
onChangeSomeInput(value);
|
|
2215
|
+
}, [onChangeSomeInput]);
|
|
2216
|
+
|
|
2217
|
+
// Handle for text input
|
|
2218
|
+
const onChangeEditable = useCallback(value => {
|
|
2219
|
+
setEditableValue(value);
|
|
2220
|
+
onChangeSomeInput(value);
|
|
2221
|
+
}, [onChangeSomeInput]);
|
|
2222
|
+
return /*#__PURE__*/React$1.createElement(React$1.Fragment, null, options.map(option => option.editable ? /*#__PURE__*/React$1.createElement(RadioGroupInput, {
|
|
2223
|
+
key: option.label,
|
|
2224
|
+
editableProps: editableProps,
|
|
2225
|
+
input: input,
|
|
2226
|
+
inputProps: inputProps,
|
|
2227
|
+
option: option,
|
|
2228
|
+
value: editableValue,
|
|
2229
|
+
onChange: onChangeEditable
|
|
2230
|
+
}) : /*#__PURE__*/React$1.createElement(RadioGroupItem, {
|
|
2231
|
+
key: option.value,
|
|
2232
|
+
input: input,
|
|
2233
|
+
inputProps: inputProps,
|
|
2234
|
+
option: option,
|
|
2235
|
+
onChange: onChangeRadio
|
|
2236
|
+
})));
|
|
2237
|
+
}
|
|
2238
|
+
|
|
2239
|
+
const RadioGroup = /*#__PURE__*/React$1.memo(function RadioGroup(props) {
|
|
2303
2240
|
const {
|
|
2304
2241
|
name,
|
|
2305
|
-
initialValue,
|
|
2306
2242
|
isDisabled,
|
|
2243
|
+
editableProps = {},
|
|
2244
|
+
fieldProps = {},
|
|
2245
|
+
inputProps = {},
|
|
2246
|
+
options = [],
|
|
2307
2247
|
classNameGroupItem,
|
|
2308
|
-
emptyMessage,
|
|
2309
|
-
emptyMessageTextColor,
|
|
2310
|
-
emptyMessageTextSize,
|
|
2311
|
-
fieldProps,
|
|
2312
|
-
inputProps,
|
|
2313
|
-
options,
|
|
2314
2248
|
showMessage,
|
|
2315
2249
|
isRequired,
|
|
2316
2250
|
onChange
|
|
2317
2251
|
} = props;
|
|
2318
|
-
const {
|
|
2319
|
-
change
|
|
2320
|
-
} = useForm();
|
|
2321
|
-
|
|
2322
|
-
// Callback for value changes
|
|
2323
|
-
const onChangeSomeInput = useCallback((inputValue, newOptionValue) => {
|
|
2324
|
-
const updatedValues = inputValue.includes(newOptionValue) ? inputValue.filter(selectedValue => selectedValue !== newOptionValue) : [...inputValue, newOptionValue];
|
|
2325
|
-
change(name, updatedValues);
|
|
2326
|
-
onChange && onChange(updatedValues);
|
|
2327
|
-
}, [change, name, onChange]);
|
|
2328
|
-
useEffect(() => {
|
|
2329
|
-
initialValue && change(name, initialValue);
|
|
2330
|
-
// update the form value only when the initialValue changes, so use disable eslint to ignore the warning
|
|
2331
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2332
|
-
}, [initialValue]);
|
|
2333
2252
|
return /*#__PURE__*/React$1.createElement(Field, {
|
|
2334
|
-
name: name
|
|
2335
|
-
initialValue: initialValue
|
|
2253
|
+
name: name
|
|
2336
2254
|
}, function Render({
|
|
2337
2255
|
input,
|
|
2338
2256
|
meta
|
|
2339
2257
|
}) {
|
|
2258
|
+
/** Note:
|
|
2259
|
+
* Create "Render" function by "eslint-react-hooks/rules-of-hooks":
|
|
2260
|
+
* React Hooks cannot be called inside a callback.
|
|
2261
|
+
* React Hooks must be called in a React function component or a
|
|
2262
|
+
* custom React Hook function.
|
|
2263
|
+
*/
|
|
2264
|
+
|
|
2340
2265
|
const {
|
|
2341
2266
|
errorKey,
|
|
2342
2267
|
errorMessage,
|
|
@@ -2351,49 +2276,30 @@ function ChipsField(props) {
|
|
|
2351
2276
|
inputProps: inputProps,
|
|
2352
2277
|
validationStateKey: isErrorState ? errorKey : 'success'
|
|
2353
2278
|
});
|
|
2354
|
-
const activeOptionsList = useMemo(() => {
|
|
2355
|
-
const emptyOptionsList = [{
|
|
2356
|
-
label: null,
|
|
2357
|
-
value: null
|
|
2358
|
-
}];
|
|
2359
|
-
if (input?.value) {
|
|
2360
|
-
const currentOptions = options.filter(option => input.value?.includes(option.value));
|
|
2361
|
-
return currentOptions || emptyOptionsList;
|
|
2362
|
-
}
|
|
2363
|
-
return emptyOptionsList;
|
|
2364
|
-
}, [input.value]);
|
|
2365
2279
|
return /*#__PURE__*/React$1.createElement(FieldWrapper, Object.assign({
|
|
2366
|
-
className: clsx('form-
|
|
2280
|
+
className: clsx('form-field_type_radio', 'form__item_type_radio"', classNameGroupItem),
|
|
2367
2281
|
errorKey: errorKey,
|
|
2368
2282
|
errorMessage: errorMessage,
|
|
2369
2283
|
isErrorState: isErrorState,
|
|
2370
2284
|
metaError: meta.error,
|
|
2371
2285
|
isDisabled: isDisabled,
|
|
2372
|
-
fieldClassName:
|
|
2286
|
+
fieldClassName: 'form-radio',
|
|
2373
2287
|
inputName: input.name,
|
|
2374
|
-
inputValue: input.value,
|
|
2288
|
+
inputValue: input.value || '',
|
|
2375
2289
|
metaActive: meta.active,
|
|
2376
2290
|
showMessage: showMessage,
|
|
2377
2291
|
isRequired: isRequired,
|
|
2378
2292
|
isValidState: isValidState
|
|
2379
|
-
}, fieldProps),
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
isDisabled: option.isDisabled,
|
|
2388
|
-
value: option.value,
|
|
2389
|
-
isActive: activeOptionsList.some(activeOption => activeOption.value === option.value),
|
|
2390
|
-
onClick: () => onChangeSomeInput(input.value, option.value)
|
|
2391
|
-
}, updatedInputProps)))) : /*#__PURE__*/React$1.createElement(Text, {
|
|
2392
|
-
size: emptyMessageTextSize,
|
|
2393
|
-
textColor: emptyMessageTextColor
|
|
2394
|
-
}, emptyMessage));
|
|
2293
|
+
}, fieldProps), /*#__PURE__*/React$1.createElement(RadioGroupList, {
|
|
2294
|
+
isDisabled: isDisabled,
|
|
2295
|
+
editableProps: editableProps,
|
|
2296
|
+
input: input,
|
|
2297
|
+
inputProps: updatedInputProps,
|
|
2298
|
+
options: options,
|
|
2299
|
+
onChange: onChange
|
|
2300
|
+
}));
|
|
2395
2301
|
});
|
|
2396
|
-
}
|
|
2302
|
+
});
|
|
2397
2303
|
|
|
2398
2304
|
const formTypes = {
|
|
2399
2305
|
code: 'code',
|
|
@@ -2417,43 +2323,43 @@ function generateField(field, config, props) {
|
|
|
2417
2323
|
switch (field.type) {
|
|
2418
2324
|
case formTypes.checkbox:
|
|
2419
2325
|
{
|
|
2420
|
-
return /*#__PURE__*/React$1.createElement(
|
|
2326
|
+
return /*#__PURE__*/React$1.createElement(FormFieldCheckbox, Object.assign({
|
|
2421
2327
|
key: config.key
|
|
2422
2328
|
}, field, props));
|
|
2423
2329
|
}
|
|
2424
2330
|
case formTypes.choice:
|
|
2425
2331
|
{
|
|
2426
|
-
return /*#__PURE__*/React$1.createElement(
|
|
2332
|
+
return /*#__PURE__*/React$1.createElement(FormFieldChoice, Object.assign({
|
|
2427
2333
|
key: config.key
|
|
2428
2334
|
}, field, props));
|
|
2429
2335
|
}
|
|
2430
2336
|
case formTypes.chips:
|
|
2431
2337
|
{
|
|
2432
|
-
return /*#__PURE__*/React$1.createElement(
|
|
2338
|
+
return /*#__PURE__*/React$1.createElement(FormFieldChips, Object.assign({
|
|
2433
2339
|
key: config.key
|
|
2434
2340
|
}, field, props));
|
|
2435
2341
|
}
|
|
2436
2342
|
case formTypes.code:
|
|
2437
2343
|
{
|
|
2438
|
-
return /*#__PURE__*/React$1.createElement(
|
|
2344
|
+
return /*#__PURE__*/React$1.createElement(FormFieldCode, Object.assign({
|
|
2439
2345
|
key: config.key
|
|
2440
2346
|
}, field, props));
|
|
2441
2347
|
}
|
|
2442
2348
|
case formTypes.switch:
|
|
2443
2349
|
{
|
|
2444
|
-
return /*#__PURE__*/React$1.createElement(
|
|
2350
|
+
return /*#__PURE__*/React$1.createElement(FormFieldSwitch, Object.assign({
|
|
2445
2351
|
key: config.key
|
|
2446
2352
|
}, field, props));
|
|
2447
2353
|
}
|
|
2448
2354
|
case formTypes.segmented:
|
|
2449
2355
|
{
|
|
2450
|
-
return /*#__PURE__*/React$1.createElement(
|
|
2356
|
+
return /*#__PURE__*/React$1.createElement(FormFieldSegmented, Object.assign({
|
|
2451
2357
|
key: config.key
|
|
2452
2358
|
}, field, props));
|
|
2453
2359
|
}
|
|
2454
2360
|
case formTypes.datePicker:
|
|
2455
2361
|
{
|
|
2456
|
-
return /*#__PURE__*/React$1.createElement(
|
|
2362
|
+
return /*#__PURE__*/React$1.createElement(FormFieldDatePicker, Object.assign({
|
|
2457
2363
|
key: config.key
|
|
2458
2364
|
}, field, props));
|
|
2459
2365
|
}
|
|
@@ -2471,37 +2377,37 @@ function generateField(field, config, props) {
|
|
|
2471
2377
|
}
|
|
2472
2378
|
case formTypes.select:
|
|
2473
2379
|
{
|
|
2474
|
-
return /*#__PURE__*/React$1.createElement(
|
|
2380
|
+
return /*#__PURE__*/React$1.createElement(FormFieldSelect, Object.assign({
|
|
2475
2381
|
key: config.key
|
|
2476
2382
|
}, field, props));
|
|
2477
2383
|
}
|
|
2478
2384
|
case formTypes.text:
|
|
2479
2385
|
{
|
|
2480
|
-
return /*#__PURE__*/React$1.createElement(
|
|
2386
|
+
return /*#__PURE__*/React$1.createElement(FormFieldInput, Object.assign({
|
|
2481
2387
|
key: config.key
|
|
2482
2388
|
}, field, props));
|
|
2483
2389
|
}
|
|
2484
2390
|
case formTypes.textarea:
|
|
2485
2391
|
{
|
|
2486
|
-
return /*#__PURE__*/React$1.createElement(
|
|
2392
|
+
return /*#__PURE__*/React$1.createElement(FormFieldTextarea, Object.assign({
|
|
2487
2393
|
key: config.key
|
|
2488
2394
|
}, field, props));
|
|
2489
2395
|
}
|
|
2490
2396
|
case formTypes.maskedInput:
|
|
2491
2397
|
{
|
|
2492
|
-
return /*#__PURE__*/React$1.createElement(
|
|
2398
|
+
return /*#__PURE__*/React$1.createElement(FormFieldMaskedInput, Object.assign({
|
|
2493
2399
|
key: config.key
|
|
2494
2400
|
}, field, props));
|
|
2495
2401
|
}
|
|
2496
2402
|
case formTypes.custom:
|
|
2497
2403
|
{
|
|
2498
|
-
return /*#__PURE__*/React$1.createElement(
|
|
2404
|
+
return /*#__PURE__*/React$1.createElement(FormFieldCustom, Object.assign({
|
|
2499
2405
|
key: config.key
|
|
2500
2406
|
}, field, props));
|
|
2501
2407
|
}
|
|
2502
2408
|
case formTypes.group:
|
|
2503
2409
|
{
|
|
2504
|
-
return /*#__PURE__*/React$1.createElement(
|
|
2410
|
+
return /*#__PURE__*/React$1.createElement(FormBlockGroup, Object.assign({
|
|
2505
2411
|
key: config.key
|
|
2506
2412
|
}, field, props), Object.entries(field.group).map(([key, value]) => {
|
|
2507
2413
|
const groupProps = {
|
|
@@ -2781,7 +2687,7 @@ const FinalForm = /*#__PURE__*/React$1.forwardRef(function FinalForm(props, ref)
|
|
|
2781
2687
|
values: true
|
|
2782
2688
|
},
|
|
2783
2689
|
onChange: onChangeFormValues
|
|
2784
|
-
}), Boolean(Object.keys(config).length) && /*#__PURE__*/React$1.createElement(React$1.Fragment, null, renderFieldsWrapper(/*#__PURE__*/React$1.createElement(Group
|
|
2690
|
+
}), Boolean(Object.keys(config).length) && /*#__PURE__*/React$1.createElement(React$1.Fragment, null, renderFieldsWrapper(/*#__PURE__*/React$1.createElement(Group, {
|
|
2785
2691
|
className: "form__wrapper",
|
|
2786
2692
|
direction: "vertical",
|
|
2787
2693
|
gap: fieldsGap || groupGap,
|
|
@@ -2797,7 +2703,7 @@ const FinalForm = /*#__PURE__*/React$1.forwardRef(function FinalForm(props, ref)
|
|
|
2797
2703
|
text: loaderText,
|
|
2798
2704
|
itemFill: loaderItemFill,
|
|
2799
2705
|
shape: loaderShape
|
|
2800
|
-
}))))), (primaryButtonLabel || primaryButton || secondaryButtonLabel || secondaryButton || tertiaryButton || tertiaryButtonLabel) && /*#__PURE__*/React$1.createElement(Group
|
|
2706
|
+
}))))), (primaryButtonLabel || primaryButton || secondaryButtonLabel || secondaryButton || tertiaryButton || tertiaryButtonLabel) && /*#__PURE__*/React$1.createElement(Group, {
|
|
2801
2707
|
className: "form__button",
|
|
2802
2708
|
direction: buttonDirection,
|
|
2803
2709
|
justifyContent: buttonJustifyContent,
|
|
@@ -3078,4 +2984,4 @@ const getErrorsForFinalForm = error => {
|
|
|
3078
2984
|
return formErrors;
|
|
3079
2985
|
};
|
|
3080
2986
|
|
|
3081
|
-
export {
|
|
2987
|
+
export { DEFAULT_MESSAGES_FIELDS, FieldWrapper, FieldWrapperBase, FileInput, FinalForm, FormBlockGroup, FormFieldCheckbox, FormFieldChips, FormFieldChoice, FormFieldCode, FormFieldCustom, FormFieldDatePicker, FormFieldInput, FormFieldMaskedInput, FormFieldSegmented, FormFieldSelect, FormFieldSwitch, FormFieldTextarea, RadioGroup, addRequiredFieldsParamToSchema, dateValidation, defaultCheckboxProps, defaultChipsProps, defaultChoiceProps, defaultCodeProps, defaultDatepickerProps, defaultDropzoneProps, defaultFieldProps, defaultFieldSizeM, defaultFieldSizeXL, defaultGroupProps, defaultInputProps, defaultRadioProps, defaultSegmentedProps, defaultSelectProps, defaultSwitchProps, defaultTextareaProps, emailValidation, focusOnError, focusOnErrorDecorator, formTypes, generateField, getErrorsForFinalForm, parseNumericField, phoneValidation, sendFormDataToServer, setErrorsMutator, useYupValidationSchema };
|