-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathOtpInput.tsx
More file actions
75 lines (61 loc) · 1.83 KB
/
OtpInput.tsx
File metadata and controls
75 lines (61 loc) · 1.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import React, { useRef } from 'react';
import styles from '@/styles/otpInput.module.css';
interface Props {
length?: number;
value: string;
inputMode?: 'numeric' | 'text';
onChange: (value: string) => void;
}
const OtpInput: React.FC<Props> = ({
length = 6,
value,
inputMode = 'numeric',
onChange,
}) => {
const inputs = useRef<Array<HTMLInputElement | null>>([]);
const values = value.split('').concat(Array(length).fill('')).slice(0, length);
const handleChange = (index: number, char: string) => {
if (inputMode === 'numeric') {
if (!/^\d?$/.test(char)) return;
}
if (inputMode === 'text') {
if (!/[a-z]/i.test(char)) return;
}
const newValue = value.substring(0, index) + char + value.substring(index + 1);
onChange(newValue.trim());
if (char && inputs.current[index + 1]) {
inputs.current[index + 1]?.focus();
}
};
const handleKeyDown = (index: number, e: React.KeyboardEvent) => {
if (e.key === 'Backspace' && !values[index] && inputs.current[index - 1]) {
inputs.current[index - 1]?.focus();
}
};
const handlePaste = (e: React.ClipboardEvent) => {
const pasted = e.clipboardData.getData('text').replace(/\D/g, '');
if (pasted.length === length) {
onChange(pasted);
inputs.current[length - 1]?.focus();
}
e.preventDefault();
};
return (
<div className={styles.otpContainer} onPaste={handlePaste}>
{values.map((digit, i) => (
<input
key={i}
ref={el => (inputs.current[i] = el)}
type="text"
inputMode={inputMode}
maxLength={1}
value={digit || ''}
className={styles.otpInput}
onChange={e => handleChange(i, e.target.value)}
onKeyDown={e => handleKeyDown(i, e)}
/>
))}
</div>
);
};
export default OtpInput;