1- import React , { useState , useRef } from "react" ;
1+ import { useState , useRef } from "react" ;
22
33// components
44import OverviewFooter from "../../../../../Shared/OverviewFooter" ;
@@ -61,6 +61,21 @@ const OtpInput = () => {
6161 }
6262 } ;
6363
64+ const handleAutoNavigationPaste = ( e , index ) => {
65+ e . preventDefault ( ) ;
66+ const pastedData = e . clipboardData . getData ( 'text' ) . replace ( / [ ^ 0 - 9 ] / g, '' ) . slice ( 0 , length ) ;
67+ const newOtp = [ ...autoNavigationInputs . current . map ( input => input . value ) ] ;
68+
69+ for ( let i = 0 ; i < pastedData . length && i < length ; i ++ ) {
70+ newOtp [ i ] = pastedData [ i ] ;
71+ autoNavigationInputs . current [ i ] . value = pastedData [ i ] ;
72+ }
73+ onChange ( newOtp . join ( '' ) ) ;
74+
75+ const focusIndex = Math . min ( pastedData . length , length - 1 ) ;
76+ autoNavigationInputs . current [ focusIndex ] . focus ( ) ;
77+ } ;
78+
6479 // for custom navigation
6580 const handleCustomNavigationInputChange = ( e , index ) => {
6681 const { value } = e . target ;
@@ -83,7 +98,6 @@ const OtpInput = () => {
8398 }
8499 }
85100
86-
87101 return (
88102 < >
89103 < aside className = "flex items-start justify-between gap-6 w-full 640px:pl-[2.5rem] px-6 640px:px-10" >
@@ -105,7 +119,7 @@ const OtpInput = () => {
105119 ref = { ( el ) => ( autoNavigationInputs . current [ index ] = el ) }
106120 className = 'p-3 text-center dark:bg-transparent dark:border-slate-700 dark:text-[#abc2d3] dark:placeholder:text-slate-500 border border-[#bcbcbc] rounded-md outline-none focus:border-primary'
107121 placeholder = '0'
108- max = "1"
122+ onWheel = { ( e ) => e . target . blur ( ) }
109123 onChange = { ( e ) => handleCustomNavigationInputChange ( e , index ) }
110124 type = 'number'
111125 />
@@ -154,7 +168,7 @@ const OtpInput = () => {
154168 ref={(el) => (navigationInputs.current[index] = el)}
155169 className="p-3 text-center dark:bg-transparent dark:border-slate-700 dark:text-[#abc2d3] dark:placeholder:text-slate-500 border border-[#bcbcbc] rounded-md outline-none focus:border-[#3B9DF8]"
156170 placeholder="0"
157- max="1"
171+ onWheel={(e) => e.target.blur()}
158172 onChange={(e) => handleInputChange(e, index)}
159173 type="number"
160174 />
@@ -174,8 +188,7 @@ export default OtpInput;
174188 < ContentHeader text = { "Keyboard navigation" } id = { "keyboard_navigation" } />
175189 </ div >
176190
177- < ComponentDescription text = 'OTP input field with keyboard navigation, enabling users to move between digits using arrow keys
178- for quick and efficient entry.' />
191+ < ComponentDescription text = 'OTP input field with keyboard navigation, enabling users to move between digits using arrow keys and paste numeric codes (extracting only numbers) for quick and efficient entry.' />
179192
180193 < ToggleTab code = { autoNavigationCode } setCode = { setAutoNavigationCode } setPreview = { setAutoNavigationPreview } preview = { autoNavigationPreview } />
181194
@@ -190,9 +203,10 @@ export default OtpInput;
190203 ref = { ( el ) => ( autoNavigationInputs . current [ index ] = el ) }
191204 className = 'p-3 text-center dark:bg-transparent dark:border-slate-700 dark:text-[#abc2d3] dark:placeholder:text-slate-500 border border-[#bcbcbc] rounded-md outline-none focus:border-primary'
192205 placeholder = '0'
193- max = "1"
206+ onWheel = { ( e ) => e . target . blur ( ) }
194207 onChange = { ( e ) => handleAutoNavigationInputChange ( e , index ) }
195208 onKeyDown = { ( e ) => handleAutoNavigationKeydown ( e , index ) }
209+ onPaste = { ( e ) => handleAutoNavigationPaste ( e , index ) }
196210 type = 'number'
197211 />
198212 ) )
@@ -236,6 +250,21 @@ const OtpInput = () => {
236250 }
237251 };
238252
253+ const handlePaste = (e, index) => {
254+ e.preventDefault();
255+ const pastedData = e.clipboardData.getData("text").replace(/[^0-9]/g, "").slice(0, length);
256+ const newOtp = [...navigationInputs.current.map(input => input.value)];
257+
258+ for (let i = 0; i < pastedData.length && i < length; i++) {
259+ newOtp[i] = pastedData[i];
260+ navigationInputs.current[i].value = pastedData[i];
261+ }
262+ onChange(newOtp.join(""));
263+
264+ const focusIndex = Math.min(pastedData.length, length - 1);
265+ navigationInputs.current[focusIndex].focus();
266+ };
267+
239268 const handleKeydown = (e, index) => {
240269 if (e.key === "Backspace" && !navigationInputs.current[index].value && index > 0) {
241270 navigationInputs.current[index - 1].focus()
@@ -251,9 +280,10 @@ const OtpInput = () => {
251280 ref={(el) => (navigationInputs.current[index] = el)}
252281 className="p-3 text-center dark:bg-transparent dark:border-slate-700 dark:text-[#abc2d3] dark:placeholder:text-slate-500 border border-[#bcbcbc] rounded-md outline-none focus:border-[#3B9DF8]"
253282 placeholder="0"
254- max="1"
283+ onWheel={(e) => e.target.blur()}
255284 onChange={(e) => handleInputChange(e, index)}
256285 onKeyDown={(e) => handleKeydown(e, index)}
286+ onPaste={(e) => handlePaste(e, index)}
257287 type="number"
258288 />
259289 ))
@@ -282,4 +312,4 @@ export default OtpInput;
282312 ) ;
283313} ;
284314
285- export default OtpInput ;
315+ export default OtpInput ;
0 commit comments