@cloud-ru/uikit-product-fields-predefined 2.4.8-preview-04a474c4.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/README.md +12 -326
- package/dist/cjs/components/index.d.ts +0 -2
- package/dist/cjs/components/index.js +0 -2
- package/dist/esm/components/index.d.ts +0 -2
- package/dist/esm/components/index.js +0 -2
- package/dist/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +3 -9
- package/src/components/index.ts +0 -2
- package/dist/cjs/components/FieldAi/FieldAi.d.ts +0 -24
- package/dist/cjs/components/FieldAi/FieldAi.js +0 -92
- package/dist/cjs/components/FieldAi/components/AlertButton/AlertButton.d.ts +0 -5
- package/dist/cjs/components/FieldAi/components/AlertButton/AlertButton.js +0 -12
- package/dist/cjs/components/FieldAi/components/AlertButton/index.d.ts +0 -1
- package/dist/cjs/components/FieldAi/components/AlertButton/index.js +0 -17
- package/dist/cjs/components/FieldAi/components/AlertButton/styles.module.css +0 -17
- package/dist/cjs/components/FieldAi/components/CheckItem/CheckItem.d.ts +0 -9
- package/dist/cjs/components/FieldAi/components/CheckItem/CheckItem.js +0 -28
- package/dist/cjs/components/FieldAi/components/CheckItem/index.d.ts +0 -1
- package/dist/cjs/components/FieldAi/components/CheckItem/index.js +0 -17
- package/dist/cjs/components/FieldAi/components/CheckItem/styles.module.css +0 -36
- package/dist/cjs/components/FieldAi/components/MobileFieldAi/MobileFieldAi.d.ts +0 -5
- package/dist/cjs/components/FieldAi/components/MobileFieldAi/MobileFieldAi.js +0 -31
- package/dist/cjs/components/FieldAi/components/MobileFieldAi/index.d.ts +0 -1
- package/dist/cjs/components/FieldAi/components/MobileFieldAi/index.js +0 -17
- package/dist/cjs/components/FieldAi/components/MobileFieldAi/styles.module.css +0 -78
- package/dist/cjs/components/FieldAi/components/PasswordValidation/PasswordValidation.d.ts +0 -7
- package/dist/cjs/components/FieldAi/components/PasswordValidation/PasswordValidation.js +0 -23
- package/dist/cjs/components/FieldAi/components/PasswordValidation/index.d.ts +0 -1
- package/dist/cjs/components/FieldAi/components/PasswordValidation/index.js +0 -17
- package/dist/cjs/components/FieldAi/components/PasswordValidation/styles.module.css +0 -36
- package/dist/cjs/components/FieldAi/components/TextArea/TextArea.d.ts +0 -39
- package/dist/cjs/components/FieldAi/components/TextArea/TextArea.js +0 -33
- package/dist/cjs/components/FieldAi/components/TextArea/index.d.ts +0 -1
- package/dist/cjs/components/FieldAi/components/TextArea/index.js +0 -17
- package/dist/cjs/components/FieldAi/components/TextArea/styles.module.css +0 -32
- package/dist/cjs/components/FieldAi/components/WithPasswordValidation/WithPasswordValidation.d.ts +0 -10
- package/dist/cjs/components/FieldAi/components/WithPasswordValidation/WithPasswordValidation.js +0 -23
- package/dist/cjs/components/FieldAi/components/WithPasswordValidation/index.d.ts +0 -1
- package/dist/cjs/components/FieldAi/components/WithPasswordValidation/index.js +0 -17
- package/dist/cjs/components/FieldAi/components/WithPasswordValidation/styles.module.css +0 -6
- package/dist/cjs/components/FieldAi/index.d.ts +0 -1
- package/dist/cjs/components/FieldAi/index.js +0 -17
- package/dist/cjs/components/FieldAi/styles.module.css +0 -61
- package/dist/cjs/components/FieldAi/utils.d.ts +0 -10
- package/dist/cjs/components/FieldAi/utils.js +0 -19
- package/dist/cjs/components/FieldCode/FieldCode.d.ts +0 -33
- package/dist/cjs/components/FieldCode/FieldCode.js +0 -48
- package/dist/cjs/components/FieldCode/components/Cell/Cell.d.ts +0 -5
- package/dist/cjs/components/FieldCode/components/Cell/Cell.js +0 -27
- package/dist/cjs/components/FieldCode/components/Cell/index.d.ts +0 -1
- package/dist/cjs/components/FieldCode/components/Cell/index.js +0 -17
- package/dist/cjs/components/FieldCode/components/Cell/styles.module.css +0 -3
- package/dist/cjs/components/FieldCode/components/ResendCode/ResendCode.d.ts +0 -8
- package/dist/cjs/components/FieldCode/components/ResendCode/ResendCode.js +0 -28
- package/dist/cjs/components/FieldCode/components/ResendCode/index.d.ts +0 -1
- package/dist/cjs/components/FieldCode/components/ResendCode/index.js +0 -17
- package/dist/cjs/components/FieldCode/components/ResendCode/utils.d.ts +0 -1
- package/dist/cjs/components/FieldCode/components/ResendCode/utils.js +0 -8
- package/dist/cjs/components/FieldCode/components/index.d.ts +0 -2
- package/dist/cjs/components/FieldCode/components/index.js +0 -18
- package/dist/cjs/components/FieldCode/constants.d.ts +0 -14
- package/dist/cjs/components/FieldCode/constants.js +0 -10
- package/dist/cjs/components/FieldCode/hooks/index.d.ts +0 -4
- package/dist/cjs/components/FieldCode/hooks/index.js +0 -20
- package/dist/cjs/components/FieldCode/hooks/useCodeInput.d.ts +0 -22
- package/dist/cjs/components/FieldCode/hooks/useCodeInput.js +0 -98
- package/dist/cjs/components/FieldCode/hooks/useFieldCodeValidate.d.ts +0 -8
- package/dist/cjs/components/FieldCode/hooks/useFieldCodeValidate.js +0 -24
- package/dist/cjs/components/FieldCode/hooks/useFieldHelpers.d.ts +0 -13
- package/dist/cjs/components/FieldCode/hooks/useFieldHelpers.js +0 -34
- package/dist/cjs/components/FieldCode/hooks/useFocusCell.d.ts +0 -5
- package/dist/cjs/components/FieldCode/hooks/useFocusCell.js +0 -22
- package/dist/cjs/components/FieldCode/index.d.ts +0 -2
- package/dist/cjs/components/FieldCode/index.js +0 -20
- package/dist/cjs/components/FieldCode/styles.module.css +0 -30
- package/dist/cjs/components/FieldCode/utils.d.ts +0 -6
- package/dist/cjs/components/FieldCode/utils.js +0 -21
- package/dist/esm/components/FieldAi/FieldAi.d.ts +0 -24
- package/dist/esm/components/FieldAi/FieldAi.js +0 -86
- package/dist/esm/components/FieldAi/components/AlertButton/AlertButton.d.ts +0 -5
- package/dist/esm/components/FieldAi/components/AlertButton/AlertButton.js +0 -6
- package/dist/esm/components/FieldAi/components/AlertButton/index.d.ts +0 -1
- package/dist/esm/components/FieldAi/components/AlertButton/index.js +0 -1
- package/dist/esm/components/FieldAi/components/AlertButton/styles.module.css +0 -17
- package/dist/esm/components/FieldAi/components/CheckItem/CheckItem.d.ts +0 -9
- package/dist/esm/components/FieldAi/components/CheckItem/CheckItem.js +0 -22
- package/dist/esm/components/FieldAi/components/CheckItem/index.d.ts +0 -1
- package/dist/esm/components/FieldAi/components/CheckItem/index.js +0 -1
- package/dist/esm/components/FieldAi/components/CheckItem/styles.module.css +0 -36
- package/dist/esm/components/FieldAi/components/MobileFieldAi/MobileFieldAi.d.ts +0 -5
- package/dist/esm/components/FieldAi/components/MobileFieldAi/MobileFieldAi.js +0 -25
- package/dist/esm/components/FieldAi/components/MobileFieldAi/index.d.ts +0 -1
- package/dist/esm/components/FieldAi/components/MobileFieldAi/index.js +0 -1
- package/dist/esm/components/FieldAi/components/MobileFieldAi/styles.module.css +0 -78
- package/dist/esm/components/FieldAi/components/PasswordValidation/PasswordValidation.d.ts +0 -7
- package/dist/esm/components/FieldAi/components/PasswordValidation/PasswordValidation.js +0 -17
- package/dist/esm/components/FieldAi/components/PasswordValidation/index.d.ts +0 -1
- package/dist/esm/components/FieldAi/components/PasswordValidation/index.js +0 -1
- package/dist/esm/components/FieldAi/components/PasswordValidation/styles.module.css +0 -36
- package/dist/esm/components/FieldAi/components/TextArea/TextArea.d.ts +0 -39
- package/dist/esm/components/FieldAi/components/TextArea/TextArea.js +0 -27
- package/dist/esm/components/FieldAi/components/TextArea/index.d.ts +0 -1
- package/dist/esm/components/FieldAi/components/TextArea/index.js +0 -1
- package/dist/esm/components/FieldAi/components/TextArea/styles.module.css +0 -32
- package/dist/esm/components/FieldAi/components/WithPasswordValidation/WithPasswordValidation.d.ts +0 -10
- package/dist/esm/components/FieldAi/components/WithPasswordValidation/WithPasswordValidation.js +0 -17
- package/dist/esm/components/FieldAi/components/WithPasswordValidation/index.d.ts +0 -1
- package/dist/esm/components/FieldAi/components/WithPasswordValidation/index.js +0 -1
- package/dist/esm/components/FieldAi/components/WithPasswordValidation/styles.module.css +0 -6
- package/dist/esm/components/FieldAi/index.d.ts +0 -1
- package/dist/esm/components/FieldAi/index.js +0 -1
- package/dist/esm/components/FieldAi/styles.module.css +0 -61
- package/dist/esm/components/FieldAi/utils.d.ts +0 -10
- package/dist/esm/components/FieldAi/utils.js +0 -15
- package/dist/esm/components/FieldCode/FieldCode.d.ts +0 -33
- package/dist/esm/components/FieldCode/FieldCode.js +0 -41
- package/dist/esm/components/FieldCode/components/Cell/Cell.d.ts +0 -5
- package/dist/esm/components/FieldCode/components/Cell/Cell.js +0 -21
- package/dist/esm/components/FieldCode/components/Cell/index.d.ts +0 -1
- package/dist/esm/components/FieldCode/components/Cell/index.js +0 -1
- package/dist/esm/components/FieldCode/components/Cell/styles.module.css +0 -3
- package/dist/esm/components/FieldCode/components/ResendCode/ResendCode.d.ts +0 -8
- package/dist/esm/components/FieldCode/components/ResendCode/ResendCode.js +0 -25
- package/dist/esm/components/FieldCode/components/ResendCode/index.d.ts +0 -1
- package/dist/esm/components/FieldCode/components/ResendCode/index.js +0 -1
- package/dist/esm/components/FieldCode/components/ResendCode/utils.d.ts +0 -1
- package/dist/esm/components/FieldCode/components/ResendCode/utils.js +0 -5
- package/dist/esm/components/FieldCode/components/index.d.ts +0 -2
- package/dist/esm/components/FieldCode/components/index.js +0 -2
- package/dist/esm/components/FieldCode/constants.d.ts +0 -14
- package/dist/esm/components/FieldCode/constants.js +0 -7
- package/dist/esm/components/FieldCode/hooks/index.d.ts +0 -4
- package/dist/esm/components/FieldCode/hooks/index.js +0 -4
- package/dist/esm/components/FieldCode/hooks/useCodeInput.d.ts +0 -22
- package/dist/esm/components/FieldCode/hooks/useCodeInput.js +0 -95
- package/dist/esm/components/FieldCode/hooks/useFieldCodeValidate.d.ts +0 -8
- package/dist/esm/components/FieldCode/hooks/useFieldCodeValidate.js +0 -21
- package/dist/esm/components/FieldCode/hooks/useFieldHelpers.d.ts +0 -13
- package/dist/esm/components/FieldCode/hooks/useFieldHelpers.js +0 -31
- package/dist/esm/components/FieldCode/hooks/useFocusCell.d.ts +0 -5
- package/dist/esm/components/FieldCode/hooks/useFocusCell.js +0 -19
- package/dist/esm/components/FieldCode/index.d.ts +0 -2
- package/dist/esm/components/FieldCode/index.js +0 -2
- package/dist/esm/components/FieldCode/styles.module.css +0 -30
- package/dist/esm/components/FieldCode/utils.d.ts +0 -6
- package/dist/esm/components/FieldCode/utils.js +0 -13
- package/src/components/FieldAi/FieldAi.tsx +0 -201
- package/src/components/FieldAi/components/AlertButton/AlertButton.tsx +0 -16
- package/src/components/FieldAi/components/AlertButton/index.ts +0 -1
- package/src/components/FieldAi/components/AlertButton/styles.module.scss +0 -20
- package/src/components/FieldAi/components/CheckItem/CheckItem.tsx +0 -45
- package/src/components/FieldAi/components/CheckItem/index.ts +0 -1
- package/src/components/FieldAi/components/CheckItem/styles.module.scss +0 -44
- package/src/components/FieldAi/components/MobileFieldAi/MobileFieldAi.tsx +0 -57
- package/src/components/FieldAi/components/MobileFieldAi/index.ts +0 -1
- package/src/components/FieldAi/components/MobileFieldAi/styles.module.scss +0 -90
- package/src/components/FieldAi/components/PasswordValidation/PasswordValidation.tsx +0 -85
- package/src/components/FieldAi/components/PasswordValidation/index.ts +0 -1
- package/src/components/FieldAi/components/PasswordValidation/styles.module.scss +0 -34
- package/src/components/FieldAi/components/TextArea/TextArea.tsx +0 -113
- package/src/components/FieldAi/components/TextArea/index.ts +0 -1
- package/src/components/FieldAi/components/TextArea/styles.module.scss +0 -35
- package/src/components/FieldAi/components/WithPasswordValidation/WithPasswordValidation.tsx +0 -63
- package/src/components/FieldAi/components/WithPasswordValidation/index.ts +0 -1
- package/src/components/FieldAi/components/WithPasswordValidation/styles.module.scss +0 -8
- package/src/components/FieldAi/index.ts +0 -1
- package/src/components/FieldAi/styles.module.scss +0 -85
- package/src/components/FieldAi/utils.ts +0 -27
- package/src/components/FieldCode/FieldCode.tsx +0 -125
- package/src/components/FieldCode/components/Cell/Cell.tsx +0 -32
- package/src/components/FieldCode/components/Cell/index.ts +0 -1
- package/src/components/FieldCode/components/Cell/styles.module.scss +0 -5
- package/src/components/FieldCode/components/ResendCode/ResendCode.tsx +0 -33
- package/src/components/FieldCode/components/ResendCode/index.ts +0 -1
- package/src/components/FieldCode/components/ResendCode/utils.ts +0 -5
- package/src/components/FieldCode/components/index.ts +0 -2
- package/src/components/FieldCode/constants.ts +0 -20
- package/src/components/FieldCode/hooks/index.ts +0 -4
- package/src/components/FieldCode/hooks/useCodeInput.ts +0 -147
- package/src/components/FieldCode/hooks/useFieldCodeValidate.ts +0 -35
- package/src/components/FieldCode/hooks/useFieldHelpers.ts +0 -52
- package/src/components/FieldCode/hooks/useFocusCell.ts +0 -29
- package/src/components/FieldCode/index.ts +0 -2
- package/src/components/FieldCode/styles.module.scss +0 -40
- package/src/components/FieldCode/utils.ts +0 -23
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { useRefState } from '@siberiacancode/reactuse';
|
|
2
|
-
import { useCallback, useEffect } from 'react';
|
|
3
|
-
import { useValueControl } from '@snack-uikit/utils';
|
|
4
|
-
import { ZERO_WIDTH_SPACE } from '../constants';
|
|
5
|
-
import { isNumberChar, isStringCodeLength, isZeroWidthSpace } from '../utils';
|
|
6
|
-
const buildCodeArray = (str, codeLength) => Array.from({ length: codeLength }, (_, idx) => str[idx] || ZERO_WIDTH_SPACE);
|
|
7
|
-
export function useCodeInput(params) {
|
|
8
|
-
const { value: valueProp, onChange: onChangeProp, codeLength, moveFocus, onComplete } = params;
|
|
9
|
-
const [value = '', onChange] = useValueControl({
|
|
10
|
-
value: valueProp,
|
|
11
|
-
onChange: onChangeProp,
|
|
12
|
-
defaultValue: '',
|
|
13
|
-
});
|
|
14
|
-
const codeRef = useRefState(buildCodeArray(value, codeLength));
|
|
15
|
-
const updateCodeByIndex = useCallback((index, newChar) => {
|
|
16
|
-
codeRef.current[index] = newChar;
|
|
17
|
-
onChange === null || onChange === void 0 ? void 0 : onChange(codeRef.current.join(''));
|
|
18
|
-
}, [codeRef, onChange]);
|
|
19
|
-
const updateFullCode = useCallback((newCode) => {
|
|
20
|
-
codeRef.current = newCode.split('');
|
|
21
|
-
onChange === null || onChange === void 0 ? void 0 : onChange(newCode);
|
|
22
|
-
moveFocus(codeLength - 1);
|
|
23
|
-
onComplete === null || onComplete === void 0 ? void 0 : onComplete(newCode);
|
|
24
|
-
}, [codeLength, codeRef, moveFocus, onChange, onComplete]);
|
|
25
|
-
const handleAfterCellUpdate = useCallback((index) => {
|
|
26
|
-
const normalizedCode = codeRef.current.join('');
|
|
27
|
-
const isLastInput = index === codeLength - 1;
|
|
28
|
-
const isAllInputsFilled = isStringCodeLength(normalizedCode, codeLength);
|
|
29
|
-
if (!isLastInput) {
|
|
30
|
-
moveFocus(index + 1);
|
|
31
|
-
}
|
|
32
|
-
else if (isAllInputsFilled) {
|
|
33
|
-
onComplete === null || onComplete === void 0 ? void 0 : onComplete(normalizedCode);
|
|
34
|
-
}
|
|
35
|
-
}, [codeLength, codeRef, moveFocus, onComplete]);
|
|
36
|
-
const deleteChar = useCallback((index) => {
|
|
37
|
-
if (codeRef.current[index] && !isZeroWidthSpace(codeRef.current[index])) {
|
|
38
|
-
updateCodeByIndex(index, ZERO_WIDTH_SPACE);
|
|
39
|
-
}
|
|
40
|
-
else if (index > 0) {
|
|
41
|
-
moveFocus(index - 1);
|
|
42
|
-
}
|
|
43
|
-
}, [codeRef, moveFocus, updateCodeByIndex]);
|
|
44
|
-
const onAutoCompleteInput = useCallback((code, index) => {
|
|
45
|
-
if (isStringCodeLength(code, codeLength)) {
|
|
46
|
-
updateFullCode(code);
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
if (!isNumberChar(code)) {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
updateCodeByIndex(index, code);
|
|
53
|
-
handleAfterCellUpdate(index);
|
|
54
|
-
}, [codeLength, handleAfterCellUpdate, updateCodeByIndex, updateFullCode]);
|
|
55
|
-
const onKeyDown = useCallback((e, index) => {
|
|
56
|
-
switch (e.key) {
|
|
57
|
-
case 'ArrowLeft':
|
|
58
|
-
moveFocus(index - 1);
|
|
59
|
-
break;
|
|
60
|
-
case 'ArrowRight':
|
|
61
|
-
moveFocus(index + 1);
|
|
62
|
-
break;
|
|
63
|
-
case 'Backspace':
|
|
64
|
-
deleteChar(index);
|
|
65
|
-
break;
|
|
66
|
-
default:
|
|
67
|
-
if (isNumberChar(e.key)) {
|
|
68
|
-
e.preventDefault();
|
|
69
|
-
updateCodeByIndex(index, e.key);
|
|
70
|
-
handleAfterCellUpdate(index);
|
|
71
|
-
}
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
}, [deleteChar, handleAfterCellUpdate, moveFocus, updateCodeByIndex]);
|
|
75
|
-
const onPaste = useCallback((e) => {
|
|
76
|
-
var _a;
|
|
77
|
-
const codeInput = (_a = e === null || e === void 0 ? void 0 : e.clipboardData.getData('text')) !== null && _a !== void 0 ? _a : '';
|
|
78
|
-
if (!isStringCodeLength(codeInput, codeLength)) {
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
updateFullCode(codeInput);
|
|
82
|
-
}, [codeLength, updateFullCode]);
|
|
83
|
-
useEffect(() => {
|
|
84
|
-
codeRef.current = buildCodeArray(value, codeLength);
|
|
85
|
-
}, [codeLength, codeRef, value]);
|
|
86
|
-
return {
|
|
87
|
-
code: codeRef.current,
|
|
88
|
-
cellHandlers: {
|
|
89
|
-
onKeyDown,
|
|
90
|
-
onPaste,
|
|
91
|
-
onChange: onAutoCompleteInput,
|
|
92
|
-
},
|
|
93
|
-
onChangeCode: onChange,
|
|
94
|
-
};
|
|
95
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export type UseFieldCodeValidateParams = {
|
|
2
|
-
/** Ожидаемая длина кода (цифр) */
|
|
3
|
-
codeLength: number;
|
|
4
|
-
};
|
|
5
|
-
/**
|
|
6
|
-
* Возвращает функцию валидации значения кода (пусто / неполный код).
|
|
7
|
-
*/
|
|
8
|
-
export declare function useFieldCodeValidate(params: UseFieldCodeValidateParams): (value?: string | number) => string | undefined;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { useCallback } from 'react';
|
|
2
|
-
import { useLocale } from '@cloud-ru/uikit-product-locale';
|
|
3
|
-
import { isNumberChar } from '../utils';
|
|
4
|
-
/**
|
|
5
|
-
* Возвращает функцию валидации значения кода (пусто / неполный код).
|
|
6
|
-
*/
|
|
7
|
-
export function useFieldCodeValidate(params) {
|
|
8
|
-
const { codeLength } = params;
|
|
9
|
-
const { t } = useLocale('FieldsPredefined');
|
|
10
|
-
return useCallback((value) => {
|
|
11
|
-
const str = value != null ? String(value) : '';
|
|
12
|
-
const digits = str.split('').filter(isNumberChar).join('');
|
|
13
|
-
if (digits.length === 0) {
|
|
14
|
-
return t('FieldCode.required');
|
|
15
|
-
}
|
|
16
|
-
if (digits.length < codeLength) {
|
|
17
|
-
return t('FieldCode.minLength', { count: codeLength });
|
|
18
|
-
}
|
|
19
|
-
return undefined;
|
|
20
|
-
}, [codeLength, t]);
|
|
21
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { type FieldCodeFocusEffect } from '../constants';
|
|
2
|
-
type UseFieldHelpersParams = {
|
|
3
|
-
onChangeCode: (code: string) => void;
|
|
4
|
-
moveFocus: (index: number) => void;
|
|
5
|
-
focusEffects: readonly FieldCodeFocusEffect[];
|
|
6
|
-
showEmptyChars?: boolean;
|
|
7
|
-
code: readonly string[];
|
|
8
|
-
codeLength: number;
|
|
9
|
-
};
|
|
10
|
-
export declare function useFieldHelpers(params: UseFieldHelpersParams): {
|
|
11
|
-
resetCode: () => void;
|
|
12
|
-
};
|
|
13
|
-
export {};
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { useCallback, useEffect, useMemo } from 'react';
|
|
2
|
-
import { getFirstEmptyCellIndex } from '../utils';
|
|
3
|
-
export function useFieldHelpers(params) {
|
|
4
|
-
const { onChangeCode, moveFocus, focusEffects: focusEffectsProp, showEmptyChars, code, codeLength } = params;
|
|
5
|
-
const focusEffectsKey = [...focusEffectsProp].sort().join(',');
|
|
6
|
-
const focusEffects = useMemo(() => [...focusEffectsProp],
|
|
7
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
8
|
-
[focusEffectsKey]);
|
|
9
|
-
const resetCode = useCallback(() => {
|
|
10
|
-
onChangeCode('');
|
|
11
|
-
if (focusEffects.includes('firstCellOnReset')) {
|
|
12
|
-
moveFocus(0);
|
|
13
|
-
}
|
|
14
|
-
}, [focusEffects, moveFocus, onChangeCode]);
|
|
15
|
-
useEffect(() => {
|
|
16
|
-
if (focusEffects.includes('firstCellOnMount')) {
|
|
17
|
-
moveFocus(0);
|
|
18
|
-
}
|
|
19
|
-
}, [focusEffects, moveFocus]);
|
|
20
|
-
useEffect(() => {
|
|
21
|
-
if (!focusEffects.includes('firstCellWhenShowEmptyChars') || !showEmptyChars) {
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
const emptyIndex = getFirstEmptyCellIndex(code);
|
|
25
|
-
if (emptyIndex >= 0) {
|
|
26
|
-
moveFocus(emptyIndex);
|
|
27
|
-
}
|
|
28
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
29
|
-
}, [showEmptyChars, focusEffects, moveFocus, codeLength]);
|
|
30
|
-
return { resetCode };
|
|
31
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { useCallback, useRef } from 'react';
|
|
2
|
-
export function useFocusCell(codeLength) {
|
|
3
|
-
const inputsRef = useRef([]);
|
|
4
|
-
const focusInput = useCallback((index) => {
|
|
5
|
-
var _a;
|
|
6
|
-
(_a = inputsRef.current[index]) === null || _a === void 0 ? void 0 : _a.focus();
|
|
7
|
-
}, [inputsRef]);
|
|
8
|
-
const moveFocus = useCallback((newIndex) => {
|
|
9
|
-
if (newIndex >= 0 && newIndex < codeLength) {
|
|
10
|
-
focusInput(newIndex);
|
|
11
|
-
}
|
|
12
|
-
}, [codeLength, focusInput]);
|
|
13
|
-
const blurFields = useCallback(() => {
|
|
14
|
-
inputsRef.current.forEach(input => {
|
|
15
|
-
input === null || input === void 0 ? void 0 : input.blur();
|
|
16
|
-
});
|
|
17
|
-
}, [inputsRef]);
|
|
18
|
-
return { inputsRef, moveFocus, blurFields };
|
|
19
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
.fieldCode{
|
|
2
|
-
display:flex;
|
|
3
|
-
flex-direction:column;
|
|
4
|
-
align-items:center;
|
|
5
|
-
gap:8px;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
.codeContainer{
|
|
9
|
-
display:flex;
|
|
10
|
-
justify-content:center;
|
|
11
|
-
}
|
|
12
|
-
.codeContainer[data-size=s]{
|
|
13
|
-
gap:8px;
|
|
14
|
-
}
|
|
15
|
-
.codeContainer[data-size=m]{
|
|
16
|
-
gap:8px;
|
|
17
|
-
}
|
|
18
|
-
.codeContainer[data-size=l]{
|
|
19
|
-
gap:12px;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
.cellSpacing[data-size=s]{
|
|
23
|
-
margin-right:2px;
|
|
24
|
-
}
|
|
25
|
-
.cellSpacing[data-size=m]{
|
|
26
|
-
margin-right:8px;
|
|
27
|
-
}
|
|
28
|
-
.cellSpacing[data-size=l]{
|
|
29
|
-
margin-right:12px;
|
|
30
|
-
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { FieldTextProps } from '@snack-uikit/fields';
|
|
2
|
-
export declare const isNumberChar: (char: string) => boolean;
|
|
3
|
-
export declare const isStringCodeLength: (input: string, codeLength: number) => boolean;
|
|
4
|
-
export declare const isZeroWidthSpace: (value: string) => value is "";
|
|
5
|
-
export declare function getFirstEmptyCellIndex(code: readonly string[]): number;
|
|
6
|
-
export declare const getCellValidationState: (value: string, showEmptyChars?: boolean, error?: boolean) => FieldTextProps["validationState"];
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { ZERO_WIDTH_SPACE } from './constants';
|
|
2
|
-
export const isNumberChar = (char) => /^\d$/.test(char);
|
|
3
|
-
export const isStringCodeLength = (input, codeLength) => new RegExp(`^\\d{${codeLength}}$`).test(input);
|
|
4
|
-
export const isZeroWidthSpace = (value) => value === ZERO_WIDTH_SPACE;
|
|
5
|
-
export function getFirstEmptyCellIndex(code) {
|
|
6
|
-
return code.findIndex(isZeroWidthSpace);
|
|
7
|
-
}
|
|
8
|
-
export const getCellValidationState = (value, showEmptyChars, error) => {
|
|
9
|
-
if (showEmptyChars) {
|
|
10
|
-
return isZeroWidthSpace(value) ? 'error' : 'default';
|
|
11
|
-
}
|
|
12
|
-
return error ? 'error' : 'default';
|
|
13
|
-
};
|
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
import cn from 'classnames';
|
|
2
|
-
import { forwardRef, KeyboardEventHandler, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
-
|
|
4
|
-
import { EyeClosedSVG, EyeSVG, PasswordLockSVG } from '@cloud-ru/uikit-product-icons';
|
|
5
|
-
import { useLocale } from '@cloud-ru/uikit-product-locale';
|
|
6
|
-
import {
|
|
7
|
-
AdaptiveFieldTextArea,
|
|
8
|
-
FieldTextAreaProps,
|
|
9
|
-
getAdaptiveFieldProps,
|
|
10
|
-
} from '@cloud-ru/uikit-product-mobile-fields';
|
|
11
|
-
import { WithLayoutType } from '@cloud-ru/uikit-product-utils';
|
|
12
|
-
import { ButtonFunction, ButtonOutline } from '@snack-uikit/button';
|
|
13
|
-
import { themeVars } from '@snack-uikit/figma-tokens';
|
|
14
|
-
import { Tooltip } from '@snack-uikit/tooltip';
|
|
15
|
-
import { Typography } from '@snack-uikit/typography';
|
|
16
|
-
|
|
17
|
-
import { FieldSubmitButton } from '../../helperComponents/FieldSubmitButton';
|
|
18
|
-
import { TextAreaActionsFooter } from '../../helperComponents/TextAreaActionsFooter';
|
|
19
|
-
import { isTouchDevice as isTouchDeviceHelper } from '../../helpers';
|
|
20
|
-
import { AIDisclaimer } from '../AIDisclaimer/AIDisclaimer';
|
|
21
|
-
import { AlertButton } from './components/AlertButton';
|
|
22
|
-
import { MobileFieldAi } from './components/MobileFieldAi';
|
|
23
|
-
import { WithPasswordValidation } from './components/WithPasswordValidation';
|
|
24
|
-
import styles from './styles.module.scss';
|
|
25
|
-
import { getValidationPassword, ValidationPasswordKey } from './utils';
|
|
26
|
-
|
|
27
|
-
export type FieldAiProps = WithLayoutType<
|
|
28
|
-
Omit<FieldTextAreaProps, 'placeholder' | 'labelTooltip' | 'label' | 'required' | 'size' | 'spellCheck' | 'footer'> & {
|
|
29
|
-
/** Режим ввода sensitive данных (пароля, API ключей, токенов, etc) */
|
|
30
|
-
secure?: boolean | 'password';
|
|
31
|
-
/** Колбек действия при отправке */
|
|
32
|
-
onSubmit(value: string): void;
|
|
33
|
-
/** Действие при клике по кнопке сброса контекста */
|
|
34
|
-
onResetContextClick?(): void;
|
|
35
|
-
/** Действие для отмены секьюрности поля */
|
|
36
|
-
onCancelSecure?(): void;
|
|
37
|
-
}
|
|
38
|
-
>;
|
|
39
|
-
|
|
40
|
-
export const FieldAi = forwardRef<HTMLTextAreaElement, FieldAiProps>(
|
|
41
|
-
(
|
|
42
|
-
{
|
|
43
|
-
secure = false,
|
|
44
|
-
onSubmit: handleSubmitProp,
|
|
45
|
-
value,
|
|
46
|
-
onResetContextClick,
|
|
47
|
-
onCancelSecure,
|
|
48
|
-
disabled,
|
|
49
|
-
className,
|
|
50
|
-
...props
|
|
51
|
-
},
|
|
52
|
-
ref,
|
|
53
|
-
) => {
|
|
54
|
-
const { layoutType, validationState } = props;
|
|
55
|
-
const { t } = useLocale('FieldsPredefined');
|
|
56
|
-
const isTouchDevice = isTouchDeviceHelper(layoutType);
|
|
57
|
-
|
|
58
|
-
const [isValueHidden, setIsValueHidden] = useState<boolean>(true);
|
|
59
|
-
const [animatedValidationKey, setAnimatedValidationKey] = useState<ValidationPasswordKey | null>(null);
|
|
60
|
-
const timerRef = useRef<NodeJS.Timeout | null>(null);
|
|
61
|
-
|
|
62
|
-
const isValueValid = typeof value === 'string' && value.trim().length > 0;
|
|
63
|
-
const isPasswordMode = secure === 'password';
|
|
64
|
-
|
|
65
|
-
const passwordValidation = useMemo(() => getValidationPassword(value), [value]);
|
|
66
|
-
const isPasswordValid = isPasswordMode ? Object.values(passwordValidation).every(Boolean) : true;
|
|
67
|
-
const showPasswordError = !isPasswordValid && secure && value;
|
|
68
|
-
const showPasswordAlert = Boolean(onCancelSecure) && secure === 'password';
|
|
69
|
-
|
|
70
|
-
useEffect(
|
|
71
|
-
() => () => {
|
|
72
|
-
if (timerRef.current) {
|
|
73
|
-
clearTimeout(timerRef.current);
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
|
-
[],
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
const handleSubmit = () => {
|
|
80
|
-
if (isValueValid && isPasswordValid) {
|
|
81
|
-
handleSubmitProp(value);
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
const triggerValidationHighlight = (key: ValidationPasswordKey) => {
|
|
86
|
-
setAnimatedValidationKey(key);
|
|
87
|
-
|
|
88
|
-
timerRef.current = setTimeout(() => {
|
|
89
|
-
setAnimatedValidationKey(null);
|
|
90
|
-
}, 1000);
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
const handleKeyDown: KeyboardEventHandler<HTMLTextAreaElement> = event => {
|
|
94
|
-
if (isTouchDevice) {
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (isPasswordMode && event.key.length === 1) {
|
|
99
|
-
const isLetter = /\p{L}/u.test(event.key);
|
|
100
|
-
const isLatinLetter = /^[a-zA-Z]$/.test(event.key);
|
|
101
|
-
|
|
102
|
-
if (isLetter && !isLatinLetter) {
|
|
103
|
-
event.preventDefault();
|
|
104
|
-
triggerValidationHighlight('onlyLatin');
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (event.key === 'Enter' && !event.shiftKey) {
|
|
110
|
-
event.preventDefault();
|
|
111
|
-
|
|
112
|
-
if (!disabled) {
|
|
113
|
-
handleSubmit();
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
if (isTouchDevice && !secure) {
|
|
121
|
-
return (
|
|
122
|
-
<MobileFieldAi
|
|
123
|
-
{...props}
|
|
124
|
-
{...getAdaptiveFieldProps(props)}
|
|
125
|
-
onSubmit={handleSubmit}
|
|
126
|
-
submitEnabled={isValueValid && !disabled}
|
|
127
|
-
ref={ref}
|
|
128
|
-
value={value}
|
|
129
|
-
/>
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return (
|
|
134
|
-
<div className={cn(styles.wrapper, isPasswordMode && styles.passwordWrapper, className)}>
|
|
135
|
-
{showPasswordAlert && (
|
|
136
|
-
<div className={styles.alert}>
|
|
137
|
-
<PasswordLockSVG size={16} color={themeVars.sys.neutral.textSupport} />
|
|
138
|
-
<Typography.SansBodyS className={styles.alertText}>{t('FieldAi.secret.alert.text')}</Typography.SansBodyS>
|
|
139
|
-
<AlertButton label={t('FieldAi.secret.alert.button')} onClick={onCancelSecure} />
|
|
140
|
-
</div>
|
|
141
|
-
)}
|
|
142
|
-
<WithPasswordValidation
|
|
143
|
-
showValidation={isPasswordMode}
|
|
144
|
-
passwordValidation={passwordValidation}
|
|
145
|
-
layoutType={layoutType}
|
|
146
|
-
animatedKey={animatedValidationKey}
|
|
147
|
-
>
|
|
148
|
-
<AdaptiveFieldTextArea
|
|
149
|
-
{...props}
|
|
150
|
-
ref={ref}
|
|
151
|
-
value={value}
|
|
152
|
-
size='m'
|
|
153
|
-
minRows={secure ? 1 : 2}
|
|
154
|
-
maxRows={secure ? 1 : 4}
|
|
155
|
-
placeholder={secure ? t('FieldAi.secret.placeholder') : t('FieldAi.regular.placeholder')}
|
|
156
|
-
className={cn(styles.textarea, secure && isValueHidden ? styles.secured : undefined)}
|
|
157
|
-
onKeyDown={handleKeyDown}
|
|
158
|
-
spellCheck={!secure}
|
|
159
|
-
validationState={showPasswordError ? 'error' : validationState}
|
|
160
|
-
footer={
|
|
161
|
-
<TextAreaActionsFooter
|
|
162
|
-
left={
|
|
163
|
-
secure && (
|
|
164
|
-
<ButtonFunction
|
|
165
|
-
size='xs'
|
|
166
|
-
icon={isValueHidden ? <EyeSVG /> : <EyeClosedSVG />}
|
|
167
|
-
onClick={() => setIsValueHidden(prev => !prev)}
|
|
168
|
-
/>
|
|
169
|
-
)
|
|
170
|
-
}
|
|
171
|
-
right={
|
|
172
|
-
<>
|
|
173
|
-
{secure && onResetContextClick && (
|
|
174
|
-
<Tooltip tip={t('FieldAi.resetContext.tooltip')} hoverDelayOpen={600}>
|
|
175
|
-
<ButtonOutline
|
|
176
|
-
size='xs'
|
|
177
|
-
label={t('FieldAi.resetContext.label')}
|
|
178
|
-
onClick={onResetContextClick}
|
|
179
|
-
appearance='destructive'
|
|
180
|
-
/>
|
|
181
|
-
</Tooltip>
|
|
182
|
-
)}
|
|
183
|
-
<FieldSubmitButton
|
|
184
|
-
showTooltip={!isTouchDevice}
|
|
185
|
-
className={cn(styles.submitButton, isTouchDevice ? styles.mobileSubmitButton : undefined)}
|
|
186
|
-
active={isValueValid && !disabled && isPasswordValid}
|
|
187
|
-
handleClick={handleSubmit}
|
|
188
|
-
size={isTouchDevice ? 's' : 'xs'}
|
|
189
|
-
/>
|
|
190
|
-
</>
|
|
191
|
-
}
|
|
192
|
-
/>
|
|
193
|
-
}
|
|
194
|
-
/>
|
|
195
|
-
</WithPasswordValidation>
|
|
196
|
-
|
|
197
|
-
{!isPasswordMode && <AIDisclaimer layoutType={layoutType} />}
|
|
198
|
-
</div>
|
|
199
|
-
);
|
|
200
|
-
},
|
|
201
|
-
);
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { Typography } from '@snack-uikit/typography';
|
|
2
|
-
|
|
3
|
-
import styles from './styles.module.scss';
|
|
4
|
-
|
|
5
|
-
export type AlertButtonProps = {
|
|
6
|
-
label: string;
|
|
7
|
-
onClick?(): void;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export function AlertButton({ label, onClick }: AlertButtonProps) {
|
|
11
|
-
return (
|
|
12
|
-
<button onClick={onClick} className={styles.button}>
|
|
13
|
-
<Typography.SansLabelM className={styles.label}>{label}</Typography.SansLabelM>
|
|
14
|
-
</button>
|
|
15
|
-
);
|
|
16
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './AlertButton';
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
@use '@cloud-ru/figma-tokens-cloud-platform/build/scss/styles-theme-variables' as stv;
|
|
2
|
-
|
|
3
|
-
.button {
|
|
4
|
-
outline: none;
|
|
5
|
-
border: none;
|
|
6
|
-
background-color: transparent;
|
|
7
|
-
cursor: pointer;
|
|
8
|
-
height: 16px;
|
|
9
|
-
display: flex;
|
|
10
|
-
align-items: center;
|
|
11
|
-
justify-content: center;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
.label {
|
|
15
|
-
color: stv.$sys-blue-text-support;
|
|
16
|
-
|
|
17
|
-
&:hover {
|
|
18
|
-
color: stv.$sys-neutral-text-main;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from 'react';
|
|
2
|
-
|
|
3
|
-
import { CheckSVG } from '@cloud-ru/uikit-product-icons';
|
|
4
|
-
import { WithLayoutType } from '@cloud-ru/uikit-product-utils';
|
|
5
|
-
import { Typography } from '@snack-uikit/typography';
|
|
6
|
-
|
|
7
|
-
import styles from './styles.module.scss';
|
|
8
|
-
|
|
9
|
-
type CheckItemProps = WithLayoutType<{
|
|
10
|
-
label: string;
|
|
11
|
-
checked: boolean;
|
|
12
|
-
shouldHide?: boolean;
|
|
13
|
-
animated?: boolean;
|
|
14
|
-
}>;
|
|
15
|
-
|
|
16
|
-
const CHECKED_ITEM_DISAPPEAR_TIMEOUT = 500;
|
|
17
|
-
|
|
18
|
-
export function CheckItem({ label, checked, layoutType, shouldHide = false, animated = false }: CheckItemProps) {
|
|
19
|
-
const [visible, setVisible] = useState(checked);
|
|
20
|
-
|
|
21
|
-
useEffect(() => {
|
|
22
|
-
if (checked) {
|
|
23
|
-
const timeoutId = setTimeout(() => {
|
|
24
|
-
setVisible(false);
|
|
25
|
-
}, CHECKED_ITEM_DISAPPEAR_TIMEOUT);
|
|
26
|
-
|
|
27
|
-
return () => clearTimeout(timeoutId);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
setVisible(true);
|
|
31
|
-
}, [checked]);
|
|
32
|
-
|
|
33
|
-
if (shouldHide && !visible) {
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return (
|
|
38
|
-
<div className={styles.checkItem} data-layout-type={layoutType} data-animated={animated}>
|
|
39
|
-
<CheckSVG size={16} className={styles.icon} data-checked={checked} />
|
|
40
|
-
<Typography.SansBodyM className={styles.label} data-checked={checked}>
|
|
41
|
-
{label}
|
|
42
|
-
</Typography.SansBodyM>
|
|
43
|
-
</div>
|
|
44
|
-
);
|
|
45
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './CheckItem';
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
@use '@cloud-ru/figma-tokens-cloud-platform/build/scss/styles-theme-variables' as ste;
|
|
2
|
-
|
|
3
|
-
@keyframes shake {
|
|
4
|
-
0%, 100% {
|
|
5
|
-
transform: translateX(0);
|
|
6
|
-
}
|
|
7
|
-
10%, 30%, 50%, 70%, 90% {
|
|
8
|
-
transform: translateX(-4px);
|
|
9
|
-
}
|
|
10
|
-
20%, 40%, 60%, 80% {
|
|
11
|
-
transform: translateX(4px);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.checkItem {
|
|
16
|
-
display: inline-flex;
|
|
17
|
-
gap: 10px;
|
|
18
|
-
|
|
19
|
-
&[data-layout-type='mobile'],
|
|
20
|
-
&[data-layout-type='tablet'] {
|
|
21
|
-
gap: 8px;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
&[data-animated='true'] {
|
|
25
|
-
animation: shake 0.5s ease-in-out;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.icon {
|
|
30
|
-
flex-shrink: 0;
|
|
31
|
-
color: ste.$sys-neutral-accent-default;
|
|
32
|
-
|
|
33
|
-
&[data-checked='true'] {
|
|
34
|
-
color: ste.$sys-primary-text-light;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
.label {
|
|
39
|
-
color: ste.$sys-neutral-text-light;
|
|
40
|
-
|
|
41
|
-
&[data-checked='true'] {
|
|
42
|
-
color: ste.$sys-primary-text-light;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { forwardRef } from 'react';
|
|
2
|
-
|
|
3
|
-
import { useLocale } from '@cloud-ru/uikit-product-locale';
|
|
4
|
-
import { FieldTextAreaProps } from '@cloud-ru/uikit-product-mobile-fields';
|
|
5
|
-
import { Scroll } from '@snack-uikit/scroll';
|
|
6
|
-
|
|
7
|
-
import { FieldSubmitButton } from '../../../../helperComponents/FieldSubmitButton';
|
|
8
|
-
import { TextArea } from '../TextArea';
|
|
9
|
-
import styles from './styles.module.scss';
|
|
10
|
-
|
|
11
|
-
type MobileFieldAiProps = Omit<
|
|
12
|
-
FieldTextAreaProps,
|
|
13
|
-
'placeholder' | 'labelTooltip' | 'label' | 'required' | 'size' | 'spellCheck' | 'footer'
|
|
14
|
-
> & {
|
|
15
|
-
onSubmit(): void;
|
|
16
|
-
submitEnabled: boolean;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const MIN_ROWS = 1;
|
|
20
|
-
const MAX_ROWS = 6;
|
|
21
|
-
|
|
22
|
-
export const MobileFieldAi = forwardRef<HTMLTextAreaElement, MobileFieldAiProps>(
|
|
23
|
-
({ onSubmit, value, submitEnabled, ...props }, ref) => {
|
|
24
|
-
const { t } = useLocale('FieldsPredefined');
|
|
25
|
-
|
|
26
|
-
return (
|
|
27
|
-
<div
|
|
28
|
-
className={styles.mobileInputWrapper}
|
|
29
|
-
style={{ '--max-rows': MAX_ROWS, '--min-rows': MIN_ROWS }}
|
|
30
|
-
data-size='m'
|
|
31
|
-
>
|
|
32
|
-
<Scroll className={styles.scrollContainer} size='s' barHideStrategy='never'>
|
|
33
|
-
<TextArea
|
|
34
|
-
{...props}
|
|
35
|
-
className={styles.textarea}
|
|
36
|
-
ref={ref}
|
|
37
|
-
value={value}
|
|
38
|
-
minRows={MIN_ROWS}
|
|
39
|
-
placeholder={t('FieldAi.regular.placeholder')}
|
|
40
|
-
spellCheck={true}
|
|
41
|
-
/>
|
|
42
|
-
</Scroll>
|
|
43
|
-
|
|
44
|
-
<div className={styles.mobileSubmitButtonWrapper}>
|
|
45
|
-
<FieldSubmitButton
|
|
46
|
-
showTooltip={false}
|
|
47
|
-
className={styles.mobileSubmitButton}
|
|
48
|
-
fullWidth={true}
|
|
49
|
-
active={submitEnabled}
|
|
50
|
-
handleClick={onSubmit}
|
|
51
|
-
size='s'
|
|
52
|
-
/>
|
|
53
|
-
</div>
|
|
54
|
-
</div>
|
|
55
|
-
);
|
|
56
|
-
},
|
|
57
|
-
);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './MobileFieldAi';
|