@@ -85,11 +85,10 @@ class SingleOtpInput extends PureComponent<*> {
85
85
...rest
86
86
} = this . props ;
87
87
88
- const numValueLimits = isInputNum ? { min : 0 , max : 9 } : { } ;
89
-
90
88
return (
91
89
< div style = { { display : 'flex' , alignItems : 'center' } } >
92
90
< input
91
+ autoComplete = "off"
93
92
style = { Object . assign (
94
93
{ width : '1em' , textAlign : 'center' } ,
95
94
isStyleObject ( inputStyle ) && inputStyle ,
@@ -103,8 +102,7 @@ class SingleOtpInput extends PureComponent<*> {
103
102
isDisabled && disabledStyle ,
104
103
hasErrored && errorStyle
105
104
) }
106
- type = { isInputNum ? 'number' : 'tel' }
107
- { ...numValueLimits }
105
+ type = { isInputNum ? 'tel' : 'text' }
108
106
maxLength = "1"
109
107
ref = { input => {
110
108
this . input = input ;
@@ -137,11 +135,20 @@ class OtpInput extends Component<Props, State> {
137
135
138
136
// Helper to return OTP from input
139
137
handleOtpChange = ( otp : string [ ] ) => {
140
- const { onChange, isInputNum } = this . props ;
138
+ const { onChange } = this . props ;
141
139
const otpValue = otp . join ( '' ) ;
140
+
142
141
onChange ( otpValue ) ;
143
142
} ;
144
143
144
+ isInputValueValid = value => {
145
+ const isTypeValid = this . props . isInputNum
146
+ ? ! isNaN ( parseInt ( value , 10 ) )
147
+ : typeof value === 'string' ;
148
+
149
+ return isTypeValid && value . trim ( ) . length === 1 ;
150
+ } ;
151
+
145
152
// Focus on input by index
146
153
focusInput = ( input : number ) => {
147
154
const { numInputs } = this . props ;
@@ -195,7 +202,11 @@ class OtpInput extends Component<Props, State> {
195
202
} ;
196
203
197
204
handleOnChange = ( e : Object ) => {
198
- this . changeCodeAtFocus ( e . target . value ) ;
205
+ const { value } = e . target ;
206
+
207
+ if ( this . isInputValueValid ( value ) ) {
208
+ this . changeCodeAtFocus ( value ) ;
209
+ }
199
210
} ;
200
211
201
212
// Handle cases of backspace, delete, left arrow, right arrow, space
@@ -216,21 +227,32 @@ class OtpInput extends Component<Props, State> {
216
227
} else if (
217
228
e . keyCode === SPACEBAR ||
218
229
e . key === ' ' ||
219
- e . key === 'Spacebar'
230
+ e . key === 'Spacebar' ||
231
+ e . key === 'Space'
220
232
) {
221
233
e . preventDefault ( ) ;
222
234
}
223
235
} ;
224
236
225
237
// The content may not have changed, but some input took place hence change the focus
226
- handleInput = ( e : Object ) => {
227
- this . focusNextInput ( ) ;
228
- }
229
-
230
- checkLength = ( e : Object ) => {
231
- if ( e . target . value . length > 1 ) {
232
- e . preventDefault ( ) ;
238
+ handleOnInput = ( e : Object ) => {
239
+ if ( this . isInputValueValid ( e . target . value ) ) {
233
240
this . focusNextInput ( ) ;
241
+ } else {
242
+ // This is a workaround for dealing with keyCode "229 Unidentified" on Android.
243
+
244
+ if ( ! this . props . isInputNum ) {
245
+ const { nativeEvent } = e ;
246
+
247
+ if (
248
+ nativeEvent . data === null &&
249
+ nativeEvent . inputType === 'deleteContentBackward'
250
+ ) {
251
+ e . preventDefault ( ) ;
252
+ this . changeCodeAtFocus ( '' ) ;
253
+ this . focusPrevInput ( ) ;
254
+ }
255
+ }
234
256
}
235
257
} ;
236
258
@@ -259,7 +281,7 @@ class OtpInput extends Component<Props, State> {
259
281
value = { otp && otp [ i ] }
260
282
onChange = { this . handleOnChange }
261
283
onKeyDown = { this . handleOnKeyDown }
262
- onInput = { this . handleInput }
284
+ onInput = { this . handleOnInput }
263
285
onPaste = { this . handleOnPaste }
264
286
onFocus = { e => {
265
287
this . setState ( { activeInput : i } ) ;
0 commit comments