-
Notifications
You must be signed in to change notification settings - Fork 47
Expand file tree
/
Copy pathuseOtpInput.ts
More file actions
88 lines (74 loc) · 2.14 KB
/
useOtpInput.ts
File metadata and controls
88 lines (74 loc) · 2.14 KB
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
import { useMemo, useRef, useState, useEffect } from "react";
import { Keyboard, TextInput } from "react-native";
import { OtpInputProps } from "./OtpInput.types";
const regexMap = {
alpha: /[^a-zA-Z]/,
numeric: /[^\d]/,
alphanumeric: /[^a-zA-Z\d]/,
};
export const useOtpInput = ({
onTextChange,
onFilled,
numberOfDigits = 6,
disabled,
autoFocus = true,
blurOnFilled,
type,
onFocus,
onBlur,
placeholder: _placeholder,
defaultValue = "", // Default value support
}: OtpInputProps) => {
const [text, setText] = useState(defaultValue.slice(0, numberOfDigits)); // Initialize with defaultValue
const [isFocused, setIsFocused] = useState(autoFocus);
const inputRef = useRef<TextInput>(null);
const focusedInputIndex = text.length;
const placeholder = useMemo(
() => (_placeholder?.length === 1 ? _placeholder.repeat(numberOfDigits) : _placeholder),
[_placeholder, numberOfDigits]
);
useEffect(() => {
// Ensure state updates if defaultValue changes dynamically
setText(defaultValue.slice(0, numberOfDigits));
}, [defaultValue, numberOfDigits]);
const handlePress = () => {
if (!Keyboard.isVisible()) {
Keyboard.dismiss();
}
inputRef.current?.focus();
};
const handleTextChange = (value: string) => {
if (type && regexMap[type].test(value)) return;
if (disabled) return;
setText(value);
onTextChange?.(value);
if (value.length === numberOfDigits) {
onFilled?.(value);
if (blurOnFilled) inputRef.current?.blur();
}
};
const setTextWithRef = (value: string) => {
const normalizedValue = value.slice(0, numberOfDigits);
setText(normalizedValue);
onTextChange?.(normalizedValue);
};
const clear = () => {
setText("");
};
const focus = () => {
inputRef.current?.focus();
};
const handleFocus = () => {
setIsFocused(true);
onFocus?.();
};
const handleBlur = () => {
setIsFocused(false);
onBlur?.();
};
return {
models: { text, inputRef, focusedInputIndex, isFocused, placeholder },
actions: { handlePress, handleTextChange, clear, focus, handleFocus, handleBlur },
forms: { setTextWithRef },
};
};