Skip to content

Commit 4a17a5b

Browse files
author
ignaciosantise
committed
chore: otp input improvements
1 parent a7336e3 commit 4a17a5b

File tree

1 file changed

+33
-14
lines changed

1 file changed

+33
-14
lines changed

packages/ui/src/composites/wui-otp/index.tsx

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,33 +29,53 @@ export function Otp({ length, style, onChangeText, autoFocus }: OtpProps) {
2929

3030
if (text.length <= 1) {
3131
newValue = [...value.slice(0, index), text, ...value.slice(index + 1)];
32+
} else if (text.length === length) {
33+
// Paste OTP
34+
newValue = text.split('');
35+
focusInputField('next', length - 1);
36+
} else if (text.length === 2) {
37+
// Replace value
38+
newValue = [
39+
...value.slice(0, index),
40+
(value[index] === text[0] ? text[1] : text[0]) ?? '',
41+
...value.slice(index + 1)
42+
];
3243
} else {
33-
newValue = text.split('', length);
44+
newValue = [...value.slice(0, index), text[0] || '', ...value.slice(index + 1)];
45+
focusInputField('next', index);
3446
}
3547

3648
setValue(newValue);
3749
onChangeText?.(newValue.join(''));
50+
};
51+
52+
const focusInputField = (dir: 'prev' | 'next', currentIndex: number, clear = false) => {
53+
let newIndex;
54+
if (dir === 'prev' && currentIndex > 0) {
55+
newIndex = currentIndex - 1;
56+
} else if (dir === 'next' && currentIndex < length - 1) {
57+
newIndex = currentIndex + 1;
58+
}
3859

39-
if (text.length === 1 && index < length - 1) {
40-
refArray[index + 1]?.current?.focus();
41-
} else if (text.length > 1) {
42-
refArray[newValue.length]?.current?.focus();
60+
if (newIndex !== undefined) {
61+
refArray[newIndex]?.current?.focus();
62+
if (clear) {
63+
refArray[newIndex]?.current?.clear();
64+
_onChangeText('', newIndex);
65+
}
4366
}
4467
};
4568

4669
const onKeyPress = (e: NativeSyntheticEvent<TextInputKeyPressEventData>, index: number) => {
4770
const currentValue = value[index] || '';
71+
const key = e.nativeEvent.key;
4872

49-
if (e.nativeEvent.key !== 'Backspace' && currentValue && index !== length - 1) {
50-
refArray[index + 1]?.current?.focus();
51-
52-
return;
53-
}
54-
55-
if (e.nativeEvent.key === 'Backspace' && index !== 0) {
73+
if (key === 'Backspace') {
5674
if (!currentValue) {
57-
refArray[index - 1]?.current?.focus();
75+
focusInputField('prev', index, true);
5876
}
77+
} else {
78+
focusInputField('next', index);
5979
}
6080
};
6181

@@ -70,7 +90,6 @@ export function Otp({ length, style, onChangeText, autoFocus }: OtpProps) {
7090
inputRef={refArray[index]}
7191
onChangeText={text => _onChangeText(text, index)}
7292
onKeyPress={(e: any) => onKeyPress(e, index)}
73-
selectTextOnFocus
7493
textContentType="oneTimeCode"
7594
autoComplete={Platform.OS === 'android' ? 'sms-otp' : 'one-time-code'}
7695
/>

0 commit comments

Comments
 (0)