@hh.ru/magritte-ui-pincode-input 1.0.1 → 1.0.3
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/PincodeInput.js +63 -87
- package/PincodeInput.js.map +1 -1
- package/index.css +110 -83
- package/index.js +0 -1
- package/index.js.map +1 -1
- package/package.json +4 -5
package/PincodeInput.js
CHANGED
|
@@ -1,82 +1,67 @@
|
|
|
1
1
|
import './index.css';
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { forwardRef, useState, useRef } from 'react';
|
|
3
|
+
import { forwardRef, useState, useRef, useLayoutEffect } from 'react';
|
|
4
4
|
import classnames from 'classnames';
|
|
5
|
-
import { keyboardMatch, keyboardKeys } from '@hh.ru/magritte-common-keyboard';
|
|
6
|
-
import { Selection } from '@hh.ru/magritte-common-text-selection';
|
|
5
|
+
import { keyboardMatch, keyboardKeys, keyboardMatches } from '@hh.ru/magritte-common-keyboard';
|
|
7
6
|
import { FormHelper } from '@hh.ru/magritte-ui-form-helper';
|
|
8
7
|
|
|
9
|
-
var styles = {"pincode-input":"magritte-pincode-input___RpWyq_1-0-
|
|
8
|
+
var styles = {"pincode-input":"magritte-pincode-input___RpWyq_1-0-3","pincodeInput":"magritte-pincode-input___RpWyq_1-0-3","medium":"magritte-medium___wfRSc_1-0-3","placeholder":"magritte-placeholder___10kQ0_1-0-3","focus":"magritte-focus___IuhXb_1-0-3","invalid":"magritte-invalid___hB8h2_1-0-3","focus-visible":"magritte-focus-visible___BN1eD_1-0-3","focusVisible":"magritte-focus-visible___BN1eD_1-0-3","digit-box-container":"magritte-digit-box-container___BqMWw_1-0-3","digitBoxContainer":"magritte-digit-box-container___BqMWw_1-0-3","digit-box":"magritte-digit-box___6J0Q2_1-0-3","digitBox":"magritte-digit-box___6J0Q2_1-0-3","digits-input":"magritte-digits-input___4QeLj_1-0-3","digitsInput":"magritte-digits-input___4QeLj_1-0-3","caret-left":"magritte-caret-left___iZMuA_1-0-3","caretLeft":"magritte-caret-left___iZMuA_1-0-3","caret-right":"magritte-caret-right___u8wNk_1-0-3","caretRight":"magritte-caret-right___u8wNk_1-0-3","caret-blink":"magritte-caret-blink___-bhg7_1-0-3","caretBlink":"magritte-caret-blink___-bhg7_1-0-3","value-container":"magritte-value-container___9JR3e_1-0-3","valueContainer":"magritte-value-container___9JR3e_1-0-3","ghost-value":"magritte-ghost-value___jPQwY_1-0-3","ghostValue":"magritte-ghost-value___jPQwY_1-0-3"};
|
|
10
9
|
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
// Поэтому двигаем её асинхронно, чтобы сдвиг происходил после нативного, иначе она окажется не в нужной позиции
|
|
14
|
-
requestAnimationFrame(() => {
|
|
15
|
-
if (ref.current) {
|
|
16
|
-
Selection.setCaretPosition(ref.current, position);
|
|
17
|
-
callback?.();
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
const getCaretPosition = (ref) => ref.current ? (Selection.getCaretPosition(ref.current) ?? 0) : 0;
|
|
10
|
+
const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
|
|
11
|
+
const noop = () => { };
|
|
21
12
|
const PincodeInput = forwardRef(({ digitsCount: _digitsCount = null, size = 'large', invalid = false, onFocus, onBlur, onChange, description, errorMessage, 'data-qa': dataQa = 'magritte-pincode-input', }, ref) => {
|
|
22
13
|
const digitsCount = _digitsCount ?? (size === 'medium' ? 6 : 4);
|
|
23
14
|
const [value, setValue] = useState('');
|
|
24
15
|
const [caretPosition, setCaretPosition] = useState(0);
|
|
25
16
|
const [focused, setFocused] = useState(false);
|
|
26
17
|
const [focusVisible, setFocusVisible] = useState(false);
|
|
18
|
+
const ghostLastDigitRef = useRef(null);
|
|
19
|
+
const containerRef = useRef(null);
|
|
27
20
|
const inputRef = useRef(null);
|
|
28
|
-
|
|
21
|
+
useLayoutEffect(() => {
|
|
22
|
+
if (!containerRef.current || !ghostLastDigitRef.current) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const lastWidth = ghostLastDigitRef.current.getBoundingClientRect().width;
|
|
26
|
+
containerRef.current.style.setProperty('--magritte-pincode-last-digit-width', `${lastWidth}px`);
|
|
27
|
+
}, [caretPosition, value]);
|
|
29
28
|
const updateValue = (newValue) => {
|
|
30
29
|
setValue(newValue);
|
|
31
30
|
onChange?.(newValue);
|
|
32
31
|
};
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
requestAnimationFrame(() => {
|
|
36
|
-
if (!inputRef.current) {
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
// Когда перемещаемся между цифрами если в позиции введена цифра, то ввод должен заменят именно её
|
|
40
|
-
// а не сдвигать весь текст после нее врпаво, как в обычном инпуте.
|
|
41
|
-
// Поэтому здесь проверяем если в позиции что-то введено, то не просто устанавливаем каретку, а выделяем
|
|
42
|
-
// символ, чтобы при вводе он заменился
|
|
43
|
-
const caretPosition = getCaretPosition(inputRef);
|
|
44
|
-
const value = inputRef.current?.value ?? '';
|
|
45
|
-
const digitNumberToSelect = Math.min(caretPosition, Math.min(value.length, digitsCount - 1));
|
|
46
|
-
const selection = Selection.get(inputRef.current);
|
|
47
|
-
if (selectionRef.current && selection.start !== selection.end) {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
selectionRef.current = null;
|
|
51
|
-
if (value.length > digitNumberToSelect) {
|
|
52
|
-
Selection.set(inputRef.current, digitNumberToSelect, digitNumberToSelect + 1, 'forward');
|
|
53
|
-
selectionRef.current = digitNumberToSelect;
|
|
54
|
-
}
|
|
55
|
-
setCaretPosition(caretPosition);
|
|
56
|
-
});
|
|
57
|
-
};
|
|
58
|
-
return (jsxs("div", { ref: ref, "data-qa": dataQa, children: [jsxs("div", { "data-qa": "magritte-pincode-input-wrapper", className: classnames(styles.pincodeInput, {
|
|
32
|
+
const caretPos = clamp(caretPosition, 0, value.length);
|
|
33
|
+
return (jsxs("div", { ref: ref, "data-qa": dataQa, children: [jsxs("div", { "data-qa": "magritte-pincode-input-wrapper", ref: containerRef, className: classnames(styles.pincodeInput, {
|
|
59
34
|
[styles.focus]: focused,
|
|
60
35
|
[styles.focusVisible]: focusVisible,
|
|
61
36
|
[styles.medium]: size === 'medium',
|
|
62
37
|
[styles.invalid]: invalid,
|
|
63
|
-
}),
|
|
38
|
+
}), onMouseDown: (event) => {
|
|
39
|
+
if (event.target === inputRef.current) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
event.preventDefault();
|
|
64
43
|
const caretPosition = Math.min(Number(event.target?.dataset?.digitIndex ?? value.length), value.length);
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
44
|
+
if (!focused) {
|
|
45
|
+
inputRef.current?.focus();
|
|
46
|
+
}
|
|
47
|
+
setCaretPosition(caretPosition);
|
|
48
|
+
}, style: {
|
|
49
|
+
'--magritte-pincode-digits-count': digitsCount,
|
|
50
|
+
'--magritte-pincode-caret-position': caretPos,
|
|
51
|
+
}, children: [jsx("input", { ref: inputRef, autoComplete: "one-time-code", pattern: `\\d{${digitsCount}}`, "data-qa": "magritte-pincode-input-field", className: styles.digitsInput, type: "text", inputMode: "numeric", maxLength: digitsCount,
|
|
52
|
+
// оставляем инпут всегда пустым, т.к. он нам нужен только для показа контекстного меню вставки,
|
|
53
|
+
// обработки события вставки и обработки фокуса
|
|
54
|
+
value: "",
|
|
55
|
+
// без change хендлера react пишет warning в консоль
|
|
56
|
+
onChange: noop, onFocus: (event) => {
|
|
72
57
|
onFocus?.(event);
|
|
73
|
-
refineCaretPosition();
|
|
74
58
|
if (!event.defaultPrevented) {
|
|
75
59
|
setFocused(true);
|
|
76
60
|
setFocusVisible(!!inputRef.current?.classList.contains('focus-visible'));
|
|
77
61
|
if (invalid) {
|
|
78
62
|
// По спеке если инпут помечен как invalid при фокусе содержимое должно очищаться
|
|
79
63
|
updateValue('');
|
|
64
|
+
setCaretPosition(0);
|
|
80
65
|
}
|
|
81
66
|
}
|
|
82
67
|
}, onBlur: (event) => {
|
|
@@ -90,73 +75,64 @@ const PincodeInput = forwardRef(({ digitsCount: _digitsCount = null, size = 'lar
|
|
|
90
75
|
return;
|
|
91
76
|
}
|
|
92
77
|
const isLeft = keyboardMatch(event, keyboardKeys.ArrowLeft);
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
78
|
+
const isRight = keyboardMatch(event, keyboardKeys.ArrowRight);
|
|
79
|
+
if (isLeft || isRight) {
|
|
80
|
+
event.preventDefault();
|
|
81
|
+
setCaretPosition((caretPosition) => clamp(caretPosition + (isRight ? 1 : -1), 0, value.length));
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (keyboardMatches(event, keyboardKeys.DigitKeys)) {
|
|
85
|
+
updateValue(`${value.slice(0, caretPos)}${event.key}${value.slice(caretPos + 1)}`);
|
|
86
|
+
setCaretPosition((caretPosition) => clamp(caretPosition + 1, 0, digitsCount - 1));
|
|
99
87
|
event.preventDefault();
|
|
100
|
-
moveCaretTo(inputRef, Math.max(0, Math.min(selectionRef.current - 1, digitsCount - 1)), refineCaretPosition);
|
|
101
88
|
return;
|
|
102
89
|
}
|
|
103
|
-
|
|
90
|
+
const isBackspace = keyboardMatch(event, keyboardKeys.Backspace);
|
|
91
|
+
const isDelete = keyboardMatch(event, keyboardKeys.Delete);
|
|
92
|
+
if (isBackspace || isDelete) {
|
|
104
93
|
// При нажатии backspace действует следующая логика:
|
|
105
94
|
// Если каретка находится в позиции последней введенной цифры, то удаляем её
|
|
106
95
|
// и оставляем каретку на той же позиции
|
|
107
96
|
// Если каретка находится в другой позиции, то удаляем цифру слева от каретки и
|
|
108
97
|
// сдвигаем каретку влево
|
|
98
|
+
const isLastDigit = caretPos === value.length - 1;
|
|
99
|
+
const deleteIndex = clamp(caretPos - (isDelete || isLastDigit ? 0 : 1), 0, digitsCount - 1);
|
|
100
|
+
updateValue(`${value.slice(0, deleteIndex)}${value.slice(deleteIndex + 1)}`);
|
|
101
|
+
setCaretPosition((caretPosition) => {
|
|
102
|
+
const newPosition = isLastDigit || isDelete ? caretPosition : Math.max(caretPosition - 1, 0);
|
|
103
|
+
return newPosition;
|
|
104
|
+
});
|
|
109
105
|
event.preventDefault();
|
|
110
|
-
const deleteIndex = selectionRef.current === value.length - 1
|
|
111
|
-
? selectionRef.current
|
|
112
|
-
: Math.max(selectionRef.current - 1, 0);
|
|
113
|
-
const newValue = `${value.slice(0, deleteIndex)}${value.slice(deleteIndex + 1)}`;
|
|
114
|
-
updateValue(newValue);
|
|
115
|
-
if (selectionRef.current !== value.length - 1) {
|
|
116
|
-
moveCaretTo(inputRef, Math.max(selectionRef.current - 1, 0), refineCaretPosition);
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
refineCaretPosition();
|
|
121
|
-
}, onChange: (event) => {
|
|
122
|
-
updateValue(event.target.value);
|
|
123
|
-
if (selectionRef.current !== null) {
|
|
124
|
-
// При изменении, если была выделена цифра, то каретку надо сдвинуть на следующую
|
|
125
|
-
// позицию вручную
|
|
126
|
-
moveCaretTo(inputRef, selectionRef.current + 1, refineCaretPosition);
|
|
127
|
-
return;
|
|
128
106
|
}
|
|
129
|
-
refineCaretPosition();
|
|
130
107
|
}, onPaste: (event) => {
|
|
131
108
|
event.preventDefault();
|
|
132
109
|
const pasteValue = event.clipboardData.getData('text').replace(/\D/g, '');
|
|
133
110
|
if (pasteValue.length === digitsCount) {
|
|
134
111
|
updateValue(pasteValue);
|
|
135
|
-
|
|
112
|
+
setCaretPosition(digitsCount - 1);
|
|
136
113
|
return;
|
|
137
114
|
}
|
|
138
|
-
const
|
|
139
|
-
const newValue = `${value.slice(0, caretPosition)}${pasteValue}${value.slice(caretPosition + pasteValue.length)}`.slice(0, digitsCount);
|
|
115
|
+
const newValue = `${value.slice(0, caretPos)}${pasteValue}${value.slice(caretPos + pasteValue.length)}`.slice(0, digitsCount);
|
|
140
116
|
updateValue(newValue);
|
|
141
|
-
|
|
117
|
+
setCaretPosition(Math.min(digitsCount - 1, caretPos + pasteValue.length));
|
|
142
118
|
} }), jsx("div", { className: styles.digitBoxContainer, children: Array.from({ length: digitsCount }).map((_, index) => (jsx("div", { className: classnames(styles.digitBox), "data-digit-index": index, children: jsx("span", { className: classnames(styles.valueContainer, {
|
|
143
119
|
// в позицию ничего не введено, и каретка не находится в этой позиции
|
|
144
120
|
[styles.placeholder]: index >= value.length &&
|
|
145
121
|
(!focused ||
|
|
146
|
-
(index !==
|
|
147
|
-
!(
|
|
122
|
+
(index !== caretPos &&
|
|
123
|
+
!(caretPos === digitsCount && index === digitsCount - 1))),
|
|
148
124
|
// в позицию введена цифра, каретка находится в этой позиции, фокус
|
|
149
125
|
// установлен в инпут, это не крайняя справа цифра из введенных
|
|
150
|
-
[styles.caretLeft]: index ===
|
|
126
|
+
[styles.caretLeft]: index === caretPos && index !== value.length - 1 && focused,
|
|
151
127
|
// в позицию введена цифра, каретка находится в этой позиции, либо в следующей
|
|
152
128
|
// если введены все цифры (потому что при вводе последней цифры каретка
|
|
153
129
|
// должна уходить за нее), фокус установлен в инпут, это крайняя справа цифра
|
|
154
130
|
// из введенных
|
|
155
|
-
[styles.caretRight]: (index ===
|
|
156
|
-
(index === digitsCount - 1 && index ===
|
|
131
|
+
[styles.caretRight]: (index === caretPos ||
|
|
132
|
+
(index === digitsCount - 1 && index === caretPos - 1)) &&
|
|
157
133
|
index === value.length - 1 &&
|
|
158
134
|
focused,
|
|
159
|
-
}), "data-qa": `magritte-pincode-input-digit-${index}`, children: value[index] || (
|
|
135
|
+
}), "data-qa": `magritte-pincode-input-digit-${index}`, children: value[index] || (caretPos === index && focused ? '' : '•') }) }, index))) }), jsx("div", { className: styles.ghostValue, ref: ghostLastDigitRef, children: value.slice(caretPos, caretPos + 1) })] }), jsx(FormHelper, { invalid: invalid, description: description, errorMessage: errorMessage, "data-qa": "magritte-pincode-input-message" })] }));
|
|
160
136
|
});
|
|
161
137
|
PincodeInput.displayName = 'PincodeInput';
|
|
162
138
|
|
package/PincodeInput.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PincodeInput.js","sources":["../src/PincodeInput.tsx"],"sourcesContent":["import { type CSSProperties, type FocusEventHandler, useRef, useState, RefObject, forwardRef } from 'react';\nimport classnames from 'classnames';\n\nimport { keyboardKeys, keyboardMatch } from '@hh.ru/magritte-common-keyboard';\nimport { Selection } from '@hh.ru/magritte-common-text-selection';\nimport { FormHelper } from '@hh.ru/magritte-ui-form-helper';\n\nimport styles from './pincodeInput.less';\n\nconst moveCaretTo = (ref: RefObject<HTMLInputElement>, position: number, callback?: VoidFunction) =>\n // Каретка сдвигается при изменении содержимого инпута автоматически\n // Поэтому двигаем её асинхронно, чтобы сдвиг происходил после нативного, иначе она окажется не в нужной позиции\n requestAnimationFrame(() => {\n if (ref.current) {\n Selection.setCaretPosition(ref.current, position);\n callback?.();\n }\n });\n\nconst getCaretPosition = (ref: RefObject<HTMLInputElement>) =>\n ref.current ? (Selection.getCaretPosition(ref.current) ?? 0) : 0;\n\nexport type PincodeInputSize = 'medium' | 'large';\n\nexport interface PincodeInputProps {\n /**\n * Количество цифр в пин-коде, если не указано будет выбрано автоматически\n * в зависимости от размера инпута ( medium - 6, large - 4)\n */\n digitsCount?: number | null;\n /** Размер инпута */\n size?: PincodeInputSize;\n /** Обработчик изменений */\n onChange?: (value: string) => void;\n /** Обработчик фокуса */\n onFocus?: FocusEventHandler<HTMLInputElement>;\n /** Обработчик потери фокуса */\n onBlur?: FocusEventHandler<HTMLInputElement>;\n /** Флаг наличия ошибки */\n invalid?: boolean;\n /** Текст описания */\n description?: string;\n /** Текст сообщения об ошибке */\n errorMessage?: string;\n 'data-qa'?: string;\n}\n\nexport const PincodeInput = forwardRef<HTMLDivElement, PincodeInputProps>(\n (\n {\n digitsCount: _digitsCount = null,\n size = 'large',\n invalid = false,\n onFocus,\n onBlur,\n onChange,\n description,\n errorMessage,\n 'data-qa': dataQa = 'magritte-pincode-input',\n },\n ref\n ) => {\n const digitsCount = _digitsCount ?? (size === 'medium' ? 6 : 4);\n const [value, setValue] = useState<string>('');\n const [caretPosition, setCaretPosition] = useState<number>(0);\n const [focused, setFocused] = useState(false);\n const [focusVisible, setFocusVisible] = useState(false);\n\n const inputRef = useRef<HTMLInputElement>(null);\n const selectionRef = useRef<number | null>(null);\n\n const updateValue = (newValue: string) => {\n setValue(newValue);\n onChange?.(newValue);\n };\n\n const refineCaretPosition = () => {\n // если попытаться получить позицию каретки синхронно, то получим позицию до изменения\n requestAnimationFrame(() => {\n if (!inputRef.current) {\n return;\n }\n // Когда перемещаемся между цифрами если в позиции введена цифра, то ввод должен заменят именно её\n // а не сдвигать весь текст после нее врпаво, как в обычном инпуте.\n // Поэтому здесь проверяем если в позиции что-то введено, то не просто устанавливаем каретку, а выделяем\n // символ, чтобы при вводе он заменился\n const caretPosition = getCaretPosition(inputRef);\n const value = inputRef.current?.value ?? '';\n const digitNumberToSelect = Math.min(caretPosition, Math.min(value.length, digitsCount - 1));\n const selection = Selection.get(inputRef.current);\n if (selectionRef.current && selection.start !== selection.end) {\n return;\n }\n selectionRef.current = null;\n if (value.length > digitNumberToSelect) {\n Selection.set(inputRef.current, digitNumberToSelect, digitNumberToSelect + 1, 'forward');\n selectionRef.current = digitNumberToSelect;\n }\n setCaretPosition(caretPosition);\n });\n };\n\n return (\n <div ref={ref} data-qa={dataQa}>\n <div\n data-qa=\"magritte-pincode-input-wrapper\"\n className={classnames(styles.pincodeInput, {\n [styles.focus]: focused,\n [styles.focusVisible]: focusVisible,\n [styles.medium]: size === 'medium',\n [styles.invalid]: invalid,\n })}\n onClick={(event) => {\n const caretPosition = Math.min(\n Number((event.target as HTMLElement)?.dataset?.digitIndex ?? value.length),\n value.length\n );\n inputRef.current?.focus();\n moveCaretTo(inputRef, caretPosition);\n refineCaretPosition();\n }}\n // Этот обработчик нужен для того, чтобы не сбрасывался фокус при клике на дочерние элементы\n // Визуально это проявляется как моргание цвета рамки если клик происходит когда инпут в фокусе\n onMouseDown={(event) => event.preventDefault()}\n style={{ '--magritte-pincode-digits-count': digitsCount } as CSSProperties}\n >\n <input\n ref={inputRef}\n autoComplete=\"one-time-code\"\n pattern={`\\\\d{${digitsCount}}`}\n data-qa=\"magritte-pincode-input-field\"\n className={styles.digitsInput}\n type=\"text\"\n inputMode=\"numeric\"\n maxLength={digitsCount}\n value={value}\n onFocus={(event) => {\n onFocus?.(event);\n refineCaretPosition();\n if (!event.defaultPrevented) {\n setFocused(true);\n setFocusVisible(!!inputRef.current?.classList.contains('focus-visible'));\n if (invalid) {\n // По спеке если инпут помечен как invalid при фокусе содержимое должно очищаться\n updateValue('');\n }\n }\n }}\n onBlur={(event) => {\n onBlur?.(event);\n if (!event.defaultPrevented) {\n setFocused(false);\n setFocusVisible(false);\n }\n }}\n onKeyDown={(event) => {\n if (!inputRef.current) {\n return;\n }\n\n const isLeft = keyboardMatch(event, keyboardKeys.ArrowLeft);\n\n // Если одна из цифр выделена, и мы пытаемся передвинут каретку влево с помощью клавиатуры,\n // нужно делать это вручную, так как цифры мы выделяем справо на лево, и при нативном\n // перемещении курсо просто встанет перед выделенной цифрой, а refineCaretPosition yсова её\n // выделит и поставит каретку в исходное положение. Т.е. без этого кода не получится\n // передвинуть каретку влево, если выделена цифра\n if (isLeft && selectionRef.current !== null) {\n event.preventDefault();\n moveCaretTo(\n inputRef,\n Math.max(0, Math.min(selectionRef.current - 1, digitsCount - 1)),\n refineCaretPosition\n );\n return;\n }\n\n if (keyboardMatch(event, keyboardKeys.Backspace) && selectionRef.current !== null) {\n // При нажатии backspace действует следующая логика:\n // Если каретка находится в позиции последней введенной цифры, то удаляем её\n // и оставляем каретку на той же позиции\n // Если каретка находится в другой позиции, то удаляем цифру слева от каретки и\n // сдвигаем каретку влево\n event.preventDefault();\n const deleteIndex =\n selectionRef.current === value.length - 1\n ? selectionRef.current\n : Math.max(selectionRef.current - 1, 0);\n const newValue = `${value.slice(0, deleteIndex)}${value.slice(deleteIndex + 1)}`;\n updateValue(newValue);\n if (selectionRef.current !== value.length - 1) {\n moveCaretTo(inputRef, Math.max(selectionRef.current - 1, 0), refineCaretPosition);\n return;\n }\n }\n\n refineCaretPosition();\n }}\n onChange={(event) => {\n updateValue(event.target.value);\n if (selectionRef.current !== null) {\n // При изменении, если была выделена цифра, то каретку надо сдвинуть на следующую\n // позицию вручную\n moveCaretTo(inputRef, selectionRef.current + 1, refineCaretPosition);\n return;\n }\n refineCaretPosition();\n }}\n onPaste={(event) => {\n event.preventDefault();\n const pasteValue = event.clipboardData.getData('text').replace(/\\D/g, '');\n if (pasteValue.length === digitsCount) {\n updateValue(pasteValue);\n moveCaretTo(inputRef, digitsCount, refineCaretPosition);\n return;\n }\n\n const caretPosition = Math.min(\n getCaretPosition(inputRef),\n selectionRef.current ?? value.length\n );\n const newValue =\n `${value.slice(0, caretPosition)}${pasteValue}${value.slice(caretPosition + pasteValue.length)}`.slice(\n 0,\n digitsCount\n );\n updateValue(newValue);\n moveCaretTo(inputRef, caretPosition + pasteValue.length, refineCaretPosition);\n }}\n />\n <div className={styles.digitBoxContainer}>\n {/* eslint-disable-next-line no-restricted-properties */}\n {Array.from({ length: digitsCount }).map((_, index) => (\n <div key={index} className={classnames(styles.digitBox)} data-digit-index={index}>\n <span\n className={classnames(styles.valueContainer, {\n // в позицию ничего не введено, и каретка не находится в этой позиции\n [styles.placeholder]:\n index >= value.length &&\n (!focused ||\n (index !== caretPosition &&\n !(caretPosition === digitsCount && index === digitsCount - 1))),\n // в позицию введена цифра, каретка находится в этой позиции, фокус\n // установлен в инпут, это не крайняя справа цифра из введенных\n [styles.caretLeft]:\n index === caretPosition && index !== value.length - 1 && focused,\n // в позицию введена цифра, каретка находится в этой позиции, либо в следующей\n // если введены все цифры (потому что при вводе последней цифры каретка\n // должна уходить за нее), фокус установлен в инпут, это крайняя справа цифра\n // из введенных\n [styles.caretRight]:\n (index === caretPosition ||\n (index === digitsCount - 1 && index === caretPosition - 1)) &&\n index === value.length - 1 &&\n focused,\n })}\n data-qa={`magritte-pincode-input-digit-${index}`}\n >\n {value[index] || (caretPosition === index && focused ? '' : '•')}\n </span>\n </div>\n ))}\n </div>\n </div>\n <FormHelper\n invalid={invalid}\n description={description}\n errorMessage={errorMessage}\n data-qa=\"magritte-pincode-input-message\"\n />\n </div>\n );\n }\n);\n\nPincodeInput.displayName = 'PincodeInput';\n"],"names":["_jsxs","_jsx"],"mappings":";;;;;;;;;AASA,MAAM,WAAW,GAAG,CAAC,GAAgC,EAAE,QAAgB,EAAE,QAAuB;AAC5F;AACA;AACA,qBAAqB,CAAC,MAAK;AACvB,IAAA,IAAI,GAAG,CAAC,OAAO,EAAE;QACb,SAAS,CAAC,gBAAgB,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAClD,QAAQ,IAAI,CAAC;KAChB;AACL,CAAC,CAAC,CAAC;AAEP,MAAM,gBAAgB,GAAG,CAAC,GAAgC,KACtD,GAAG,CAAC,OAAO,IAAI,SAAS,CAAC,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AA2BxD,MAAA,YAAY,GAAG,UAAU,CAClC,CACI,EACI,WAAW,EAAE,YAAY,GAAG,IAAI,EAChC,IAAI,GAAG,OAAO,EACd,OAAO,GAAG,KAAK,EACf,OAAO,EACP,MAAM,EACN,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,SAAS,EAAE,MAAM,GAAG,wBAAwB,GAC/C,EACD,GAAG,KACH;AACA,IAAA,MAAM,WAAW,GAAG,YAAY,KAAK,IAAI,KAAK,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAS,EAAE,CAAC,CAAC;IAC/C,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAS,CAAC,CAAC,CAAC;IAC9D,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;AAExD,IAAA,MAAM,QAAQ,GAAG,MAAM,CAAmB,IAAI,CAAC,CAAC;AAChD,IAAA,MAAM,YAAY,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAC;AAEjD,IAAA,MAAM,WAAW,GAAG,CAAC,QAAgB,KAAI;QACrC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACnB,QAAA,QAAQ,GAAG,QAAQ,CAAC,CAAC;AACzB,KAAC,CAAC;IAEF,MAAM,mBAAmB,GAAG,MAAK;;QAE7B,qBAAqB,CAAC,MAAK;AACvB,YAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE;gBACnB,OAAO;aACV;;;;;AAKD,YAAA,MAAM,aAAa,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YACjD,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC;YAC5C,MAAM,mBAAmB,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC;YAC7F,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAClD,YAAA,IAAI,YAAY,CAAC,OAAO,IAAI,SAAS,CAAC,KAAK,KAAK,SAAS,CAAC,GAAG,EAAE;gBAC3D,OAAO;aACV;AACD,YAAA,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC;AAC5B,YAAA,IAAI,KAAK,CAAC,MAAM,GAAG,mBAAmB,EAAE;AACpC,gBAAA,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC;AACzF,gBAAA,YAAY,CAAC,OAAO,GAAG,mBAAmB,CAAC;aAC9C;YACD,gBAAgB,CAAC,aAAa,CAAC,CAAC;AACpC,SAAC,CAAC,CAAC;AACP,KAAC,CAAC;AAEF,IAAA,QACIA,IAAK,CAAA,KAAA,EAAA,EAAA,GAAG,EAAE,GAAG,EAAA,SAAA,EAAW,MAAM,EAC1B,QAAA,EAAA,CAAAA,IAAA,CAAA,KAAA,EAAA,EAAA,SAAA,EACY,gCAAgC,EACxC,SAAS,EAAE,UAAU,CAAC,MAAM,CAAC,YAAY,EAAE;AACvC,oBAAA,CAAC,MAAM,CAAC,KAAK,GAAG,OAAO;AACvB,oBAAA,CAAC,MAAM,CAAC,YAAY,GAAG,YAAY;AACnC,oBAAA,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,KAAK,QAAQ;AAClC,oBAAA,CAAC,MAAM,CAAC,OAAO,GAAG,OAAO;AAC5B,iBAAA,CAAC,EACF,OAAO,EAAE,CAAC,KAAK,KAAI;oBACf,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAC1B,MAAM,CAAE,KAAK,CAAC,MAAsB,EAAE,OAAO,EAAE,UAAU,IAAI,KAAK,CAAC,MAAM,CAAC,EAC1E,KAAK,CAAC,MAAM,CACf,CAAC;AACF,oBAAA,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;AAC1B,oBAAA,WAAW,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;AACrC,oBAAA,mBAAmB,EAAE,CAAC;iBACzB;;;AAGD,gBAAA,WAAW,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,cAAc,EAAE,EAC9C,KAAK,EAAE,EAAE,iCAAiC,EAAE,WAAW,EAAmB,EAE1E,QAAA,EAAA,CAAAC,GAAA,CAAA,OAAA,EAAA,EACI,GAAG,EAAE,QAAQ,EACb,YAAY,EAAC,eAAe,EAC5B,OAAO,EAAE,CAAA,IAAA,EAAO,WAAW,CAAA,CAAA,CAAG,EACtB,SAAA,EAAA,8BAA8B,EACtC,SAAS,EAAE,MAAM,CAAC,WAAW,EAC7B,IAAI,EAAC,MAAM,EACX,SAAS,EAAC,SAAS,EACnB,SAAS,EAAE,WAAW,EACtB,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,CAAC,KAAK,KAAI;AACf,4BAAA,OAAO,GAAG,KAAK,CAAC,CAAC;AACjB,4BAAA,mBAAmB,EAAE,CAAC;AACtB,4BAAA,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE;gCACzB,UAAU,CAAC,IAAI,CAAC,CAAC;AACjB,gCAAA,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC;gCACzE,IAAI,OAAO,EAAE;;oCAET,WAAW,CAAC,EAAE,CAAC,CAAC;iCACnB;6BACJ;AACL,yBAAC,EACD,MAAM,EAAE,CAAC,KAAK,KAAI;AACd,4BAAA,MAAM,GAAG,KAAK,CAAC,CAAC;AAChB,4BAAA,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE;gCACzB,UAAU,CAAC,KAAK,CAAC,CAAC;gCAClB,eAAe,CAAC,KAAK,CAAC,CAAC;6BAC1B;AACL,yBAAC,EACD,SAAS,EAAE,CAAC,KAAK,KAAI;AACjB,4BAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE;gCACnB,OAAO;6BACV;4BAED,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;;;;;;4BAO5D,IAAI,MAAM,IAAI,YAAY,CAAC,OAAO,KAAK,IAAI,EAAE;gCACzC,KAAK,CAAC,cAAc,EAAE,CAAC;gCACvB,WAAW,CACP,QAAQ,EACR,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,GAAG,CAAC,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC,EAChE,mBAAmB,CACtB,CAAC;gCACF,OAAO;6BACV;AAED,4BAAA,IAAI,aAAa,CAAC,KAAK,EAAE,YAAY,CAAC,SAAS,CAAC,IAAI,YAAY,CAAC,OAAO,KAAK,IAAI,EAAE;;;;;;gCAM/E,KAAK,CAAC,cAAc,EAAE,CAAC;gCACvB,MAAM,WAAW,GACb,YAAY,CAAC,OAAO,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC;sCACnC,YAAY,CAAC,OAAO;AACtB,sCAAE,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;gCAChD,MAAM,QAAQ,GAAG,CAAG,EAAA,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,CAAG,EAAA,KAAK,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC,CAAA,CAAE,CAAC;gCACjF,WAAW,CAAC,QAAQ,CAAC,CAAC;gCACtB,IAAI,YAAY,CAAC,OAAO,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;AAC3C,oCAAA,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC;oCAClF,OAAO;iCACV;6BACJ;AAED,4BAAA,mBAAmB,EAAE,CAAC;AAC1B,yBAAC,EACD,QAAQ,EAAE,CAAC,KAAK,KAAI;AAChB,4BAAA,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChC,4BAAA,IAAI,YAAY,CAAC,OAAO,KAAK,IAAI,EAAE;;;gCAG/B,WAAW,CAAC,QAAQ,EAAE,YAAY,CAAC,OAAO,GAAG,CAAC,EAAE,mBAAmB,CAAC,CAAC;gCACrE,OAAO;6BACV;AACD,4BAAA,mBAAmB,EAAE,CAAC;AAC1B,yBAAC,EACD,OAAO,EAAE,CAAC,KAAK,KAAI;4BACf,KAAK,CAAC,cAAc,EAAE,CAAC;AACvB,4BAAA,MAAM,UAAU,GAAG,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC1E,4BAAA,IAAI,UAAU,CAAC,MAAM,KAAK,WAAW,EAAE;gCACnC,WAAW,CAAC,UAAU,CAAC,CAAC;AACxB,gCAAA,WAAW,CAAC,QAAQ,EAAE,WAAW,EAAE,mBAAmB,CAAC,CAAC;gCACxD,OAAO;6BACV;AAED,4BAAA,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAC1B,gBAAgB,CAAC,QAAQ,CAAC,EAC1B,YAAY,CAAC,OAAO,IAAI,KAAK,CAAC,MAAM,CACvC,CAAC;AACF,4BAAA,MAAM,QAAQ,GACV,CAAG,EAAA,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,CAAG,EAAA,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,aAAa,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA,CAAE,CAAC,KAAK,CAClG,CAAC,EACD,WAAW,CACd,CAAC;4BACN,WAAW,CAAC,QAAQ,CAAC,CAAC;4BACtB,WAAW,CAAC,QAAQ,EAAE,aAAa,GAAG,UAAU,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;yBACjF,EAAA,CACH,EACFA,GAAK,CAAA,KAAA,EAAA,EAAA,SAAS,EAAE,MAAM,CAAC,iBAAiB,EAAA,QAAA,EAEnC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,MAC9CA,GAAA,CAAA,KAAA,EAAA,EAAiB,SAAS,EAAE,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAoB,kBAAA,EAAA,KAAK,EAC5E,QAAA,EAAAA,GAAA,CAAA,MAAA,EAAA,EACI,SAAS,EAAE,UAAU,CAAC,MAAM,CAAC,cAAc,EAAE;;oCAEzC,CAAC,MAAM,CAAC,WAAW,GACf,KAAK,IAAI,KAAK,CAAC,MAAM;AACrB,yCAAC,CAAC,OAAO;6CACJ,KAAK,KAAK,aAAa;AACpB,gDAAA,EAAE,aAAa,KAAK,WAAW,IAAI,KAAK,KAAK,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC;;;AAG3E,oCAAA,CAAC,MAAM,CAAC,SAAS,GACb,KAAK,KAAK,aAAa,IAAI,KAAK,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO;;;;;oCAKpE,CAAC,MAAM,CAAC,UAAU,GACd,CAAC,KAAK,KAAK,aAAa;AACpB,yCAAC,KAAK,KAAK,WAAW,GAAG,CAAC,IAAI,KAAK,KAAK,aAAa,GAAG,CAAC,CAAC;AAC9D,wCAAA,KAAK,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC;wCAC1B,OAAO;iCACd,CAAC,EAAA,SAAA,EACO,CAAgC,6BAAA,EAAA,KAAK,CAAE,CAAA,EAAA,QAAA,EAE/C,KAAK,CAAC,KAAK,CAAC,KAAK,aAAa,KAAK,KAAK,IAAI,OAAO,GAAG,EAAE,GAAG,GAAG,CAAC,EAAA,CAC7D,IA1BD,KAAK,CA2BT,CACT,CAAC,EACA,CAAA,CAAA,EAAA,CACJ,EACNA,GAAC,CAAA,UAAU,EACP,EAAA,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,WAAW,EACxB,YAAY,EAAE,YAAY,EAAA,SAAA,EAClB,gCAAgC,EAAA,CAC1C,CACA,EAAA,CAAA,EACR;AACN,CAAC,EACH;AAEF,YAAY,CAAC,WAAW,GAAG,cAAc;;;;"}
|
|
1
|
+
{"version":3,"file":"PincodeInput.js","sources":["../src/PincodeInput.tsx"],"sourcesContent":["import { type CSSProperties, type FocusEventHandler, useRef, useState, forwardRef, useLayoutEffect } from 'react';\nimport classnames from 'classnames';\n\nimport { keyboardKeys, keyboardMatch, keyboardMatches } from '@hh.ru/magritte-common-keyboard';\nimport { FormHelper } from '@hh.ru/magritte-ui-form-helper';\n\nimport styles from './pincodeInput.less';\n\nexport type PincodeInputSize = 'medium' | 'large';\n\nexport interface PincodeInputProps {\n /**\n * Количество цифр в пин-коде, если не указано будет выбрано автоматически\n * в зависимости от размера инпута ( medium - 6, large - 4)\n */\n digitsCount?: number | null;\n /** Размер инпута */\n size?: PincodeInputSize;\n /** Обработчик изменений */\n onChange?: (value: string) => void;\n /** Обработчик фокуса */\n onFocus?: FocusEventHandler<HTMLInputElement>;\n /** Обработчик потери фокуса */\n onBlur?: FocusEventHandler<HTMLInputElement>;\n /** Флаг наличия ошибки */\n invalid?: boolean;\n /** Текст описания */\n description?: string;\n /** Текст сообщения об ошибке */\n errorMessage?: string;\n 'data-qa'?: string;\n}\n\nconst clamp = (value: number, min: number, max: number) => Math.min(Math.max(value, min), max);\nconst noop = () => {};\n\nexport const PincodeInput = forwardRef<HTMLDivElement, PincodeInputProps>(\n (\n {\n digitsCount: _digitsCount = null,\n size = 'large',\n invalid = false,\n onFocus,\n onBlur,\n onChange,\n description,\n errorMessage,\n 'data-qa': dataQa = 'magritte-pincode-input',\n },\n ref\n ) => {\n const digitsCount = _digitsCount ?? (size === 'medium' ? 6 : 4);\n const [value, setValue] = useState<string>('');\n const [caretPosition, setCaretPosition] = useState<number>(0);\n const [focused, setFocused] = useState(false);\n const [focusVisible, setFocusVisible] = useState(false);\n\n const ghostLastDigitRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n useLayoutEffect(() => {\n if (!containerRef.current || !ghostLastDigitRef.current) {\n return;\n }\n\n const lastWidth = ghostLastDigitRef.current.getBoundingClientRect().width;\n containerRef.current.style.setProperty('--magritte-pincode-last-digit-width', `${lastWidth}px`);\n }, [caretPosition, value]);\n\n const updateValue = (newValue: string) => {\n setValue(newValue);\n onChange?.(newValue);\n };\n\n const caretPos = clamp(caretPosition, 0, value.length);\n\n return (\n <div ref={ref} data-qa={dataQa}>\n <div\n data-qa=\"magritte-pincode-input-wrapper\"\n ref={containerRef}\n className={classnames(styles.pincodeInput, {\n [styles.focus]: focused,\n [styles.focusVisible]: focusVisible,\n [styles.medium]: size === 'medium',\n [styles.invalid]: invalid,\n })}\n onMouseDown={(event) => {\n if (event.target === inputRef.current) {\n return;\n }\n event.preventDefault();\n\n const caretPosition = Math.min(\n Number((event.target as HTMLElement)?.dataset?.digitIndex ?? value.length),\n value.length\n );\n\n if (!focused) {\n inputRef.current?.focus();\n }\n\n setCaretPosition(caretPosition);\n }}\n style={\n {\n '--magritte-pincode-digits-count': digitsCount,\n '--magritte-pincode-caret-position': caretPos,\n } as CSSProperties\n }\n >\n <input\n ref={inputRef}\n autoComplete=\"one-time-code\"\n pattern={`\\\\d{${digitsCount}}`}\n data-qa=\"magritte-pincode-input-field\"\n className={styles.digitsInput}\n type=\"text\"\n inputMode=\"numeric\"\n maxLength={digitsCount}\n // оставляем инпут всегда пустым, т.к. он нам нужен только для показа контекстного меню вставки,\n // обработки события вставки и обработки фокуса\n value=\"\"\n // без change хендлера react пишет warning в консоль\n onChange={noop}\n onFocus={(event) => {\n onFocus?.(event);\n if (!event.defaultPrevented) {\n setFocused(true);\n setFocusVisible(!!inputRef.current?.classList.contains('focus-visible'));\n if (invalid) {\n // По спеке если инпут помечен как invalid при фокусе содержимое должно очищаться\n updateValue('');\n setCaretPosition(0);\n }\n }\n }}\n onBlur={(event) => {\n onBlur?.(event);\n if (!event.defaultPrevented) {\n setFocused(false);\n setFocusVisible(false);\n }\n }}\n onKeyDown={(event) => {\n if (!inputRef.current) {\n return;\n }\n\n const isLeft = keyboardMatch(event, keyboardKeys.ArrowLeft);\n const isRight = keyboardMatch(event, keyboardKeys.ArrowRight);\n if (isLeft || isRight) {\n event.preventDefault();\n setCaretPosition((caretPosition) =>\n clamp(caretPosition + (isRight ? 1 : -1), 0, value.length)\n );\n return;\n }\n\n if (keyboardMatches(event, keyboardKeys.DigitKeys)) {\n updateValue(`${value.slice(0, caretPos)}${event.key}${value.slice(caretPos + 1)}`);\n setCaretPosition((caretPosition) => clamp(caretPosition + 1, 0, digitsCount - 1));\n event.preventDefault();\n return;\n }\n\n const isBackspace = keyboardMatch(event, keyboardKeys.Backspace);\n const isDelete = keyboardMatch(event, keyboardKeys.Delete);\n\n if (isBackspace || isDelete) {\n // При нажатии backspace действует следующая логика:\n // Если каретка находится в позиции последней введенной цифры, то удаляем её\n // и оставляем каретку на той же позиции\n // Если каретка находится в другой позиции, то удаляем цифру слева от каретки и\n // сдвигаем каретку влево\n\n const isLastDigit = caretPos === value.length - 1;\n const deleteIndex = clamp(\n caretPos - (isDelete || isLastDigit ? 0 : 1),\n 0,\n digitsCount - 1\n );\n updateValue(`${value.slice(0, deleteIndex)}${value.slice(deleteIndex + 1)}`);\n setCaretPosition((caretPosition) => {\n const newPosition =\n isLastDigit || isDelete ? caretPosition : Math.max(caretPosition - 1, 0);\n\n return newPosition;\n });\n\n event.preventDefault();\n }\n }}\n onPaste={(event) => {\n event.preventDefault();\n const pasteValue = event.clipboardData.getData('text').replace(/\\D/g, '');\n if (pasteValue.length === digitsCount) {\n updateValue(pasteValue);\n setCaretPosition(digitsCount - 1);\n return;\n }\n\n const newValue =\n `${value.slice(0, caretPos)}${pasteValue}${value.slice(caretPos + pasteValue.length)}`.slice(\n 0,\n digitsCount\n );\n updateValue(newValue);\n setCaretPosition(Math.min(digitsCount - 1, caretPos + pasteValue.length));\n }}\n />\n <div className={styles.digitBoxContainer}>\n {/* eslint-disable-next-line no-restricted-properties */}\n {Array.from({ length: digitsCount }).map((_, index) => (\n <div key={index} className={classnames(styles.digitBox)} data-digit-index={index}>\n <span\n className={classnames(styles.valueContainer, {\n // в позицию ничего не введено, и каретка не находится в этой позиции\n [styles.placeholder]:\n index >= value.length &&\n (!focused ||\n (index !== caretPos &&\n !(caretPos === digitsCount && index === digitsCount - 1))),\n // в позицию введена цифра, каретка находится в этой позиции, фокус\n // установлен в инпут, это не крайняя справа цифра из введенных\n [styles.caretLeft]: index === caretPos && index !== value.length - 1 && focused,\n // в позицию введена цифра, каретка находится в этой позиции, либо в следующей\n // если введены все цифры (потому что при вводе последней цифры каретка\n // должна уходить за нее), фокус установлен в инпут, это крайняя справа цифра\n // из введенных\n [styles.caretRight]:\n (index === caretPos ||\n (index === digitsCount - 1 && index === caretPos - 1)) &&\n index === value.length - 1 &&\n focused,\n })}\n data-qa={`magritte-pincode-input-digit-${index}`}\n >\n {value[index] || (caretPos === index && focused ? '' : '•')}\n </span>\n </div>\n ))}\n </div>\n <div className={styles.ghostValue} ref={ghostLastDigitRef}>\n {value.slice(caretPos, caretPos + 1)}\n </div>\n </div>\n <FormHelper\n invalid={invalid}\n description={description}\n errorMessage={errorMessage}\n data-qa=\"magritte-pincode-input-message\"\n />\n </div>\n );\n }\n);\n\nPincodeInput.displayName = 'PincodeInput';\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
|
package/index.css
CHANGED
|
@@ -1,143 +1,170 @@
|
|
|
1
1
|
:root{
|
|
2
|
-
--magritte-color-text-primary-v21-
|
|
3
|
-
--magritte-color-component-input-stroke-state-field-hovered-v21-
|
|
4
|
-
--magritte-color-component-input-stroke-state-field-focused-v21-
|
|
5
|
-
--magritte-color-component-input-stroke-state-accent-focused-accessible-v21-
|
|
6
|
-
--magritte-color-component-input-stroke-state-field-invalid-v21-
|
|
7
|
-
--magritte-color-component-input-
|
|
8
|
-
--magritte-color-component-input-background-
|
|
9
|
-
--magritte-color-component-input-background-state-field-
|
|
10
|
-
--magritte-color-component-input-background-state-field-
|
|
11
|
-
--magritte-color-component-input-
|
|
12
|
-
--magritte-color-component-input-
|
|
13
|
-
--magritte-color-component-input-text-state-
|
|
14
|
-
--magritte-color-component-input-text-state-placeholder-
|
|
15
|
-
--magritte-color-component-input-text-state-placeholder-
|
|
16
|
-
--magritte-color-component-input-text-placeholder-v21-
|
|
2
|
+
--magritte-color-text-primary-v21-1-0:#000000;
|
|
3
|
+
--magritte-color-component-input-stroke-state-field-hovered-v21-1-0:#CCD5DF;
|
|
4
|
+
--magritte-color-component-input-stroke-state-field-focused-v21-1-0:#0070ff;
|
|
5
|
+
--magritte-color-component-input-stroke-state-accent-focused-accessible-v21-1-0:#0070ff7a;
|
|
6
|
+
--magritte-color-component-input-stroke-state-field-invalid-v21-1-0:#ff4d3a;
|
|
7
|
+
--magritte-color-component-input-stroke-state-negative-focused-accessible-v21-1-0:#ff4d3a7a;
|
|
8
|
+
--magritte-color-component-input-background-field-v21-1-0:#ffffff;
|
|
9
|
+
--magritte-color-component-input-background-state-field-hovered-v21-1-0:#ffffff;
|
|
10
|
+
--magritte-color-component-input-background-state-field-focused-v21-1-0:#ffffff;
|
|
11
|
+
--magritte-color-component-input-background-state-field-invalid-v21-1-0:#ffffff;
|
|
12
|
+
--magritte-color-component-input-stroke-field-v21-1-0:#DCE3EB;
|
|
13
|
+
--magritte-color-component-input-text-state-content-focused-v21-1-0:#000000;
|
|
14
|
+
--magritte-color-component-input-text-state-placeholder-hovered-v21-1-0:#768694;
|
|
15
|
+
--magritte-color-component-input-text-state-placeholder-focused-v21-1-0:#AABBCA;
|
|
16
|
+
--magritte-color-component-input-text-state-placeholder-invalid-v21-1-0:#AABBCA;
|
|
17
|
+
--magritte-color-component-input-text-placeholder-v21-1-0:#AABBCA;
|
|
17
18
|
}
|
|
18
19
|
:root{
|
|
19
|
-
--magritte-font-families-body-v21-
|
|
20
|
-
--magritte-semantic-border-width-default-v21-
|
|
21
|
-
--magritte-semantic-border-width-focused-v21-
|
|
22
|
-
--magritte-static-border-radius-300-v21-
|
|
23
|
-
--magritte-static-border-radius-450-v21-
|
|
20
|
+
--magritte-font-families-body-v21-1-0:hh sans;
|
|
21
|
+
--magritte-semantic-border-width-default-v21-1-0:1px;
|
|
22
|
+
--magritte-semantic-border-width-focused-v21-1-0:2px;
|
|
23
|
+
--magritte-static-border-radius-300-v21-1-0:12px;
|
|
24
|
+
--magritte-static-border-radius-450-v21-1-0:18px;
|
|
24
25
|
}
|
|
25
26
|
.magritte-night-theme{
|
|
26
|
-
--magritte-color-text-primary-v21-
|
|
27
|
-
--magritte-color-component-input-stroke-state-field-hovered-v21-
|
|
28
|
-
--magritte-color-component-input-stroke-state-field-focused-v21-
|
|
29
|
-
--magritte-color-component-input-stroke-state-accent-focused-accessible-v21-
|
|
30
|
-
--magritte-color-component-input-stroke-state-field-invalid-v21-
|
|
31
|
-
--magritte-color-component-input-
|
|
32
|
-
--magritte-color-component-input-background-
|
|
33
|
-
--magritte-color-component-input-background-state-field-
|
|
34
|
-
--magritte-color-component-input-background-state-field-
|
|
35
|
-
--magritte-color-component-input-
|
|
36
|
-
--magritte-color-component-input-
|
|
37
|
-
--magritte-color-component-input-text-
|
|
38
|
-
--magritte-color-component-input-text-state-
|
|
39
|
-
--magritte-color-component-input-text-state-placeholder-
|
|
40
|
-
--magritte-color-component-input-text-state-placeholder-
|
|
41
|
-
|
|
42
|
-
|
|
27
|
+
--magritte-color-text-primary-v21-1-0:#ffffff;
|
|
28
|
+
--magritte-color-component-input-stroke-state-field-hovered-v21-1-0:#3B3B3B;
|
|
29
|
+
--magritte-color-component-input-stroke-state-field-focused-v21-1-0:#0070ff;
|
|
30
|
+
--magritte-color-component-input-stroke-state-accent-focused-accessible-v21-1-0:#0070ff7a;
|
|
31
|
+
--magritte-color-component-input-stroke-state-field-invalid-v21-1-0:#ff4d3a;
|
|
32
|
+
--magritte-color-component-input-stroke-state-negative-focused-accessible-v21-1-0:#ff4d3a7a;
|
|
33
|
+
--magritte-color-component-input-background-field-v21-1-0:#1B1B1B;
|
|
34
|
+
--magritte-color-component-input-background-state-field-hovered-v21-1-0:#1B1B1B;
|
|
35
|
+
--magritte-color-component-input-background-state-field-focused-v21-1-0:#1B1B1B;
|
|
36
|
+
--magritte-color-component-input-background-state-field-invalid-v21-1-0:#1B1B1B;
|
|
37
|
+
--magritte-color-component-input-stroke-field-v21-1-0:#303030;
|
|
38
|
+
--magritte-color-component-input-text-placeholder-v21-1-0:#535353;
|
|
39
|
+
--magritte-color-component-input-text-state-content-focused-v21-1-0:#ffffff;
|
|
40
|
+
--magritte-color-component-input-text-state-placeholder-hovered-v21-1-0:#5E5E5E;
|
|
41
|
+
--magritte-color-component-input-text-state-placeholder-focused-v21-1-0:#535353;
|
|
42
|
+
--magritte-color-component-input-text-state-placeholder-invalid-v21-1-0:#535353;
|
|
43
|
+
}
|
|
44
|
+
.magritte-pincode-input___RpWyq_1-0-3{
|
|
43
45
|
--magritte-pincode-input-padding-horizontal:20px;
|
|
44
46
|
--magritte-pincode-input-padding-vertical:8px;
|
|
45
47
|
--magritte-pincode-input-gap:6px;
|
|
48
|
+
--magritte-digit-box-width:calc((100% - (var(--magritte-pincode-input-gap) * (var(--magritte-pincode-digits-count) - 1)) - (var(--magritte-pincode-input-padding-horizontal) * 2)) / var(--magritte-pincode-digits-count));
|
|
46
49
|
box-sizing:border-box;
|
|
47
50
|
height:88px;
|
|
48
|
-
|
|
49
|
-
border-radius:var(--magritte-static-border-radius-450-v21-
|
|
50
|
-
background-color:var(--magritte-color-component-input-background-field-v21-
|
|
51
|
-
padding:var(--magritte-pincode-input-padding-vertical) var(--magritte-pincode-input-padding-horizontal);
|
|
51
|
+
box-shadow:inset 0 0 0 var(--magritte-semantic-border-width-default-v21-1-0) var(--magritte-color-component-input-stroke-field-v21-1-0);
|
|
52
|
+
border-radius:var(--magritte-static-border-radius-450-v21-1-0);
|
|
53
|
+
background-color:var(--magritte-color-component-input-background-field-v21-1-0);
|
|
52
54
|
position:relative;
|
|
55
|
+
overflow:clip;
|
|
53
56
|
cursor:text;
|
|
54
|
-
font-family:var(--magritte-font-families-body-v21-
|
|
57
|
+
font-family:var(--magritte-font-families-body-v21-1-0);
|
|
55
58
|
font-size:32px;
|
|
56
59
|
font-style:normal;
|
|
57
60
|
font-weight:normal;
|
|
58
61
|
line-height:40px;
|
|
59
|
-
color:var(--magritte-color-component-input-text-state-content-focused-v21-
|
|
62
|
+
color:var(--magritte-color-component-input-text-state-content-focused-v21-1-0);
|
|
60
63
|
}
|
|
61
|
-
.magritte-pincode-input___RpWyq_1-0-
|
|
64
|
+
.magritte-pincode-input___RpWyq_1-0-3.magritte-medium___wfRSc_1-0-3{
|
|
62
65
|
font-size:28px;
|
|
63
66
|
--magritte-pincode-input-padding-horizontal:16px;
|
|
64
67
|
--magritte-pincode-input-padding-vertical:6px;
|
|
65
68
|
--magritte-pincode-input-gap:4px;
|
|
66
|
-
border-radius:var(--magritte-static-border-radius-300-v21-
|
|
69
|
+
border-radius:var(--magritte-static-border-radius-300-v21-1-0);
|
|
67
70
|
height:76px;
|
|
68
71
|
}
|
|
69
|
-
.magritte-pincode-input___RpWyq_1-0-
|
|
70
|
-
|
|
71
|
-
background-color:var(--magritte-color-component-input-background-state-field-hovered-v21-
|
|
72
|
+
.magritte-pincode-input___RpWyq_1-0-3:hover{
|
|
73
|
+
box-shadow:inset 0 0 0 var(--magritte-semantic-border-width-default-v21-1-0) var(--magritte-color-component-input-stroke-state-field-hovered-v21-1-0);
|
|
74
|
+
background-color:var(--magritte-color-component-input-background-state-field-hovered-v21-1-0);
|
|
72
75
|
}
|
|
73
|
-
.magritte-pincode-input___RpWyq_1-0-
|
|
74
|
-
color:var(--magritte-color-component-input-text-state-placeholder-hovered-v21-
|
|
76
|
+
.magritte-pincode-input___RpWyq_1-0-3:hover .magritte-placeholder___10kQ0_1-0-3{
|
|
77
|
+
color:var(--magritte-color-component-input-text-state-placeholder-hovered-v21-1-0);
|
|
75
78
|
}
|
|
76
|
-
.magritte-pincode-input___RpWyq_1-0-
|
|
77
|
-
|
|
78
|
-
background-color:var(--magritte-color-component-input-background-state-field-focused-v21-
|
|
79
|
-
padding:var(--magritte-pincode-input-padding-vertical) calc(var(--magritte-pincode-input-padding-horizontal) - 1px);
|
|
79
|
+
.magritte-pincode-input___RpWyq_1-0-3.magritte-focus___IuhXb_1-0-3{
|
|
80
|
+
box-shadow:inset 0 0 0 var(--magritte-semantic-border-width-focused-v21-1-0) var(--magritte-color-component-input-stroke-state-field-focused-v21-1-0);
|
|
81
|
+
background-color:var(--magritte-color-component-input-background-state-field-focused-v21-1-0);
|
|
80
82
|
}
|
|
81
|
-
.magritte-pincode-input___RpWyq_1-0-
|
|
82
|
-
color:var(--magritte-color-component-input-text-state-placeholder-focused-v21-
|
|
83
|
+
.magritte-pincode-input___RpWyq_1-0-3.magritte-focus___IuhXb_1-0-3 .magritte-placeholder___10kQ0_1-0-3{
|
|
84
|
+
color:var(--magritte-color-component-input-text-state-placeholder-focused-v21-1-0);
|
|
83
85
|
}
|
|
84
|
-
.magritte-pincode-input___RpWyq_1-0-
|
|
85
|
-
|
|
86
|
-
background-color:var(--magritte-color-component-input-background-state-field-invalid-v21-
|
|
86
|
+
.magritte-pincode-input___RpWyq_1-0-3.magritte-invalid___hB8h2_1-0-3{
|
|
87
|
+
box-shadow:inset 0 0 0 var(--magritte-semantic-border-width-default-v21-1-0) var(--magritte-color-component-input-stroke-state-field-invalid-v21-1-0);
|
|
88
|
+
background-color:var(--magritte-color-component-input-background-state-field-invalid-v21-1-0);
|
|
87
89
|
}
|
|
88
|
-
.magritte-pincode-input___RpWyq_1-0-
|
|
89
|
-
color:var(--magritte-color-component-input-text-state-placeholder-invalid-v21-
|
|
90
|
+
.magritte-pincode-input___RpWyq_1-0-3.magritte-invalid___hB8h2_1-0-3 .magritte-placeholder___10kQ0_1-0-3{
|
|
91
|
+
color:var(--magritte-color-component-input-text-state-placeholder-invalid-v21-1-0);
|
|
90
92
|
}
|
|
91
|
-
.magritte-pincode-input___RpWyq_1-0-
|
|
92
|
-
outline:var(--magritte-color-component-input-stroke-state-accent-focused-accessible-v21-
|
|
93
|
+
.magritte-pincode-input___RpWyq_1-0-3.magritte-focus-visible___BN1eD_1-0-3{
|
|
94
|
+
outline:var(--magritte-color-component-input-stroke-state-accent-focused-accessible-v21-1-0) solid 4px;
|
|
93
95
|
}
|
|
94
|
-
.magritte-
|
|
96
|
+
.magritte-pincode-input___RpWyq_1-0-3.magritte-focus-visible___BN1eD_1-0-3.magritte-invalid___hB8h2_1-0-3{
|
|
97
|
+
outline-color:var(--magritte-color-component-input-stroke-state-negative-focused-accessible-v21-1-0);
|
|
98
|
+
}
|
|
99
|
+
.magritte-digit-box-container___BqMWw_1-0-3{
|
|
95
100
|
display:flex;
|
|
96
101
|
gap:var(--magritte-pincode-input-gap);
|
|
97
|
-
position:
|
|
98
|
-
|
|
102
|
+
position:absolute;
|
|
103
|
+
inset:0;
|
|
104
|
+
justify-content:center;
|
|
99
105
|
align-items:stretch;
|
|
100
106
|
height:100%;
|
|
107
|
+
pointer-events:none;
|
|
108
|
+
z-index:0;
|
|
101
109
|
}
|
|
102
|
-
.magritte-digit-box___6J0Q2_1-0-
|
|
103
|
-
flex:0 0
|
|
110
|
+
.magritte-digit-box___6J0Q2_1-0-3{
|
|
111
|
+
flex:0 0 var(--magritte-digit-box-width);
|
|
112
|
+
pointer-events:auto;
|
|
104
113
|
display:flex;
|
|
105
114
|
align-items:center;
|
|
106
115
|
justify-content:center;
|
|
116
|
+
user-select:none;
|
|
117
|
+
}
|
|
118
|
+
.magritte-digit-box___6J0Q2_1-0-3::selection{
|
|
119
|
+
background-color:transparent;
|
|
107
120
|
}
|
|
108
|
-
.magritte-
|
|
121
|
+
.magritte-digit-box___6J0Q2_1-0-3::-moz-selection{
|
|
122
|
+
background-color:transparent;
|
|
123
|
+
}
|
|
124
|
+
.magritte-digits-input___4QeLj_1-0-3{
|
|
109
125
|
display:block;
|
|
110
126
|
position:absolute;
|
|
111
|
-
|
|
127
|
+
top:0;
|
|
128
|
+
bottom:0;
|
|
129
|
+
--last-digit-width:max(var(--magritte-pincode-last-digit-width), 10px);
|
|
130
|
+
padding:0 calc(var(--last-digit-width) / 2);
|
|
131
|
+
left:calc(var(--magritte-pincode-input-padding-horizontal) + (var(--magritte-pincode-caret-position) * var(--magritte-digit-box-width)) + (var(--magritte-pincode-caret-position) * var(--magritte-pincode-input-gap)) + (var(--magritte-digit-box-width) / 2) - var(--last-digit-width) / 2);
|
|
132
|
+
height:100%;
|
|
133
|
+
width:var(--last-digit-width);
|
|
134
|
+
z-index:1;
|
|
112
135
|
border-width:0;
|
|
113
136
|
background:none;
|
|
114
|
-
|
|
137
|
+
color:transparent;
|
|
115
138
|
outline:none;
|
|
116
139
|
appearance:none;
|
|
117
140
|
caret-color:transparent;
|
|
118
|
-
z-index:0;
|
|
119
|
-
pointer-events:none;
|
|
120
141
|
}
|
|
121
|
-
.magritte-digits-input___4QeLj_1-0-
|
|
142
|
+
.magritte-digits-input___4QeLj_1-0-3::selection{
|
|
122
143
|
background-color:transparent;
|
|
144
|
+
appearance:none;
|
|
123
145
|
}
|
|
124
|
-
.magritte-digits-input___4QeLj_1-0-
|
|
146
|
+
.magritte-digits-input___4QeLj_1-0-3::-moz-selection{
|
|
125
147
|
background-color:transparent;
|
|
148
|
+
appearance:none;
|
|
126
149
|
}
|
|
127
|
-
.magritte-caret-left___iZMuA_1-0-
|
|
128
|
-
.magritte-caret-right___u8wNk_1-0-
|
|
150
|
+
.magritte-caret-left___iZMuA_1-0-3::before,
|
|
151
|
+
.magritte-caret-right___u8wNk_1-0-3::after{
|
|
129
152
|
content:'';
|
|
130
153
|
block-size:1em;
|
|
131
|
-
border-left:1px solid var(--magritte-color-text-primary-v21-
|
|
132
|
-
animation:magritte-caret-blink___-bhg7_1-0-
|
|
154
|
+
border-left:1px solid var(--magritte-color-text-primary-v21-1-0);
|
|
155
|
+
animation:magritte-caret-blink___-bhg7_1-0-3 1s steps(1) infinite;
|
|
133
156
|
}
|
|
134
|
-
.magritte-placeholder___10kQ0_1-0-
|
|
135
|
-
color:var(--magritte-color-component-input-text-placeholder-v21-
|
|
157
|
+
.magritte-placeholder___10kQ0_1-0-3{
|
|
158
|
+
color:var(--magritte-color-component-input-text-placeholder-v21-1-0);
|
|
136
159
|
}
|
|
137
|
-
.magritte-value-container___9JR3e_1-0-
|
|
160
|
+
.magritte-value-container___9JR3e_1-0-3{
|
|
138
161
|
pointer-events:none;
|
|
139
162
|
}
|
|
140
|
-
|
|
163
|
+
.magritte-ghost-value___jPQwY_1-0-3{
|
|
164
|
+
display:inline-block;
|
|
165
|
+
visibility:hidden;
|
|
166
|
+
}
|
|
167
|
+
@keyframes magritte-caret-blink___-bhg7_1-0-3{
|
|
141
168
|
50%{
|
|
142
169
|
opacity:0;
|
|
143
170
|
}
|
package/index.js
CHANGED
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hh.ru/magritte-ui-pincode-input",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"types": "index.d.ts",
|
|
6
6
|
"sideEffects": [
|
|
@@ -23,13 +23,12 @@
|
|
|
23
23
|
"access": "public"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@hh.ru/magritte-common-keyboard": "4.0
|
|
27
|
-
"@hh.ru/magritte-
|
|
28
|
-
"@hh.ru/magritte-ui-form-helper": "1.0.21"
|
|
26
|
+
"@hh.ru/magritte-common-keyboard": "4.1.0",
|
|
27
|
+
"@hh.ru/magritte-ui-form-helper": "1.0.22"
|
|
29
28
|
},
|
|
30
29
|
"peerDependencies": {
|
|
31
30
|
"classnames": ">=2.3.2",
|
|
32
31
|
"react": ">=18.2.0"
|
|
33
32
|
},
|
|
34
|
-
"gitHead": "
|
|
33
|
+
"gitHead": "d271475c7ce8c1d6fc8b33ed345f1d9a6dcd8835"
|
|
35
34
|
}
|