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
93
94
95
96
97
98
99
100
101
102
103
104import React, {useState, useEffect} from 'react';
import {
Button,
Text,
View,
StyleSheet,
Platform,
TouchableWithoutFeedback,
Keyboard,
} from 'react-native';
import {AvoidSoftInput} from 'react-native-avoid-softinput';
import {
CodeField,
Cursor,
useBlurOnFulfill,
useClearByFocusCell,
} from 'react-native-confirmation-code-field';
import {useKeyboard} from '@react-native-community/hooks';
const CELL_COUNT = 6;
export function Test() {
const {keyboardHeight} = useKeyboard();
const [value, setValue] = useState('');
const ref = useBlurOnFulfill({value, cellCount: CELL_COUNT});
const [props, getCellOnLayoutHandler] = useClearByFocusCell({
value,
setValue,
});
useEffect(() => {
AvoidSoftInput.setShouldMimicIOSBehavior(true);
AvoidSoftInput.setEnabled(true);
AvoidSoftInput.setAvoidOffset(keyboardHeight - 100);
return () => {
AvoidSoftInput.setAvoidOffset(0);
AvoidSoftInput.setEnabled(false);
AvoidSoftInput.setShouldMimicIOSBehavior(false);
};
}, [keyboardHeight]);
return (
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={styles.root}>
<CodeField
ref={ref}
{...props}
// Use `caretHidden={false}` when users can't paste a text value, because context menu doesn't appear
value={value}
onChangeText={setValue}
cellCount={CELL_COUNT}
rootStyle={styles.codeFieldRoot}
keyboardType="number-pad"
textContentType="oneTimeCode"
autoComplete={Platform.select<
'sms-otp' | 'one-time-code' | undefined
>({
android: 'sms-otp',
default: 'one-time-code',
})}
testID="my-code-input"
renderCell={({index, symbol, isFocused}) => (
<Text
key={index}
style={[styles.cell, isFocused && styles.focusCell]}
onLayout={getCellOnLayoutHandler(index)}>
{symbol || (isFocused ? <Cursor /> : null)}
</Text>
)}
/>
<View height={10} />
<Button title="Confirm" disabled={value.length !== CELL_COUNT} />
<View height={10} />
<Button title="Cancel" onPress={() => setValue('')} />
<View height={10} />
</View>
</TouchableWithoutFeedback>
);
}
const styles = StyleSheet.create({
root: {flex: 1, padding: 20, justifyContent: 'center'},
title: {textAlign: 'center', fontSize: 30},
codeFieldRoot: {marginTop: 20},
cell: {
width: 40,
height: 40,
lineHeight: 38,
fontSize: 24,
borderWidth: 2,
borderColor: '#00000030',
textAlign: 'center',
},
focusCell: {
borderColor: '#000',
},
});