@itcase/forms 1.1.9 → 1.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/css/form/Field/FileInput/FileInput.css +5 -0
- package/package.json +21 -17
- package/dist/itcase-forms.cjs.js +0 -3113
- package/dist/itcase-forms.esm.js +0 -3046
package/dist/itcase-forms.esm.js
DELETED
|
@@ -1,3046 +0,0 @@
|
|
|
1
|
-
import { isPossiblePhoneNumber } from 'libphonenumber-js';
|
|
2
|
-
import React$1, { useMemo, useEffect, useCallback, useState } from 'react';
|
|
3
|
-
import { setIn, FORM_ERROR, getIn } from 'final-form';
|
|
4
|
-
import { useForm, Field, Form, FormSpy } from 'react-final-form';
|
|
5
|
-
export { Field, useForm, useFormState } from 'react-final-form';
|
|
6
|
-
import clsx from 'clsx';
|
|
7
|
-
import { Checkbox } from '@itcase/ui/components/Checkbox';
|
|
8
|
-
import { Divider } from '@itcase/ui/components/Divider';
|
|
9
|
-
import { Text } from '@itcase/ui/components/Text';
|
|
10
|
-
import { useDeviceTargetClass } from '@itcase/ui/hooks/useDeviceTargetClass';
|
|
11
|
-
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
|
-
import axios from 'axios';
|
|
20
|
-
import { fromEvent } from 'file-selector';
|
|
21
|
-
import castArray from 'lodash/castArray';
|
|
22
|
-
import { useDropzone, ErrorCode } from 'react-dropzone';
|
|
23
|
-
import { createFileFromDataURL } from '@itcase/common';
|
|
24
|
-
import { Loader } from '@itcase/ui/components/Loader';
|
|
25
|
-
import { Title } from '@itcase/ui/components/Title';
|
|
26
|
-
import { Input } from '@itcase/ui/components/Input';
|
|
27
|
-
import { Radio } from '@itcase/ui/components/Radio';
|
|
28
|
-
import { Segmented } from '@itcase/ui/components/Segmented';
|
|
29
|
-
import { Select } from '@itcase/ui/components/Select';
|
|
30
|
-
import { Switch } from '@itcase/ui/components/Switch';
|
|
31
|
-
import { Textarea } from '@itcase/ui/components/Textarea';
|
|
32
|
-
import { useIMask } from 'react-imask';
|
|
33
|
-
import { Chips } from '@itcase/ui/components/Chips';
|
|
34
|
-
import { Button } from '@itcase/ui/components/Button';
|
|
35
|
-
import { Group as Group$1 } from '@itcase/ui/components/Group';
|
|
36
|
-
import { NotificationItem } from '@itcase/ui/components/Notification';
|
|
37
|
-
import createDecorator from 'final-form-focus';
|
|
38
|
-
|
|
39
|
-
const phoneValidation = value => {
|
|
40
|
-
if (!value) {
|
|
41
|
-
return true;
|
|
42
|
-
}
|
|
43
|
-
return isPossiblePhoneNumber(value, 'RU');
|
|
44
|
-
};
|
|
45
|
-
const emailValidation = value => {
|
|
46
|
-
// from https://emailregex.com/
|
|
47
|
-
if (!value) {
|
|
48
|
-
return true;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// from https://www.regular-expressions.info/email.html
|
|
52
|
-
const regexp = /^[a-za-яёЁ0-9_-]+(?:\.[a-za-яёЁ0-9_-]+)*@(?:[a-za-яёЁ0-9](?:[a-za-яёЁ0-9-]*[a-za-яёЁ0-9])?\.)+[a-za-яёЁ0-9]+$/;
|
|
53
|
-
return regexp.test(String(value).toLowerCase());
|
|
54
|
-
};
|
|
55
|
-
const dateValidation = value => {
|
|
56
|
-
const valueDate = value instanceof Date ? value : new Date(value);
|
|
57
|
-
const isDateValid = !isNaN(valueDate.getTime());
|
|
58
|
-
return isDateValid;
|
|
59
|
-
};
|
|
60
|
-
const addRequiredFieldsParamToSchema = schema => {
|
|
61
|
-
const fields = Object.entries(schema.fields);
|
|
62
|
-
schema.requiredFields = fields.reduce((list, [fieldName, validationProps]) => {
|
|
63
|
-
if (validationProps.exclusiveTests?.required) {
|
|
64
|
-
list.push(fieldName);
|
|
65
|
-
}
|
|
66
|
-
return list;
|
|
67
|
-
}, []);
|
|
68
|
-
return schema;
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Sets the `innerError.message` in an `errors` object at the key
|
|
73
|
-
* defined by `innerError.path`.
|
|
74
|
-
* @param {Object} errors The object to set the error in.
|
|
75
|
-
* @param {{ path: string, message: string }} innerError A `yup` field error.
|
|
76
|
-
* @returns {Object} The result of setting the new error message onto `errors`.
|
|
77
|
-
*/
|
|
78
|
-
const setInError = (errors, innerError) => {
|
|
79
|
-
return setIn(errors, innerError.path, innerError.message);
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Empty object map with no prototype. Used as default
|
|
84
|
-
* value for reducing the `err.inner` array of errors
|
|
85
|
-
* from a `yup~ValidationError`.
|
|
86
|
-
*/
|
|
87
|
-
const emptyObj = Object.create(null);
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Takes a `yup` validation schema and returns a function that expects
|
|
91
|
-
* a map of values to validate. If the validation passes, the function resolves to `undefined`
|
|
92
|
-
* (signalling that the values are valid). If the validation doesn't pass, it resolves
|
|
93
|
-
* to a map of invalid field names to errors.
|
|
94
|
-
* @param {import('yup').ObjectSchema} schema `yup` schema definition.
|
|
95
|
-
* @returns {(values: Object) => Promise<?Object>} An async function that expects some `values`
|
|
96
|
-
* and resolves to either `undefined` or a map of field names to error messages.
|
|
97
|
-
*/
|
|
98
|
-
|
|
99
|
-
const makeValidate = schema => {
|
|
100
|
-
return async function validate(values) {
|
|
101
|
-
try {
|
|
102
|
-
await schema.validate(values, {
|
|
103
|
-
abortEarly: false
|
|
104
|
-
});
|
|
105
|
-
} catch (error) {
|
|
106
|
-
if (error.inner) {
|
|
107
|
-
return error.inner.reduce(setInError, emptyObj);
|
|
108
|
-
} else {
|
|
109
|
-
console.warn('itcase-forms schema.validate error: An error not related to the form occurred during validation. Validation ignored.');
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
};
|
|
114
|
-
function useYupValidationSchema(schema, language) {
|
|
115
|
-
const validate = useMemo(() => schema && makeValidate(schema), [schema, language]);
|
|
116
|
-
return validate;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const defaultFieldProps = {
|
|
120
|
-
width: 'fill',
|
|
121
|
-
direction: 'vertical',
|
|
122
|
-
labelTextColor: 'surfaceTextPrimary',
|
|
123
|
-
labelTextSize: 'm',
|
|
124
|
-
errorMessageTextColor: 'errorTextSecondary',
|
|
125
|
-
errorMessageTextSize: 's',
|
|
126
|
-
dividerFill: 'errorPrimary',
|
|
127
|
-
helpTextColor: 'surfaceTextQuaternary',
|
|
128
|
-
helpTextSize: 's',
|
|
129
|
-
messageTextColor: 'surfaceTextSecondary',
|
|
130
|
-
messageTextSize: 's',
|
|
131
|
-
requiredMessageTextColor: 'warningTextSecondary',
|
|
132
|
-
requiredMessageTextSize: 's',
|
|
133
|
-
showMessage: true
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
function FieldWrapperBase(props) {
|
|
137
|
-
const {
|
|
138
|
-
id,
|
|
139
|
-
className,
|
|
140
|
-
type = 'normal',
|
|
141
|
-
label,
|
|
142
|
-
labelHidden,
|
|
143
|
-
labelTextColor,
|
|
144
|
-
labelTextSize,
|
|
145
|
-
labelTextSizeMobile,
|
|
146
|
-
labelTextSizeTablet,
|
|
147
|
-
labelTextWeight,
|
|
148
|
-
desc,
|
|
149
|
-
descTextColor,
|
|
150
|
-
descTextSize,
|
|
151
|
-
descTextWeight,
|
|
152
|
-
errorKey,
|
|
153
|
-
errorMessage,
|
|
154
|
-
isErrorState,
|
|
155
|
-
metaError,
|
|
156
|
-
helpTextColorSuccess,
|
|
157
|
-
isDisabled,
|
|
158
|
-
afterItem,
|
|
159
|
-
beforeItem,
|
|
160
|
-
dataTour,
|
|
161
|
-
dividerDirection,
|
|
162
|
-
dividerFill,
|
|
163
|
-
dividerSize,
|
|
164
|
-
dividerWidth,
|
|
165
|
-
fieldClassName,
|
|
166
|
-
helpText,
|
|
167
|
-
helpTextColor,
|
|
168
|
-
helpTextSize,
|
|
169
|
-
helpTextSizeMobile,
|
|
170
|
-
helpTextWeight,
|
|
171
|
-
inputName,
|
|
172
|
-
inputValue,
|
|
173
|
-
messageTextSize,
|
|
174
|
-
metaActive,
|
|
175
|
-
showDivider,
|
|
176
|
-
showMessage,
|
|
177
|
-
tag: Tag = 'div',
|
|
178
|
-
before,
|
|
179
|
-
after,
|
|
180
|
-
isHidden,
|
|
181
|
-
isRequired,
|
|
182
|
-
isValidState,
|
|
183
|
-
children
|
|
184
|
-
} = props;
|
|
185
|
-
const formFieldClass = useMemo(() => clsx(className, isValidState && 'form__item_state_success', isRequired && 'form__item_state_required', isDisabled && 'form__item_state_disabled', metaActive && 'form__item_state_focus', inputValue && 'form__item_state_filled', isErrorState && `form__item_state_${errorKey}`), [className, isErrorState, isValidState, isRequired, metaActive, inputValue, isDisabled, metaError]);
|
|
186
|
-
const fieldClass = useMemo(() => clsx(fieldClassName, isValidState && `${fieldClassName}_state_success`, metaActive && `${fieldClassName}_state_focus`, inputValue && `${fieldClassName}_state_filled`, isDisabled && `${fieldClassName}_state_disabled`, isErrorState && `${fieldClassName}_state_${errorKey}`), [fieldClassName, isErrorState, isValidState, metaActive, inputValue, isDisabled, metaError]);
|
|
187
|
-
const sizeClass = useDeviceTargetClass(props, {
|
|
188
|
-
prefix: 'form-field_size_',
|
|
189
|
-
propsKey: 'size'
|
|
190
|
-
});
|
|
191
|
-
const fillClass = useDeviceTargetClass(props, {
|
|
192
|
-
prefix: 'fill_',
|
|
193
|
-
propsKey: 'fill'
|
|
194
|
-
});
|
|
195
|
-
const inputFillClass = useDeviceTargetClass(props, {
|
|
196
|
-
prefix: 'fill_',
|
|
197
|
-
propsKey: 'inputFill'
|
|
198
|
-
});
|
|
199
|
-
const shapeClass = useDeviceTargetClass(props, {
|
|
200
|
-
prefix: 'form-field_shape_',
|
|
201
|
-
propsKey: 'shape'
|
|
202
|
-
});
|
|
203
|
-
const inputShapeClass = useDeviceTargetClass(props, {
|
|
204
|
-
prefix: 'form-field__item-value_shape_',
|
|
205
|
-
propsKey: 'inputShape'
|
|
206
|
-
});
|
|
207
|
-
const directionClass = useDeviceTargetClass(props, {
|
|
208
|
-
prefix: 'direction_',
|
|
209
|
-
propsKey: 'direction'
|
|
210
|
-
});
|
|
211
|
-
const widthClass = useDeviceTargetClass(props, {
|
|
212
|
-
prefix: 'width_',
|
|
213
|
-
propsKey: 'width'
|
|
214
|
-
});
|
|
215
|
-
const {
|
|
216
|
-
styles: formFieldStyles
|
|
217
|
-
} = useStyles(props);
|
|
218
|
-
const errorTextSize = props[`${errorKey}MessageTextSize`];
|
|
219
|
-
const errorTextColor = props[`${errorKey}MessageTextColor`];
|
|
220
|
-
const errorTextWeight = props[`${errorKey}MessageTextWeight`];
|
|
221
|
-
return /*#__PURE__*/React$1.createElement(Tag, {
|
|
222
|
-
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),
|
|
223
|
-
"data-test-id": `${inputName}Field`,
|
|
224
|
-
"data-tour": dataTour,
|
|
225
|
-
style: formFieldStyles
|
|
226
|
-
}, before, (label || labelHidden) && /*#__PURE__*/React$1.createElement("div", {
|
|
227
|
-
className: clsx('form-field__label'),
|
|
228
|
-
"data-test-id": `${inputName}FieldLabel`,
|
|
229
|
-
htmlFor: id
|
|
230
|
-
}, /*#__PURE__*/React$1.createElement(Text, {
|
|
231
|
-
size: labelTextSize,
|
|
232
|
-
textColor: labelTextColor,
|
|
233
|
-
textWeight: labelTextWeight,
|
|
234
|
-
sizeMobile: labelTextSizeMobile,
|
|
235
|
-
sizeTablet: labelTextSizeTablet
|
|
236
|
-
}, label, labelHidden && '\u00A0')), desc && /*#__PURE__*/React$1.createElement("div", {
|
|
237
|
-
className: "form-field__desc",
|
|
238
|
-
"data-test-id": `${inputName}FieldDesc`
|
|
239
|
-
}, /*#__PURE__*/React$1.createElement(Text, {
|
|
240
|
-
size: descTextSize,
|
|
241
|
-
textColor: descTextColor,
|
|
242
|
-
textWeight: descTextWeight
|
|
243
|
-
}, desc)), /*#__PURE__*/React$1.createElement("div", {
|
|
244
|
-
className: clsx('form-field__content', inputFillClass, inputShapeClass)
|
|
245
|
-
}, /*#__PURE__*/React$1.createElement("div", {
|
|
246
|
-
className: clsx('form-field__content-inner', fieldClass)
|
|
247
|
-
}, beforeItem, children, afterItem), showDivider && /*#__PURE__*/React$1.createElement(Divider, {
|
|
248
|
-
className: "form-field__item-divider",
|
|
249
|
-
width: dividerWidth,
|
|
250
|
-
direction: dividerDirection,
|
|
251
|
-
size: dividerSize,
|
|
252
|
-
fill: dividerFill
|
|
253
|
-
})), showMessage && /*#__PURE__*/React$1.createElement("div", {
|
|
254
|
-
className: "form-field__message",
|
|
255
|
-
"data-test-id": `${inputName}FieldMessage`
|
|
256
|
-
}, isErrorState && errorMessage && /*#__PURE__*/React$1.createElement(Text, {
|
|
257
|
-
id: `${inputName}-error`,
|
|
258
|
-
className: "form-field__message-item form-field__message-item_type-error",
|
|
259
|
-
size: errorTextSize,
|
|
260
|
-
textColor: errorTextColor,
|
|
261
|
-
textWeight: errorTextWeight,
|
|
262
|
-
dataTestId: `${inputName}FieldMessageError`
|
|
263
|
-
}, errorMessage), Boolean(helpText) && (!isErrorState || !errorMessage) && /*#__PURE__*/React$1.createElement(Text, {
|
|
264
|
-
className: "form-field__message-item form-field__message-item_type_help-text",
|
|
265
|
-
size: helpTextSize,
|
|
266
|
-
textColor: isValidState ? helpTextColorSuccess : helpTextColor,
|
|
267
|
-
textWeight: helpTextWeight,
|
|
268
|
-
dataTestId: `${inputName}FieldMessageHelpText`,
|
|
269
|
-
sizeMobile: helpTextSizeMobile
|
|
270
|
-
}, helpText), (!isErrorState && !helpText || isErrorState && !helpText && !errorMessage) && /*#__PURE__*/React$1.createElement(Text, {
|
|
271
|
-
className: "form-field__message-item form-field__message-item_type_help-text",
|
|
272
|
-
size: messageTextSize,
|
|
273
|
-
dataTestId: `${inputName}FieldMessageHelpText`
|
|
274
|
-
}, '\u00A0')), after);
|
|
275
|
-
}
|
|
276
|
-
function FieldWrapper(props) {
|
|
277
|
-
const {
|
|
278
|
-
inputName
|
|
279
|
-
} = props;
|
|
280
|
-
const {
|
|
281
|
-
change
|
|
282
|
-
} = useForm(); // , mutators
|
|
283
|
-
|
|
284
|
-
useEffect(() => {
|
|
285
|
-
return () => {
|
|
286
|
-
change(inputName, undefined);
|
|
287
|
-
};
|
|
288
|
-
}, []);
|
|
289
|
-
return /*#__PURE__*/React$1.createElement(FieldWrapperBase, props);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
// Whether to display an error message based on "fieldProps" and meta-objects
|
|
293
|
-
function useFieldValidationState(props) {
|
|
294
|
-
const {
|
|
295
|
-
fieldProps = {},
|
|
296
|
-
meta = {},
|
|
297
|
-
input = {}
|
|
298
|
-
} = props;
|
|
299
|
-
// Determines if there's a submission error that hasn't been rectified since the last submission.
|
|
300
|
-
const submitError = !meta.modifiedSinceLastSubmit && meta.submitError;
|
|
301
|
-
|
|
302
|
-
// Determines a key for the error, defaulting to 'error' if no specific key is found.
|
|
303
|
-
const errorKey = meta.error?.key || 'error';
|
|
304
|
-
const successKey = 'success';
|
|
305
|
-
|
|
306
|
-
// Determines if the field is in an error state based on various conditions.
|
|
307
|
-
const isErrorState = useMemo(() => {
|
|
308
|
-
if (fieldProps.showErrorsOnSubmit) {
|
|
309
|
-
return Boolean(meta.submitFailed && meta.touched && (meta.error || submitError));
|
|
310
|
-
} else {
|
|
311
|
-
return Boolean(meta.touched && (meta.error || submitError));
|
|
312
|
-
}
|
|
313
|
-
}, [fieldProps.showErrorsOnSubmit, meta.submitFailed, meta.touched, meta.error, submitError]);
|
|
314
|
-
|
|
315
|
-
// Determines if the field's input state is valid
|
|
316
|
-
const isValidState = useMemo(() => {
|
|
317
|
-
const hasValue = Array.isArray(input?.value) ? input?.value.length : input?.value;
|
|
318
|
-
const isModifiedAfterSubmit = meta.modifiedSinceLastSubmit && !meta.error && submitError;
|
|
319
|
-
return Boolean(hasValue && (meta.valid || isModifiedAfterSubmit));
|
|
320
|
-
}, [input?.value, meta.valid, meta.error, submitError, meta.modifiedSinceLastSubmit]);
|
|
321
|
-
const errorMessage = useMemo(() => {
|
|
322
|
-
// If final-form field has error in "meta" render-property.
|
|
323
|
-
// If field not modified after last form submit - use submit error
|
|
324
|
-
const error = meta.error || submitError || false;
|
|
325
|
-
if (error) {
|
|
326
|
-
// And error in "meta" is string
|
|
327
|
-
if (typeof error === 'string') {
|
|
328
|
-
// Return error as message
|
|
329
|
-
return error;
|
|
330
|
-
}
|
|
331
|
-
// Or if error in "meta" has "message" property(is object of error)
|
|
332
|
-
if (error.message) {
|
|
333
|
-
// Return message from error
|
|
334
|
-
return error.message;
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
// Field doesn't have error message
|
|
339
|
-
return '';
|
|
340
|
-
}, [meta.error, submitError]);
|
|
341
|
-
return {
|
|
342
|
-
errorKey,
|
|
343
|
-
successKey,
|
|
344
|
-
isErrorState,
|
|
345
|
-
isValidState,
|
|
346
|
-
errorMessage
|
|
347
|
-
};
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
// This hook changes the props of the child component depending on the type of error,
|
|
351
|
-
// looks at what props were in initialProps, if they are there then changes
|
|
352
|
-
function useValidationAppearanceInputProps(props) {
|
|
353
|
-
const {
|
|
354
|
-
validationStateKey,
|
|
355
|
-
inputProps
|
|
356
|
-
} = props;
|
|
357
|
-
|
|
358
|
-
// TODO: need to add props that can change during errors in this field
|
|
359
|
-
const validationAppearanceInputProps = useMemo(() => {
|
|
360
|
-
// const resultAppearanceProps = {
|
|
361
|
-
// messageTextColor: props.errorMessageTextColor,
|
|
362
|
-
// messageTextSize: props.errorMessageTextSize,
|
|
363
|
-
// messageTextWeight: props.errorMessageTextWeight,
|
|
364
|
-
// // Override appearance(styled) props for child input
|
|
365
|
-
// inputProps: {},
|
|
366
|
-
// }
|
|
367
|
-
const updatedInputProps = {};
|
|
368
|
-
if (validationStateKey) {
|
|
369
|
-
Object.entries(inputProps).forEach(([propKey, propValue]) => {
|
|
370
|
-
// Convert the input property key to "snake_case" format.
|
|
371
|
-
// e.g. "requiredBorderColor" -> "required_border_color".
|
|
372
|
-
const propKeySnake = snakeCase(propKey);
|
|
373
|
-
// Check if this property is for appearance.
|
|
374
|
-
// Key maybe starts with: "error", "required", "success", etc from validation config.
|
|
375
|
-
const isPropForValidationState = propKeySnake.startsWith(`${validationStateKey}_`);
|
|
376
|
-
|
|
377
|
-
// If property is for appearance
|
|
378
|
-
if (isPropForValidationState) {
|
|
379
|
-
// Remove validation state part from begin of property key, to make clean appearance property.
|
|
380
|
-
// e.g. "required_border_color" -> "border_color".
|
|
381
|
-
const stateTargetKeySnake = propKeySnake.replace(`${validationStateKey}_`, '');
|
|
382
|
-
// Convert clean appearance property key to "camelCase" format.
|
|
383
|
-
// e.g. "border_color" -> "borderColor"
|
|
384
|
-
const stateTargetKey = camelCase(stateTargetKeySnake);
|
|
385
|
-
// And save the value with a new clean property key
|
|
386
|
-
updatedInputProps[stateTargetKey] = propValue;
|
|
387
|
-
// Else if not already added earlier
|
|
388
|
-
} else if (!updatedInputProps[propKey]) {
|
|
389
|
-
// Just save original property
|
|
390
|
-
updatedInputProps[propKey] = propValue;
|
|
391
|
-
}
|
|
392
|
-
});
|
|
393
|
-
}
|
|
394
|
-
return updatedInputProps;
|
|
395
|
-
}, [validationStateKey, inputProps]);
|
|
396
|
-
return validationAppearanceInputProps;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
const defaultCheckboxProps = {
|
|
400
|
-
appearance: 'defaultPrimary',
|
|
401
|
-
width: 'fill',
|
|
402
|
-
errorBorderColor: 'errorBorderSecondary',
|
|
403
|
-
requiredBorderColor: 'warningBorderSecondary'
|
|
404
|
-
};
|
|
405
|
-
|
|
406
|
-
const CheckboxField = /*#__PURE__*/React$1.memo(function CheckboxField(props) {
|
|
407
|
-
const {
|
|
408
|
-
name,
|
|
409
|
-
initialValue,
|
|
410
|
-
isDisabled,
|
|
411
|
-
classNameGroupItem,
|
|
412
|
-
fieldProps = {},
|
|
413
|
-
inputProps = {},
|
|
414
|
-
showMessage,
|
|
415
|
-
isRequired,
|
|
416
|
-
onChange
|
|
417
|
-
} = props;
|
|
418
|
-
return /*#__PURE__*/React$1.createElement(Field, {
|
|
419
|
-
type: "checkbox",
|
|
420
|
-
name: name,
|
|
421
|
-
initialValue: initialValue
|
|
422
|
-
}, function Render({
|
|
423
|
-
input,
|
|
424
|
-
meta
|
|
425
|
-
}) {
|
|
426
|
-
/** Note:
|
|
427
|
-
* Create "Render" function by "eslint-react-hooks/rules-of-hooks":
|
|
428
|
-
* React Hooks cannot be called inside a callback.
|
|
429
|
-
* React Hooks must be called in a React function component or a
|
|
430
|
-
* custom React Hook function.
|
|
431
|
-
*/
|
|
432
|
-
|
|
433
|
-
const onChangeField = useCallback(event => {
|
|
434
|
-
input.onChange(event);
|
|
435
|
-
if (onChange) {
|
|
436
|
-
onChange(event.target.checked, input.name);
|
|
437
|
-
}
|
|
438
|
-
}, [onChange, input.onChange]);
|
|
439
|
-
const {
|
|
440
|
-
errorKey,
|
|
441
|
-
errorMessage,
|
|
442
|
-
isErrorState,
|
|
443
|
-
isValidState
|
|
444
|
-
} = useFieldValidationState({
|
|
445
|
-
fieldProps: fieldProps,
|
|
446
|
-
input: input,
|
|
447
|
-
meta: meta
|
|
448
|
-
});
|
|
449
|
-
const updatedInputProps = useValidationAppearanceInputProps({
|
|
450
|
-
inputProps: inputProps,
|
|
451
|
-
validationStateKey: isErrorState ? errorKey : 'success'
|
|
452
|
-
});
|
|
453
|
-
return /*#__PURE__*/React$1.createElement(FieldWrapper, Object.assign({
|
|
454
|
-
className: clsx('form-field_type_checkbox', 'form__item_type_checkbox', classNameGroupItem),
|
|
455
|
-
errorKey: errorKey,
|
|
456
|
-
errorMessage: errorMessage,
|
|
457
|
-
isErrorState: isErrorState,
|
|
458
|
-
metaError: meta.error,
|
|
459
|
-
isDisabled: isDisabled,
|
|
460
|
-
fieldClassName: "form-checkbox",
|
|
461
|
-
inputName: input.name,
|
|
462
|
-
inputValue: input.checked,
|
|
463
|
-
metaActive: meta.active,
|
|
464
|
-
showMessage: showMessage,
|
|
465
|
-
tag: "label",
|
|
466
|
-
isRequired: isRequired,
|
|
467
|
-
isValidState: isValidState
|
|
468
|
-
}, fieldProps), /*#__PURE__*/React$1.createElement(Checkbox, Object.assign({
|
|
469
|
-
type: "checkbox",
|
|
470
|
-
name: input.name,
|
|
471
|
-
isDisabled: isDisabled,
|
|
472
|
-
autoComplete: "nope",
|
|
473
|
-
checked: input.checked,
|
|
474
|
-
onBlur: input.onBlur,
|
|
475
|
-
onChange: onChangeField,
|
|
476
|
-
onFocus: input.onFocus
|
|
477
|
-
}, updatedInputProps)));
|
|
478
|
-
});
|
|
479
|
-
});
|
|
480
|
-
|
|
481
|
-
const defaultChoiceProps = {
|
|
482
|
-
width: 'fill',
|
|
483
|
-
borderColor: 'surfaceBorderTertiary',
|
|
484
|
-
// error
|
|
485
|
-
errorBorderColor: 'errorBorderPrimary',
|
|
486
|
-
fill: 'surfaceSecondary',
|
|
487
|
-
fillActive: 'accentPrimary',
|
|
488
|
-
fillActiveDisabled: 'surfaceTertiary',
|
|
489
|
-
fillHover: 'surfacePrimaryHover',
|
|
490
|
-
indicatorFill: 'accentPrimary',
|
|
491
|
-
labelTextActiveColor: 'accentTextPrimary',
|
|
492
|
-
labelTextActiveColorDisabled: 'surfaceTextDisabled',
|
|
493
|
-
labelTextColor: 'surfaceTextPrimary',
|
|
494
|
-
labelTextColorDisabled: 'surfaceTextDisabled',
|
|
495
|
-
labelTextSize: 'm',
|
|
496
|
-
requiredBorderColor: 'warningBorderPrimary',
|
|
497
|
-
shape: 'rounded'
|
|
498
|
-
};
|
|
499
|
-
|
|
500
|
-
const ChoiceField = /*#__PURE__*/React$1.memo(function ChoiceField(props) {
|
|
501
|
-
const {
|
|
502
|
-
name,
|
|
503
|
-
initialValue,
|
|
504
|
-
label,
|
|
505
|
-
isDisabled,
|
|
506
|
-
classNameGroupItem,
|
|
507
|
-
fieldProps,
|
|
508
|
-
inputProps,
|
|
509
|
-
messageType,
|
|
510
|
-
options,
|
|
511
|
-
placeholder,
|
|
512
|
-
showMessage,
|
|
513
|
-
isCheckbox,
|
|
514
|
-
isRequired,
|
|
515
|
-
onChange
|
|
516
|
-
} = props;
|
|
517
|
-
const {
|
|
518
|
-
change
|
|
519
|
-
} = useForm();
|
|
520
|
-
const setActiveSegment = useCallback((option, isChecked) => {
|
|
521
|
-
change(name, isChecked && option.value);
|
|
522
|
-
if (onChange) {
|
|
523
|
-
onChange(option.value, name, isChecked);
|
|
524
|
-
}
|
|
525
|
-
}, [change, onChange]);
|
|
526
|
-
return /*#__PURE__*/React$1.createElement(Field, {
|
|
527
|
-
initialValue: initialValue,
|
|
528
|
-
name: name
|
|
529
|
-
}, function Render({
|
|
530
|
-
input,
|
|
531
|
-
meta
|
|
532
|
-
}) {
|
|
533
|
-
/** Note:
|
|
534
|
-
* Create "Render" function by "eslint-react-hooks/rules-of-hooks":
|
|
535
|
-
* React Hooks cannot be called inside a callback.
|
|
536
|
-
* React Hooks must be called in a React function component or a
|
|
537
|
-
* custom React Hook function.
|
|
538
|
-
*/
|
|
539
|
-
const activeOption = useMemo(() => {
|
|
540
|
-
const emptyOption = {
|
|
541
|
-
value: null,
|
|
542
|
-
label: null
|
|
543
|
-
};
|
|
544
|
-
if (input.value) {
|
|
545
|
-
const currentOption = options.find(option => option.value === input.value);
|
|
546
|
-
return currentOption || emptyOption;
|
|
547
|
-
}
|
|
548
|
-
return emptyOption;
|
|
549
|
-
}, [input.value]);
|
|
550
|
-
const {
|
|
551
|
-
isErrorState,
|
|
552
|
-
isValidState,
|
|
553
|
-
errorKey,
|
|
554
|
-
errorMessage
|
|
555
|
-
} = useFieldValidationState({
|
|
556
|
-
fieldProps: fieldProps,
|
|
557
|
-
input: input,
|
|
558
|
-
meta: meta
|
|
559
|
-
});
|
|
560
|
-
const updatedInputProps = useValidationAppearanceInputProps({
|
|
561
|
-
inputProps: inputProps,
|
|
562
|
-
validationStateKey: isErrorState ? errorKey : 'success'
|
|
563
|
-
});
|
|
564
|
-
return /*#__PURE__*/React$1.createElement(FieldWrapper, Object.assign({
|
|
565
|
-
className: clsx('form-field_type_choice', 'form__item_type_choice', classNameGroupItem),
|
|
566
|
-
label: label,
|
|
567
|
-
errorKey: errorKey,
|
|
568
|
-
errorMessage: errorMessage,
|
|
569
|
-
isErrorState: isErrorState,
|
|
570
|
-
metaError: meta.error,
|
|
571
|
-
isDisabled: isDisabled,
|
|
572
|
-
fieldClassName: "form-choice",
|
|
573
|
-
inputName: input.name,
|
|
574
|
-
inputValue: input.value || [],
|
|
575
|
-
messageType: messageType,
|
|
576
|
-
metaActive: meta.active,
|
|
577
|
-
showMessage: showMessage,
|
|
578
|
-
isRequired: isRequired,
|
|
579
|
-
isValidState: isValidState
|
|
580
|
-
}, fieldProps), /*#__PURE__*/React$1.createElement(Choice, Object.assign({
|
|
581
|
-
className: clsx(meta.active && 'form-choice_state_focus', meta.error && meta.touched && `form-choice_state_${errorKey}`),
|
|
582
|
-
name: input.name,
|
|
583
|
-
isDisabled: isDisabled,
|
|
584
|
-
active: activeOption,
|
|
585
|
-
inputValue: input.value || [],
|
|
586
|
-
options: options,
|
|
587
|
-
placeholder: placeholder,
|
|
588
|
-
isCheckbox: isCheckbox,
|
|
589
|
-
isRequired: isRequired,
|
|
590
|
-
setActiveSegment: setActiveSegment
|
|
591
|
-
}, updatedInputProps)));
|
|
592
|
-
});
|
|
593
|
-
});
|
|
594
|
-
|
|
595
|
-
const CustomField = /*#__PURE__*/React$1.memo(function CustomField(props) {
|
|
596
|
-
const {
|
|
597
|
-
Component,
|
|
598
|
-
isDisabled,
|
|
599
|
-
isRequired,
|
|
600
|
-
name,
|
|
601
|
-
initialValue,
|
|
602
|
-
fieldProps = {},
|
|
603
|
-
classNameGroupItem,
|
|
604
|
-
showMessage,
|
|
605
|
-
clearIcon,
|
|
606
|
-
clearIconFill,
|
|
607
|
-
clearIconFillHover,
|
|
608
|
-
clearIconShape,
|
|
609
|
-
clearIconSize,
|
|
610
|
-
onClickClearIcon
|
|
611
|
-
} = props;
|
|
612
|
-
return /*#__PURE__*/React$1.createElement(Field, {
|
|
613
|
-
initialValue: initialValue,
|
|
614
|
-
name: name
|
|
615
|
-
}, function Render({
|
|
616
|
-
input,
|
|
617
|
-
meta
|
|
618
|
-
}) {
|
|
619
|
-
/** Note:
|
|
620
|
-
* Create "Render" function by "eslint-react-hooks/rules-of-hooks":
|
|
621
|
-
* React Hooks cannot be called inside a callback.
|
|
622
|
-
* React Hooks must be called in a React function component or a
|
|
623
|
-
* custom React Hook function.
|
|
624
|
-
*/
|
|
625
|
-
|
|
626
|
-
const {
|
|
627
|
-
isErrorState,
|
|
628
|
-
isValidState,
|
|
629
|
-
errorKey,
|
|
630
|
-
errorMessage
|
|
631
|
-
} = useFieldValidationState({
|
|
632
|
-
fieldProps: fieldProps,
|
|
633
|
-
input: input,
|
|
634
|
-
meta: meta
|
|
635
|
-
});
|
|
636
|
-
const updatedInputProps = useValidationAppearanceInputProps({
|
|
637
|
-
validationStateKey: isErrorState ? errorKey : 'success',
|
|
638
|
-
// For "Custom" field we pass all props. Can contain some special props, we don't known.
|
|
639
|
-
inputProps: props
|
|
640
|
-
});
|
|
641
|
-
return /*#__PURE__*/React$1.createElement(FieldWrapper, Object.assign({
|
|
642
|
-
className: clsx('form-field_type_custom', 'form__item_type_custom', classNameGroupItem),
|
|
643
|
-
errorKey: errorKey,
|
|
644
|
-
errorMessage: errorMessage,
|
|
645
|
-
fieldClassName: 'form-custom',
|
|
646
|
-
inputName: input.name,
|
|
647
|
-
inputValue: input.value,
|
|
648
|
-
isDisabled: isDisabled,
|
|
649
|
-
isErrorState: isErrorState,
|
|
650
|
-
isRequired: isRequired,
|
|
651
|
-
isValidState: isValidState,
|
|
652
|
-
metaActive: meta.active,
|
|
653
|
-
metaError: meta.error,
|
|
654
|
-
showMessage: showMessage
|
|
655
|
-
}, fieldProps), /*#__PURE__*/React$1.createElement(Component, Object.assign({}, updatedInputProps, {
|
|
656
|
-
input: input,
|
|
657
|
-
isDisabled: isDisabled,
|
|
658
|
-
meta: meta
|
|
659
|
-
})), clearIcon && /*#__PURE__*/React$1.createElement(Icon, {
|
|
660
|
-
className: "form-field__icon",
|
|
661
|
-
iconFill: clearIconFill,
|
|
662
|
-
iconFillHover: clearIconFillHover,
|
|
663
|
-
imageSrc: clearIcon,
|
|
664
|
-
shape: clearIconShape,
|
|
665
|
-
size: clearIconSize,
|
|
666
|
-
SvgImage: clearIcon,
|
|
667
|
-
onClick: onClickClearIcon
|
|
668
|
-
}));
|
|
669
|
-
});
|
|
670
|
-
});
|
|
671
|
-
|
|
672
|
-
const defaultCodeProps = {
|
|
673
|
-
fieldProps: {
|
|
674
|
-
size: 'l',
|
|
675
|
-
labelTextColor: 'surfaceTextPrimary',
|
|
676
|
-
labelTextSize: 's',
|
|
677
|
-
labelTextWeight: 'normal',
|
|
678
|
-
helpText: 'Supporting text',
|
|
679
|
-
helpTextColor: 'surfaceTextPrimary',
|
|
680
|
-
helpTextSize: 's',
|
|
681
|
-
helpTextWeight: 'normal',
|
|
682
|
-
showMessage: true
|
|
683
|
-
},
|
|
684
|
-
inputProps: {
|
|
685
|
-
width: 'fill',
|
|
686
|
-
size: 'l',
|
|
687
|
-
fill: 'surfaceSecondary',
|
|
688
|
-
inputBorderColor: 'surfaceBorderTertiary',
|
|
689
|
-
inputBorderColorHover: 'surfaceBorderQuaternary',
|
|
690
|
-
inputBorderFocusColor: 'surfaceBorderAccent',
|
|
691
|
-
inputCaretColor: 'surfaceItemAccent',
|
|
692
|
-
inputFill: 'surfacePrimary',
|
|
693
|
-
inputFillHover: 'surfaceSecondary',
|
|
694
|
-
inputPlaceholderTextColor: 'surfaceSecondary',
|
|
695
|
-
inputSize: 'l',
|
|
696
|
-
inputTextColor: 'surfaceSecondary',
|
|
697
|
-
inputTextSize: 'xxl',
|
|
698
|
-
inputTextWeight: 'normal'
|
|
699
|
-
}
|
|
700
|
-
};
|
|
701
|
-
|
|
702
|
-
const CodeField = /*#__PURE__*/React$1.memo(function CodeField(props) {
|
|
703
|
-
const {
|
|
704
|
-
name,
|
|
705
|
-
initialValue,
|
|
706
|
-
isDisabled,
|
|
707
|
-
classNameGroupItem,
|
|
708
|
-
fieldProps = {},
|
|
709
|
-
inputProps = {},
|
|
710
|
-
showMessage,
|
|
711
|
-
isRequired
|
|
712
|
-
} = props;
|
|
713
|
-
return /*#__PURE__*/React$1.createElement(Field, {
|
|
714
|
-
name: name,
|
|
715
|
-
initialValue: initialValue
|
|
716
|
-
}, function Render({
|
|
717
|
-
input,
|
|
718
|
-
meta
|
|
719
|
-
}) {
|
|
720
|
-
/** Note:
|
|
721
|
-
* Create "Render" function by "eslint-react-hooks/rules-of-hooks":
|
|
722
|
-
* React Hooks cannot be called inside a callback.
|
|
723
|
-
* React Hooks must be called in a React function component or a
|
|
724
|
-
* custom React Hook function.
|
|
725
|
-
*/
|
|
726
|
-
|
|
727
|
-
const {
|
|
728
|
-
isErrorState,
|
|
729
|
-
isValidState,
|
|
730
|
-
errorKey} = useFieldValidationState({
|
|
731
|
-
fieldProps: fieldProps,
|
|
732
|
-
input: input,
|
|
733
|
-
meta: meta
|
|
734
|
-
});
|
|
735
|
-
const updatedInputProps = useValidationAppearanceInputProps({
|
|
736
|
-
inputProps: inputProps,
|
|
737
|
-
validationStateKey: isErrorState ? errorKey : 'success'
|
|
738
|
-
});
|
|
739
|
-
return /*#__PURE__*/React$1.createElement(FieldWrapper, Object.assign({
|
|
740
|
-
className: clsx('form-field_type_code', 'form__item_type_code', classNameGroupItem),
|
|
741
|
-
fieldClassName: 'form-code',
|
|
742
|
-
inputName: input.name,
|
|
743
|
-
inputValue: input.value,
|
|
744
|
-
metaActive: meta.active,
|
|
745
|
-
showMessage: showMessage,
|
|
746
|
-
isRequired: isRequired,
|
|
747
|
-
isValidState: isValidState
|
|
748
|
-
}, fieldProps), /*#__PURE__*/React$1.createElement(Code, Object.assign({
|
|
749
|
-
name: input.name,
|
|
750
|
-
isDisabled: isDisabled,
|
|
751
|
-
autoComplete: "nope",
|
|
752
|
-
value: input.value,
|
|
753
|
-
onBlur: input.onBlur,
|
|
754
|
-
onChange: input.onChange,
|
|
755
|
-
onFocus: input.onFocus
|
|
756
|
-
}, updatedInputProps)));
|
|
757
|
-
});
|
|
758
|
-
});
|
|
759
|
-
|
|
760
|
-
const defaultDatepickerProps = {
|
|
761
|
-
dateFormat: 'dd/MM/yyyy - HH:mm',
|
|
762
|
-
readOnly: false,
|
|
763
|
-
selectsRange: false,
|
|
764
|
-
showTimeSelect: true,
|
|
765
|
-
timeCaption: 'Время',
|
|
766
|
-
timeFormat: 'p',
|
|
767
|
-
timeIntervals: 60,
|
|
768
|
-
isClearable: true,
|
|
769
|
-
isStartDefaultNull: true
|
|
770
|
-
};
|
|
771
|
-
|
|
772
|
-
function DatePickerField(props) {
|
|
773
|
-
const {
|
|
774
|
-
name,
|
|
775
|
-
isDisabled,
|
|
776
|
-
classNameGroupItem,
|
|
777
|
-
datePickerProps,
|
|
778
|
-
fieldProps = {},
|
|
779
|
-
inputProps = {},
|
|
780
|
-
showMessage,
|
|
781
|
-
isRequired,
|
|
782
|
-
onChange
|
|
783
|
-
} = props;
|
|
784
|
-
return /*#__PURE__*/React$1.createElement(Field, {
|
|
785
|
-
name: name
|
|
786
|
-
}, function Render({
|
|
787
|
-
input,
|
|
788
|
-
meta
|
|
789
|
-
}) {
|
|
790
|
-
/** Note:
|
|
791
|
-
* Create "Render" function by "eslint-react-hooks/rules-of-hooks":
|
|
792
|
-
* React Hooks cannot be called inside a callback.
|
|
793
|
-
* React Hooks must be called in a React function component or a
|
|
794
|
-
* custom React Hook function.
|
|
795
|
-
*/
|
|
796
|
-
|
|
797
|
-
const onChangeField = useCallback((startDate, endDate) => {
|
|
798
|
-
if (!datePickerProps.selectsRange) {
|
|
799
|
-
// When we need to save single date, value is date
|
|
800
|
-
// TODO: make object with one date? need to check all forms with DatePickerField
|
|
801
|
-
input.onChange(startDate);
|
|
802
|
-
} else {
|
|
803
|
-
// When we need to save range, value is object with two date
|
|
804
|
-
input.onChange({
|
|
805
|
-
endDate,
|
|
806
|
-
startDate
|
|
807
|
-
});
|
|
808
|
-
}
|
|
809
|
-
if (onChange) {
|
|
810
|
-
onChange(startDate, endDate);
|
|
811
|
-
}
|
|
812
|
-
}, [input.onChange, onChange]);
|
|
813
|
-
const {
|
|
814
|
-
errorKey,
|
|
815
|
-
errorMessage,
|
|
816
|
-
isErrorState,
|
|
817
|
-
isValidState
|
|
818
|
-
} = useFieldValidationState({
|
|
819
|
-
fieldProps: fieldProps,
|
|
820
|
-
input: input,
|
|
821
|
-
meta: meta
|
|
822
|
-
});
|
|
823
|
-
const updatedInputProps = useValidationAppearanceInputProps({
|
|
824
|
-
inputProps: inputProps,
|
|
825
|
-
validationStateKey: isErrorState ? errorKey : 'success'
|
|
826
|
-
});
|
|
827
|
-
return /*#__PURE__*/React$1.createElement(FieldWrapper, Object.assign({
|
|
828
|
-
className: clsx('form-field_type_datepicker', 'form__item_type_datepicker', classNameGroupItem),
|
|
829
|
-
errorKey: errorKey,
|
|
830
|
-
errorMessage: errorMessage,
|
|
831
|
-
isErrorState: isErrorState,
|
|
832
|
-
metaError: meta.error,
|
|
833
|
-
isDisabled: isDisabled,
|
|
834
|
-
fieldClassName: "form-datepicker",
|
|
835
|
-
inputName: input.name,
|
|
836
|
-
inputValue: input.value || '',
|
|
837
|
-
metaActive: meta.active,
|
|
838
|
-
showMessage: showMessage,
|
|
839
|
-
isRequired: isRequired,
|
|
840
|
-
isValidState: isValidState
|
|
841
|
-
}, fieldProps), /*#__PURE__*/React$1.createElement(DatePickerInput, {
|
|
842
|
-
name: input.name,
|
|
843
|
-
isDisabled: isDisabled,
|
|
844
|
-
datePickerProps: datePickerProps,
|
|
845
|
-
endValue: datePickerProps.selectsRange ? input.value.endDate : null,
|
|
846
|
-
inputProps: updatedInputProps,
|
|
847
|
-
value: datePickerProps.selectsRange ? input.value.startDate : input.value,
|
|
848
|
-
onBlur: input.onBlur,
|
|
849
|
-
onChange: onChangeField,
|
|
850
|
-
onFocus: input.onFocus
|
|
851
|
-
}));
|
|
852
|
-
});
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
const defaultDropzoneProps = {
|
|
856
|
-
fill: 'surfacePrimary',
|
|
857
|
-
borderColor: 'surfaceBorderTertiary',
|
|
858
|
-
borderColorHover: 'surfaceBorderQuaternary',
|
|
859
|
-
hintTitle: 'Перетащите изображение или выберите файл с компьютера',
|
|
860
|
-
hintTitleTextColor: 'surfaceTextPrimary',
|
|
861
|
-
hintTitleTextSize: 'm',
|
|
862
|
-
removeThumbText: 'удалить',
|
|
863
|
-
removeThumbTextColor: 'errorTextPrimary',
|
|
864
|
-
removeThumbTextHoverColor: 'errorTextPrimaryHover',
|
|
865
|
-
removeThumbTextSize: 's',
|
|
866
|
-
shape: 'rounded',
|
|
867
|
-
showFilename: true,
|
|
868
|
-
thumbBorderColor: 'surfaceBorderTertiary',
|
|
869
|
-
thumbBorderColorHover: 'surfaceBorderQuaternary',
|
|
870
|
-
thumbBorderWidth: 1,
|
|
871
|
-
thumbNameTextColor: 'surfaceTextPrimary',
|
|
872
|
-
thumbNameTextSize: 's',
|
|
873
|
-
isPreviews: true
|
|
874
|
-
};
|
|
875
|
-
|
|
876
|
-
const FileInputDropzone = /*#__PURE__*/React$1.memo(function FileInputDropzone(props) {
|
|
877
|
-
const {
|
|
878
|
-
className,
|
|
879
|
-
maxFiles,
|
|
880
|
-
maxSize,
|
|
881
|
-
size,
|
|
882
|
-
fileErrorText,
|
|
883
|
-
dropzoneProps = {},
|
|
884
|
-
hintDescription,
|
|
885
|
-
hintTitle,
|
|
886
|
-
inputName,
|
|
887
|
-
inputValue,
|
|
888
|
-
showFilename,
|
|
889
|
-
thumbColumn,
|
|
890
|
-
isPreviews,
|
|
891
|
-
onAddFiles,
|
|
892
|
-
onDeleteFile
|
|
893
|
-
} = props;
|
|
894
|
-
|
|
895
|
-
// TODO: delete react-final-form things out of here?
|
|
896
|
-
const {
|
|
897
|
-
change
|
|
898
|
-
} = useForm();
|
|
899
|
-
const [fileError, setFileError] = useState('');
|
|
900
|
-
const [fileIsLoading, setFileIsLoading] = useState(false);
|
|
901
|
-
const filesList = useMemo(() => inputValue ? castArray(inputValue) : [], [inputValue]);
|
|
902
|
-
const changeFormState = useCallback(newFiles => {
|
|
903
|
-
// If max files in dropzone is 1 - return file as it self, else as array of files
|
|
904
|
-
// ps: for old projects compatibility
|
|
905
|
-
const toSave = dropzoneProps.maxFiles == 1 ? newFiles[0] : newFiles;
|
|
906
|
-
change(inputName, toSave);
|
|
907
|
-
return toSave;
|
|
908
|
-
},
|
|
909
|
-
// If "inputName" will be changes, then it should be a different field
|
|
910
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
911
|
-
[dropzoneProps, change]);
|
|
912
|
-
|
|
913
|
-
//
|
|
914
|
-
const convertFiledValueAndSaveAsFiles = useCallback(async currentFilesList => {
|
|
915
|
-
setFileIsLoading(true);
|
|
916
|
-
const newFiles = [];
|
|
917
|
-
for (const fileItem of currentFilesList) {
|
|
918
|
-
if (typeof fileItem === 'string') {
|
|
919
|
-
const newFile = await convertToFile(fileItem, isPreviews);
|
|
920
|
-
if (newFile) {
|
|
921
|
-
newFiles.push(newFile);
|
|
922
|
-
}
|
|
923
|
-
} else {
|
|
924
|
-
newFiles.push(fileItem);
|
|
925
|
-
}
|
|
926
|
-
}
|
|
927
|
-
changeFormState(newFiles);
|
|
928
|
-
setFileIsLoading(false);
|
|
929
|
-
}, [isPreviews, changeFormState]);
|
|
930
|
-
|
|
931
|
-
// Delete file from dropzone
|
|
932
|
-
const removeFile = useCallback((event, index) => {
|
|
933
|
-
event.stopPropagation();
|
|
934
|
-
event.preventDefault();
|
|
935
|
-
const newFiles = [...filesList];
|
|
936
|
-
newFiles.splice(index, 1);
|
|
937
|
-
if (onDeleteFile) {
|
|
938
|
-
onDeleteFile(filesList[index], inputName);
|
|
939
|
-
}
|
|
940
|
-
changeFormState(newFiles);
|
|
941
|
-
},
|
|
942
|
-
// If "inputName" will be changes, then it should be a different field
|
|
943
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
944
|
-
[filesList, changeFormState, onDeleteFile]);
|
|
945
|
-
|
|
946
|
-
// Create dropzone options
|
|
947
|
-
const {
|
|
948
|
-
getInputProps,
|
|
949
|
-
getRootProps
|
|
950
|
-
} = useDropzone({
|
|
951
|
-
maxFiles: maxFiles || 5,
|
|
952
|
-
maxSize: maxSize || 10485760,
|
|
953
|
-
// 10mb
|
|
954
|
-
// accept: { 'image/*': [] },
|
|
955
|
-
...dropzoneProps,
|
|
956
|
-
getFilesFromEvent: async event => {
|
|
957
|
-
const result = await fromEvent(event);
|
|
958
|
-
const newFiles = result.filter(item => item instanceof File);
|
|
959
|
-
// Add exists and new files to accepted(or rejected)
|
|
960
|
-
return [...filesList, ...newFiles];
|
|
961
|
-
},
|
|
962
|
-
onDropAccepted: acceptedFiles => {
|
|
963
|
-
// If dropped files has accepted and we need a previews
|
|
964
|
-
if (isPreviews) {
|
|
965
|
-
// Add preview to every file
|
|
966
|
-
acceptedFiles.forEach(file => {
|
|
967
|
-
if (!file.error) {
|
|
968
|
-
file.preview = URL.createObjectURL(file);
|
|
969
|
-
}
|
|
970
|
-
});
|
|
971
|
-
}
|
|
972
|
-
// Save to form data (including empty when files are not valid)
|
|
973
|
-
const filesToSave = changeFormState(acceptedFiles);
|
|
974
|
-
setFileError('');
|
|
975
|
-
|
|
976
|
-
// Save DataURL for all files
|
|
977
|
-
const readerPromisesList = acceptedFiles.map(file => {
|
|
978
|
-
return new Promise(resolve => setFileDataURL(file, resolve));
|
|
979
|
-
});
|
|
980
|
-
// Save files to form values
|
|
981
|
-
Promise.all(readerPromisesList).then(() => {
|
|
982
|
-
if (onAddFiles) {
|
|
983
|
-
onAddFiles(filesToSave, inputName);
|
|
984
|
-
}
|
|
985
|
-
});
|
|
986
|
-
},
|
|
987
|
-
onDropRejected: rejectedFiles => {
|
|
988
|
-
// If dropped files has rejected
|
|
989
|
-
if (rejectedFiles.length) {
|
|
990
|
-
let fileErrorMessage = 'Ошибка при добавлении файла';
|
|
991
|
-
const firstFileErrorItem = rejectedFiles[0].errors[0];
|
|
992
|
-
if (firstFileErrorItem) {
|
|
993
|
-
if (firstFileErrorItem.code === ErrorCode.TooManyFiles) {
|
|
994
|
-
fileErrorMessage = `Максимальное количество файлов: ${maxFiles}`;
|
|
995
|
-
} else {
|
|
996
|
-
fileErrorMessage = firstFileErrorItem.message;
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
// Show error
|
|
1000
|
-
setFileError(fileErrorMessage);
|
|
1001
|
-
} else {
|
|
1002
|
-
// Else clean error
|
|
1003
|
-
setFileError('');
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1006
|
-
});
|
|
1007
|
-
useEffect(() => {
|
|
1008
|
-
const currentFilesList = castArray(inputValue);
|
|
1009
|
-
const isNeedToConvert = currentFilesList.some(fileItem => typeof fileItem === 'string');
|
|
1010
|
-
if (isNeedToConvert) {
|
|
1011
|
-
// First time convert value to Files and save to local and form state
|
|
1012
|
-
convertFiledValueAndSaveAsFiles(currentFilesList);
|
|
1013
|
-
}
|
|
1014
|
-
|
|
1015
|
-
// Make sure to revoke the data uris to avoid memory leaks, will run on unmount
|
|
1016
|
-
return () => {
|
|
1017
|
-
filesList.forEach(file => {
|
|
1018
|
-
if (file?.preview) {
|
|
1019
|
-
URL.revokeObjectURL(file.preview);
|
|
1020
|
-
}
|
|
1021
|
-
});
|
|
1022
|
-
};
|
|
1023
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1024
|
-
}, [inputValue]);
|
|
1025
|
-
const propsGenerator = useDevicePropsGenerator(props);
|
|
1026
|
-
const {
|
|
1027
|
-
fillClass,
|
|
1028
|
-
fillHoverClass,
|
|
1029
|
-
borderColorClass,
|
|
1030
|
-
borderColorHoverClass,
|
|
1031
|
-
borderTypeClass,
|
|
1032
|
-
borderWidthClass,
|
|
1033
|
-
errorMessageTextColor,
|
|
1034
|
-
errorMessageTextSize,
|
|
1035
|
-
errorMessageTextWeight,
|
|
1036
|
-
hintDescriptionTextColor,
|
|
1037
|
-
hintDescriptionTextSize,
|
|
1038
|
-
hintDescriptionTextWeight,
|
|
1039
|
-
hintDescriptionTextWrap,
|
|
1040
|
-
hintTitleTextColor,
|
|
1041
|
-
hintTitleTextSize,
|
|
1042
|
-
hintTitleTextWeight,
|
|
1043
|
-
hintTitleTextWrap,
|
|
1044
|
-
removeThumbText,
|
|
1045
|
-
removeThumbTextColor,
|
|
1046
|
-
removeThumbTextHoverColor,
|
|
1047
|
-
removeThumbTextSize,
|
|
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} thumbColumn 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: "form-dropzone__thumb-remove",
|
|
1101
|
-
onClick: event => removeFile(event, index)
|
|
1102
|
-
}, /*#__PURE__*/React$1.createElement(Text, {
|
|
1103
|
-
className: "form-dropzone__thumb-remove-text",
|
|
1104
|
-
size: removeThumbTextSize,
|
|
1105
|
-
textColor: removeThumbTextColor,
|
|
1106
|
-
textColorHover: removeThumbTextHoverColor,
|
|
1107
|
-
textWeight: removeThumbTextWeight
|
|
1108
|
-
}, removeThumbText || 'Удалить')))), !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'), /*#__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'), /*#__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'
|
|
1150
|
-
});
|
|
1151
|
-
const blobObject = response.data;
|
|
1152
|
-
const dirtyFilename = response.headers['content-disposition']?.split('filename=')[1];
|
|
1153
|
-
// Remove double quotes
|
|
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
|
|
1163
|
-
});
|
|
1164
|
-
} catch (error) {
|
|
1165
|
-
console.log('error: ', error);
|
|
1166
|
-
return null;
|
|
1167
|
-
}
|
|
1168
|
-
}
|
|
1169
|
-
async function convertToFile(inputValue, isPreviews) {
|
|
1170
|
-
let newFile = null;
|
|
1171
|
-
|
|
1172
|
-
// Download image by url and save as File instance
|
|
1173
|
-
const isURL = typeof inputValue === 'string' && inputValue.includes('/');
|
|
1174
|
-
if (inputValue.image || isURL) {
|
|
1175
|
-
newFile = await getFileByURL(inputValue.image || inputValue);
|
|
1176
|
-
if (newFile) {
|
|
1177
|
-
setFileDataURL(newFile);
|
|
1178
|
-
}
|
|
1179
|
-
}
|
|
1180
|
-
|
|
1181
|
-
// Convert dataURL to File instance
|
|
1182
|
-
if (inputValue.dataURL) {
|
|
1183
|
-
newFile = createFileFromDataURL(inputValue.name || inputValue.path, inputValue.dataURL);
|
|
1184
|
-
newFile.dataURL = inputValue.dataURL;
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1187
|
-
// Save new File to state
|
|
1188
|
-
if (newFile) {
|
|
1189
|
-
newFile.id = inputValue.id;
|
|
1190
|
-
if (isPreviews) {
|
|
1191
|
-
newFile.preview = URL.createObjectURL(newFile);
|
|
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;
|
|
1201
|
-
|
|
1202
|
-
// Set handlers
|
|
1203
|
-
reader.onabort = () => resolve();
|
|
1204
|
-
reader.onerror = () => resolve();
|
|
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
|
-
}
|
|
1216
|
-
|
|
1217
|
-
const FileInput = /*#__PURE__*/React$1.memo(function FileInput(props) {
|
|
1218
|
-
const {
|
|
1219
|
-
className,
|
|
1220
|
-
name,
|
|
1221
|
-
width,
|
|
1222
|
-
maxFiles,
|
|
1223
|
-
maxSize,
|
|
1224
|
-
label,
|
|
1225
|
-
fileErrorText,
|
|
1226
|
-
classNameGroupItem,
|
|
1227
|
-
dropzoneProps,
|
|
1228
|
-
fieldProps,
|
|
1229
|
-
hintDescription,
|
|
1230
|
-
hintTitle,
|
|
1231
|
-
showFilename,
|
|
1232
|
-
showMessage,
|
|
1233
|
-
isPreviews,
|
|
1234
|
-
isRequired,
|
|
1235
|
-
onAddFiles,
|
|
1236
|
-
onDeleteFile
|
|
1237
|
-
} = props;
|
|
1238
|
-
const propsGenerator = useDevicePropsGenerator(props);
|
|
1239
|
-
const {
|
|
1240
|
-
size,
|
|
1241
|
-
fill,
|
|
1242
|
-
fillHover,
|
|
1243
|
-
labelTextColor,
|
|
1244
|
-
borderColorHover,
|
|
1245
|
-
borderType,
|
|
1246
|
-
borderWidth,
|
|
1247
|
-
errorMessageTextColor = 'errorTextPrimary',
|
|
1248
|
-
errorMessageTextSize = 's',
|
|
1249
|
-
errorMessageTextWeight,
|
|
1250
|
-
hintDescriptionTextColor,
|
|
1251
|
-
hintDescriptionTextSize,
|
|
1252
|
-
hintDescriptionTextWeight,
|
|
1253
|
-
hintDescriptionTextWrap,
|
|
1254
|
-
hintTitleTextColor,
|
|
1255
|
-
hintTitleTextSize,
|
|
1256
|
-
hintTitleTextWeight,
|
|
1257
|
-
hintTitleTextWrap,
|
|
1258
|
-
removeThumbText,
|
|
1259
|
-
removeThumbTextColor,
|
|
1260
|
-
removeThumbTextHoverColor,
|
|
1261
|
-
removeThumbTextSize,
|
|
1262
|
-
removeThumbTextWeight,
|
|
1263
|
-
shape,
|
|
1264
|
-
thumbBorderColor,
|
|
1265
|
-
thumbBorderColorHover,
|
|
1266
|
-
thumbBorderType,
|
|
1267
|
-
thumbBorderWidth,
|
|
1268
|
-
thumbColumn = 1,
|
|
1269
|
-
thumbDirection = 'vertical',
|
|
1270
|
-
thumbNameTextColor,
|
|
1271
|
-
thumbNameTextSize,
|
|
1272
|
-
thumbNameTextWeight,
|
|
1273
|
-
thumbNameTextWrap
|
|
1274
|
-
} = propsGenerator;
|
|
1275
|
-
return /*#__PURE__*/React$1.createElement(Field, {
|
|
1276
|
-
name: name
|
|
1277
|
-
}, function Render({
|
|
1278
|
-
input,
|
|
1279
|
-
meta
|
|
1280
|
-
}) {
|
|
1281
|
-
/** Note:
|
|
1282
|
-
* Create "Render" function by "eslint-react-hooks/rules-of-hooks":
|
|
1283
|
-
* React Hooks cannot be called inside a callback.
|
|
1284
|
-
* React Hooks must be called in a React function component or a
|
|
1285
|
-
* custom React Hook function.
|
|
1286
|
-
*/
|
|
1287
|
-
|
|
1288
|
-
const {
|
|
1289
|
-
errorKey,
|
|
1290
|
-
errorMessage,
|
|
1291
|
-
isErrorState,
|
|
1292
|
-
isValidState
|
|
1293
|
-
} = useFieldValidationState({
|
|
1294
|
-
fieldProps: fieldProps,
|
|
1295
|
-
input: input,
|
|
1296
|
-
meta: meta
|
|
1297
|
-
});
|
|
1298
|
-
const updatedInputProps = useValidationAppearanceInputProps({
|
|
1299
|
-
inputProps: props,
|
|
1300
|
-
validationStateKey: isErrorState ? errorKey : 'success'
|
|
1301
|
-
});
|
|
1302
|
-
|
|
1303
|
-
/** TODO:
|
|
1304
|
-
* REFACTOR PROPERTIES
|
|
1305
|
-
*/
|
|
1306
|
-
return /*#__PURE__*/React$1.createElement(FieldWrapper, Object.assign({
|
|
1307
|
-
className: clsx('form-field_type_dropzone', 'form__item_type_dropzone', classNameGroupItem),
|
|
1308
|
-
width: width,
|
|
1309
|
-
label: label,
|
|
1310
|
-
labelTextColor: labelTextColor,
|
|
1311
|
-
errorKey: errorKey,
|
|
1312
|
-
errorMessage: errorMessage,
|
|
1313
|
-
isErrorState: isErrorState,
|
|
1314
|
-
metaError: meta.error,
|
|
1315
|
-
fieldClassName: "form-dropzone",
|
|
1316
|
-
inputName: input.name,
|
|
1317
|
-
inputValue: input.value,
|
|
1318
|
-
metaActive: meta.active,
|
|
1319
|
-
metaTouched: meta.touched,
|
|
1320
|
-
showMessage: showMessage,
|
|
1321
|
-
isRequired: isRequired,
|
|
1322
|
-
isValidState: isValidState
|
|
1323
|
-
}, fieldProps), /*#__PURE__*/React$1.createElement(FileInputDropzone, {
|
|
1324
|
-
className: className,
|
|
1325
|
-
maxFiles: maxFiles,
|
|
1326
|
-
maxSize: maxSize,
|
|
1327
|
-
size: size,
|
|
1328
|
-
fill: fill,
|
|
1329
|
-
fillHover: fillHover,
|
|
1330
|
-
borderColor: updatedInputProps.borderColor,
|
|
1331
|
-
borderColorHover: borderColorHover,
|
|
1332
|
-
borderType: borderType,
|
|
1333
|
-
borderWidth: borderWidth,
|
|
1334
|
-
errorMessageTextColor: errorMessageTextColor,
|
|
1335
|
-
errorMessageTextSize: errorMessageTextSize,
|
|
1336
|
-
errorMessageWeight: errorMessageTextWeight,
|
|
1337
|
-
fileErrorText: fileErrorText,
|
|
1338
|
-
metaError: meta.error,
|
|
1339
|
-
dropzoneProps: dropzoneProps,
|
|
1340
|
-
hintDescription: hintDescription,
|
|
1341
|
-
hintDescriptionTextColor: hintDescriptionTextColor,
|
|
1342
|
-
hintDescriptionTextSize: hintDescriptionTextSize,
|
|
1343
|
-
hintDescriptionTextWeight: hintDescriptionTextWeight,
|
|
1344
|
-
hintDescriptionTextWrap: hintDescriptionTextWrap,
|
|
1345
|
-
hintTitle: hintTitle,
|
|
1346
|
-
hintTitleTextColor: hintTitleTextColor,
|
|
1347
|
-
hintTitleTextSize: hintTitleTextSize,
|
|
1348
|
-
hintTitleTextWeight: hintTitleTextWeight,
|
|
1349
|
-
hintTitleTextWrap: hintTitleTextWrap,
|
|
1350
|
-
inputName: input.name,
|
|
1351
|
-
inputValue: input.value,
|
|
1352
|
-
metaTouched: meta.touched,
|
|
1353
|
-
removeThumbText: removeThumbText,
|
|
1354
|
-
removeThumbTextColor: removeThumbTextColor,
|
|
1355
|
-
removeThumbTextHoverColor: removeThumbTextHoverColor,
|
|
1356
|
-
removeThumbTextSize: removeThumbTextSize,
|
|
1357
|
-
removeThumbTextWeight: removeThumbTextWeight,
|
|
1358
|
-
shape: shape,
|
|
1359
|
-
showFilename: showFilename,
|
|
1360
|
-
thumbBorderColor: thumbBorderColor,
|
|
1361
|
-
thumbBorderColorHover: thumbBorderColorHover,
|
|
1362
|
-
thumbBorderType: thumbBorderType,
|
|
1363
|
-
thumbBorderWidth: thumbBorderWidth,
|
|
1364
|
-
thumbColumn: thumbColumn,
|
|
1365
|
-
thumbDirection: thumbDirection,
|
|
1366
|
-
thumbNameTextColor: thumbNameTextColor,
|
|
1367
|
-
thumbNameTextSize: thumbNameTextSize,
|
|
1368
|
-
thumbNameTextWeight: thumbNameTextWeight,
|
|
1369
|
-
thumbNameTextWrap: thumbNameTextWrap,
|
|
1370
|
-
isPreviews: isPreviews,
|
|
1371
|
-
onAddFiles: onAddFiles,
|
|
1372
|
-
onDeleteFile: onDeleteFile
|
|
1373
|
-
}));
|
|
1374
|
-
});
|
|
1375
|
-
});
|
|
1376
|
-
|
|
1377
|
-
const Group = /*#__PURE__*/React$1.memo(function Group(props) {
|
|
1378
|
-
const {
|
|
1379
|
-
className,
|
|
1380
|
-
name,
|
|
1381
|
-
label,
|
|
1382
|
-
labelTextColor,
|
|
1383
|
-
labelTextSize,
|
|
1384
|
-
labelTextWeight,
|
|
1385
|
-
message,
|
|
1386
|
-
dataTour,
|
|
1387
|
-
messageTextColor = 'surfaceTextTertiary',
|
|
1388
|
-
messageTextSize = 's',
|
|
1389
|
-
messageTextWeight,
|
|
1390
|
-
showGroupMessage,
|
|
1391
|
-
before,
|
|
1392
|
-
after,
|
|
1393
|
-
isHidden,
|
|
1394
|
-
children
|
|
1395
|
-
} = props;
|
|
1396
|
-
return /*#__PURE__*/React$1.createElement(Field, {
|
|
1397
|
-
name: name
|
|
1398
|
-
}, function Render({
|
|
1399
|
-
input,
|
|
1400
|
-
meta
|
|
1401
|
-
}) {
|
|
1402
|
-
/** Note:
|
|
1403
|
-
* Create "Render" function by "eslint-react-hooks/rules-of-hooks":
|
|
1404
|
-
* React Hooks cannot be called inside a callback.
|
|
1405
|
-
* React Hooks must be called in a React function component or a
|
|
1406
|
-
* custom React Hook function.
|
|
1407
|
-
*/
|
|
1408
|
-
const {
|
|
1409
|
-
isErrorState,
|
|
1410
|
-
errorKey,
|
|
1411
|
-
errorMessage
|
|
1412
|
-
} = useFieldValidationState({
|
|
1413
|
-
fieldProps: props,
|
|
1414
|
-
// or fieldProps?
|
|
1415
|
-
input: input,
|
|
1416
|
-
meta: meta
|
|
1417
|
-
});
|
|
1418
|
-
const updatedProps = useValidationAppearanceInputProps({
|
|
1419
|
-
inputProps: props,
|
|
1420
|
-
validationStateKey: isErrorState ? errorKey : 'success'
|
|
1421
|
-
});
|
|
1422
|
-
return /*#__PURE__*/React$1.createElement("div", {
|
|
1423
|
-
className: clsx('form__group', className, isHidden && 'form__group_hidden'),
|
|
1424
|
-
"data-tour": dataTour
|
|
1425
|
-
}, /*#__PURE__*/React$1.createElement("div", {
|
|
1426
|
-
className: "form__group-wrapper"
|
|
1427
|
-
}, before, label && /*#__PURE__*/React$1.createElement("div", {
|
|
1428
|
-
className: "form__group-label"
|
|
1429
|
-
}, /*#__PURE__*/React$1.createElement(Title, {
|
|
1430
|
-
size: labelTextSize,
|
|
1431
|
-
textColor: labelTextColor,
|
|
1432
|
-
textWeight: labelTextWeight
|
|
1433
|
-
}, label)), /*#__PURE__*/React$1.createElement("div", {
|
|
1434
|
-
className: "form__group-items"
|
|
1435
|
-
}, children), after), showGroupMessage && /*#__PURE__*/React$1.createElement(React$1.Fragment, null, isErrorState && errorMessage && /*#__PURE__*/React$1.createElement(Text, {
|
|
1436
|
-
className: `form__group-message form__group-message_type-${errorKey}`,
|
|
1437
|
-
id: `${name}-error`,
|
|
1438
|
-
size: updatedProps.messageTextSize,
|
|
1439
|
-
textColor: updatedProps.messageTextColor,
|
|
1440
|
-
textWeight: updatedProps.messageTextWeight
|
|
1441
|
-
}, errorMessage), Boolean(message) && (!isErrorState || !errorMessage) && /*#__PURE__*/React$1.createElement(Text, {
|
|
1442
|
-
className: "form__group-message",
|
|
1443
|
-
size: messageTextSize,
|
|
1444
|
-
textColor: messageTextColor,
|
|
1445
|
-
textWeight: messageTextWeight
|
|
1446
|
-
}, message), !isErrorState && !message && /*#__PURE__*/React$1.createElement(Text, {
|
|
1447
|
-
className: "form__group-message",
|
|
1448
|
-
size: messageTextSize
|
|
1449
|
-
}, '\u00A0')));
|
|
1450
|
-
});
|
|
1451
|
-
});
|
|
1452
|
-
|
|
1453
|
-
const defaultInputProps = {
|
|
1454
|
-
appearance: 'sizeM defaultSecondary',
|
|
1455
|
-
width: 'fill',
|
|
1456
|
-
errorBorderColor: 'errorBorderSecondary',
|
|
1457
|
-
requiredBorderColor: 'warningBorderSecondary',
|
|
1458
|
-
shape: 'rounded'
|
|
1459
|
-
};
|
|
1460
|
-
|
|
1461
|
-
const InputField = /*#__PURE__*/React$1.memo(function InputField(props) {
|
|
1462
|
-
const {
|
|
1463
|
-
name,
|
|
1464
|
-
initialValue,
|
|
1465
|
-
isDisabled,
|
|
1466
|
-
classNameGroupItem,
|
|
1467
|
-
// dataTestId,
|
|
1468
|
-
// iconBorder,
|
|
1469
|
-
// iconBorderHover,
|
|
1470
|
-
clearIcon,
|
|
1471
|
-
clearIconFill,
|
|
1472
|
-
clearIconFillHover,
|
|
1473
|
-
clearIconShape,
|
|
1474
|
-
clearIconSize,
|
|
1475
|
-
fieldProps = {},
|
|
1476
|
-
iconFill,
|
|
1477
|
-
iconFillHover,
|
|
1478
|
-
iconRevealableHide,
|
|
1479
|
-
iconRevealableShow,
|
|
1480
|
-
iconShape,
|
|
1481
|
-
iconSize,
|
|
1482
|
-
inputProps = {},
|
|
1483
|
-
parse,
|
|
1484
|
-
showMessage,
|
|
1485
|
-
isPassword,
|
|
1486
|
-
isRequired,
|
|
1487
|
-
isRevealable,
|
|
1488
|
-
onChange,
|
|
1489
|
-
onClickClearIcon
|
|
1490
|
-
} = props;
|
|
1491
|
-
const [isRevealed, setIsRevealed] = useState(false);
|
|
1492
|
-
const inputType = useMemo(() => {
|
|
1493
|
-
if (isPassword) {
|
|
1494
|
-
return isRevealed ? 'text' : 'password';
|
|
1495
|
-
} else {
|
|
1496
|
-
return 'text';
|
|
1497
|
-
}
|
|
1498
|
-
}, [isRevealed, isPassword]);
|
|
1499
|
-
const onClickIconReveal = useCallback(event => {
|
|
1500
|
-
event.preventDefault();
|
|
1501
|
-
setIsRevealed(prev => !prev);
|
|
1502
|
-
}, []);
|
|
1503
|
-
return /*#__PURE__*/React$1.createElement(Field, {
|
|
1504
|
-
name: name,
|
|
1505
|
-
initialValue: initialValue,
|
|
1506
|
-
parse: parse
|
|
1507
|
-
}, function Render({
|
|
1508
|
-
input,
|
|
1509
|
-
meta
|
|
1510
|
-
}) {
|
|
1511
|
-
/** Note:
|
|
1512
|
-
* Create "Render" function by "eslint-react-hooks/rules-of-hooks":
|
|
1513
|
-
* React Hooks cannot be called inside a callback.
|
|
1514
|
-
* React Hooks must be called in a React function component or a
|
|
1515
|
-
* custom React Hook function.
|
|
1516
|
-
*/
|
|
1517
|
-
|
|
1518
|
-
const onChangeField = useCallback(event => {
|
|
1519
|
-
input.onChange(event);
|
|
1520
|
-
if (onChange) {
|
|
1521
|
-
onChange(event.target.value, input.name);
|
|
1522
|
-
}
|
|
1523
|
-
}, [onChange, input.onChange]);
|
|
1524
|
-
const {
|
|
1525
|
-
isErrorState,
|
|
1526
|
-
isValidState,
|
|
1527
|
-
errorKey,
|
|
1528
|
-
errorMessage
|
|
1529
|
-
} = useFieldValidationState({
|
|
1530
|
-
fieldProps: fieldProps,
|
|
1531
|
-
input: input,
|
|
1532
|
-
meta: meta
|
|
1533
|
-
});
|
|
1534
|
-
const updatedInputProps = useValidationAppearanceInputProps({
|
|
1535
|
-
inputProps: inputProps,
|
|
1536
|
-
validationStateKey: isErrorState ? errorKey : 'success'
|
|
1537
|
-
});
|
|
1538
|
-
return /*#__PURE__*/React$1.createElement(FieldWrapper, Object.assign({
|
|
1539
|
-
className: clsx('form-field_type_input', 'form__item_type_input', classNameGroupItem),
|
|
1540
|
-
errorKey: errorKey,
|
|
1541
|
-
errorMessage: errorMessage,
|
|
1542
|
-
isErrorState: isErrorState,
|
|
1543
|
-
metaError: meta.error,
|
|
1544
|
-
isDisabled: isDisabled,
|
|
1545
|
-
fieldClassName: isRevealable ? 'form-password' : 'form-input',
|
|
1546
|
-
inputName: input.name,
|
|
1547
|
-
inputValue: input.value || '',
|
|
1548
|
-
metaActive: meta.active,
|
|
1549
|
-
showMessage: showMessage,
|
|
1550
|
-
isRequired: isRequired,
|
|
1551
|
-
isValidState: isValidState
|
|
1552
|
-
}, fieldProps), /*#__PURE__*/React$1.createElement(Input, Object.assign({
|
|
1553
|
-
className: clsx(meta.active && 'input_state_focus', meta.error && meta.touched && `input_state_${errorKey}`),
|
|
1554
|
-
type: inputType,
|
|
1555
|
-
name: input.name,
|
|
1556
|
-
isDisabled: isDisabled,
|
|
1557
|
-
autoComplete: "nope",
|
|
1558
|
-
dataTestId: `${input.name}FieldInput`,
|
|
1559
|
-
value: input.value || '',
|
|
1560
|
-
onBlur: input.onBlur,
|
|
1561
|
-
onChange: onChangeField,
|
|
1562
|
-
onFocus: input.onFocus
|
|
1563
|
-
}, updatedInputProps)), isRevealable && /*#__PURE__*/React$1.createElement(Icon, {
|
|
1564
|
-
className: "form-field__icon",
|
|
1565
|
-
size: iconSize,
|
|
1566
|
-
iconFill: iconFill,
|
|
1567
|
-
iconFillHover: iconFillHover,
|
|
1568
|
-
imageSrc: isRevealed ? iconRevealableHide : iconRevealableShow,
|
|
1569
|
-
shape: iconShape,
|
|
1570
|
-
SvgImage: isRevealed ? iconRevealableHide : iconRevealableShow,
|
|
1571
|
-
onClick: onClickIconReveal
|
|
1572
|
-
}), clearIcon && /*#__PURE__*/React$1.createElement(Icon, {
|
|
1573
|
-
className: "form-field__icon",
|
|
1574
|
-
size: clearIconSize,
|
|
1575
|
-
iconFill: clearIconFill,
|
|
1576
|
-
iconFillHover: clearIconFillHover,
|
|
1577
|
-
imageSrc: clearIcon,
|
|
1578
|
-
shape: clearIconShape,
|
|
1579
|
-
SvgImage: clearIcon,
|
|
1580
|
-
onClick: onClickClearIcon
|
|
1581
|
-
}));
|
|
1582
|
-
});
|
|
1583
|
-
});
|
|
1584
|
-
|
|
1585
|
-
const defaultRadioProps = {
|
|
1586
|
-
fieldProps: {
|
|
1587
|
-
width: 'fill',
|
|
1588
|
-
size: 'm',
|
|
1589
|
-
labelTextColor: 'surfaceTextPrimary',
|
|
1590
|
-
labelTextSize: 's',
|
|
1591
|
-
labelTextWeight: 'normal',
|
|
1592
|
-
textColor: 'surfaceTextPrimary',
|
|
1593
|
-
helpText: 'Supporting text',
|
|
1594
|
-
helpTextColor: 'surfaceTextPrimary',
|
|
1595
|
-
helpTextSize: 's',
|
|
1596
|
-
helpTextWeight: 'normal',
|
|
1597
|
-
showMessage: true
|
|
1598
|
-
},
|
|
1599
|
-
inputProps: {
|
|
1600
|
-
width: 'fill',
|
|
1601
|
-
size: 'm',
|
|
1602
|
-
labelTextColor: 'surfaceTextPrimary',
|
|
1603
|
-
labelTextSize: 's',
|
|
1604
|
-
descTextColor: 'surfaceTextPrimary',
|
|
1605
|
-
descTextSize: 's'
|
|
1606
|
-
}
|
|
1607
|
-
};
|
|
1608
|
-
|
|
1609
|
-
function RadioGroupInput(props) {
|
|
1610
|
-
const {
|
|
1611
|
-
input,
|
|
1612
|
-
value,
|
|
1613
|
-
onChange
|
|
1614
|
-
} = props;
|
|
1615
|
-
const onChangeField = useCallback(event => onChange(event.target.value), [onChange]);
|
|
1616
|
-
return /*#__PURE__*/React.createElement(Input, Object.assign({
|
|
1617
|
-
name: input.name,
|
|
1618
|
-
autoComplete: "nope",
|
|
1619
|
-
value: value,
|
|
1620
|
-
onBlur: input.onBlur,
|
|
1621
|
-
onChange: onChangeField,
|
|
1622
|
-
onFocus: input.onFocus
|
|
1623
|
-
}, props));
|
|
1624
|
-
}
|
|
1625
|
-
|
|
1626
|
-
function RadioGroupItem(props) {
|
|
1627
|
-
const {
|
|
1628
|
-
input,
|
|
1629
|
-
inputProps,
|
|
1630
|
-
option,
|
|
1631
|
-
onChange
|
|
1632
|
-
} = props;
|
|
1633
|
-
const onChangeField = useCallback(event => {
|
|
1634
|
-
if (event.target.checked) {
|
|
1635
|
-
onChange(option.value);
|
|
1636
|
-
}
|
|
1637
|
-
}, [onChange]);
|
|
1638
|
-
return /*#__PURE__*/React.createElement(Radio, Object.assign({
|
|
1639
|
-
className: "form-radio__item",
|
|
1640
|
-
type: "radio",
|
|
1641
|
-
name: input.name,
|
|
1642
|
-
label: option.label,
|
|
1643
|
-
checked: option.value === input.value,
|
|
1644
|
-
value: option.value,
|
|
1645
|
-
onBlur: input.onBlur,
|
|
1646
|
-
onChange: onChangeField,
|
|
1647
|
-
onFocus: input.onFocus
|
|
1648
|
-
}, inputProps));
|
|
1649
|
-
}
|
|
1650
|
-
|
|
1651
|
-
function RadioGroupList(props) {
|
|
1652
|
-
const {
|
|
1653
|
-
editableProps,
|
|
1654
|
-
input,
|
|
1655
|
-
inputProps,
|
|
1656
|
-
options,
|
|
1657
|
-
onChange
|
|
1658
|
-
} = props;
|
|
1659
|
-
const [editableValue, setEditableValue] = useState(() => {
|
|
1660
|
-
const isRadioValue = options.find(option => option.value === input.value);
|
|
1661
|
-
if (!isRadioValue) {
|
|
1662
|
-
return input.value;
|
|
1663
|
-
}
|
|
1664
|
-
return '';
|
|
1665
|
-
});
|
|
1666
|
-
useEffect(() => {
|
|
1667
|
-
// When a new value from outside enters the form
|
|
1668
|
-
if (input.value) {
|
|
1669
|
-
// Check value for radio type
|
|
1670
|
-
const isRadioValue = options.find(option => option.value === input.value && !option.editable);
|
|
1671
|
-
// If new value not in radio list - set to editable input
|
|
1672
|
-
setEditableValue(isRadioValue ? '' : input.value);
|
|
1673
|
-
} else {
|
|
1674
|
-
// If new value is empty - clear editable input
|
|
1675
|
-
setEditableValue('');
|
|
1676
|
-
}
|
|
1677
|
-
}, [input.value]);
|
|
1678
|
-
|
|
1679
|
-
// Callback for value changes
|
|
1680
|
-
const onChangeSomeInput = useCallback(value => {
|
|
1681
|
-
// Save to form values
|
|
1682
|
-
input.onChange(value);
|
|
1683
|
-
if (onChange) {
|
|
1684
|
-
// Pass to custom event
|
|
1685
|
-
onChange(value, input.name);
|
|
1686
|
-
}
|
|
1687
|
-
}, [input, onChange]);
|
|
1688
|
-
|
|
1689
|
-
// Handle for radio inputs
|
|
1690
|
-
const onChangeRadio = useCallback(value => {
|
|
1691
|
-
setEditableValue('');
|
|
1692
|
-
onChangeSomeInput(value);
|
|
1693
|
-
}, [onChangeSomeInput]);
|
|
1694
|
-
|
|
1695
|
-
// Handle for text input
|
|
1696
|
-
const onChangeEditable = useCallback(value => {
|
|
1697
|
-
setEditableValue(value);
|
|
1698
|
-
onChangeSomeInput(value);
|
|
1699
|
-
}, [onChangeSomeInput]);
|
|
1700
|
-
return /*#__PURE__*/React$1.createElement(React$1.Fragment, null, options.map(option => option.editable ? /*#__PURE__*/React$1.createElement(RadioGroupInput, {
|
|
1701
|
-
key: option.label,
|
|
1702
|
-
editableProps: editableProps,
|
|
1703
|
-
input: input,
|
|
1704
|
-
inputProps: inputProps,
|
|
1705
|
-
option: option,
|
|
1706
|
-
value: editableValue,
|
|
1707
|
-
onChange: onChangeEditable
|
|
1708
|
-
}) : /*#__PURE__*/React$1.createElement(RadioGroupItem, {
|
|
1709
|
-
key: option.value,
|
|
1710
|
-
input: input,
|
|
1711
|
-
inputProps: inputProps,
|
|
1712
|
-
option: option,
|
|
1713
|
-
onChange: onChangeRadio
|
|
1714
|
-
})));
|
|
1715
|
-
}
|
|
1716
|
-
|
|
1717
|
-
const RadioGroup = /*#__PURE__*/React$1.memo(function RadioGroup(props) {
|
|
1718
|
-
const {
|
|
1719
|
-
name,
|
|
1720
|
-
isDisabled,
|
|
1721
|
-
editableProps = {},
|
|
1722
|
-
fieldProps = {},
|
|
1723
|
-
inputProps = {},
|
|
1724
|
-
options = [],
|
|
1725
|
-
showMessage,
|
|
1726
|
-
isRequired,
|
|
1727
|
-
onChange
|
|
1728
|
-
} = props;
|
|
1729
|
-
return /*#__PURE__*/React$1.createElement(Field, {
|
|
1730
|
-
name: name
|
|
1731
|
-
}, function Render({
|
|
1732
|
-
input,
|
|
1733
|
-
meta
|
|
1734
|
-
}) {
|
|
1735
|
-
/** Note:
|
|
1736
|
-
* Create "Render" function by "eslint-react-hooks/rules-of-hooks":
|
|
1737
|
-
* React Hooks cannot be called inside a callback.
|
|
1738
|
-
* React Hooks must be called in a React function component or a
|
|
1739
|
-
* custom React Hook function.
|
|
1740
|
-
*/
|
|
1741
|
-
|
|
1742
|
-
const {
|
|
1743
|
-
errorKey,
|
|
1744
|
-
errorMessage,
|
|
1745
|
-
isErrorState,
|
|
1746
|
-
isValidState
|
|
1747
|
-
} = useFieldValidationState({
|
|
1748
|
-
fieldProps: fieldProps,
|
|
1749
|
-
input: input,
|
|
1750
|
-
meta: meta
|
|
1751
|
-
});
|
|
1752
|
-
const updatedInputProps = useValidationAppearanceInputProps({
|
|
1753
|
-
inputProps: inputProps,
|
|
1754
|
-
validationStateKey: isErrorState ? errorKey : 'success'
|
|
1755
|
-
});
|
|
1756
|
-
return /*#__PURE__*/React$1.createElement(FieldWrapper, Object.assign({
|
|
1757
|
-
className: clsx('form-field_type_radio', 'form__item_type_radio"', classNameGroupItem),
|
|
1758
|
-
errorKey: errorKey,
|
|
1759
|
-
errorMessage: errorMessage,
|
|
1760
|
-
isErrorState: isErrorState,
|
|
1761
|
-
metaError: meta.error,
|
|
1762
|
-
isDisabled: isDisabled,
|
|
1763
|
-
fieldClassName: 'form-radio',
|
|
1764
|
-
inputName: input.name,
|
|
1765
|
-
inputValue: input.value || '',
|
|
1766
|
-
metaActive: meta.active,
|
|
1767
|
-
showMessage: showMessage,
|
|
1768
|
-
isRequired: isRequired,
|
|
1769
|
-
isValidState: isValidState
|
|
1770
|
-
}, fieldProps), /*#__PURE__*/React$1.createElement(RadioGroupList, {
|
|
1771
|
-
isDisabled: isDisabled,
|
|
1772
|
-
editableProps: editableProps,
|
|
1773
|
-
input: input,
|
|
1774
|
-
inputProps: updatedInputProps,
|
|
1775
|
-
options: options,
|
|
1776
|
-
onChange: onChange
|
|
1777
|
-
}));
|
|
1778
|
-
});
|
|
1779
|
-
});
|
|
1780
|
-
|
|
1781
|
-
const defaultSegmentedProps = {
|
|
1782
|
-
appearance: 'sizeM surfacePrimary',
|
|
1783
|
-
width: 'fill',
|
|
1784
|
-
errorLabelTextColor: 'errorTextPrimary',
|
|
1785
|
-
requiredLabelTextColor: 'warningTextPrimary',
|
|
1786
|
-
shape: 'rounded'
|
|
1787
|
-
};
|
|
1788
|
-
|
|
1789
|
-
function SegmentedField(props) {
|
|
1790
|
-
const {
|
|
1791
|
-
name,
|
|
1792
|
-
isDisabled,
|
|
1793
|
-
fieldProps,
|
|
1794
|
-
inputProps,
|
|
1795
|
-
options,
|
|
1796
|
-
showMessage,
|
|
1797
|
-
isRequired
|
|
1798
|
-
} = props;
|
|
1799
|
-
const {
|
|
1800
|
-
change
|
|
1801
|
-
} = useForm();
|
|
1802
|
-
const setActiveSegment = useCallback(option => {
|
|
1803
|
-
change(name, option.value);
|
|
1804
|
-
}, [change]);
|
|
1805
|
-
return /*#__PURE__*/React$1.createElement(Field, {
|
|
1806
|
-
name: name
|
|
1807
|
-
}, function Render({
|
|
1808
|
-
input,
|
|
1809
|
-
meta
|
|
1810
|
-
}) {
|
|
1811
|
-
/** Note:
|
|
1812
|
-
* Create "Render" function by "eslint-react-hooks/rules-of-hooks":
|
|
1813
|
-
* React Hooks cannot be called inside a callback.
|
|
1814
|
-
* React Hooks must be called in a React function component or a
|
|
1815
|
-
* custom React Hook function.
|
|
1816
|
-
*/
|
|
1817
|
-
|
|
1818
|
-
const activeOption = useMemo(() => {
|
|
1819
|
-
const emptyOption = {
|
|
1820
|
-
label: null,
|
|
1821
|
-
value: null
|
|
1822
|
-
};
|
|
1823
|
-
if (input.value) {
|
|
1824
|
-
const currentOption = options.find(option => option.value === input.value);
|
|
1825
|
-
return currentOption || emptyOption;
|
|
1826
|
-
}
|
|
1827
|
-
return emptyOption;
|
|
1828
|
-
}, [input.value]);
|
|
1829
|
-
const {
|
|
1830
|
-
errorKey,
|
|
1831
|
-
errorMessage,
|
|
1832
|
-
isErrorState,
|
|
1833
|
-
isValidState
|
|
1834
|
-
} = useFieldValidationState({
|
|
1835
|
-
fieldProps: fieldProps,
|
|
1836
|
-
input: input,
|
|
1837
|
-
meta: meta
|
|
1838
|
-
});
|
|
1839
|
-
const updatedInputProps = useValidationAppearanceInputProps({
|
|
1840
|
-
inputProps: inputProps,
|
|
1841
|
-
validationStateKey: isErrorState ? errorKey : 'success'
|
|
1842
|
-
});
|
|
1843
|
-
return /*#__PURE__*/React$1.createElement(FieldWrapper, Object.assign({
|
|
1844
|
-
className: clsx('form-field_type_segmented', 'form__item_type_segmented'),
|
|
1845
|
-
errorKey: errorKey,
|
|
1846
|
-
errorMessage: errorMessage,
|
|
1847
|
-
isErrorState: isErrorState,
|
|
1848
|
-
metaError: meta.error,
|
|
1849
|
-
isDisabled: isDisabled,
|
|
1850
|
-
fieldClassName: "form-segmented",
|
|
1851
|
-
inputName: input.name,
|
|
1852
|
-
inputValue: input.value || [],
|
|
1853
|
-
metaActive: meta.active,
|
|
1854
|
-
showMessage: showMessage,
|
|
1855
|
-
isRequired: isRequired,
|
|
1856
|
-
isValidState: isValidState
|
|
1857
|
-
}, fieldProps), /*#__PURE__*/React$1.createElement(Segmented, Object.assign({
|
|
1858
|
-
isDisabled: isDisabled,
|
|
1859
|
-
activeSegment: activeOption,
|
|
1860
|
-
segments: options,
|
|
1861
|
-
setActiveSegment: setActiveSegment
|
|
1862
|
-
}, updatedInputProps)));
|
|
1863
|
-
});
|
|
1864
|
-
}
|
|
1865
|
-
|
|
1866
|
-
const defaultSelectProps = {
|
|
1867
|
-
elevation: 8,
|
|
1868
|
-
isClearable: true,
|
|
1869
|
-
isSearchable: true,
|
|
1870
|
-
badgeAppearance: 'accent',
|
|
1871
|
-
badgeSize: 'm',
|
|
1872
|
-
badgeTextSize: 'm',
|
|
1873
|
-
// clearIcon: icon24.Clear,
|
|
1874
|
-
clearIconFill: 'surfaceItemPrimary',
|
|
1875
|
-
closeMenuOnSelect: true,
|
|
1876
|
-
// optionSelected: <Icon iconFill="surfaceItemAccent" SvgImage={icon24.Check} />,
|
|
1877
|
-
|
|
1878
|
-
dividerDirection: 'horizontal',
|
|
1879
|
-
dividerFill: 'surfaceTertiary',
|
|
1880
|
-
dividerSize: 'xxs',
|
|
1881
|
-
// dropdownIcon: icon24.ChevronDownSmall,
|
|
1882
|
-
dropdownIconFill: 'surfaceItemPrimary',
|
|
1883
|
-
// error
|
|
1884
|
-
errorInputBorderColor: 'errorBorderPrimary',
|
|
1885
|
-
headingFill: 'surfaceSecondary',
|
|
1886
|
-
loadingMessage: /*#__PURE__*/React$1.createElement(Loader, {
|
|
1887
|
-
width: "fill",
|
|
1888
|
-
height: "fill",
|
|
1889
|
-
fill: "surfacePrimary",
|
|
1890
|
-
position: "absolute",
|
|
1891
|
-
left: "0px",
|
|
1892
|
-
right: "0px",
|
|
1893
|
-
zIndex: "1",
|
|
1894
|
-
itemFill: "surfaceItemAccent",
|
|
1895
|
-
set: "simple"
|
|
1896
|
-
})
|
|
1897
|
-
};
|
|
1898
|
-
|
|
1899
|
-
function getDefaultValue(options, selectValue) {
|
|
1900
|
-
const selectValues = Array.isArray(selectValue) ? selectValue : [selectValue];
|
|
1901
|
-
let result = [];
|
|
1902
|
-
options.forEach(item => {
|
|
1903
|
-
const isValue = selectValues.includes(item.value);
|
|
1904
|
-
const isLabel = selectValues.includes(item.label);
|
|
1905
|
-
let childOptions = [];
|
|
1906
|
-
if (item.options) {
|
|
1907
|
-
childOptions = getDefaultValue(item.options, selectValue);
|
|
1908
|
-
}
|
|
1909
|
-
if (isValue || isLabel) {
|
|
1910
|
-
result.push(item);
|
|
1911
|
-
} else if (childOptions.length) {
|
|
1912
|
-
result = result.concat(childOptions);
|
|
1913
|
-
}
|
|
1914
|
-
});
|
|
1915
|
-
return result;
|
|
1916
|
-
}
|
|
1917
|
-
const SelectField = /*#__PURE__*/React$1.memo(function SelectField(props) {
|
|
1918
|
-
const {
|
|
1919
|
-
isDisabled,
|
|
1920
|
-
isRequired,
|
|
1921
|
-
classNameGroupItem,
|
|
1922
|
-
fieldProps,
|
|
1923
|
-
initialValue,
|
|
1924
|
-
name,
|
|
1925
|
-
options = [],
|
|
1926
|
-
selectProps,
|
|
1927
|
-
selectRef,
|
|
1928
|
-
showMessage,
|
|
1929
|
-
onChange,
|
|
1930
|
-
onInputChange
|
|
1931
|
-
} = props;
|
|
1932
|
-
return /*#__PURE__*/React$1.createElement(Field, {
|
|
1933
|
-
name: name,
|
|
1934
|
-
initialValue: initialValue
|
|
1935
|
-
}, function Render({
|
|
1936
|
-
input,
|
|
1937
|
-
meta
|
|
1938
|
-
}) {
|
|
1939
|
-
/** Note:
|
|
1940
|
-
* Create "Render" function by "eslint-react-hooks/rules-of-hooks":
|
|
1941
|
-
* React Hooks cannot be called inside a callback.
|
|
1942
|
-
* React Hooks must be called in a React function component or a
|
|
1943
|
-
* custom React Hook function.
|
|
1944
|
-
*/
|
|
1945
|
-
const [selectedOptions, setSelectedOptions] = useState(null);
|
|
1946
|
-
const defaultValue = useMemo(() => {
|
|
1947
|
-
const optionsValues = getDefaultValue(options, input.value);
|
|
1948
|
-
if (!optionsValues.length && input.value?.length) {
|
|
1949
|
-
optionsValues.push({
|
|
1950
|
-
label: input.value,
|
|
1951
|
-
value: input.value
|
|
1952
|
-
});
|
|
1953
|
-
}
|
|
1954
|
-
return optionsValues;
|
|
1955
|
-
}, [input.value]);
|
|
1956
|
-
const onChangeField = useCallback(value => {
|
|
1957
|
-
input.onChange(value);
|
|
1958
|
-
if (onChange) {
|
|
1959
|
-
onChange(value, input.name);
|
|
1960
|
-
}
|
|
1961
|
-
}, [onChange, input.onChange]);
|
|
1962
|
-
const onChangeValue = useCallback((option, actionMeta) => {
|
|
1963
|
-
const value = Array.isArray(option) ? option.map(o => o.value) : option?.value || null;
|
|
1964
|
-
setSelectedOptions(option);
|
|
1965
|
-
onChangeField(value);
|
|
1966
|
-
}, [onChangeField]);
|
|
1967
|
-
useEffect(() => {
|
|
1968
|
-
setSelectedOptions(defaultValue);
|
|
1969
|
-
}, [defaultValue]);
|
|
1970
|
-
const {
|
|
1971
|
-
isErrorState,
|
|
1972
|
-
isValidState,
|
|
1973
|
-
errorKey,
|
|
1974
|
-
errorMessage
|
|
1975
|
-
} = useFieldValidationState({
|
|
1976
|
-
fieldProps: fieldProps,
|
|
1977
|
-
input: input,
|
|
1978
|
-
meta: meta
|
|
1979
|
-
});
|
|
1980
|
-
const updatedSelectProps = useValidationAppearanceInputProps({
|
|
1981
|
-
inputProps: selectProps,
|
|
1982
|
-
validationStateKey: isErrorState ? errorKey : 'success'
|
|
1983
|
-
});
|
|
1984
|
-
return /*#__PURE__*/React$1.createElement(FieldWrapper, Object.assign({
|
|
1985
|
-
className: clsx('form-field_type_select', 'form__item_type_select', classNameGroupItem),
|
|
1986
|
-
errorKey: errorKey,
|
|
1987
|
-
errorMessage: errorMessage,
|
|
1988
|
-
isErrorState: isErrorState,
|
|
1989
|
-
metaError: meta.error,
|
|
1990
|
-
isDisabled: isDisabled,
|
|
1991
|
-
fieldClassName: 'form-select',
|
|
1992
|
-
inputName: input.name,
|
|
1993
|
-
inputValue: input.value,
|
|
1994
|
-
metaActive: meta.active,
|
|
1995
|
-
showMessage: showMessage,
|
|
1996
|
-
isRequired: isRequired,
|
|
1997
|
-
isValidState: isValidState
|
|
1998
|
-
}, fieldProps), /*#__PURE__*/React$1.createElement(Select, Object.assign({
|
|
1999
|
-
className: "form-select-item",
|
|
2000
|
-
isDisabled: isDisabled,
|
|
2001
|
-
instanceId: `id_${input.name}`,
|
|
2002
|
-
options: options,
|
|
2003
|
-
ref: selectRef,
|
|
2004
|
-
value: selectedOptions,
|
|
2005
|
-
onChange: onChangeValue,
|
|
2006
|
-
onInputChange: onInputChange
|
|
2007
|
-
}, updatedSelectProps)));
|
|
2008
|
-
});
|
|
2009
|
-
});
|
|
2010
|
-
|
|
2011
|
-
const defaultSwitchProps = {
|
|
2012
|
-
fieldProps: {
|
|
2013
|
-
width: 'fill',
|
|
2014
|
-
size: 'xl',
|
|
2015
|
-
labelTextColor: 'surfaceTextPrimary',
|
|
2016
|
-
labelTextSize: 's',
|
|
2017
|
-
labelTextWeight: 'normal',
|
|
2018
|
-
textColor: 'surfaceTextPrimary',
|
|
2019
|
-
helpText: 'Supporting text',
|
|
2020
|
-
helpTextColor: 'surfaceTextPrimary',
|
|
2021
|
-
helpTextSize: 's',
|
|
2022
|
-
helpTextWeight: 'normal',
|
|
2023
|
-
showMessage: true
|
|
2024
|
-
},
|
|
2025
|
-
inputProps: {
|
|
2026
|
-
size: 'm',
|
|
2027
|
-
fill: 'surfaceSecondary',
|
|
2028
|
-
title: 'Switch',
|
|
2029
|
-
titleTextColor: 'surfaceTextPrimary',
|
|
2030
|
-
titleTextSize: 's',
|
|
2031
|
-
desc: 'Description',
|
|
2032
|
-
descTextColor: 'surfaceTextPrimary',
|
|
2033
|
-
descTextSize: 'xs'
|
|
2034
|
-
}
|
|
2035
|
-
};
|
|
2036
|
-
|
|
2037
|
-
const SwitchField = /*#__PURE__*/React$1.memo(function SwitchField(props) {
|
|
2038
|
-
const {
|
|
2039
|
-
name,
|
|
2040
|
-
isDisabled,
|
|
2041
|
-
classNameGroupItem,
|
|
2042
|
-
fieldProps = {},
|
|
2043
|
-
inputProps = {},
|
|
2044
|
-
showMessage,
|
|
2045
|
-
isRequired,
|
|
2046
|
-
onChange
|
|
2047
|
-
} = props;
|
|
2048
|
-
return /*#__PURE__*/React$1.createElement(Field, {
|
|
2049
|
-
type: "checkbox",
|
|
2050
|
-
name: name
|
|
2051
|
-
}, function Render({
|
|
2052
|
-
input,
|
|
2053
|
-
meta
|
|
2054
|
-
}) {
|
|
2055
|
-
/** Note:
|
|
2056
|
-
* Create "Render" function by "eslint-react-hooks/rules-of-hooks":
|
|
2057
|
-
* React Hooks cannot be called inside a callback.
|
|
2058
|
-
* React Hooks must be called in a React function component or a
|
|
2059
|
-
* custom React Hook function.
|
|
2060
|
-
*/
|
|
2061
|
-
|
|
2062
|
-
const onChangeField = useCallback(event => {
|
|
2063
|
-
input.onChange(event);
|
|
2064
|
-
if (onChange) {
|
|
2065
|
-
onChange(event.target.checked, input.name);
|
|
2066
|
-
}
|
|
2067
|
-
}, [onChange, input.onChange]);
|
|
2068
|
-
const {
|
|
2069
|
-
errorKey,
|
|
2070
|
-
errorMessage,
|
|
2071
|
-
isErrorState,
|
|
2072
|
-
isValidState
|
|
2073
|
-
} = useFieldValidationState({
|
|
2074
|
-
fieldProps: fieldProps,
|
|
2075
|
-
input: input,
|
|
2076
|
-
meta: meta
|
|
2077
|
-
});
|
|
2078
|
-
const updatedInputProps = useValidationAppearanceInputProps({
|
|
2079
|
-
inputProps: inputProps,
|
|
2080
|
-
validationStateKey: isErrorState ? errorKey : 'success'
|
|
2081
|
-
});
|
|
2082
|
-
return /*#__PURE__*/React$1.createElement(FieldWrapper, Object.assign({
|
|
2083
|
-
className: clsx('form-field_type_switch', 'form__item_type_switch', classNameGroupItem),
|
|
2084
|
-
errorKey: errorKey,
|
|
2085
|
-
errorMessage: errorMessage,
|
|
2086
|
-
isErrorState: isErrorState,
|
|
2087
|
-
metaError: meta.error,
|
|
2088
|
-
isDisabled: isDisabled,
|
|
2089
|
-
fieldClassName: "form-switch",
|
|
2090
|
-
inputName: input.name,
|
|
2091
|
-
inputValue: input.checked,
|
|
2092
|
-
metaActive: meta.active,
|
|
2093
|
-
showMessage: showMessage,
|
|
2094
|
-
tag: "label",
|
|
2095
|
-
isRequired: isRequired,
|
|
2096
|
-
isValidState: isValidState
|
|
2097
|
-
}, fieldProps), /*#__PURE__*/React$1.createElement(Switch, Object.assign({
|
|
2098
|
-
type: "checkbox",
|
|
2099
|
-
name: input.name,
|
|
2100
|
-
isDisabled: isDisabled,
|
|
2101
|
-
autoComplete: "nope",
|
|
2102
|
-
checked: input.checked,
|
|
2103
|
-
onBlur: input.onBlur,
|
|
2104
|
-
onChange: onChangeField,
|
|
2105
|
-
onFocus: input.onFocus
|
|
2106
|
-
}, updatedInputProps)));
|
|
2107
|
-
});
|
|
2108
|
-
});
|
|
2109
|
-
|
|
2110
|
-
const defaultTextareaProps = {
|
|
2111
|
-
appearance: 'sizeM defaultSecondary',
|
|
2112
|
-
width: 'fill',
|
|
2113
|
-
errorBorderColor: 'errorBorderSecondary',
|
|
2114
|
-
requiredBorderColor: 'warningBorderSecondary',
|
|
2115
|
-
shape: 'rounded'
|
|
2116
|
-
};
|
|
2117
|
-
|
|
2118
|
-
const TextareaField = /*#__PURE__*/React$1.memo(function TextareaField(props) {
|
|
2119
|
-
const {
|
|
2120
|
-
name,
|
|
2121
|
-
isDisabled,
|
|
2122
|
-
classNameGroupItem,
|
|
2123
|
-
fieldProps = {},
|
|
2124
|
-
inputProps = {},
|
|
2125
|
-
showMessage,
|
|
2126
|
-
isRequired
|
|
2127
|
-
} = props;
|
|
2128
|
-
return /*#__PURE__*/React$1.createElement(Field, {
|
|
2129
|
-
name: name
|
|
2130
|
-
}, function Render({
|
|
2131
|
-
input,
|
|
2132
|
-
meta
|
|
2133
|
-
}) {
|
|
2134
|
-
/** Note:
|
|
2135
|
-
* Create "Render" function by "eslint-react-hooks/rules-of-hooks":
|
|
2136
|
-
* React Hooks cannot be called inside a callback.
|
|
2137
|
-
* React Hooks must be called in a React function component or a
|
|
2138
|
-
* custom React Hook function.
|
|
2139
|
-
*/
|
|
2140
|
-
|
|
2141
|
-
const {
|
|
2142
|
-
errorKey,
|
|
2143
|
-
errorMessage,
|
|
2144
|
-
isErrorState,
|
|
2145
|
-
isValidState
|
|
2146
|
-
} = useFieldValidationState({
|
|
2147
|
-
fieldProps: fieldProps,
|
|
2148
|
-
input: input,
|
|
2149
|
-
meta: meta
|
|
2150
|
-
});
|
|
2151
|
-
const updatedInputProps = useValidationAppearanceInputProps({
|
|
2152
|
-
inputProps: inputProps,
|
|
2153
|
-
validationStateKey: isErrorState ? errorKey : 'success'
|
|
2154
|
-
});
|
|
2155
|
-
return /*#__PURE__*/React$1.createElement(FieldWrapper, Object.assign({
|
|
2156
|
-
className: clsx('form-field_type_textarea', 'form__item_type_textarea', classNameGroupItem),
|
|
2157
|
-
errorKey: errorKey,
|
|
2158
|
-
errorMessage: errorMessage,
|
|
2159
|
-
isErrorState: isErrorState,
|
|
2160
|
-
metaError: meta.error,
|
|
2161
|
-
isDisabled: isDisabled,
|
|
2162
|
-
fieldClassName: 'form-textarea',
|
|
2163
|
-
inputName: input.name,
|
|
2164
|
-
inputValue: input.value,
|
|
2165
|
-
metaActive: meta.active,
|
|
2166
|
-
showMessage: showMessage,
|
|
2167
|
-
isRequired: isRequired,
|
|
2168
|
-
isValidState: isValidState
|
|
2169
|
-
}, fieldProps), /*#__PURE__*/React$1.createElement(Textarea, Object.assign({
|
|
2170
|
-
name: input.name,
|
|
2171
|
-
isDisabled: isDisabled,
|
|
2172
|
-
autoComplete: "nope",
|
|
2173
|
-
value: input.value,
|
|
2174
|
-
onBlur: input.onBlur,
|
|
2175
|
-
onChange: input.onChange,
|
|
2176
|
-
onFocus: input.onFocus
|
|
2177
|
-
}, updatedInputProps)));
|
|
2178
|
-
});
|
|
2179
|
-
});
|
|
2180
|
-
|
|
2181
|
-
const MaskedInputField = /*#__PURE__*/React$1.memo(function MaskedInputField(props) {
|
|
2182
|
-
const {
|
|
2183
|
-
name,
|
|
2184
|
-
initialValue,
|
|
2185
|
-
isDisabled,
|
|
2186
|
-
classNameGroupItem,
|
|
2187
|
-
clearIcon,
|
|
2188
|
-
clearIconFill,
|
|
2189
|
-
clearIconFillHover,
|
|
2190
|
-
clearIconShape,
|
|
2191
|
-
clearIconSize,
|
|
2192
|
-
fieldProps = {},
|
|
2193
|
-
inputProps = {},
|
|
2194
|
-
optionsMask,
|
|
2195
|
-
showMessage,
|
|
2196
|
-
unmasked,
|
|
2197
|
-
isRequired,
|
|
2198
|
-
onClickClearIcon
|
|
2199
|
-
} = props;
|
|
2200
|
-
return /*#__PURE__*/React$1.createElement(Field, {
|
|
2201
|
-
name: name,
|
|
2202
|
-
initialValue: initialValue
|
|
2203
|
-
}, function Render({
|
|
2204
|
-
input,
|
|
2205
|
-
meta
|
|
2206
|
-
}) {
|
|
2207
|
-
/** Note:
|
|
2208
|
-
* Create "Render" function by "eslint-react-hooks/rules-of-hooks":
|
|
2209
|
-
* React Hooks cannot be called inside a callback.
|
|
2210
|
-
* React Hooks must be called in a React function component or a
|
|
2211
|
-
* custom React Hook function.
|
|
2212
|
-
*/
|
|
2213
|
-
|
|
2214
|
-
const {
|
|
2215
|
-
ref,
|
|
2216
|
-
unmaskedValue,
|
|
2217
|
-
value,
|
|
2218
|
-
setUnmaskedValue
|
|
2219
|
-
} = useIMask(optionsMask, {
|
|
2220
|
-
onAccept: (newValue, event, element) => {
|
|
2221
|
-
if (element) {
|
|
2222
|
-
input.onChange(event._unmaskedValue);
|
|
2223
|
-
}
|
|
2224
|
-
}
|
|
2225
|
-
});
|
|
2226
|
-
useEffect(() => {
|
|
2227
|
-
if (input.value !== unmaskedValue) {
|
|
2228
|
-
setUnmaskedValue(input.value.replace(unmasked, ''));
|
|
2229
|
-
}
|
|
2230
|
-
}, [input.value]);
|
|
2231
|
-
const {
|
|
2232
|
-
errorKey,
|
|
2233
|
-
errorMessage,
|
|
2234
|
-
isErrorState,
|
|
2235
|
-
isValidState
|
|
2236
|
-
} = useFieldValidationState({
|
|
2237
|
-
fieldProps: fieldProps,
|
|
2238
|
-
input: input,
|
|
2239
|
-
meta: meta
|
|
2240
|
-
});
|
|
2241
|
-
const updatedInputProps = useValidationAppearanceInputProps({
|
|
2242
|
-
inputProps: inputProps,
|
|
2243
|
-
validationStateKey: isErrorState ? errorKey : 'success'
|
|
2244
|
-
});
|
|
2245
|
-
return /*#__PURE__*/React$1.createElement(FieldWrapper, Object.assign({
|
|
2246
|
-
className: clsx('form-field_type_maskedInput', 'form__item_type_maskedInput', classNameGroupItem),
|
|
2247
|
-
errorKey: errorKey,
|
|
2248
|
-
errorMessage: errorMessage,
|
|
2249
|
-
isErrorState: isErrorState,
|
|
2250
|
-
metaError: meta.error,
|
|
2251
|
-
isDisabled: isDisabled,
|
|
2252
|
-
fieldClassName: 'form-maskedInput',
|
|
2253
|
-
inputName: input.name,
|
|
2254
|
-
inputValue: input.value,
|
|
2255
|
-
metaActive: meta.active,
|
|
2256
|
-
showMessage: showMessage,
|
|
2257
|
-
isRequired: isRequired,
|
|
2258
|
-
isValidState: isValidState
|
|
2259
|
-
}, fieldProps), /*#__PURE__*/React$1.createElement(Input, Object.assign({
|
|
2260
|
-
className: clsx(meta.active && 'input_state_focus', meta.error && meta.touched && `input_state_${errorKey}`),
|
|
2261
|
-
ref: ref,
|
|
2262
|
-
value: value,
|
|
2263
|
-
onBlur: input.onBlur,
|
|
2264
|
-
onFocus: input.onFocus
|
|
2265
|
-
}, updatedInputProps)), clearIcon && /*#__PURE__*/React$1.createElement(Icon, {
|
|
2266
|
-
className: "form-field__icon",
|
|
2267
|
-
size: clearIconSize,
|
|
2268
|
-
iconFill: clearIconFill,
|
|
2269
|
-
iconFillHover: clearIconFillHover,
|
|
2270
|
-
imageSrc: clearIcon,
|
|
2271
|
-
shape: clearIconShape,
|
|
2272
|
-
SvgImage: clearIcon,
|
|
2273
|
-
onClick: onClickClearIcon
|
|
2274
|
-
}));
|
|
2275
|
-
});
|
|
2276
|
-
});
|
|
2277
|
-
|
|
2278
|
-
const defaultChipsProps = {
|
|
2279
|
-
appearance: 'surfacePrimary',
|
|
2280
|
-
width: 'fill',
|
|
2281
|
-
errorBorderColor: 'errorBorderSecondary',
|
|
2282
|
-
requiredBorderColor: 'warningBorderSecondary'
|
|
2283
|
-
};
|
|
2284
|
-
|
|
2285
|
-
function ChipsField(props) {
|
|
2286
|
-
const {
|
|
2287
|
-
name,
|
|
2288
|
-
initialValue,
|
|
2289
|
-
isDisabled,
|
|
2290
|
-
classNameGroupItem,
|
|
2291
|
-
emptyMessage,
|
|
2292
|
-
emptyMessageTextColor,
|
|
2293
|
-
emptyMessageTextSize,
|
|
2294
|
-
fieldProps,
|
|
2295
|
-
inputProps,
|
|
2296
|
-
options,
|
|
2297
|
-
showMessage,
|
|
2298
|
-
isRequired,
|
|
2299
|
-
onChange
|
|
2300
|
-
} = props;
|
|
2301
|
-
const {
|
|
2302
|
-
change
|
|
2303
|
-
} = useForm();
|
|
2304
|
-
|
|
2305
|
-
// Callback for value changes
|
|
2306
|
-
const onChangeSomeInput = useCallback((inputValue, newOptionValue) => {
|
|
2307
|
-
const updatedValues = inputValue.includes(newOptionValue) ? inputValue.filter(selectedValue => selectedValue !== newOptionValue) : [...inputValue, newOptionValue];
|
|
2308
|
-
change(name, updatedValues);
|
|
2309
|
-
onChange && onChange(updatedValues);
|
|
2310
|
-
}, [change, name, onChange]);
|
|
2311
|
-
useEffect(() => {
|
|
2312
|
-
initialValue && change(name, initialValue);
|
|
2313
|
-
// update the form value only when the initialValue changes, so use disable eslint to ignore the warning
|
|
2314
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2315
|
-
}, [initialValue]);
|
|
2316
|
-
return /*#__PURE__*/React$1.createElement(Field, {
|
|
2317
|
-
name: name,
|
|
2318
|
-
initialValue: initialValue
|
|
2319
|
-
}, function Render({
|
|
2320
|
-
input,
|
|
2321
|
-
meta
|
|
2322
|
-
}) {
|
|
2323
|
-
const {
|
|
2324
|
-
errorKey,
|
|
2325
|
-
errorMessage,
|
|
2326
|
-
isErrorState,
|
|
2327
|
-
isValidState
|
|
2328
|
-
} = useFieldValidationState({
|
|
2329
|
-
fieldProps: fieldProps,
|
|
2330
|
-
input: input,
|
|
2331
|
-
meta: meta
|
|
2332
|
-
});
|
|
2333
|
-
const updatedInputProps = useValidationAppearanceInputProps({
|
|
2334
|
-
inputProps: inputProps,
|
|
2335
|
-
validationStateKey: isErrorState ? errorKey : 'success'
|
|
2336
|
-
});
|
|
2337
|
-
const activeOptionsList = useMemo(() => {
|
|
2338
|
-
const emptyOptionsList = [{
|
|
2339
|
-
label: null,
|
|
2340
|
-
value: null
|
|
2341
|
-
}];
|
|
2342
|
-
if (input?.value) {
|
|
2343
|
-
const currentOptions = options.filter(option => input.value?.includes(option.value));
|
|
2344
|
-
return currentOptions || emptyOptionsList;
|
|
2345
|
-
}
|
|
2346
|
-
return emptyOptionsList;
|
|
2347
|
-
}, [input.value]);
|
|
2348
|
-
return /*#__PURE__*/React$1.createElement(FieldWrapper, Object.assign({
|
|
2349
|
-
className: clsx('form-field_type_chips', 'form__item_type_chips', classNameGroupItem),
|
|
2350
|
-
errorKey: errorKey,
|
|
2351
|
-
errorMessage: errorMessage,
|
|
2352
|
-
isErrorState: isErrorState,
|
|
2353
|
-
metaError: meta.error,
|
|
2354
|
-
isDisabled: isDisabled,
|
|
2355
|
-
fieldClassName: "form-chips",
|
|
2356
|
-
inputName: input.name,
|
|
2357
|
-
inputValue: input.value,
|
|
2358
|
-
metaActive: meta.active,
|
|
2359
|
-
showMessage: showMessage,
|
|
2360
|
-
isRequired: isRequired,
|
|
2361
|
-
isValidState: isValidState
|
|
2362
|
-
}, fieldProps), options.length ? options.map(option => /*#__PURE__*/React$1.createElement(Chips, Object.assign({
|
|
2363
|
-
className: clsx(meta.active && 'form-chips_state_focus', meta.error && meta.touched && `form-chips_state_${errorKey}`),
|
|
2364
|
-
key: option.value,
|
|
2365
|
-
label: option.label,
|
|
2366
|
-
isDisabled: option.isDisabled,
|
|
2367
|
-
value: option.value,
|
|
2368
|
-
isActive: activeOptionsList.some(activeOption => activeOption.value === option.value),
|
|
2369
|
-
onClick: () => onChangeSomeInput(input.value, option.value)
|
|
2370
|
-
}, updatedInputProps))) : /*#__PURE__*/React$1.createElement(Text, {
|
|
2371
|
-
size: emptyMessageTextSize,
|
|
2372
|
-
textColor: emptyMessageTextColor
|
|
2373
|
-
}, emptyMessage));
|
|
2374
|
-
});
|
|
2375
|
-
}
|
|
2376
|
-
|
|
2377
|
-
const formTypes = {
|
|
2378
|
-
code: 'code',
|
|
2379
|
-
text: 'text',
|
|
2380
|
-
textarea: 'textarea',
|
|
2381
|
-
custom: 'custom',
|
|
2382
|
-
checkbox: 'checkbox',
|
|
2383
|
-
chips: 'chips',
|
|
2384
|
-
choice: 'choice',
|
|
2385
|
-
datePicker: 'datePicker',
|
|
2386
|
-
dateRangePicker: 'dateRangePicker',
|
|
2387
|
-
fileInput: 'fileInput',
|
|
2388
|
-
group: 'group',
|
|
2389
|
-
maskedInput: 'maskedInput',
|
|
2390
|
-
radioGroup: 'radioGroup',
|
|
2391
|
-
segmented: 'segmented',
|
|
2392
|
-
select: 'select',
|
|
2393
|
-
switch: 'switch'
|
|
2394
|
-
};
|
|
2395
|
-
function generateField(field, config, props) {
|
|
2396
|
-
switch (field.type) {
|
|
2397
|
-
case formTypes.checkbox:
|
|
2398
|
-
{
|
|
2399
|
-
return /*#__PURE__*/React$1.createElement(CheckboxField, Object.assign({
|
|
2400
|
-
key: config.key
|
|
2401
|
-
}, field, props));
|
|
2402
|
-
}
|
|
2403
|
-
case formTypes.choice:
|
|
2404
|
-
{
|
|
2405
|
-
return /*#__PURE__*/React$1.createElement(ChoiceField, Object.assign({
|
|
2406
|
-
key: config.key
|
|
2407
|
-
}, field, props));
|
|
2408
|
-
}
|
|
2409
|
-
case formTypes.chips:
|
|
2410
|
-
{
|
|
2411
|
-
return /*#__PURE__*/React$1.createElement(ChipsField, Object.assign({
|
|
2412
|
-
key: config.key
|
|
2413
|
-
}, field, props));
|
|
2414
|
-
}
|
|
2415
|
-
case formTypes.code:
|
|
2416
|
-
{
|
|
2417
|
-
return /*#__PURE__*/React$1.createElement(CodeField, Object.assign({
|
|
2418
|
-
key: config.key
|
|
2419
|
-
}, field, props));
|
|
2420
|
-
}
|
|
2421
|
-
case formTypes.switch:
|
|
2422
|
-
{
|
|
2423
|
-
return /*#__PURE__*/React$1.createElement(SwitchField, Object.assign({
|
|
2424
|
-
key: config.key
|
|
2425
|
-
}, field, props));
|
|
2426
|
-
}
|
|
2427
|
-
case formTypes.segmented:
|
|
2428
|
-
{
|
|
2429
|
-
return /*#__PURE__*/React$1.createElement(SegmentedField, Object.assign({
|
|
2430
|
-
key: config.key
|
|
2431
|
-
}, field, props));
|
|
2432
|
-
}
|
|
2433
|
-
case formTypes.datePicker:
|
|
2434
|
-
{
|
|
2435
|
-
return /*#__PURE__*/React$1.createElement(DatePickerField, Object.assign({
|
|
2436
|
-
key: config.key
|
|
2437
|
-
}, field, props));
|
|
2438
|
-
}
|
|
2439
|
-
case formTypes.fileInput:
|
|
2440
|
-
{
|
|
2441
|
-
return /*#__PURE__*/React$1.createElement(FileInput, Object.assign({
|
|
2442
|
-
key: config.key
|
|
2443
|
-
}, field, props));
|
|
2444
|
-
}
|
|
2445
|
-
case formTypes.radioGroup:
|
|
2446
|
-
{
|
|
2447
|
-
return /*#__PURE__*/React$1.createElement(RadioGroup, Object.assign({
|
|
2448
|
-
key: config.key
|
|
2449
|
-
}, field, props));
|
|
2450
|
-
}
|
|
2451
|
-
case formTypes.select:
|
|
2452
|
-
{
|
|
2453
|
-
return /*#__PURE__*/React$1.createElement(SelectField, Object.assign({
|
|
2454
|
-
key: config.key
|
|
2455
|
-
}, field, props));
|
|
2456
|
-
}
|
|
2457
|
-
case formTypes.text:
|
|
2458
|
-
{
|
|
2459
|
-
return /*#__PURE__*/React$1.createElement(InputField, Object.assign({
|
|
2460
|
-
key: config.key
|
|
2461
|
-
}, field, props));
|
|
2462
|
-
}
|
|
2463
|
-
case formTypes.textarea:
|
|
2464
|
-
{
|
|
2465
|
-
return /*#__PURE__*/React$1.createElement(TextareaField, Object.assign({
|
|
2466
|
-
key: config.key
|
|
2467
|
-
}, field, props));
|
|
2468
|
-
}
|
|
2469
|
-
case formTypes.maskedInput:
|
|
2470
|
-
{
|
|
2471
|
-
return /*#__PURE__*/React$1.createElement(MaskedInputField, Object.assign({
|
|
2472
|
-
key: config.key
|
|
2473
|
-
}, field, props));
|
|
2474
|
-
}
|
|
2475
|
-
case formTypes.custom:
|
|
2476
|
-
{
|
|
2477
|
-
return /*#__PURE__*/React$1.createElement(CustomField, Object.assign({
|
|
2478
|
-
key: config.key
|
|
2479
|
-
}, field, props));
|
|
2480
|
-
}
|
|
2481
|
-
case formTypes.group:
|
|
2482
|
-
{
|
|
2483
|
-
return /*#__PURE__*/React$1.createElement(Group, Object.assign({
|
|
2484
|
-
key: config.key
|
|
2485
|
-
}, field, props), Object.entries(field.group).map(([key, value]) => {
|
|
2486
|
-
const groupProps = {
|
|
2487
|
-
...value,
|
|
2488
|
-
classNameGroupItem: value.classNameGroupItem || 'form__group-item',
|
|
2489
|
-
showMessage: field.showMessage
|
|
2490
|
-
};
|
|
2491
|
-
return generateField(groupProps, {
|
|
2492
|
-
key: key + '_form_group'
|
|
2493
|
-
}, props);
|
|
2494
|
-
}));
|
|
2495
|
-
}
|
|
2496
|
-
}
|
|
2497
|
-
}
|
|
2498
|
-
|
|
2499
|
-
const focusOnError = (formElementsList, errors) => {
|
|
2500
|
-
const selectsIds = Object.keys(errors).map(fieldName => {
|
|
2501
|
-
if (fieldName === FORM_ERROR) {
|
|
2502
|
-
// TODO: get from somewhere
|
|
2503
|
-
return 'notification__item_status_error';
|
|
2504
|
-
}
|
|
2505
|
-
return `react-select-id_${fieldName}-input`;
|
|
2506
|
-
});
|
|
2507
|
-
const errorFieldElement = formElementsList.find(element => {
|
|
2508
|
-
if (element.name) {
|
|
2509
|
-
return getIn(errors, element.name);
|
|
2510
|
-
} else {
|
|
2511
|
-
return selectsIds.includes(element.id);
|
|
2512
|
-
}
|
|
2513
|
-
});
|
|
2514
|
-
const errorsList = Object.keys(errors);
|
|
2515
|
-
if (!errorFieldElement && errorsList.length) {
|
|
2516
|
-
let errorElement;
|
|
2517
|
-
try {
|
|
2518
|
-
const fieldName = errorsList[0];
|
|
2519
|
-
if (fieldName === FORM_ERROR) {
|
|
2520
|
-
errorElement = document.querySelector('notification__item_status_error');
|
|
2521
|
-
} else {
|
|
2522
|
-
errorElement = document.querySelector(`#${fieldName}-error`);
|
|
2523
|
-
if (!errorElement) {
|
|
2524
|
-
errorElement = document.querySelector(`#id_${fieldName}`);
|
|
2525
|
-
}
|
|
2526
|
-
}
|
|
2527
|
-
} catch (err) {
|
|
2528
|
-
console.warn(err);
|
|
2529
|
-
}
|
|
2530
|
-
if (errorElement) {
|
|
2531
|
-
errorElement.scrollIntoView({
|
|
2532
|
-
block: 'center'
|
|
2533
|
-
}); // , behavior: 'smooth'
|
|
2534
|
-
}
|
|
2535
|
-
}
|
|
2536
|
-
|
|
2537
|
-
// The field is covered by the header because header is "sticky",
|
|
2538
|
-
// that's we scroll manually so that the field falls into the center of the visible area
|
|
2539
|
-
if (errorFieldElement) {
|
|
2540
|
-
errorFieldElement.scrollIntoView({
|
|
2541
|
-
block: 'center'
|
|
2542
|
-
});
|
|
2543
|
-
}
|
|
2544
|
-
return null;
|
|
2545
|
-
};
|
|
2546
|
-
const focusOnErrorDecorator = createDecorator(null, focusOnError);
|
|
2547
|
-
const setErrorsMutator = (args, state) => {
|
|
2548
|
-
const [fieldName, data] = args;
|
|
2549
|
-
const submitError = data.submitError;
|
|
2550
|
-
const fieldError = data.error;
|
|
2551
|
-
if (fieldName === 'non_field_errors') {
|
|
2552
|
-
// state.formState.invalid = true
|
|
2553
|
-
// state.formState.valid = false
|
|
2554
|
-
state.formState.error = fieldError;
|
|
2555
|
-
state.formState.submitError = submitError;
|
|
2556
|
-
} else if (fieldName in state.fields) {
|
|
2557
|
-
if (fieldError) {
|
|
2558
|
-
const errorsState = Object.assign({}, state.formState.errors, {
|
|
2559
|
-
[fieldName]: fieldError
|
|
2560
|
-
});
|
|
2561
|
-
state.fields[fieldName].touched = true;
|
|
2562
|
-
state.fields[fieldName].error = fieldError;
|
|
2563
|
-
state.formState.errors = errorsState;
|
|
2564
|
-
}
|
|
2565
|
-
if (submitError) {
|
|
2566
|
-
const submitErrorsState = Object.assign({}, state.formState.submitErrors, {
|
|
2567
|
-
[fieldName]: submitError
|
|
2568
|
-
});
|
|
2569
|
-
|
|
2570
|
-
// state.fields[fieldName].submitFailed = true
|
|
2571
|
-
// state.fields[fieldName].submitSucceeded = false
|
|
2572
|
-
state.fields[fieldName].submitError = submitError;
|
|
2573
|
-
state.formState.submitErrors = submitErrorsState;
|
|
2574
|
-
state.formState.submitFailed = true;
|
|
2575
|
-
state.formState.submitSucceeded = false;
|
|
2576
|
-
state.formState.lastSubmittedValues = state.formState.values;
|
|
2577
|
-
}
|
|
2578
|
-
}
|
|
2579
|
-
};
|
|
2580
|
-
const sendFormDataToServer = async (url, data) => {
|
|
2581
|
-
try {
|
|
2582
|
-
const response = await axios({
|
|
2583
|
-
url: url,
|
|
2584
|
-
method: 'POST',
|
|
2585
|
-
data: data
|
|
2586
|
-
});
|
|
2587
|
-
return {
|
|
2588
|
-
success: true,
|
|
2589
|
-
response
|
|
2590
|
-
};
|
|
2591
|
-
} catch (error) {
|
|
2592
|
-
const formErrors = {};
|
|
2593
|
-
if (typeof error.response?.data === 'string') {
|
|
2594
|
-
formErrors[FORM_ERROR] = 'Something went wrong';
|
|
2595
|
-
}
|
|
2596
|
-
if (typeof error.response?.data === 'object') {
|
|
2597
|
-
Object.entries(error.response.data).forEach(([fieldName, errorsList]) => {
|
|
2598
|
-
formErrors[fieldName] = errorsList[0];
|
|
2599
|
-
});
|
|
2600
|
-
}
|
|
2601
|
-
return {
|
|
2602
|
-
success: false,
|
|
2603
|
-
formErrors,
|
|
2604
|
-
error
|
|
2605
|
-
};
|
|
2606
|
-
}
|
|
2607
|
-
};
|
|
2608
|
-
|
|
2609
|
-
const FinalForm = /*#__PURE__*/React$1.forwardRef(function FinalForm(props, ref) {
|
|
2610
|
-
const {
|
|
2611
|
-
className,
|
|
2612
|
-
type,
|
|
2613
|
-
initialValues,
|
|
2614
|
-
initialValuesEqual,
|
|
2615
|
-
config,
|
|
2616
|
-
title,
|
|
2617
|
-
titleFill,
|
|
2618
|
-
titleTextColor,
|
|
2619
|
-
titleTextSize,
|
|
2620
|
-
titleTextWeight,
|
|
2621
|
-
desc,
|
|
2622
|
-
descSize,
|
|
2623
|
-
descTextColor,
|
|
2624
|
-
descTextWeight,
|
|
2625
|
-
primaryButton,
|
|
2626
|
-
primaryButtonFill,
|
|
2627
|
-
primaryButtonFillHover,
|
|
2628
|
-
primaryButtonLabel,
|
|
2629
|
-
primaryButtonLabelSize,
|
|
2630
|
-
primaryButtonLabelTextColor,
|
|
2631
|
-
primaryButtonLabelTextWeight,
|
|
2632
|
-
primaryButtonSize,
|
|
2633
|
-
secondaryButton,
|
|
2634
|
-
secondaryButtonFill,
|
|
2635
|
-
secondaryButtonFillHover,
|
|
2636
|
-
secondaryButtonLabel,
|
|
2637
|
-
secondaryButtonLabelSize,
|
|
2638
|
-
secondaryButtonLabelTextColor,
|
|
2639
|
-
secondaryButtonLabelTextWeight,
|
|
2640
|
-
secondaryButtonSize,
|
|
2641
|
-
tertiaryButton,
|
|
2642
|
-
tertiaryButtonFill,
|
|
2643
|
-
tertiaryButtonFillHover,
|
|
2644
|
-
tertiaryButtonLabel,
|
|
2645
|
-
tertiaryButtonLabelSize,
|
|
2646
|
-
tertiaryButtonLabelTextColor,
|
|
2647
|
-
tertiaryButtonLabelTextWeight,
|
|
2648
|
-
tertiaryButtonSize,
|
|
2649
|
-
dataTestIdPrimaryButton,
|
|
2650
|
-
dataTourPrimaryButton,
|
|
2651
|
-
dataTestIdSecondaryButton,
|
|
2652
|
-
dataTourSecondaryButton,
|
|
2653
|
-
onClickSecondaryButton,
|
|
2654
|
-
dataTestIdTertiaryButton,
|
|
2655
|
-
dataTourTertiaryButton,
|
|
2656
|
-
onClickTertiaryButton,
|
|
2657
|
-
additionalProps = {},
|
|
2658
|
-
buttonDirection = 'vertical',
|
|
2659
|
-
buttonFill,
|
|
2660
|
-
buttonGap,
|
|
2661
|
-
buttonJustifyContent,
|
|
2662
|
-
buttonPadding,
|
|
2663
|
-
buttonPosition,
|
|
2664
|
-
dataTestId,
|
|
2665
|
-
dataTestIdButtons,
|
|
2666
|
-
dataTour,
|
|
2667
|
-
dataTourButtons,
|
|
2668
|
-
disableFieldsAutoComplete = false,
|
|
2669
|
-
fieldsGap,
|
|
2670
|
-
formName,
|
|
2671
|
-
groupGap,
|
|
2672
|
-
language,
|
|
2673
|
-
loader,
|
|
2674
|
-
loaderFill,
|
|
2675
|
-
loaderItemFill,
|
|
2676
|
-
loaderShape,
|
|
2677
|
-
loaderSize,
|
|
2678
|
-
loaderText,
|
|
2679
|
-
loaderType,
|
|
2680
|
-
mutators,
|
|
2681
|
-
notificationCloseButton,
|
|
2682
|
-
notificationType,
|
|
2683
|
-
renderFieldsWrapper = wrapperChildren => wrapperChildren,
|
|
2684
|
-
validationSchema,
|
|
2685
|
-
before,
|
|
2686
|
-
after,
|
|
2687
|
-
isLoading,
|
|
2688
|
-
onChangeFormValues,
|
|
2689
|
-
onSubmit
|
|
2690
|
-
} = props;
|
|
2691
|
-
const validate = useYupValidationSchema(validationSchema, language);
|
|
2692
|
-
const onRefFormInstance = useCallback(formInstance => {
|
|
2693
|
-
if (ref) {
|
|
2694
|
-
ref.current = formInstance;
|
|
2695
|
-
}
|
|
2696
|
-
}, [ref]);
|
|
2697
|
-
const propsGenerator = useDevicePropsGenerator(props);
|
|
2698
|
-
const {
|
|
2699
|
-
directionClass,
|
|
2700
|
-
fillClass,
|
|
2701
|
-
elevationClass,
|
|
2702
|
-
shapeClass
|
|
2703
|
-
} = propsGenerator;
|
|
2704
|
-
const {
|
|
2705
|
-
styles: formStyles,
|
|
2706
|
-
wrapper: wrapperStyles
|
|
2707
|
-
} = useStyles(props);
|
|
2708
|
-
return /*#__PURE__*/React$1.createElement(Form, {
|
|
2709
|
-
initialValues: initialValues,
|
|
2710
|
-
initialValuesEqual: initialValuesEqual,
|
|
2711
|
-
render: ({
|
|
2712
|
-
submitError,
|
|
2713
|
-
form,
|
|
2714
|
-
handleSubmit,
|
|
2715
|
-
modifiedSinceLastSubmit
|
|
2716
|
-
}) => {
|
|
2717
|
-
return /*#__PURE__*/React$1.createElement("form", {
|
|
2718
|
-
className: clsx(className, 'form', type && `form_type_${type}`, buttonPosition && `form_button-position_${buttonPosition}`, directionClass, fillClass, shapeClass, elevationClass),
|
|
2719
|
-
name: formName,
|
|
2720
|
-
autoCapitalize: disableFieldsAutoComplete ? 'off' : undefined,
|
|
2721
|
-
autoComplete: disableFieldsAutoComplete ? 'off' : undefined,
|
|
2722
|
-
autoCorrect: disableFieldsAutoComplete ? 'off' : undefined,
|
|
2723
|
-
"data-test-id": dataTestId,
|
|
2724
|
-
"data-tour": dataTour
|
|
2725
|
-
// We no need set reference to html element, we need reference to "final-form" instance
|
|
2726
|
-
,
|
|
2727
|
-
ref: () => onRefFormInstance(form),
|
|
2728
|
-
spellCheck: disableFieldsAutoComplete ? 'false' : undefined,
|
|
2729
|
-
style: formStyles,
|
|
2730
|
-
onSubmit: handleSubmit
|
|
2731
|
-
}, before, title && /*#__PURE__*/React$1.createElement(Title, {
|
|
2732
|
-
className: "form__title",
|
|
2733
|
-
size: titleTextSize,
|
|
2734
|
-
fill: titleFill,
|
|
2735
|
-
textColor: titleTextColor,
|
|
2736
|
-
textWeight: titleTextWeight
|
|
2737
|
-
}, title), desc && /*#__PURE__*/React$1.createElement(Text, {
|
|
2738
|
-
className: "form__desc",
|
|
2739
|
-
size: descSize,
|
|
2740
|
-
textColor: descTextColor,
|
|
2741
|
-
textWeight: descTextWeight
|
|
2742
|
-
}, desc), submitError && !modifiedSinceLastSubmit && /*#__PURE__*/React$1.createElement("div", {
|
|
2743
|
-
className: clsx('notification', 'form-notification', notificationType ? `form-notification_type_${notificationType}` : 'form-notification_type_global')
|
|
2744
|
-
}, /*#__PURE__*/React$1.createElement(NotificationItem, {
|
|
2745
|
-
className: "form-notification__item",
|
|
2746
|
-
title: form.getState().submitError,
|
|
2747
|
-
titleTextSize: "h6",
|
|
2748
|
-
status: "error",
|
|
2749
|
-
closeButton: notificationCloseButton,
|
|
2750
|
-
set: "form"
|
|
2751
|
-
})), onChangeFormValues && /*#__PURE__*/React$1.createElement(FormSpy, {
|
|
2752
|
-
subscription: {
|
|
2753
|
-
values: true
|
|
2754
|
-
},
|
|
2755
|
-
onChange: onChangeFormValues
|
|
2756
|
-
}), Boolean(Object.keys(config).length) && /*#__PURE__*/React$1.createElement(React$1.Fragment, null, renderFieldsWrapper(/*#__PURE__*/React$1.createElement(Group$1, {
|
|
2757
|
-
className: "form__wrapper",
|
|
2758
|
-
direction: "vertical",
|
|
2759
|
-
gap: fieldsGap || groupGap,
|
|
2760
|
-
style: wrapperStyles
|
|
2761
|
-
}, Object.keys(config).map(key => generateField(config[key], {
|
|
2762
|
-
key
|
|
2763
|
-
}, additionalProps[config[key].name])), isLoading && (loader || /*#__PURE__*/React$1.createElement(Loader, {
|
|
2764
|
-
className: "form__loader",
|
|
2765
|
-
type: loaderType,
|
|
2766
|
-
size: loaderSize,
|
|
2767
|
-
fill: loaderFill,
|
|
2768
|
-
text: loaderText,
|
|
2769
|
-
itemFill: loaderItemFill,
|
|
2770
|
-
shape: loaderShape
|
|
2771
|
-
}))))), (primaryButtonLabel || primaryButton || secondaryButtonLabel || secondaryButton || tertiaryButton || tertiaryButtonLabel) && /*#__PURE__*/React$1.createElement(Group$1, {
|
|
2772
|
-
className: "form__button",
|
|
2773
|
-
direction: buttonDirection,
|
|
2774
|
-
justifyContent: buttonJustifyContent,
|
|
2775
|
-
fill: buttonFill,
|
|
2776
|
-
padding: buttonPadding,
|
|
2777
|
-
gap: buttonGap,
|
|
2778
|
-
dataTestId: dataTestIdButtons,
|
|
2779
|
-
dataTour: dataTourButtons
|
|
2780
|
-
}, primaryButtonLabel ? /*#__PURE__*/React$1.createElement(Button, {
|
|
2781
|
-
className: "form__button-item",
|
|
2782
|
-
width: "fill",
|
|
2783
|
-
size: primaryButtonSize,
|
|
2784
|
-
fill: primaryButtonFill,
|
|
2785
|
-
fillHover: primaryButtonFillHover,
|
|
2786
|
-
label: primaryButtonLabel,
|
|
2787
|
-
labelTextColor: primaryButtonLabelTextColor,
|
|
2788
|
-
labelTextSize: primaryButtonLabelSize,
|
|
2789
|
-
labelTextWeight: primaryButtonLabelTextWeight,
|
|
2790
|
-
dataTestId: dataTestIdPrimaryButton,
|
|
2791
|
-
dataTour: dataTourPrimaryButton
|
|
2792
|
-
}) : primaryButton, secondaryButtonLabel ? /*#__PURE__*/React$1.createElement(Button, {
|
|
2793
|
-
className: "form__button-item",
|
|
2794
|
-
width: "fill",
|
|
2795
|
-
size: secondaryButtonSize,
|
|
2796
|
-
fill: secondaryButtonFill,
|
|
2797
|
-
fillHover: secondaryButtonFillHover,
|
|
2798
|
-
label: secondaryButtonLabel,
|
|
2799
|
-
labelTextColor: secondaryButtonLabelTextColor,
|
|
2800
|
-
labelTextSize: secondaryButtonLabelSize,
|
|
2801
|
-
labelTextWeight: secondaryButtonLabelTextWeight,
|
|
2802
|
-
dataTestId: dataTestIdSecondaryButton,
|
|
2803
|
-
dataTour: dataTourSecondaryButton,
|
|
2804
|
-
onClick: onClickSecondaryButton
|
|
2805
|
-
}) : secondaryButton, tertiaryButtonLabel ? /*#__PURE__*/React$1.createElement(Button, {
|
|
2806
|
-
className: "form__button-item",
|
|
2807
|
-
width: "fill",
|
|
2808
|
-
size: tertiaryButtonSize,
|
|
2809
|
-
fill: tertiaryButtonFill,
|
|
2810
|
-
fillHover: tertiaryButtonFillHover,
|
|
2811
|
-
label: tertiaryButtonLabel,
|
|
2812
|
-
labelTextColor: tertiaryButtonLabelTextColor,
|
|
2813
|
-
labelTextSize: tertiaryButtonLabelSize,
|
|
2814
|
-
labelTextWeight: tertiaryButtonLabelTextWeight,
|
|
2815
|
-
dataTestId: dataTestIdTertiaryButton,
|
|
2816
|
-
dataTour: dataTourTertiaryButton,
|
|
2817
|
-
onClick: onClickTertiaryButton
|
|
2818
|
-
}) : tertiaryButton), after);
|
|
2819
|
-
},
|
|
2820
|
-
decorators: [focusOnErrorDecorator],
|
|
2821
|
-
mutators: mutators,
|
|
2822
|
-
subscription: {
|
|
2823
|
-
submitError: true,
|
|
2824
|
-
modifiedSinceLastSubmit: true,
|
|
2825
|
-
pristine: true,
|
|
2826
|
-
submitting: true
|
|
2827
|
-
},
|
|
2828
|
-
validate: validate,
|
|
2829
|
-
onSubmit: onSubmit
|
|
2830
|
-
});
|
|
2831
|
-
});
|
|
2832
|
-
FinalForm.defaultProps = {
|
|
2833
|
-
direction: 'vertical'
|
|
2834
|
-
};
|
|
2835
|
-
|
|
2836
|
-
const DEFAULT_MESSAGES_FIELDS = {
|
|
2837
|
-
/*
|
|
2838
|
-
!!! it also works without props simply based on the class and key as before `input_state_${meta.error.key}`
|
|
2839
|
-
the KEY is needed for example for border color
|
|
2840
|
-
the name of the key is anything you want, the main thing is that there is a props with the same KEY and color in FieldProps
|
|
2841
|
-
...example
|
|
2842
|
-
required - KEY for yellow color
|
|
2843
|
-
error - KEY for red color
|
|
2844
|
-
custom or blue - KEY blue or other color
|
|
2845
|
-
requiredBorderColor: 'warningBorderPrimary',
|
|
2846
|
-
errorBorderColor: 'errorBorderPrimary',
|
|
2847
|
-
customBorderColor: 'customBorderPrimary',
|
|
2848
|
-
blueBorderColor: 'blueBorderPrimary',
|
|
2849
|
-
const defaultFieldProps = {
|
|
2850
|
-
messageTextSize: 's',
|
|
2851
|
-
messageTextColor: 'surfaceTextSecondary',
|
|
2852
|
-
requiredMessageTextSize: 's',
|
|
2853
|
-
requiredMessageTextColor: 'warningTextPrimary',
|
|
2854
|
-
errorMessageTextSize: 's',
|
|
2855
|
-
errorMessageTextColor: 'errorTextPrimary',
|
|
2856
|
-
}
|
|
2857
|
-
// INPUT
|
|
2858
|
-
const defaultInputProps = {
|
|
2859
|
-
... other
|
|
2860
|
-
stateBorderColor: 'surfaceBorderTertiary',
|
|
2861
|
-
requiredStateBorderColor: 'warningBorderPrimary',
|
|
2862
|
-
errorStateBorderColor: 'errorBorderPrimary',
|
|
2863
|
-
}
|
|
2864
|
-
// RADIO
|
|
2865
|
-
const defaultRadioProps = {
|
|
2866
|
-
... other
|
|
2867
|
-
stateBorderColor: 'surfaceBorderTertiary',
|
|
2868
|
-
requiredStateBorderColor: 'warningBorderPrimary',
|
|
2869
|
-
errorStateBorderColor: 'errorBorderPrimary',
|
|
2870
|
-
}
|
|
2871
|
-
// SELECT
|
|
2872
|
-
const defaultSelectProps = {
|
|
2873
|
-
... other
|
|
2874
|
-
borderColor: 'surfaceBorderTertiary',
|
|
2875
|
-
requiredBorderColor: 'warningBorderPrimary',
|
|
2876
|
-
errorBorderColor: 'errorBorderPrimary',
|
|
2877
|
-
inputBorderColor: 'surfaceBorderTertiary',
|
|
2878
|
-
requiredInputBorderColor: 'warningBorderPrimary',
|
|
2879
|
-
errorInputBorderColor: 'errorBorderPrimary',
|
|
2880
|
-
}
|
|
2881
|
-
... etc
|
|
2882
|
-
*/
|
|
2883
|
-
|
|
2884
|
-
// DEFAULT
|
|
2885
|
-
// required - KEY for yellow color
|
|
2886
|
-
// error - KEY for red color
|
|
2887
|
-
|
|
2888
|
-
// key: 'required'
|
|
2889
|
-
required: {
|
|
2890
|
-
key: 'required',
|
|
2891
|
-
message: 'Обязательное поле'
|
|
2892
|
-
},
|
|
2893
|
-
phone_required: {
|
|
2894
|
-
key: 'required',
|
|
2895
|
-
message: 'Укажите номер телефона'
|
|
2896
|
-
},
|
|
2897
|
-
email_required: {
|
|
2898
|
-
key: 'required',
|
|
2899
|
-
message: 'Укажите адрес электронной почты'
|
|
2900
|
-
},
|
|
2901
|
-
password_required: {
|
|
2902
|
-
key: 'required',
|
|
2903
|
-
message: 'Введите пароль'
|
|
2904
|
-
},
|
|
2905
|
-
phone_or_email_required: {
|
|
2906
|
-
key: 'required',
|
|
2907
|
-
message: 'Введите телефон или адрес эл. почты'
|
|
2908
|
-
},
|
|
2909
|
-
// key: 'error'
|
|
2910
|
-
matches: {
|
|
2911
|
-
key: 'error',
|
|
2912
|
-
message: 'Допускается ввод только цифр от 0 до 9'
|
|
2913
|
-
},
|
|
2914
|
-
min: {
|
|
2915
|
-
key: 'error',
|
|
2916
|
-
message: ({
|
|
2917
|
-
min
|
|
2918
|
-
}) => `Значение должно быть не менее ${min} символов`
|
|
2919
|
-
},
|
|
2920
|
-
max: {
|
|
2921
|
-
key: 'error',
|
|
2922
|
-
message: ({
|
|
2923
|
-
max
|
|
2924
|
-
}) => `Значение должно быть не менее ${max} символов`
|
|
2925
|
-
},
|
|
2926
|
-
url: {
|
|
2927
|
-
key: 'error',
|
|
2928
|
-
message: 'Введите корректный URL-адрес'
|
|
2929
|
-
},
|
|
2930
|
-
invalid_value: {
|
|
2931
|
-
key: 'error',
|
|
2932
|
-
message: 'Некорректное значение'
|
|
2933
|
-
},
|
|
2934
|
-
numeric_value: {
|
|
2935
|
-
key: 'error',
|
|
2936
|
-
message: 'Только числовое значение'
|
|
2937
|
-
},
|
|
2938
|
-
phone_error: {
|
|
2939
|
-
key: 'error',
|
|
2940
|
-
message: 'Введите корректный номер телефона'
|
|
2941
|
-
},
|
|
2942
|
-
email_error: {
|
|
2943
|
-
key: 'error',
|
|
2944
|
-
message: 'Введите корректный адрес электронной почты'
|
|
2945
|
-
}
|
|
2946
|
-
};
|
|
2947
|
-
|
|
2948
|
-
const parseNumericField = value => {
|
|
2949
|
-
const numberValue = value.slice(0, 10).replace(/,/g, '.').replace(/[^\d.]/g, '');
|
|
2950
|
-
const parsedValue = parseFloat(numberValue);
|
|
2951
|
-
if (parsedValue || parsedValue === 0) {
|
|
2952
|
-
if (numberValue.endsWith('.')) {
|
|
2953
|
-
if ((numberValue.match(/\./g) || []).length > 1) {
|
|
2954
|
-
return numberValue.slice(0, -1);
|
|
2955
|
-
}
|
|
2956
|
-
return numberValue;
|
|
2957
|
-
}
|
|
2958
|
-
return numberValue;
|
|
2959
|
-
}
|
|
2960
|
-
return '';
|
|
2961
|
-
};
|
|
2962
|
-
|
|
2963
|
-
// const getErrorsForFinalForm = (errorData) => {
|
|
2964
|
-
// /*
|
|
2965
|
-
// * errorData - its an "axios" error
|
|
2966
|
-
// */
|
|
2967
|
-
|
|
2968
|
-
// const formErrors = {}
|
|
2969
|
-
|
|
2970
|
-
// const responseErrorMessage = errorData.toJSON ? errorData.toJSON().message : errorData.message
|
|
2971
|
-
|
|
2972
|
-
// // const status = (errorData.response && errorData.response.status) || null
|
|
2973
|
-
// const problemError = getProblemFromError(errorData)
|
|
2974
|
-
// // const problemStatus = getProblemFromStatus(status)
|
|
2975
|
-
|
|
2976
|
-
// if (problemError === NETWORK_ERROR || problemError === CONNECTION_ERROR) {
|
|
2977
|
-
// // Say to "react-final-form" that we have general error
|
|
2978
|
-
// formErrors[FORM_ERROR] = 'Проблемы с подключением к сервису'
|
|
2979
|
-
// } else if (errorData.response?.data) {
|
|
2980
|
-
// // Collect errors for some fields, which in the response from server
|
|
2981
|
-
// const serverErrors = errorData.response.data
|
|
2982
|
-
// if (typeof serverErrors === 'string') {
|
|
2983
|
-
// if (errorData.response.status === 500) {
|
|
2984
|
-
// formErrors[FORM_ERROR] =
|
|
2985
|
-
// 'Во время обработки запроса произошла ошибка, попробуйте повторить запрос'
|
|
2986
|
-
// }
|
|
2987
|
-
// // formErrors[FORM_ERROR] = responseErrorMessage
|
|
2988
|
-
// } else {
|
|
2989
|
-
// if (errorData.response.status === 500) {
|
|
2990
|
-
// formErrors[FORM_ERROR] =
|
|
2991
|
-
// 'Во время обработки запроса произошла ошибка, попробуйте повторить запрос'
|
|
2992
|
-
// }
|
|
2993
|
-
// for (const key in serverErrors) {
|
|
2994
|
-
// // TODO: what is forms has "detail" field? show as form error is well?
|
|
2995
|
-
// const errorFieldKey = key === 'non_field_errors' || key === 'detail' ? FORM_ERROR : key
|
|
2996
|
-
// // Say to "react-final-form" that we have some fields errors
|
|
2997
|
-
// formErrors[errorFieldKey] = castArray(serverErrors[key])[0]
|
|
2998
|
-
// }
|
|
2999
|
-
// }
|
|
3000
|
-
// } else if (typeof errorData === 'object' && Object.keys(errorData).length) {
|
|
3001
|
-
// for (const key in errorData) {
|
|
3002
|
-
// const errorFieldKey = key === 'non_field_errors' || key === 'detail' ? FORM_ERROR : key
|
|
3003
|
-
// // Say to "react-final-form" that we have some fields errors
|
|
3004
|
-
// formErrors[errorFieldKey] = castArray(errorData[key])[0]
|
|
3005
|
-
// }
|
|
3006
|
-
// } else {
|
|
3007
|
-
// // Say to "react-final-form" that we have general error
|
|
3008
|
-
// formErrors[FORM_ERROR] = responseErrorMessage || 'Произошла ошибка'
|
|
3009
|
-
// }
|
|
3010
|
-
|
|
3011
|
-
// return formErrors
|
|
3012
|
-
// }
|
|
3013
|
-
|
|
3014
|
-
const getErrorsForFinalForm = error => {
|
|
3015
|
-
/*
|
|
3016
|
-
* error - its an "axios" error in many cases
|
|
3017
|
-
*/
|
|
3018
|
-
|
|
3019
|
-
const formErrors = {};
|
|
3020
|
-
const serverErrors = error.response?.data;
|
|
3021
|
-
if (serverErrors) {
|
|
3022
|
-
// Collect errors for some fields, which in the response from server
|
|
3023
|
-
if (typeof serverErrors === 'string') {
|
|
3024
|
-
// Server may send an html page as error data
|
|
3025
|
-
formErrors[FORM_ERROR] = 'Во время обработки запроса произошла ошибка, попробуйте повторить запрос';
|
|
3026
|
-
} else {
|
|
3027
|
-
for (const key in serverErrors) {
|
|
3028
|
-
// "non_field_errors" and "detail" is special keys in django to mark errors not for fields
|
|
3029
|
-
const errorFieldKey = key === 'non_field_errors' || key === 'detail' ? FORM_ERROR : key;
|
|
3030
|
-
|
|
3031
|
-
// Say to "react-final-form" that we have some fields errors
|
|
3032
|
-
formErrors[errorFieldKey] = castArray(serverErrors[key])[0];
|
|
3033
|
-
}
|
|
3034
|
-
}
|
|
3035
|
-
} else {
|
|
3036
|
-
// const responseErrorMessage = error.toJSON
|
|
3037
|
-
// ? error.toJSON().message
|
|
3038
|
-
// : error.message
|
|
3039
|
-
|
|
3040
|
-
// Say to "react-final-form" that we have general error
|
|
3041
|
-
formErrors[FORM_ERROR] = error.message || 'Произошла ошибка';
|
|
3042
|
-
}
|
|
3043
|
-
return formErrors;
|
|
3044
|
-
};
|
|
3045
|
-
|
|
3046
|
-
export { CheckboxField, ChipsField, ChoiceField, CodeField, CustomField, DEFAULT_MESSAGES_FIELDS, DatePickerField, FieldWrapper, FieldWrapperBase, FileInput, FinalForm, Group, InputField, MaskedInputField, RadioGroup, SegmentedField, SelectField, SwitchField, TextareaField, addRequiredFieldsParamToSchema, dateValidation, defaultCheckboxProps, defaultChipsProps, defaultChoiceProps, defaultCodeProps, defaultDatepickerProps, defaultDropzoneProps, defaultFieldProps, defaultInputProps, defaultRadioProps, defaultSegmentedProps, defaultSelectProps, defaultSwitchProps, defaultTextareaProps, emailValidation, focusOnError, focusOnErrorDecorator, formTypes, generateField, getErrorsForFinalForm, parseNumericField, phoneValidation, sendFormDataToServer, setErrorsMutator, useYupValidationSchema };
|