@cloud-ru/uikit-product-fields-predefined 2.4.3 → 2.4.4-preview-347b88f7.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.
Files changed (52) hide show
  1. package/README.md +19 -0
  2. package/dist/cjs/components/FieldCode/FieldCode.d.ts +50 -0
  3. package/dist/cjs/components/FieldCode/FieldCode.js +66 -0
  4. package/dist/cjs/components/FieldCode/hooks/index.d.ts +4 -0
  5. package/dist/cjs/components/FieldCode/hooks/index.js +20 -0
  6. package/dist/cjs/components/FieldCode/hooks/useCodeInput.d.ts +21 -0
  7. package/dist/cjs/components/FieldCode/hooks/useCodeInput.js +129 -0
  8. package/dist/cjs/components/FieldCode/hooks/useCodeInputEffects.d.ts +17 -0
  9. package/dist/cjs/components/FieldCode/hooks/useCodeInputEffects.js +62 -0
  10. package/dist/cjs/components/FieldCode/hooks/useFocusFields.d.ts +7 -0
  11. package/dist/cjs/components/FieldCode/hooks/useFocusFields.js +16 -0
  12. package/dist/cjs/components/FieldCode/hooks/useStateWithRef.d.ts +2 -0
  13. package/dist/cjs/components/FieldCode/hooks/useStateWithRef.js +21 -0
  14. package/dist/cjs/components/FieldCode/index.d.ts +1 -0
  15. package/dist/cjs/components/FieldCode/index.js +17 -0
  16. package/dist/cjs/components/FieldCode/styles.module.css +42 -0
  17. package/dist/cjs/components/FieldCode/utils.d.ts +13 -0
  18. package/dist/cjs/components/FieldCode/utils.js +33 -0
  19. package/dist/cjs/components/index.d.ts +1 -0
  20. package/dist/cjs/components/index.js +1 -0
  21. package/dist/esm/components/FieldCode/FieldCode.d.ts +50 -0
  22. package/dist/esm/components/FieldCode/FieldCode.js +60 -0
  23. package/dist/esm/components/FieldCode/hooks/index.d.ts +4 -0
  24. package/dist/esm/components/FieldCode/hooks/index.js +4 -0
  25. package/dist/esm/components/FieldCode/hooks/useCodeInput.d.ts +21 -0
  26. package/dist/esm/components/FieldCode/hooks/useCodeInput.js +126 -0
  27. package/dist/esm/components/FieldCode/hooks/useCodeInputEffects.d.ts +17 -0
  28. package/dist/esm/components/FieldCode/hooks/useCodeInputEffects.js +59 -0
  29. package/dist/esm/components/FieldCode/hooks/useFocusFields.d.ts +7 -0
  30. package/dist/esm/components/FieldCode/hooks/useFocusFields.js +13 -0
  31. package/dist/esm/components/FieldCode/hooks/useStateWithRef.d.ts +2 -0
  32. package/dist/esm/components/FieldCode/hooks/useStateWithRef.js +18 -0
  33. package/dist/esm/components/FieldCode/index.d.ts +1 -0
  34. package/dist/esm/components/FieldCode/index.js +1 -0
  35. package/dist/esm/components/FieldCode/styles.module.css +42 -0
  36. package/dist/esm/components/FieldCode/utils.d.ts +13 -0
  37. package/dist/esm/components/FieldCode/utils.js +22 -0
  38. package/dist/esm/components/index.d.ts +1 -0
  39. package/dist/esm/components/index.js +1 -0
  40. package/dist/tsconfig.cjs.tsbuildinfo +1 -1
  41. package/dist/tsconfig.esm.tsbuildinfo +1 -1
  42. package/package.json +5 -3
  43. package/src/components/FieldCode/FieldCode.tsx +130 -0
  44. package/src/components/FieldCode/hooks/index.ts +4 -0
  45. package/src/components/FieldCode/hooks/useCodeInput.ts +192 -0
  46. package/src/components/FieldCode/hooks/useCodeInputEffects.ts +96 -0
  47. package/src/components/FieldCode/hooks/useFocusFields.ts +26 -0
  48. package/src/components/FieldCode/hooks/useStateWithRef.ts +22 -0
  49. package/src/components/FieldCode/index.ts +1 -0
  50. package/src/components/FieldCode/styles.module.scss +63 -0
  51. package/src/components/FieldCode/utils.ts +40 -0
  52. package/src/components/index.ts +1 -0
@@ -0,0 +1,60 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { jsx as _jsx } from "react/jsx-runtime";
13
+ import cn from 'classnames';
14
+ import { forwardRef, useImperativeHandle, useMemo, useRef } from 'react';
15
+ import { FieldDecorator, FieldText } from '@snack-uikit/fields';
16
+ import { useCodeInput, useCodeInputEffects, useFocusFields } from './hooks';
17
+ import styles from './styles.module.css';
18
+ import { getValidationState, ZERO_WIDTH_SPACE } from './utils';
19
+ export const FieldCode = forwardRef(function FieldCode(_a, ref) {
20
+ var { codeLength, className, showEmptyChars, incorrectCodeState, loading, onChange: onChangeProp, onComplete, withoutFocus, value: valueProp, fieldClassName, withoutErrorFocus = false, size = 'l', spacing } = _a, decoratorProps = __rest(_a, ["codeLength", "className", "showEmptyChars", "incorrectCodeState", "loading", "onChange", "onComplete", "withoutFocus", "value", "fieldClassName", "withoutErrorFocus", "size", "spacing"]);
21
+ const inputsRef = useRef([]);
22
+ const moveFocus = useFocusFields({ inputsRef, codeLength });
23
+ const { code, setCode, buildCodeArray, handleInputChange, handleKeyDown, handlePaste } = useCodeInput({
24
+ codeLength,
25
+ value: valueProp,
26
+ onChange: onChangeProp,
27
+ onComplete,
28
+ moveFocus,
29
+ });
30
+ const blurFields = () => {
31
+ inputsRef.current.forEach(input => input === null || input === void 0 ? void 0 : input.blur());
32
+ };
33
+ useImperativeHandle(ref, () => ({
34
+ blur: blurFields,
35
+ }));
36
+ useCodeInputEffects({
37
+ codeLength,
38
+ code,
39
+ valueProp,
40
+ loading,
41
+ incorrectCodeState,
42
+ showEmptyChars,
43
+ withoutFocus,
44
+ withoutErrorFocus,
45
+ buildCodeArray,
46
+ setCode,
47
+ onChange: onChangeProp,
48
+ moveFocus,
49
+ inputsRef,
50
+ });
51
+ const resolvedDecoratorProps = Object.assign(Object.assign({}, decoratorProps), { size });
52
+ // Определяем индексы полей, после которых нужен отступ (0-based индексы)
53
+ const spacingIndices = useMemo(() => {
54
+ if (!spacing || spacing.length === 0) {
55
+ return new Set();
56
+ }
57
+ return new Set(spacing.filter(pos => pos >= 0 && pos < codeLength - 1));
58
+ }, [spacing, codeLength]);
59
+ return (_jsx(FieldDecorator, Object.assign({}, resolvedDecoratorProps, { className: className, children: _jsx("div", { className: styles.codeContainer, "data-size": size, children: code.map((char, index) => (_jsx(FieldText, { inputMode: 'numeric', autoComplete: 'one-time-code', className: cn(styles.codeInput, spacingIndices.has(index) && styles.codeInputWithSpacing, fieldClassName), "data-size": size, showClearButton: false, value: char === ZERO_WIDTH_SPACE ? '' : char, validationState: getValidationState({ char, incorrectCodeState, showEmptyChars }), ref: ref => (inputsRef.current[index] = ref), onKeyDown: e => handleKeyDown(e, index), onChange: code => handleInputChange(code, index), onPaste: e => handlePaste({ e }), size: resolvedDecoratorProps.size, disabled: resolvedDecoratorProps.disabled, readonly: resolvedDecoratorProps.readonly }, index))) }) })));
60
+ });
@@ -0,0 +1,4 @@
1
+ export * from './useCodeInput';
2
+ export * from './useCodeInputEffects';
3
+ export * from './useFocusFields';
4
+ export * from './useStateWithRef';
@@ -0,0 +1,4 @@
1
+ export * from './useCodeInput';
2
+ export * from './useCodeInputEffects';
3
+ export * from './useFocusFields';
4
+ export * from './useStateWithRef';
@@ -0,0 +1,21 @@
1
+ import { ClipboardEvent, KeyboardEvent } from 'react';
2
+ type UseCodeInputParams = {
3
+ codeLength: number;
4
+ value?: string;
5
+ onChange?: (code: string) => void;
6
+ onComplete?: (code: string) => void;
7
+ moveFocus: (index: number) => void;
8
+ };
9
+ export declare function useCodeInput({ codeLength, value: valueProp, onChange: onChangeProp, onComplete, moveFocus, }: UseCodeInputParams): {
10
+ code: string[];
11
+ setCode: (newValue: string[] | ((prevValue: string[]) => string[])) => void;
12
+ codeRef: import("react").MutableRefObject<string[]>;
13
+ buildCodeArray: (str: string) => string[];
14
+ handleInputChange: (char: string, index: number) => void;
15
+ handleKeyDown: ({ key }: KeyboardEvent<HTMLInputElement>, index: number) => void;
16
+ handlePaste: ({ e, fullCode }: {
17
+ e?: ClipboardEvent<HTMLInputElement>;
18
+ fullCode?: string;
19
+ }) => void;
20
+ };
21
+ export {};
@@ -0,0 +1,126 @@
1
+ import { useCallback, useRef } from 'react';
2
+ import { useValueControl } from '@snack-uikit/utils';
3
+ import { generateRangeWithStep, getCleanValue, getPaddedValue, isNumberChar, isOutsideAutoComplete, isStringCodeLength, isZeroWidthSpace, } from '../utils';
4
+ import { useStateWithRef } from './useStateWithRef';
5
+ export function useCodeInput({ codeLength, value: valueProp, onChange: onChangeProp, onComplete, moveFocus, }) {
6
+ const buildCodeArray = useCallback((str) => Array.from({ length: codeLength }, (_, idx) => { var _a; return (_a = str[idx]) !== null && _a !== void 0 ? _a : ''; }), [codeLength]);
7
+ const [value = '', onChange] = useValueControl({
8
+ value: valueProp,
9
+ onChange: onChangeProp,
10
+ defaultValue: '',
11
+ });
12
+ const [code, setCode, codeRef] = useStateWithRef(buildCodeArray(value));
13
+ const pasteFlag = useRef(false);
14
+ const keyInputFlag = useRef(false);
15
+ const updateCode = useCallback((index, newChar) => {
16
+ const updatedCode = [...codeRef.current];
17
+ updatedCode[index] = newChar;
18
+ setCode(updatedCode);
19
+ const normalizedCode = getPaddedValue(updatedCode).join('');
20
+ onChange === null || onChange === void 0 ? void 0 : onChange(normalizedCode);
21
+ return updatedCode;
22
+ }, [codeRef, setCode, onChange]);
23
+ const handleAutoComplete = useCallback((char, charIndex) => {
24
+ for (const idx of generateRangeWithStep(1, charIndex)) {
25
+ updateCode(idx - 1, codeRef.current[idx]);
26
+ }
27
+ updateCode(charIndex, char);
28
+ const updatedCode = codeRef.current.join('');
29
+ if (isStringCodeLength(updatedCode, codeLength)) {
30
+ onComplete === null || onComplete === void 0 ? void 0 : onComplete(updatedCode);
31
+ }
32
+ }, [codeLength, codeRef, onComplete, updateCode]);
33
+ const handlePaste = useCallback(({ e, fullCode }) => {
34
+ var _a;
35
+ if (e) {
36
+ pasteFlag.current = true;
37
+ }
38
+ const codeInput = (_a = (fullCode || (e === null || e === void 0 ? void 0 : e.clipboardData.getData('text')))) !== null && _a !== void 0 ? _a : '';
39
+ if (!isStringCodeLength(codeInput, codeLength)) {
40
+ return;
41
+ }
42
+ const codeArray = codeInput.split('');
43
+ setCode(codeArray);
44
+ onChange === null || onChange === void 0 ? void 0 : onChange(codeInput);
45
+ onComplete === null || onComplete === void 0 ? void 0 : onComplete(codeInput);
46
+ moveFocus(codeLength - 1);
47
+ }, [codeLength, moveFocus, onChange, onComplete, setCode]);
48
+ const deleteChar = useCallback((index) => {
49
+ if (codeRef.current[index] && !isZeroWidthSpace(codeRef.current[index])) {
50
+ updateCode(index, '');
51
+ }
52
+ else if (index > 0) {
53
+ moveFocus(index - 1);
54
+ }
55
+ }, [codeRef, moveFocus, updateCode]);
56
+ const handleInputChange = useCallback((char, index) => {
57
+ var _a;
58
+ if (pasteFlag.current || keyInputFlag.current) {
59
+ pasteFlag.current = false;
60
+ keyInputFlag.current = false;
61
+ return;
62
+ }
63
+ if (isStringCodeLength(char, codeLength)) {
64
+ handlePaste({ fullCode: char });
65
+ return;
66
+ }
67
+ // autocomplete если фокус был не на первой ячейке
68
+ if (isOutsideAutoComplete(char, index, codeRef.current)) {
69
+ handleAutoComplete((_a = char.at(-1)) !== null && _a !== void 0 ? _a : '', index);
70
+ return;
71
+ }
72
+ let lastChar = char;
73
+ if (char.length > 1) {
74
+ const prev = codeRef.current[index];
75
+ const candidates = Array.from(char);
76
+ const found = candidates.find(c => c !== prev && isNumberChar(c));
77
+ const newDigit = found !== null && found !== void 0 ? found : candidates[candidates.length - 1];
78
+ lastChar = isNumberChar(newDigit) ? newDigit : '';
79
+ }
80
+ if (char === '') {
81
+ deleteChar(index);
82
+ return;
83
+ }
84
+ if (!isNumberChar(lastChar)) {
85
+ return;
86
+ }
87
+ const updated = updateCode(index, lastChar);
88
+ const cleaned = getCleanValue(updated).join('');
89
+ const isLastInput = index === codeLength - 1;
90
+ const isAllInputsFilled = isStringCodeLength(cleaned, codeLength);
91
+ if (!isLastInput) {
92
+ moveFocus(index + 1);
93
+ }
94
+ else if (isAllInputsFilled) {
95
+ onComplete === null || onComplete === void 0 ? void 0 : onComplete(cleaned);
96
+ }
97
+ }, [codeLength, codeRef, deleteChar, handleAutoComplete, handlePaste, moveFocus, onComplete, updateCode]);
98
+ const handleKeyDown = useCallback(({ key }, index) => {
99
+ switch (key) {
100
+ case 'ArrowLeft':
101
+ moveFocus(index - 1);
102
+ break;
103
+ case 'ArrowRight':
104
+ moveFocus(index + 1);
105
+ break;
106
+ case 'Backspace':
107
+ deleteChar(index);
108
+ break;
109
+ default:
110
+ if (isNumberChar(key)) {
111
+ handleInputChange(key, index);
112
+ keyInputFlag.current = true;
113
+ }
114
+ break;
115
+ }
116
+ }, [deleteChar, handleInputChange, moveFocus]);
117
+ return {
118
+ code,
119
+ setCode,
120
+ codeRef,
121
+ buildCodeArray,
122
+ handleInputChange,
123
+ handleKeyDown,
124
+ handlePaste,
125
+ };
126
+ }
@@ -0,0 +1,17 @@
1
+ type UseCodeInputEffectsParams = {
2
+ codeLength: number;
3
+ code: string[];
4
+ valueProp?: string;
5
+ loading?: boolean;
6
+ incorrectCodeState?: boolean;
7
+ showEmptyChars?: boolean;
8
+ withoutFocus?: boolean;
9
+ withoutErrorFocus?: boolean;
10
+ buildCodeArray: (str: string) => string[];
11
+ setCode: (code: string[]) => void;
12
+ onChange?: (code: string) => void;
13
+ moveFocus: (index: number) => void;
14
+ inputsRef: React.MutableRefObject<(HTMLInputElement | null)[]>;
15
+ };
16
+ export declare function useCodeInputEffects({ codeLength, code, valueProp, loading, incorrectCodeState, showEmptyChars, withoutFocus, withoutErrorFocus, buildCodeArray, setCode, onChange, moveFocus, inputsRef, }: UseCodeInputEffectsParams): void;
17
+ export {};
@@ -0,0 +1,59 @@
1
+ import { useCallback, useEffect } from 'react';
2
+ import { getCleanValue, ZERO_WIDTH_SPACE } from '../utils';
3
+ export function useCodeInputEffects({ codeLength, code, valueProp, loading, incorrectCodeState, showEmptyChars, withoutFocus, withoutErrorFocus, buildCodeArray, setCode, onChange, moveFocus, inputsRef, }) {
4
+ const blurFields = useCallback(() => {
5
+ inputsRef.current.forEach(input => input === null || input === void 0 ? void 0 : input.blur());
6
+ }, [inputsRef]);
7
+ // Фокус при загрузке
8
+ useEffect(() => {
9
+ if (withoutFocus || loading)
10
+ return;
11
+ requestAnimationFrame(() => {
12
+ moveFocus(0);
13
+ });
14
+ }, [loading, moveFocus, withoutFocus]);
15
+ // Фокус при ошибке (если withoutErrorFocus = false)
16
+ useEffect(() => {
17
+ var _a;
18
+ if (withoutErrorFocus)
19
+ return;
20
+ if (showEmptyChars) {
21
+ const idx = getCleanValue(code).findIndex(c => c === '');
22
+ const focusIndex = idx >= 0 ? idx : codeLength - 1;
23
+ (_a = inputsRef.current[focusIndex]) === null || _a === void 0 ? void 0 : _a.focus();
24
+ }
25
+ }, [code, codeLength, incorrectCodeState, showEmptyChars, withoutErrorFocus, inputsRef]);
26
+ // Фокус при ошибке (если withoutErrorFocus = true)
27
+ useEffect(() => {
28
+ var _a;
29
+ if (incorrectCodeState) {
30
+ (_a = inputsRef.current[0]) === null || _a === void 0 ? void 0 : _a.focus();
31
+ }
32
+ }, [incorrectCodeState, inputsRef]);
33
+ // Блюр при ошибке (если withoutErrorFocus = true)
34
+ useEffect(() => {
35
+ if (!withoutErrorFocus)
36
+ return;
37
+ if (incorrectCodeState || showEmptyChars) {
38
+ blurFields();
39
+ }
40
+ }, [incorrectCodeState, showEmptyChars, withoutErrorFocus, blurFields]);
41
+ // Сброс кода при изменении длины
42
+ useEffect(() => {
43
+ setCode(Array(codeLength).fill(''));
44
+ }, [codeLength, setCode]);
45
+ // Обновление кода при изменении valueProp (только если valueProp не пустой)
46
+ useEffect(() => {
47
+ if (valueProp === null || valueProp === void 0 ? void 0 : valueProp.length) {
48
+ setCode(buildCodeArray(valueProp));
49
+ }
50
+ }, [buildCodeArray, setCode, valueProp]);
51
+ // Сброс кода при очистке valueProp
52
+ useEffect(() => {
53
+ if (!(valueProp === null || valueProp === void 0 ? void 0 : valueProp.length)) {
54
+ setCode(Array(codeLength).fill(''));
55
+ onChange === null || onChange === void 0 ? void 0 : onChange(ZERO_WIDTH_SPACE.repeat(codeLength));
56
+ moveFocus(0);
57
+ }
58
+ }, [valueProp, codeLength, moveFocus, setCode, onChange]);
59
+ }
@@ -0,0 +1,7 @@
1
+ import { MutableRefObject } from 'react';
2
+ type UseFocusFields = {
3
+ inputsRef: MutableRefObject<(HTMLInputElement | null)[]>;
4
+ codeLength: number;
5
+ };
6
+ export declare function useFocusFields({ inputsRef, codeLength }: UseFocusFields): (newIndex: number) => void;
7
+ export {};
@@ -0,0 +1,13 @@
1
+ import { useCallback } from 'react';
2
+ export function useFocusFields({ inputsRef, codeLength }) {
3
+ const focusInput = useCallback((index) => {
4
+ var _a;
5
+ (_a = inputsRef.current[index]) === null || _a === void 0 ? void 0 : _a.focus();
6
+ }, [inputsRef]);
7
+ const moveFocus = useCallback((newIndex) => {
8
+ if (newIndex >= 0 && newIndex < codeLength) {
9
+ focusInput(newIndex);
10
+ }
11
+ }, [codeLength, focusInput]);
12
+ return moveFocus;
13
+ }
@@ -0,0 +1,2 @@
1
+ import { MutableRefObject } from 'react';
2
+ export declare function useStateWithRef<T>(initialValue: T): [T, (newValue: T | ((prevValue: T) => T)) => void, MutableRefObject<T>];
@@ -0,0 +1,18 @@
1
+ import { useCallback, useRef, useState } from 'react';
2
+ export function useStateWithRef(initialValue) {
3
+ const [state, setState] = useState(initialValue);
4
+ const ref = useRef(state);
5
+ const setStateAndRef = useCallback((newValue) => {
6
+ if (typeof newValue === 'function') {
7
+ const updater = newValue;
8
+ const updatedValue = updater(ref.current);
9
+ setState(updatedValue);
10
+ ref.current = updatedValue;
11
+ }
12
+ else {
13
+ setState(newValue);
14
+ ref.current = newValue;
15
+ }
16
+ }, []);
17
+ return [state, setStateAndRef, ref];
18
+ }
@@ -0,0 +1 @@
1
+ export * from './FieldCode';
@@ -0,0 +1 @@
1
+ export * from './FieldCode';
@@ -0,0 +1,42 @@
1
+ .codeContainer{
2
+ display:flex;
3
+ justify-content:center;
4
+ }
5
+ .codeContainer[data-size=s]{
6
+ gap:6px;
7
+ }
8
+ .codeContainer[data-size=m]{
9
+ gap:8px;
10
+ }
11
+ .codeContainer[data-size=l]{
12
+ gap:12px;
13
+ }
14
+
15
+ .codeInputWithSpacing[data-size=s]{
16
+ margin-right:2px;
17
+ }
18
+ .codeInputWithSpacing[data-size=m]{
19
+ margin-right:8px;
20
+ }
21
+ .codeInputWithSpacing[data-size=l]{
22
+ margin-right:12px;
23
+ }
24
+
25
+ .codeInput{
26
+ width:100%;
27
+ }
28
+ .codeInput input{
29
+ text-align:center;
30
+ }
31
+ .codeInput input[data-size=s]{
32
+ font-size:16px;
33
+ line-height:22px;
34
+ }
35
+ .codeInput input[data-size=m]{
36
+ font-size:18px;
37
+ line-height:26px;
38
+ }
39
+ .codeInput input[data-size=l]{
40
+ font-size:20px;
41
+ line-height:28px;
42
+ }
@@ -0,0 +1,13 @@
1
+ export declare const ZERO_WIDTH_SPACE = "\u200B";
2
+ export declare const getValidationState: ({ char, incorrectCodeState, showEmptyChars, }: {
3
+ char: string;
4
+ incorrectCodeState?: boolean;
5
+ showEmptyChars?: boolean;
6
+ }) => "error" | "default";
7
+ export declare const isNumberChar: (char: string) => boolean;
8
+ export declare const isStringCodeLength: (input: string, codeLength: number) => boolean;
9
+ export declare const isOutsideAutoComplete: (input: string, index: number, code: string[]) => boolean;
10
+ export declare const getPaddedValue: (value: string[]) => string[];
11
+ export declare const getCleanValue: (value: string[]) => string[];
12
+ export declare const isZeroWidthSpace: (value: string) => value is "​";
13
+ export declare const generateRangeWithStep: (start: number, end: number) => number[];
@@ -0,0 +1,22 @@
1
+ export const ZERO_WIDTH_SPACE = '\u200B';
2
+ export const getValidationState = ({ char, incorrectCodeState, showEmptyChars, }) => {
3
+ if (incorrectCodeState) {
4
+ return 'error';
5
+ }
6
+ if (!showEmptyChars) {
7
+ return 'default';
8
+ }
9
+ return char && char !== ZERO_WIDTH_SPACE ? 'default' : 'error';
10
+ };
11
+ const isStringCode = (input) => new RegExp(`^\\d+$`).test(input);
12
+ export const isNumberChar = (char) => /^\d$/.test(char);
13
+ export const isStringCodeLength = (input, codeLength) => new RegExp(`^\\d{${codeLength}}$`).test(input);
14
+ export const isOutsideAutoComplete = (input, index, code) => input.length > 1 && isStringCode(input) && input.at(0) === code.at(index);
15
+ export const getPaddedValue = (value) => value.map(char => (char === '' ? ZERO_WIDTH_SPACE : char));
16
+ export const getCleanValue = (value) => value.map(char => (char !== ZERO_WIDTH_SPACE ? char : ''));
17
+ export const isZeroWidthSpace = (value) => value === ZERO_WIDTH_SPACE;
18
+ export const generateRangeWithStep = (start, end) => {
19
+ const step = start <= end ? 1 : -1;
20
+ const length = Math.abs(end - start) + 1;
21
+ return Array.from({ length }, (_, i) => start + i * step);
22
+ };
@@ -6,3 +6,4 @@ export * from './AIDisclaimer';
6
6
  export * from './FieldName';
7
7
  export * from './FieldDescription';
8
8
  export * from './FieldMask';
9
+ export * from './FieldCode';
@@ -6,3 +6,4 @@ export * from './AIDisclaimer';
6
6
  export * from './FieldName';
7
7
  export * from './FieldDescription';
8
8
  export * from './FieldMask';
9
+ export * from './FieldCode';