@@ -20,6 +20,7 @@ type Props = {
2020 errorStyle ?: Object ,
2121 shouldAutoFocus ?: boolean ,
2222 isInputNum ?: boolean ,
23+ value ?: string ,
2324} ;
2425
2526type State = {
@@ -123,28 +124,30 @@ class OtpInput extends Component<Props, State> {
123124 onChange : ( otp : number ) : void => console . log ( otp ) ,
124125 isDisabled : false ,
125126 shouldAutoFocus : false ,
127+ value : '' ,
126128 } ;
127129
128130 state = {
129131 activeInput : 0 ,
130- otp : [ ] ,
131132 } ;
132133
134+ getOtpValue = ( ) => (
135+ this . props . value ? this . props . value . toString ( ) . split ( '' ) : [ ]
136+ ) ;
137+
133138 // Helper to return OTP from input
134- getOtp = ( ) => {
139+ handleOtpChange = ( otp : string [ ] ) => {
135140 const { onChange, isInputNum } = this . props ;
136- const otp = this . state . otp . join ( '' ) ;
137- onChange ( isInputNum ? Number ( otp ) : otp ) ;
141+ const otpValue = otp . join ( '' ) ;
142+ onChange ( isInputNum ? Number ( otpValue ) : otpValue ) ;
138143 } ;
139144
140145 // Focus on input by index
141146 focusInput = ( input : number ) => {
142147 const { numInputs } = this . props ;
143148 const activeInput = Math . max ( Math . min ( numInputs - 1 , input ) , 0 ) ;
144149
145- this . setState ( {
146- activeInput,
147- } ) ;
150+ this . setState ( { activeInput } ) ;
148151 } ;
149152
150153 // Focus on next input
@@ -161,20 +164,19 @@ class OtpInput extends Component<Props, State> {
161164
162165 // Change OTP value at focused input
163166 changeCodeAtFocus = ( value : string ) => {
164- const { activeInput, otp } = this . state ;
167+ const { activeInput } = this . state ;
168+ const otp = this . getOtpValue ( ) ;
165169 otp [ activeInput ] = value [ 0 ] ;
166170
167- this . setState ( {
168- otp,
169- } ) ;
170- this . getOtp ( ) ;
171+ this . handleOtpChange ( otp ) ;
171172 } ;
172173
173174 // Handle pasted OTP
174175 handleOnPaste = ( e : Object ) = > {
175176 e . preventDefault ( ) ;
176177 const { numInputs } = this . props ;
177- const { activeInput , otp } = this . state ;
178+ const { activeInput } = this . state ;
179+ const otp = this . getOtpValue ( ) ;
178180
179181 // Get pastedData in an array of max size (num of inputs - current position)
180182 const pastedData = e . clipboardData
@@ -189,11 +191,7 @@ class OtpInput extends Component<Props, State> {
189191 }
190192 }
191193
192- this . setState ( {
193- otp,
194- } ) ;
195-
196- this . getOtp ( ) ;
194+ this . handleOtpChange ( otp ) ;
197195 } ;
198196
199197 handleOnChange = ( e : Object ) => {
@@ -203,31 +201,31 @@ class OtpInput extends Component<Props, State> {
203201
204202 // Handle cases of backspace, delete, left arrow, right arrow
205203 handleOnKeyDown = ( e : Object ) => {
206- switch ( e . keyCode ) {
207- case BACKSPACE :
208- e . preventDefault ( ) ;
209- this . changeCodeAtFocus ( '' ) ;
210- this . focusPrevInput ( ) ;
211- break ;
212- case DELETE :
213- e . preventDefault ( ) ;
214- this . changeCodeAtFocus ( '' ) ;
215- break ;
216- case LEFT_ARROW :
217- e . preventDefault ( ) ;
218- this . focusPrevInput ( ) ;
219- break ;
220- case RIGHT_ARROW :
221- e . preventDefault ( ) ;
222- this . focusNextInput ( ) ;
223- break ;
224- default :
225- break ;
204+ if ( e . keyCode === BACKSPACE || e . key === 'Backspace' ) {
205+ e . preventDefault ( ) ;
206+ this . changeCodeAtFocus ( '' ) ;
207+ this . focusPrevInput ( ) ;
208+ } else if ( e . keyCode === DELETE || e . key === 'Delete' ) {
209+ e . preventDefault ( ) ;
210+ this . changeCodeAtFocus ( '' ) ;
211+ } else if ( e . keyCode === LEFT_ARROW || e . key === 'ArrowLeft' ) {
212+ e . preventDefault ( ) ;
213+ this . focusPrevInput ( ) ;
214+ } else if ( e . keyCode === RIGHT_ARROW || e . key === 'ArrowRight' ) {
215+ e . preventDefault ( ) ;
216+ this . focusNextInput ( ) ;
226217 }
227218 } ;
228219
220+ checkLength = ( e : Object ) => {
221+ if ( e . target . value . length > 1 ) {
222+ e . preventDefault ( ) ;
223+ this . focusNextInput ( ) ;
224+ }
225+ }
226+
229227 renderInputs = ( ) => {
230- const { activeInput, otp } = this . state ;
228+ const { activeInput } = this . state ;
231229 const {
232230 numInputs,
233231 inputStyle,
@@ -240,6 +238,7 @@ class OtpInput extends Component<Props, State> {
240238 shouldAutoFocus,
241239 isInputNum,
242240 } = this . props ;
241+ const otp = this . getOtpValue ( ) ;
243242 const inputs = [ ] ;
244243
245244 for ( let i = 0 ; i < numInputs ; i ++ ) {
@@ -250,11 +249,10 @@ class OtpInput extends Component<Props, State> {
250249 value = { otp && otp [ i ] }
251250 onChange = { this . handleOnChange }
252251 onKeyDown = { this . handleOnKeyDown }
252+ onInput = { this . checkLength }
253253 onPaste = { this . handleOnPaste }
254254 onFocus = { e => {
255- this . setState ( {
256- activeInput : i ,
257- } ) ;
255+ this . setState ( { activeInput : i } ) ;
258256 e . target . select ( ) ;
259257 } }
260258 onBlur = { ( ) => this . setState ( { activeInput : - 1 } ) }
0 commit comments