@@ -20,6 +20,7 @@ type Props = {
20
20
errorStyle ?: Object ,
21
21
shouldAutoFocus ?: boolean ,
22
22
isInputNum ?: boolean ,
23
+ value ?: string ,
23
24
} ;
24
25
25
26
type State = {
@@ -123,28 +124,30 @@ class OtpInput extends Component<Props, State> {
123
124
onChange : ( otp : number ) : void => console . log ( otp ) ,
124
125
isDisabled : false ,
125
126
shouldAutoFocus : false ,
127
+ value : '' ,
126
128
} ;
127
129
128
130
state = {
129
131
activeInput : 0 ,
130
- otp : [ ] ,
131
132
} ;
132
133
134
+ getOtpValue = ( ) => (
135
+ this . props . value ? this . props . value . toString ( ) . split ( '' ) : [ ]
136
+ ) ;
137
+
133
138
// Helper to return OTP from input
134
- getOtp = ( ) => {
139
+ handleOtpChange = ( otp : string [ ] ) => {
135
140
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 ) ;
138
143
} ;
139
144
140
145
// Focus on input by index
141
146
focusInput = ( input : number ) => {
142
147
const { numInputs } = this . props ;
143
148
const activeInput = Math . max ( Math . min ( numInputs - 1 , input ) , 0 ) ;
144
149
145
- this . setState ( {
146
- activeInput,
147
- } ) ;
150
+ this . setState ( { activeInput } ) ;
148
151
} ;
149
152
150
153
// Focus on next input
@@ -161,20 +164,19 @@ class OtpInput extends Component<Props, State> {
161
164
162
165
// Change OTP value at focused input
163
166
changeCodeAtFocus = ( value : string ) => {
164
- const { activeInput, otp } = this . state ;
167
+ const { activeInput } = this . state ;
168
+ const otp = this . getOtpValue ( ) ;
165
169
otp [ activeInput ] = value [ 0 ] ;
166
170
167
- this . setState ( {
168
- otp,
169
- } ) ;
170
- this . getOtp ( ) ;
171
+ this . handleOtpChange ( otp ) ;
171
172
} ;
172
173
173
174
// Handle pasted OTP
174
175
handleOnPaste = ( e : Object ) = > {
175
176
e . preventDefault ( ) ;
176
177
const { numInputs } = this . props ;
177
- const { activeInput , otp } = this . state ;
178
+ const { activeInput } = this . state ;
179
+ const otp = this . getOtpValue ( ) ;
178
180
179
181
// Get pastedData in an array of max size (num of inputs - current position)
180
182
const pastedData = e . clipboardData
@@ -189,11 +191,7 @@ class OtpInput extends Component<Props, State> {
189
191
}
190
192
}
191
193
192
- this . setState ( {
193
- otp,
194
- } ) ;
195
-
196
- this . getOtp ( ) ;
194
+ this . handleOtpChange ( otp ) ;
197
195
} ;
198
196
199
197
handleOnChange = ( e : Object ) => {
@@ -203,31 +201,31 @@ class OtpInput extends Component<Props, State> {
203
201
204
202
// Handle cases of backspace, delete, left arrow, right arrow
205
203
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 ( ) ;
226
217
}
227
218
} ;
228
219
220
+ checkLength = ( e : Object ) => {
221
+ if ( e . target . value . length > 1 ) {
222
+ e . preventDefault ( ) ;
223
+ this . focusNextInput ( ) ;
224
+ }
225
+ }
226
+
229
227
renderInputs = ( ) => {
230
- const { activeInput, otp } = this . state ;
228
+ const { activeInput } = this . state ;
231
229
const {
232
230
numInputs,
233
231
inputStyle,
@@ -240,6 +238,7 @@ class OtpInput extends Component<Props, State> {
240
238
shouldAutoFocus,
241
239
isInputNum,
242
240
} = this . props ;
241
+ const otp = this . getOtpValue ( ) ;
243
242
const inputs = [ ] ;
244
243
245
244
for ( let i = 0 ; i < numInputs ; i ++ ) {
@@ -250,11 +249,10 @@ class OtpInput extends Component<Props, State> {
250
249
value = { otp && otp [ i ] }
251
250
onChange = { this . handleOnChange }
252
251
onKeyDown = { this . handleOnKeyDown }
252
+ onInput = { this . checkLength }
253
253
onPaste = { this . handleOnPaste }
254
254
onFocus = { e => {
255
- this . setState ( {
256
- activeInput : i ,
257
- } ) ;
255
+ this . setState ( { activeInput : i } ) ;
258
256
e . target . select ( ) ;
259
257
} }
260
258
onBlur = { ( ) => this . setState ( { activeInput : - 1 } ) }
0 commit comments