mimir-ui-kit 0.0.19 → 0.0.21

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,12 @@
1
1
  import { TInputProps } from '../Input';
2
2
 
3
- type TProps = Omit<TInputProps, 'onChange' | 'label'> & {
3
+ /**
4
+ * Компонент ввода одноразового пароля (OTP).
5
+ *
6
+ * Компонент представляет собой набор вводов, каждый из которых может содержать только цифры.
7
+ * Пользователь может вводить цифры в каждый ввод, и при вводе каждой цифры происходит автоматическое переключение на следующий ввод.
8
+ */
9
+ export declare const OtpInput: import('react').ForwardRefExoticComponent<Omit<TInputProps, "label" | "onChange"> & {
4
10
  value?: string;
5
11
  /**
6
12
  * Количество полей ввода.
@@ -14,15 +20,4 @@ type TProps = Omit<TInputProps, 'onChange' | 'label'> & {
14
20
  * Флаг, показывающий нужно ли отображать разделитель между вводами.
15
21
  */
16
22
  needSeparator?: boolean;
17
- };
18
- /**
19
- * Компонент ввода одноразового пароля (OTP).
20
- *
21
- * Компонент представляет собой набор вводов, каждый из которых может содержать только цифры.
22
- * Пользователь может вводить цифры в каждый ввод, и при вводе каждой цифры происходит автоматическое переключение на следующий ввод.
23
- */
24
- export declare const OtpInput: {
25
- ({ value, valueLength, needSeparator, onChange, ...props }: TProps): import("react/jsx-runtime").JSX.Element;
26
- displayName: string;
27
- };
28
- export {};
23
+ } & import('react').RefAttributes<unknown>>;
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- import { useRef, useMemo, Fragment } from "react";
2
+ import { forwardRef, useRef, useImperativeHandle, useMemo, Fragment } from "react";
3
3
  import { c as classNames } from "../../index-CweZ_OcN.js";
4
4
  import { Input } from "../Input/Input.js";
5
5
  import { RE_DIGIT, ITEMS_PER_SEPARATOR, DEFAULT_VALUE_LENGTH } from "./constants.js";
@@ -12,121 +12,129 @@ const cls = {
12
12
  input,
13
13
  separator
14
14
  };
15
- const OtpInput = ({
16
- value = "",
17
- valueLength = DEFAULT_VALUE_LENGTH,
18
- needSeparator = true,
19
- onChange,
20
- ...props
21
- }) => {
22
- const inputRefs = useRef([]);
23
- const valueItems = useMemo(() => {
24
- const valueArray = value.split("");
25
- const items = [];
26
- for (let i = 0; i < valueLength; i++) {
27
- const char = valueArray[i];
28
- if (RE_DIGIT.test(char)) {
29
- items.push(char);
30
- } else {
31
- items.push("");
15
+ const OtpInput = forwardRef(
16
+ ({
17
+ value = "",
18
+ valueLength = DEFAULT_VALUE_LENGTH,
19
+ needSeparator = true,
20
+ onChange,
21
+ ...props
22
+ }, ref) => {
23
+ const inputRefs = useRef([]);
24
+ useImperativeHandle(ref, () => ({
25
+ focus: () => {
26
+ var _a;
27
+ (_a = inputRefs.current[0]) == null ? void 0 : _a.focus();
32
28
  }
33
- }
34
- return items;
35
- }, [value, valueLength]);
36
- const handleFocusToNextInput = (index) => {
37
- var _a;
38
- if (index < valueLength - 1) {
39
- (_a = inputRefs.current[index + 1]) == null ? void 0 : _a.focus();
40
- }
41
- };
42
- const handleFocusToPrevInput = (index) => {
43
- var _a;
44
- if (index > 0) {
45
- (_a = inputRefs.current[index - 1]) == null ? void 0 : _a.focus();
46
- }
47
- };
48
- const handleChange = (e, index) => {
49
- const target = e.target;
50
- let targetValue = target.value.trim();
51
- const isTargetValueDigit = RE_DIGIT.test(targetValue);
52
- if (!isTargetValueDigit && targetValue !== "") {
53
- return;
54
- }
55
- const nextInputEl = inputRefs.current[index + 1];
56
- if (!isTargetValueDigit && nextInputEl && nextInputEl.value !== "") {
57
- return;
58
- }
59
- targetValue = isTargetValueDigit ? targetValue : " ";
60
- const targetValueLength = targetValue.length;
61
- if (targetValueLength === 1) {
62
- const newValue = value.substring(0, index) + targetValue + value.substring(index + 1);
63
- onChange == null ? void 0 : onChange(newValue);
64
- if (isTargetValueDigit) {
65
- handleFocusToNextInput(index);
29
+ }));
30
+ const valueItems = useMemo(() => {
31
+ const valueArray = value.split("");
32
+ const items = [];
33
+ for (let i = 0; i < valueLength; i++) {
34
+ const char = valueArray[i];
35
+ if (RE_DIGIT.test(char)) {
36
+ items.push(char);
37
+ } else {
38
+ items.push("");
39
+ }
40
+ }
41
+ return items;
42
+ }, [value, valueLength]);
43
+ const handleFocusToNextInput = (index) => {
44
+ var _a;
45
+ if (index < valueLength - 1) {
46
+ (_a = inputRefs.current[index + 1]) == null ? void 0 : _a.focus();
47
+ }
48
+ };
49
+ const handleFocusToPrevInput = (index) => {
50
+ var _a;
51
+ if (index > 0) {
52
+ (_a = inputRefs.current[index - 1]) == null ? void 0 : _a.focus();
66
53
  }
67
- } else if (targetValueLength === valueLength) {
68
- onChange == null ? void 0 : onChange(targetValue);
69
- target.blur();
70
- }
71
- };
72
- const handleKeyDown = (e, index) => {
73
- const { key } = e;
74
- const target = e.target;
75
- switch (key) {
76
- case "ArrowRight":
77
- case "ArrowDown": {
78
- e.preventDefault();
79
- return handleFocusToNextInput(index);
54
+ };
55
+ const handleChange = (e, index) => {
56
+ const target = e.target;
57
+ let targetValue = target.value.trim();
58
+ const isTargetValueDigit = RE_DIGIT.test(targetValue);
59
+ if (!isTargetValueDigit && targetValue !== "") {
60
+ return;
80
61
  }
81
- case "ArrowLeft":
82
- case "ArrowUp": {
83
- e.preventDefault();
84
- return handleFocusToPrevInput(index);
62
+ const nextInputEl = inputRefs.current[index + 1];
63
+ if (!isTargetValueDigit && nextInputEl && nextInputEl.value !== "") {
64
+ return;
85
65
  }
86
- }
87
- const targetValue = target.value;
88
- target.setSelectionRange(0, targetValue.length);
89
- if (e.key !== "Backspace" || targetValue !== "") {
90
- return;
91
- }
92
- const newValue = `${value.substring(0, index - 1)} ${value.substring(index)}`;
93
- onChange == null ? void 0 : onChange(newValue);
94
- handleFocusToPrevInput(index);
95
- };
96
- const handleFocus = (e, index) => {
97
- const target = e.target;
98
- const prevInputEl = inputRefs.current[index - 1];
99
- if (prevInputEl && prevInputEl.value === "") {
100
- prevInputEl.focus();
101
- }
102
- target.setSelectionRange(0, target.value.length);
103
- };
104
- return /* @__PURE__ */ jsx("div", { className: classNames(cls.otp), children: valueItems.map((digit, idx) => {
105
- const nextIndex = idx + 1;
106
- const showSeparator = needSeparator && nextIndex % ITEMS_PER_SEPARATOR === 0 && nextIndex !== valueItems.length;
107
- return /* @__PURE__ */ jsxs(Fragment, { children: [
108
- /* @__PURE__ */ jsx(
109
- Input,
110
- {
111
- ref: (el) => inputRefs.current[idx] = el,
112
- type: "text",
113
- inputMode: "numeric",
114
- autoComplete: "one-time-code",
115
- pattern: "\\d{1}",
116
- maxLength: 1,
117
- value: digit,
118
- className: cls.input,
119
- wrapperClassName: cls["input-wrapper"],
120
- onChange: (e) => handleChange(e, idx),
121
- onKeyDown: (e) => handleKeyDown(e, idx),
122
- onFocus: (e) => handleFocus(e, idx),
123
- ...props
66
+ targetValue = isTargetValueDigit ? targetValue.trim() : " ";
67
+ const targetValueLength = targetValue.length;
68
+ if (targetValueLength === 1) {
69
+ const newValue = value.substring(0, index) + targetValue + value.substring(index + 1);
70
+ onChange == null ? void 0 : onChange(newValue.trim());
71
+ if (isTargetValueDigit) {
72
+ handleFocusToNextInput(index);
124
73
  }
125
- ),
126
- showSeparator && /* @__PURE__ */ jsx("span", { className: classNames(cls.separator) })
127
- ] }, idx);
128
- }) });
129
- };
74
+ } else if (targetValueLength === valueLength) {
75
+ onChange == null ? void 0 : onChange(targetValue.trim());
76
+ target.blur();
77
+ }
78
+ };
79
+ const handleKeyDown = (e, index) => {
80
+ const { key } = e;
81
+ const target = e.target;
82
+ switch (key) {
83
+ case "ArrowRight":
84
+ case "ArrowDown": {
85
+ e.preventDefault();
86
+ return handleFocusToNextInput(index);
87
+ }
88
+ case "ArrowLeft":
89
+ case "ArrowUp": {
90
+ e.preventDefault();
91
+ return handleFocusToPrevInput(index);
92
+ }
93
+ }
94
+ const targetValue = target.value.trim();
95
+ target.setSelectionRange(0, targetValue.length);
96
+ if (e.key !== "Backspace" || targetValue !== "") {
97
+ return;
98
+ }
99
+ const newValue = `${value.substring(0, index - 1)} ${value.substring(index)}`;
100
+ onChange == null ? void 0 : onChange(newValue.trim());
101
+ handleFocusToPrevInput(index);
102
+ };
103
+ const handleFocus = (e, index) => {
104
+ const target = e.target;
105
+ const prevInputEl = inputRefs.current[index - 1];
106
+ if (prevInputEl && prevInputEl.value === "") {
107
+ prevInputEl.focus();
108
+ }
109
+ target.setSelectionRange(0, target.value.length);
110
+ };
111
+ return /* @__PURE__ */ jsx("div", { className: classNames(cls.otp), children: valueItems.map((digit, idx) => {
112
+ const nextIndex = idx + 1;
113
+ const showSeparator = needSeparator && nextIndex % ITEMS_PER_SEPARATOR === 0 && nextIndex !== valueItems.length;
114
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
115
+ /* @__PURE__ */ jsx(
116
+ Input,
117
+ {
118
+ ref: (el) => inputRefs.current[idx] = el,
119
+ type: "text",
120
+ inputMode: "numeric",
121
+ autoComplete: "one-time-code",
122
+ pattern: "\\d{1}",
123
+ maxLength: 1,
124
+ value: digit,
125
+ className: cls.input,
126
+ wrapperClassName: cls["input-wrapper"],
127
+ onChange: (e) => handleChange(e, idx),
128
+ onKeyDown: (e) => handleKeyDown(e, idx),
129
+ onFocus: (e) => handleFocus(e, idx),
130
+ ...props
131
+ }
132
+ ),
133
+ showSeparator && /* @__PURE__ */ jsx("span", { className: classNames(cls.separator) })
134
+ ] }, idx);
135
+ }) });
136
+ }
137
+ );
130
138
  OtpInput.displayName = "OtpInput";
131
139
  export {
132
140
  OtpInput
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mimir-ui-kit",
3
3
  "private": false,
4
- "version": "0.0.19",
4
+ "version": "0.0.21",
5
5
  "type": "module",
6
6
  "exports": "./dist/index.js",
7
7
  "module": "./dist/index.js",