/
OtpInput.tsx
92 lines (85 loc) · 2.38 KB
/
OtpInput.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import React, { forwardRef, RefObject, useEffect, useMemo, useState } from 'react';
import {
NativeSyntheticEvent,
Platform,
StyleProp,
TextInput,
TextInputKeyPressEventData,
TextInputProps,
TextStyle,
View,
ViewStyle,
} from 'react-native';
type Props = TextInputProps & {
inputContainerStyles?: StyleProp<ViewStyle>;
firstInput: boolean;
focusStyles?: StyleProp<ViewStyle>;
inputStyles?: StyleProp<TextStyle>;
numberOfInputs: number;
handleTextChange: (text: string) => void;
inputValue: string;
handleKeyPress: (keyPressEvent: NativeSyntheticEvent<TextInputKeyPressEventData>) => void;
};
const majorVersionIOS: number = parseInt(`${Platform.Version}`, 10);
const isOTPSupported: boolean = Platform.OS === 'ios' && majorVersionIOS >= 12;
const OtpInput = forwardRef<TextInput, Props>(
(
{
autoFocus,
focusStyles,
handleKeyPress,
handleTextChange,
inputContainerStyles,
inputStyles,
inputValue,
placeholder,
selectTextOnFocus,
secureTextEntry,
...rest
},
ref,
) => {
const [focused, setFocused] = useState(false);
useEffect(() => {
(ref as RefObject<TextInput>)?.current?.setNativeProps({
value: inputValue,
text: inputValue,
secureTextEntry,
});
}, [ref, inputValue, secureTextEntry]);
const restProps = useMemo(
() =>
Platform.select({
default: rest,
web: { value: inputValue, ...rest },
}),
[inputValue, rest],
);
return (
// @ts-expect-error
<View style={[inputContainerStyles, focused && focusStyles]}>
{/* @ts-expect-error */}
<TextInput
autoFocus={autoFocus}
onBlur={() => setFocused(false)}
onChangeText={handleTextChange}
onFocus={() => setFocused(true)}
onKeyPress={handleKeyPress}
placeholder={placeholder}
ref={ref}
secureTextEntry={secureTextEntry}
// https://github.com/facebook/react-native/issues/18339
selectTextOnFocus={Platform.select({
ios: selectTextOnFocus,
android: true,
})}
style={inputStyles}
textContentType={isOTPSupported ? 'oneTimeCode' : 'none'}
underlineColorAndroid="transparent"
{...restProps}
/>
</View>
);
},
);
export default React.memo(OtpInput);