Skip to content

Commit 8ada8fc

Browse files
committed
feat: handle pasting
1 parent c015c58 commit 8ada8fc

File tree

1 file changed

+38
-22
lines changed

1 file changed

+38
-22
lines changed

src/index.tsx

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React, {
22
ChangeEvent,
3+
ClipboardEvent,
34
createRef,
45
Fragment,
56
KeyboardEvent,
@@ -31,8 +32,9 @@ const ReactInputVerificationCode = ({
3132
dataCy = 'verification-code',
3233
type = 'number',
3334
}: ReactInputVerificationCodeProps) => {
34-
const [values, setValues] = useState(new Array(length).fill(placeholder));
35+
const emptyValues = new Array(length).fill(placeholder);
3536

37+
const [values, setValues] = useState([...emptyValues]);
3638
const [focusedIndex, setFocusedIndex] = useState<number>(-1);
3739

3840
// const codeInputRef = createRef<HTMLInputElement>();
@@ -55,11 +57,11 @@ const ReactInputVerificationCode = ({
5557

5658
const validate = (input: string) => {
5759
if (type === 'number') {
58-
return /^\d$/.test(input);
60+
return /^\d/.test(input);
5961
}
6062

6163
if (type === 'alphanumeric') {
62-
return /^[a-zA-Z0-9]$/.test(input);
64+
return /^[a-zA-Z0-9]/.test(input);
6365
}
6466

6567
return true;
@@ -180,6 +182,38 @@ const ReactInputVerificationCode = ({
180182
}
181183
};
182184

185+
const onInputPaste = (
186+
event: ClipboardEvent<HTMLInputElement>,
187+
index: number
188+
) => {
189+
event.preventDefault();
190+
191+
const pastedValue = event.clipboardData.getData('text');
192+
const nextValues = pastedValue.slice(0, length);
193+
194+
if (!validate(nextValues)) {
195+
return;
196+
}
197+
198+
/**
199+
* generate a new array filled with placeholders
200+
* map through it and replace with the pasted value when possible
201+
*/
202+
setValues(
203+
[...emptyValues].map((value, index) => nextValues[index] || value)
204+
);
205+
206+
const isCompleted = nextValues.length === length;
207+
208+
if (isCompleted) {
209+
onCompleted(nextValues);
210+
blurInput(index);
211+
return;
212+
}
213+
214+
focusInput(nextValues.length);
215+
};
216+
183217
/**
184218
* autoFocus
185219
*/
@@ -189,25 +223,6 @@ const ReactInputVerificationCode = ({
189223
}
190224
}, [inputsRefs]);
191225

192-
// handle pasting
193-
// useEffect(() => {
194-
// const codeInput = codeInputRef.current;
195-
// if (!codeInput) return;
196-
197-
// const onPaste = (e: ClipboardEvent) => {
198-
// e.preventDefault();
199-
200-
// const pastedString = e.clipboardData?.getData('text');
201-
// if (!pastedString) return;
202-
203-
// const isNumber = /^\d+$/.test(pastedString);
204-
// if (isNumber) setValue(pastedString.split('').slice(0, length));
205-
// };
206-
207-
// codeInput.addEventListener('paste', onPaste);
208-
// return () => codeInput.removeEventListener('paste', onPaste);
209-
// }, []);
210-
211226
return (
212227
<Fragment>
213228
<S.GlobalStyle />
@@ -234,6 +249,7 @@ const ReactInputVerificationCode = ({
234249
onChange={(event) => onInputChange(event, i)}
235250
onFocus={() => onInputFocus(i)}
236251
onKeyDown={(event) => onInputKeyDown(event, i)}
252+
onPaste={(event) => onInputPaste(event, i)}
237253
/>
238254
))}
239255
</S.Container>

0 commit comments

Comments
 (0)