@digigov/form 0.12.1 → 0.12.2
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 +8 -1
- package/es/inputs/OtpInput/index.js +38 -49
- package/esm/index.js +1 -1
- package/esm/inputs/OtpInput/index.js +38 -49
- package/inputs/OtpInput/index.js +38 -49
- package/package.json +4 -4
- package/src/inputs/OtpInput/index.tsx +36 -47
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
# Change Log - @digigov/form
|
|
2
2
|
|
|
3
|
-
This log was last generated on Tue,
|
|
3
|
+
This log was last generated on Tue, 13 Jun 2023 09:12:26 GMT and should not be manually modified.
|
|
4
|
+
|
|
5
|
+
## 0.12.2
|
|
6
|
+
Tue, 13 Jun 2023 09:12:26 GMT
|
|
7
|
+
|
|
8
|
+
### Patches
|
|
9
|
+
|
|
10
|
+
- Improve OtpInput implementation
|
|
4
11
|
|
|
5
12
|
## 0.12.0
|
|
6
13
|
Tue, 16 May 2023 13:42:28 GMT
|
|
@@ -12,34 +12,27 @@ function useOtp(onChange, maxLength) {
|
|
|
12
12
|
var _useState = useState(Array(maxLength).fill('')),
|
|
13
13
|
_useState2 = _slicedToArray(_useState, 2),
|
|
14
14
|
otpValues = _useState2[0],
|
|
15
|
-
|
|
15
|
+
setOtpValues = _useState2[1];
|
|
16
16
|
|
|
17
|
-
var
|
|
17
|
+
var handleChange = useCallback(function (otp) {
|
|
18
|
+
setOtpValues(otp);
|
|
18
19
|
var otpValue = otp.join('');
|
|
19
20
|
onChange(otpValue);
|
|
20
21
|
}, [onChange]);
|
|
21
22
|
|
|
22
|
-
var
|
|
23
|
+
var setOtp = function setOtp(item, idx) {
|
|
23
24
|
var updatedOTPValues = _toConsumableArray(otpValues);
|
|
24
25
|
|
|
25
26
|
if (item.length === 1 || item.length === 0) {
|
|
26
27
|
updatedOTPValues[idx] = item[0] || '';
|
|
27
|
-
|
|
28
|
-
handleOtpChange(updatedOTPValues);
|
|
28
|
+
handleChange(updatedOTPValues);
|
|
29
29
|
} else if (item.length === maxLength) {
|
|
30
|
-
var valueArray = item.split('');
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
for (var i = 0; i < maxLength; i++) {
|
|
34
|
-
var _char = valueArray[i];
|
|
35
|
-
items.push(_char);
|
|
36
|
-
setOTPValues(items);
|
|
37
|
-
handleOtpChange(items);
|
|
38
|
-
}
|
|
30
|
+
var valueArray = item.split('').slice(0, maxLength);
|
|
31
|
+
handleChange(valueArray);
|
|
39
32
|
}
|
|
40
33
|
};
|
|
41
34
|
|
|
42
|
-
var
|
|
35
|
+
var setSelectionRange = useCallback(function (target) {
|
|
43
36
|
return target.setSelectionRange(0, target.value.length);
|
|
44
37
|
}, []);
|
|
45
38
|
var focusToNextInput = useCallback(function (target) {
|
|
@@ -56,11 +49,11 @@ function useOtp(onChange, maxLength) {
|
|
|
56
49
|
previousElement.focus();
|
|
57
50
|
}
|
|
58
51
|
}, []);
|
|
59
|
-
var
|
|
52
|
+
var handleKeyDown = useCallback(function (e, idx) {
|
|
60
53
|
var key = e.key;
|
|
61
54
|
var target = e.target;
|
|
62
55
|
var targetValue = target.value;
|
|
63
|
-
|
|
56
|
+
setSelectionRange(target);
|
|
64
57
|
|
|
65
58
|
if (key === 'ArrowRight' || key === 'ArrowDown') {
|
|
66
59
|
e.preventDefault();
|
|
@@ -79,50 +72,44 @@ function useOtp(onChange, maxLength) {
|
|
|
79
72
|
focusToPrevInput(target);
|
|
80
73
|
}
|
|
81
74
|
|
|
82
|
-
|
|
75
|
+
setOtp(targetValue, idx);
|
|
83
76
|
return e.preventDefault();
|
|
84
77
|
}
|
|
85
|
-
}, [
|
|
86
|
-
var
|
|
78
|
+
}, [setOtp, focusToPrevInput, focusToNextInput]);
|
|
79
|
+
var handleFocus = useCallback(function (e) {
|
|
87
80
|
var target = e.target;
|
|
88
|
-
|
|
89
|
-
}, [
|
|
90
|
-
var
|
|
81
|
+
setSelectionRange(target);
|
|
82
|
+
}, [setSelectionRange]);
|
|
83
|
+
var handleOtpChange = useCallback(function (e, idx) {
|
|
91
84
|
var target = e.target;
|
|
92
85
|
var targetValue = target.value;
|
|
93
|
-
var isTargetValueDigit = RE_DIGIT.test(targetValue);
|
|
94
|
-
|
|
95
|
-
if (!isTargetValueDigit && e.target.value !== '') {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
86
|
+
var isTargetValueDigit = RE_DIGIT.test(targetValue); // We want to pass the empty string when the value is deleted
|
|
87
|
+
// emptry string replaces the deleted value
|
|
98
88
|
|
|
99
|
-
|
|
100
|
-
|
|
89
|
+
if (isTargetValueDigit || targetValue === '') {
|
|
90
|
+
setOtp(targetValue, idx);
|
|
101
91
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
92
|
+
if (target.value.length > 1) {
|
|
93
|
+
target.blur();
|
|
94
|
+
}
|
|
105
95
|
|
|
106
|
-
|
|
107
|
-
return;
|
|
96
|
+
focusToNextInput(target);
|
|
108
97
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}, [handleOtpChange, itemsArray, inputOnKeyDown, inputOnFocus]);
|
|
112
|
-
var handleOnPaste = useCallback(function (e) {
|
|
98
|
+
}, [setOtp, handleKeyDown, handleFocus]);
|
|
99
|
+
var handlePaste = useCallback(function (e) {
|
|
113
100
|
e.preventDefault();
|
|
114
101
|
var pastedData = e.clipboardData.getData('text/plain').replace(REMOVE_SPACES, '');
|
|
115
102
|
|
|
116
103
|
if (pastedData) {
|
|
117
|
-
|
|
104
|
+
setOtp(pastedData, 0);
|
|
118
105
|
}
|
|
119
106
|
}, []);
|
|
120
107
|
return {
|
|
121
108
|
otpValues: otpValues,
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
109
|
+
handleOtpChange: handleOtpChange,
|
|
110
|
+
handleKeyDown: handleKeyDown,
|
|
111
|
+
handleFocus: handleFocus,
|
|
112
|
+
handlePaste: handlePaste
|
|
126
113
|
};
|
|
127
114
|
}
|
|
128
115
|
|
|
@@ -151,16 +138,18 @@ export var OtpInput = function OtpInput(_ref2) {
|
|
|
151
138
|
disabled: props.disabled,
|
|
152
139
|
"aria-required": props['aria-required'],
|
|
153
140
|
onChange: function onChange(e) {
|
|
154
|
-
return otp.
|
|
141
|
+
return otp.handleOtpChange(e, idx);
|
|
155
142
|
},
|
|
156
143
|
onInput: function onInput(e) {
|
|
157
|
-
|
|
144
|
+
if (e.target.value === digit) {
|
|
145
|
+
otp.handleOtpChange(e, idx);
|
|
146
|
+
}
|
|
158
147
|
},
|
|
159
148
|
onKeyDown: function onKeyDown(e) {
|
|
160
|
-
return otp.
|
|
149
|
+
return otp.handleKeyDown(e, idx);
|
|
161
150
|
},
|
|
162
|
-
onFocus: otp.
|
|
163
|
-
onPaste: otp.
|
|
151
|
+
onFocus: otp.handleFocus,
|
|
152
|
+
onPaste: otp.handlePaste,
|
|
164
153
|
error: !digit ? props.error : false
|
|
165
154
|
});
|
|
166
155
|
}));
|
package/esm/index.js
CHANGED
|
@@ -12,34 +12,27 @@ function useOtp(onChange, maxLength) {
|
|
|
12
12
|
var _useState = useState(Array(maxLength).fill('')),
|
|
13
13
|
_useState2 = _slicedToArray(_useState, 2),
|
|
14
14
|
otpValues = _useState2[0],
|
|
15
|
-
|
|
15
|
+
setOtpValues = _useState2[1];
|
|
16
16
|
|
|
17
|
-
var
|
|
17
|
+
var handleChange = useCallback(function (otp) {
|
|
18
|
+
setOtpValues(otp);
|
|
18
19
|
var otpValue = otp.join('');
|
|
19
20
|
onChange(otpValue);
|
|
20
21
|
}, [onChange]);
|
|
21
22
|
|
|
22
|
-
var
|
|
23
|
+
var setOtp = function setOtp(item, idx) {
|
|
23
24
|
var updatedOTPValues = _toConsumableArray(otpValues);
|
|
24
25
|
|
|
25
26
|
if (item.length === 1 || item.length === 0) {
|
|
26
27
|
updatedOTPValues[idx] = item[0] || '';
|
|
27
|
-
|
|
28
|
-
handleOtpChange(updatedOTPValues);
|
|
28
|
+
handleChange(updatedOTPValues);
|
|
29
29
|
} else if (item.length === maxLength) {
|
|
30
|
-
var valueArray = item.split('');
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
for (var i = 0; i < maxLength; i++) {
|
|
34
|
-
var _char = valueArray[i];
|
|
35
|
-
items.push(_char);
|
|
36
|
-
setOTPValues(items);
|
|
37
|
-
handleOtpChange(items);
|
|
38
|
-
}
|
|
30
|
+
var valueArray = item.split('').slice(0, maxLength);
|
|
31
|
+
handleChange(valueArray);
|
|
39
32
|
}
|
|
40
33
|
};
|
|
41
34
|
|
|
42
|
-
var
|
|
35
|
+
var setSelectionRange = useCallback(function (target) {
|
|
43
36
|
return target.setSelectionRange(0, target.value.length);
|
|
44
37
|
}, []);
|
|
45
38
|
var focusToNextInput = useCallback(function (target) {
|
|
@@ -56,11 +49,11 @@ function useOtp(onChange, maxLength) {
|
|
|
56
49
|
previousElement.focus();
|
|
57
50
|
}
|
|
58
51
|
}, []);
|
|
59
|
-
var
|
|
52
|
+
var handleKeyDown = useCallback(function (e, idx) {
|
|
60
53
|
var key = e.key;
|
|
61
54
|
var target = e.target;
|
|
62
55
|
var targetValue = target.value;
|
|
63
|
-
|
|
56
|
+
setSelectionRange(target);
|
|
64
57
|
|
|
65
58
|
if (key === 'ArrowRight' || key === 'ArrowDown') {
|
|
66
59
|
e.preventDefault();
|
|
@@ -79,50 +72,44 @@ function useOtp(onChange, maxLength) {
|
|
|
79
72
|
focusToPrevInput(target);
|
|
80
73
|
}
|
|
81
74
|
|
|
82
|
-
|
|
75
|
+
setOtp(targetValue, idx);
|
|
83
76
|
return e.preventDefault();
|
|
84
77
|
}
|
|
85
|
-
}, [
|
|
86
|
-
var
|
|
78
|
+
}, [setOtp, focusToPrevInput, focusToNextInput]);
|
|
79
|
+
var handleFocus = useCallback(function (e) {
|
|
87
80
|
var target = e.target;
|
|
88
|
-
|
|
89
|
-
}, [
|
|
90
|
-
var
|
|
81
|
+
setSelectionRange(target);
|
|
82
|
+
}, [setSelectionRange]);
|
|
83
|
+
var handleOtpChange = useCallback(function (e, idx) {
|
|
91
84
|
var target = e.target;
|
|
92
85
|
var targetValue = target.value;
|
|
93
|
-
var isTargetValueDigit = RE_DIGIT.test(targetValue);
|
|
94
|
-
|
|
95
|
-
if (!isTargetValueDigit && e.target.value !== '') {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
86
|
+
var isTargetValueDigit = RE_DIGIT.test(targetValue); // We want to pass the empty string when the value is deleted
|
|
87
|
+
// emptry string replaces the deleted value
|
|
98
88
|
|
|
99
|
-
|
|
100
|
-
|
|
89
|
+
if (isTargetValueDigit || targetValue === '') {
|
|
90
|
+
setOtp(targetValue, idx);
|
|
101
91
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
92
|
+
if (target.value.length > 1) {
|
|
93
|
+
target.blur();
|
|
94
|
+
}
|
|
105
95
|
|
|
106
|
-
|
|
107
|
-
return;
|
|
96
|
+
focusToNextInput(target);
|
|
108
97
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}, [handleOtpChange, itemsArray, inputOnKeyDown, inputOnFocus]);
|
|
112
|
-
var handleOnPaste = useCallback(function (e) {
|
|
98
|
+
}, [setOtp, handleKeyDown, handleFocus]);
|
|
99
|
+
var handlePaste = useCallback(function (e) {
|
|
113
100
|
e.preventDefault();
|
|
114
101
|
var pastedData = e.clipboardData.getData('text/plain').replace(REMOVE_SPACES, '');
|
|
115
102
|
|
|
116
103
|
if (pastedData) {
|
|
117
|
-
|
|
104
|
+
setOtp(pastedData, 0);
|
|
118
105
|
}
|
|
119
106
|
}, []);
|
|
120
107
|
return {
|
|
121
108
|
otpValues: otpValues,
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
109
|
+
handleOtpChange: handleOtpChange,
|
|
110
|
+
handleKeyDown: handleKeyDown,
|
|
111
|
+
handleFocus: handleFocus,
|
|
112
|
+
handlePaste: handlePaste
|
|
126
113
|
};
|
|
127
114
|
}
|
|
128
115
|
|
|
@@ -151,16 +138,18 @@ export var OtpInput = function OtpInput(_ref2) {
|
|
|
151
138
|
disabled: props.disabled,
|
|
152
139
|
"aria-required": props['aria-required'],
|
|
153
140
|
onChange: function onChange(e) {
|
|
154
|
-
return otp.
|
|
141
|
+
return otp.handleOtpChange(e, idx);
|
|
155
142
|
},
|
|
156
143
|
onInput: function onInput(e) {
|
|
157
|
-
|
|
144
|
+
if (e.target.value === digit) {
|
|
145
|
+
otp.handleOtpChange(e, idx);
|
|
146
|
+
}
|
|
158
147
|
},
|
|
159
148
|
onKeyDown: function onKeyDown(e) {
|
|
160
|
-
return otp.
|
|
149
|
+
return otp.handleKeyDown(e, idx);
|
|
161
150
|
},
|
|
162
|
-
onFocus: otp.
|
|
163
|
-
onPaste: otp.
|
|
151
|
+
onFocus: otp.handleFocus,
|
|
152
|
+
onPaste: otp.handlePaste,
|
|
164
153
|
error: !digit ? props.error : false
|
|
165
154
|
});
|
|
166
155
|
}));
|
package/inputs/OtpInput/index.js
CHANGED
|
@@ -36,34 +36,27 @@ function useOtp(onChange, maxLength) {
|
|
|
36
36
|
var _useState = (0, _react.useState)(Array(maxLength).fill('')),
|
|
37
37
|
_useState2 = (0, _slicedToArray2["default"])(_useState, 2),
|
|
38
38
|
otpValues = _useState2[0],
|
|
39
|
-
|
|
39
|
+
setOtpValues = _useState2[1];
|
|
40
40
|
|
|
41
|
-
var
|
|
41
|
+
var handleChange = (0, _react.useCallback)(function (otp) {
|
|
42
|
+
setOtpValues(otp);
|
|
42
43
|
var otpValue = otp.join('');
|
|
43
44
|
onChange(otpValue);
|
|
44
45
|
}, [onChange]);
|
|
45
46
|
|
|
46
|
-
var
|
|
47
|
+
var setOtp = function setOtp(item, idx) {
|
|
47
48
|
var updatedOTPValues = (0, _toConsumableArray2["default"])(otpValues);
|
|
48
49
|
|
|
49
50
|
if (item.length === 1 || item.length === 0) {
|
|
50
51
|
updatedOTPValues[idx] = item[0] || '';
|
|
51
|
-
|
|
52
|
-
handleOtpChange(updatedOTPValues);
|
|
52
|
+
handleChange(updatedOTPValues);
|
|
53
53
|
} else if (item.length === maxLength) {
|
|
54
|
-
var valueArray = item.split('');
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
for (var i = 0; i < maxLength; i++) {
|
|
58
|
-
var _char = valueArray[i];
|
|
59
|
-
items.push(_char);
|
|
60
|
-
setOTPValues(items);
|
|
61
|
-
handleOtpChange(items);
|
|
62
|
-
}
|
|
54
|
+
var valueArray = item.split('').slice(0, maxLength);
|
|
55
|
+
handleChange(valueArray);
|
|
63
56
|
}
|
|
64
57
|
};
|
|
65
58
|
|
|
66
|
-
var
|
|
59
|
+
var setSelectionRange = (0, _react.useCallback)(function (target) {
|
|
67
60
|
return target.setSelectionRange(0, target.value.length);
|
|
68
61
|
}, []);
|
|
69
62
|
var focusToNextInput = (0, _react.useCallback)(function (target) {
|
|
@@ -80,11 +73,11 @@ function useOtp(onChange, maxLength) {
|
|
|
80
73
|
previousElement.focus();
|
|
81
74
|
}
|
|
82
75
|
}, []);
|
|
83
|
-
var
|
|
76
|
+
var handleKeyDown = (0, _react.useCallback)(function (e, idx) {
|
|
84
77
|
var key = e.key;
|
|
85
78
|
var target = e.target;
|
|
86
79
|
var targetValue = target.value;
|
|
87
|
-
|
|
80
|
+
setSelectionRange(target);
|
|
88
81
|
|
|
89
82
|
if (key === 'ArrowRight' || key === 'ArrowDown') {
|
|
90
83
|
e.preventDefault();
|
|
@@ -103,50 +96,44 @@ function useOtp(onChange, maxLength) {
|
|
|
103
96
|
focusToPrevInput(target);
|
|
104
97
|
}
|
|
105
98
|
|
|
106
|
-
|
|
99
|
+
setOtp(targetValue, idx);
|
|
107
100
|
return e.preventDefault();
|
|
108
101
|
}
|
|
109
|
-
}, [
|
|
110
|
-
var
|
|
102
|
+
}, [setOtp, focusToPrevInput, focusToNextInput]);
|
|
103
|
+
var handleFocus = (0, _react.useCallback)(function (e) {
|
|
111
104
|
var target = e.target;
|
|
112
|
-
|
|
113
|
-
}, [
|
|
114
|
-
var
|
|
105
|
+
setSelectionRange(target);
|
|
106
|
+
}, [setSelectionRange]);
|
|
107
|
+
var handleOtpChange = (0, _react.useCallback)(function (e, idx) {
|
|
115
108
|
var target = e.target;
|
|
116
109
|
var targetValue = target.value;
|
|
117
|
-
var isTargetValueDigit = RE_DIGIT.test(targetValue);
|
|
118
|
-
|
|
119
|
-
if (!isTargetValueDigit && e.target.value !== '') {
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
110
|
+
var isTargetValueDigit = RE_DIGIT.test(targetValue); // We want to pass the empty string when the value is deleted
|
|
111
|
+
// emptry string replaces the deleted value
|
|
122
112
|
|
|
123
|
-
|
|
124
|
-
|
|
113
|
+
if (isTargetValueDigit || targetValue === '') {
|
|
114
|
+
setOtp(targetValue, idx);
|
|
125
115
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
116
|
+
if (target.value.length > 1) {
|
|
117
|
+
target.blur();
|
|
118
|
+
}
|
|
129
119
|
|
|
130
|
-
|
|
131
|
-
return;
|
|
120
|
+
focusToNextInput(target);
|
|
132
121
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}, [handleOtpChange, itemsArray, inputOnKeyDown, inputOnFocus]);
|
|
136
|
-
var handleOnPaste = (0, _react.useCallback)(function (e) {
|
|
122
|
+
}, [setOtp, handleKeyDown, handleFocus]);
|
|
123
|
+
var handlePaste = (0, _react.useCallback)(function (e) {
|
|
137
124
|
e.preventDefault();
|
|
138
125
|
var pastedData = e.clipboardData.getData('text/plain').replace(REMOVE_SPACES, '');
|
|
139
126
|
|
|
140
127
|
if (pastedData) {
|
|
141
|
-
|
|
128
|
+
setOtp(pastedData, 0);
|
|
142
129
|
}
|
|
143
130
|
}, []);
|
|
144
131
|
return {
|
|
145
132
|
otpValues: otpValues,
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
133
|
+
handleOtpChange: handleOtpChange,
|
|
134
|
+
handleKeyDown: handleKeyDown,
|
|
135
|
+
handleFocus: handleFocus,
|
|
136
|
+
handlePaste: handlePaste
|
|
150
137
|
};
|
|
151
138
|
}
|
|
152
139
|
|
|
@@ -173,16 +160,18 @@ var OtpInput = function OtpInput(_ref2) {
|
|
|
173
160
|
disabled: props.disabled,
|
|
174
161
|
"aria-required": props['aria-required'],
|
|
175
162
|
onChange: function onChange(e) {
|
|
176
|
-
return otp.
|
|
163
|
+
return otp.handleOtpChange(e, idx);
|
|
177
164
|
},
|
|
178
165
|
onInput: function onInput(e) {
|
|
179
|
-
|
|
166
|
+
if (e.target.value === digit) {
|
|
167
|
+
otp.handleOtpChange(e, idx);
|
|
168
|
+
}
|
|
180
169
|
},
|
|
181
170
|
onKeyDown: function onKeyDown(e) {
|
|
182
|
-
return otp.
|
|
171
|
+
return otp.handleKeyDown(e, idx);
|
|
183
172
|
},
|
|
184
|
-
onFocus: otp.
|
|
185
|
-
onPaste: otp.
|
|
173
|
+
onFocus: otp.handleFocus,
|
|
174
|
+
onPaste: otp.handlePaste,
|
|
186
175
|
error: !digit ? props.error : false
|
|
187
176
|
});
|
|
188
177
|
}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@digigov/form",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.2",
|
|
4
4
|
"description": "@digigov form builder",
|
|
5
5
|
"author": "GRNET Developers <devs@lists.grnet.gr>",
|
|
6
6
|
"license": "BSD-2-Clause",
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
"publint": "0.1.8"
|
|
20
20
|
},
|
|
21
21
|
"peerDependencies": {
|
|
22
|
-
"@digigov/ui": "0.
|
|
23
|
-
"@digigov/react-core": "0.
|
|
24
|
-
"@digigov/react-extensions": "0.22.
|
|
22
|
+
"@digigov/ui": "0.34.0",
|
|
23
|
+
"@digigov/react-core": "0.25.0",
|
|
24
|
+
"@digigov/react-extensions": "0.22.1",
|
|
25
25
|
"clsx": "1.1.1",
|
|
26
26
|
"react": "^16.8.0 || ^17.0.0",
|
|
27
27
|
"react-dom": "^16.8.0 || ^17.0.0"
|
|
@@ -7,34 +7,28 @@ export const RE_DIGIT = new RegExp(/^\d+$/);
|
|
|
7
7
|
export const REMOVE_SPACES = new RegExp(/\s+/g);
|
|
8
8
|
|
|
9
9
|
function useOtp(onChange, maxLength) {
|
|
10
|
-
const [otpValues,
|
|
11
|
-
const
|
|
10
|
+
const [otpValues, setOtpValues] = useState(Array<string>(maxLength).fill(''));
|
|
11
|
+
const handleChange = useCallback(
|
|
12
12
|
(otp: string[]) => {
|
|
13
|
+
setOtpValues(otp);
|
|
13
14
|
const otpValue = otp.join('');
|
|
14
15
|
onChange(otpValue);
|
|
15
16
|
},
|
|
16
17
|
[onChange]
|
|
17
18
|
);
|
|
18
19
|
|
|
19
|
-
const
|
|
20
|
+
const setOtp = (item: string, idx) => {
|
|
20
21
|
const updatedOTPValues = [...otpValues];
|
|
21
22
|
if (item.length === 1 || item.length === 0) {
|
|
22
23
|
updatedOTPValues[idx] = item[0] || '';
|
|
23
|
-
|
|
24
|
-
handleOtpChange(updatedOTPValues);
|
|
24
|
+
handleChange(updatedOTPValues);
|
|
25
25
|
} else if (item.length === maxLength) {
|
|
26
|
-
const valueArray = item.split('');
|
|
27
|
-
|
|
28
|
-
for (let i = 0; i < maxLength; i++) {
|
|
29
|
-
const char = valueArray[i];
|
|
30
|
-
items.push(char);
|
|
31
|
-
setOTPValues(items);
|
|
32
|
-
handleOtpChange(items);
|
|
33
|
-
}
|
|
26
|
+
const valueArray = item.split('').slice(0, maxLength);
|
|
27
|
+
handleChange(valueArray);
|
|
34
28
|
}
|
|
35
29
|
};
|
|
36
30
|
|
|
37
|
-
const
|
|
31
|
+
const setSelectionRange = useCallback((target) => {
|
|
38
32
|
return target.setSelectionRange(0, target.value.length);
|
|
39
33
|
}, []);
|
|
40
34
|
|
|
@@ -52,12 +46,12 @@ function useOtp(onChange, maxLength) {
|
|
|
52
46
|
}
|
|
53
47
|
}, []);
|
|
54
48
|
|
|
55
|
-
const
|
|
49
|
+
const handleKeyDown = useCallback(
|
|
56
50
|
(e: React.KeyboardEvent<HTMLInputElement>, idx: number) => {
|
|
57
51
|
const { key } = e;
|
|
58
52
|
const target = e.target as HTMLInputElement;
|
|
59
53
|
let targetValue = target.value;
|
|
60
|
-
|
|
54
|
+
setSelectionRange(target);
|
|
61
55
|
if (key === 'ArrowRight' || key === 'ArrowDown') {
|
|
62
56
|
e.preventDefault();
|
|
63
57
|
return focusToNextInput(target);
|
|
@@ -72,60 +66,56 @@ function useOtp(onChange, maxLength) {
|
|
|
72
66
|
} else {
|
|
73
67
|
focusToPrevInput(target);
|
|
74
68
|
}
|
|
75
|
-
|
|
69
|
+
setOtp(targetValue, idx);
|
|
76
70
|
return e.preventDefault();
|
|
77
71
|
}
|
|
78
72
|
},
|
|
79
|
-
[
|
|
73
|
+
[setOtp, focusToPrevInput, focusToNextInput]
|
|
80
74
|
);
|
|
81
75
|
|
|
82
|
-
const
|
|
76
|
+
const handleFocus = useCallback(
|
|
83
77
|
(e: React.FocusEvent<HTMLInputElement>) => {
|
|
84
78
|
const { target } = e;
|
|
85
|
-
|
|
79
|
+
setSelectionRange(target);
|
|
86
80
|
},
|
|
87
|
-
[
|
|
81
|
+
[setSelectionRange]
|
|
88
82
|
);
|
|
89
|
-
const
|
|
83
|
+
const handleOtpChange = useCallback(
|
|
90
84
|
(e: React.ChangeEvent<HTMLInputElement>, idx: number) => {
|
|
91
85
|
const target = e.target;
|
|
92
86
|
let targetValue = target.value;
|
|
93
87
|
const isTargetValueDigit = RE_DIGIT.test(targetValue);
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if (!isTargetValueDigit) {
|
|
103
|
-
return;
|
|
88
|
+
// We want to pass the empty string when the value is deleted
|
|
89
|
+
// emptry string replaces the deleted value
|
|
90
|
+
if (isTargetValueDigit || targetValue === '') {
|
|
91
|
+
setOtp(targetValue, idx);
|
|
92
|
+
if (target.value.length > 1) {
|
|
93
|
+
target.blur();
|
|
94
|
+
}
|
|
95
|
+
focusToNextInput(target);
|
|
104
96
|
}
|
|
105
|
-
focusToNextInput(target);
|
|
106
97
|
},
|
|
107
|
-
[
|
|
98
|
+
[setOtp, handleKeyDown, handleFocus]
|
|
108
99
|
);
|
|
109
100
|
|
|
110
|
-
const
|
|
101
|
+
const handlePaste = useCallback(
|
|
111
102
|
(e: React.ClipboardEvent<HTMLInputElement>) => {
|
|
112
103
|
e.preventDefault();
|
|
113
104
|
const pastedData = e.clipboardData
|
|
114
105
|
.getData('text/plain')
|
|
115
106
|
.replace(REMOVE_SPACES, '');
|
|
116
107
|
if (pastedData) {
|
|
117
|
-
|
|
108
|
+
setOtp(pastedData, 0);
|
|
118
109
|
}
|
|
119
110
|
},
|
|
120
111
|
[]
|
|
121
112
|
);
|
|
122
|
-
|
|
123
113
|
return {
|
|
124
114
|
otpValues,
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
115
|
+
handleOtpChange,
|
|
116
|
+
handleKeyDown,
|
|
117
|
+
handleFocus,
|
|
118
|
+
handlePaste,
|
|
129
119
|
};
|
|
130
120
|
}
|
|
131
121
|
|
|
@@ -135,7 +125,6 @@ const SingleCharacterInputItemPart = ({ ...props }) => {
|
|
|
135
125
|
|
|
136
126
|
export const OtpInput = function OtpInput({ name, maxLength = 6, ...props }) {
|
|
137
127
|
const otp = useOtp(props.onChange, maxLength);
|
|
138
|
-
|
|
139
128
|
return (
|
|
140
129
|
<SingleCharacterInputContainer>
|
|
141
130
|
{otp.otpValues.map((digit, idx) => (
|
|
@@ -149,11 +138,11 @@ export const OtpInput = function OtpInput({ name, maxLength = 6, ...props }) {
|
|
|
149
138
|
value={digit}
|
|
150
139
|
disabled={props.disabled}
|
|
151
140
|
aria-required={props['aria-required']}
|
|
152
|
-
onChange={(e) => otp.
|
|
153
|
-
onInput={(e) => otp.
|
|
154
|
-
onKeyDown={(e) => otp.
|
|
155
|
-
onFocus={otp.
|
|
156
|
-
onPaste={otp.
|
|
141
|
+
onChange={(e) => otp.handleOtpChange(e, idx)}
|
|
142
|
+
onInput={(e) => { if (e.target.value === digit) { otp.handleOtpChange(e, idx) } }}
|
|
143
|
+
onKeyDown={(e) => otp.handleKeyDown(e, idx)}
|
|
144
|
+
onFocus={otp.handleFocus}
|
|
145
|
+
onPaste={otp.handlePaste}
|
|
157
146
|
error={!digit ? props.error : false}
|
|
158
147
|
/>
|
|
159
148
|
))}
|