11import 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 - z A - Z 0 - 9 ] $ / . test ( input ) ;
64+ return / ^ [ a - z A - Z 0 - 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