@itcase/forms 1.1.24 → 1.1.26

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