Skip to content

Commit ec64358

Browse files
committed
feat: add caret hidden option
- add caretHidden prop to TextInputOTPProvider - update TextInputOTPSlot to conditionally render caret - update types and context to include caretHidden property
1 parent 0c624ce commit ec64358

File tree

3 files changed

+35
-12
lines changed

3 files changed

+35
-12
lines changed

src/components/text-input-otp-slot.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ function TextInputOTPSlotComponent({
1919
slotTextStyles,
2020
...rest
2121
}: TextInputOTPSlotProps & TextInputOTPSlotInternalProps) {
22-
const { code, currentIndex, handlePress } = useTextInputOTP();
22+
const { code, currentIndex, handlePress, caretHidden } = useTextInputOTP();
2323
const isFocused = currentIndex === index;
2424
const borderStyles = useSlotBorderStyles({ isFocused, isFirst, isLast });
25+
const shouldRenderCaret = isFocused && !code[index] && !caretHidden;
2526

2627
return (
2728
<Pressable
@@ -44,7 +45,7 @@ function TextInputOTPSlotComponent({
4445
</Text>
4546
)}
4647

47-
{isFocused && !code[index] && <AnimatedCaret />}
48+
{shouldRenderCaret && <AnimatedCaret />}
4849
</Pressable>
4950
);
5051
}

src/hooks/use-text-input-otp.tsx

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ import {
55
useMemo,
66
useRef,
77
useState,
8-
type PropsWithChildren,
98
} from 'react';
109
import type { TextInput } from 'react-native';
11-
import type { TextInputOTPContextProps, TextInputOTPProps } from '../types';
10+
import type {
11+
TextInputOTPContextProps,
12+
TextInputOTPProviderProps,
13+
} from '../types';
1214

1315
const TextInputOTPContext = createContext<TextInputOTPContextProps>({
1416
code: '',
@@ -20,6 +22,7 @@ const TextInputOTPContext = createContext<TextInputOTPContextProps>({
2022
focus: () => {},
2123
blur: () => {},
2224
clear: () => {},
25+
caretHidden: false,
2326
});
2427

2528
export function TextInputOTPProvider({
@@ -28,13 +31,9 @@ export function TextInputOTPProvider({
2831
value = '',
2932
onFilled,
3033
onChangeText,
34+
caretHidden = false,
3135
children,
32-
}: PropsWithChildren<
33-
Pick<
34-
TextInputOTPProps,
35-
'autoFocus' | 'maxLength' | 'onFilled' | 'onChangeText' | 'value'
36-
>
37-
>) {
36+
}: TextInputOTPProviderProps) {
3837
const [code, setCode] = useState(value);
3938
const [currentIndex, setCurrentIndex] = useState(() => (autoFocus ? 0 : -1));
4039
const inputRef = useRef<TextInput>(null);
@@ -98,8 +97,18 @@ export function TextInputOTPProvider({
9897
focus,
9998
blur,
10099
clear,
100+
caretHidden,
101101
}),
102-
[clear, code, currentIndex, handleChangeText, handlePress, setValue, value]
102+
[
103+
clear,
104+
code,
105+
currentIndex,
106+
handleChangeText,
107+
handlePress,
108+
setValue,
109+
value,
110+
caretHidden,
111+
]
103112
);
104113

105114
return (

src/types.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ReactNode, RefObject } from 'react';
1+
import type { PropsWithChildren, ReactNode, RefObject } from 'react';
22
import type {
33
PressableProps,
44
StyleProp,
@@ -19,8 +19,21 @@ export type TextInputOTPContextProps = {
1919
focus: () => void;
2020
blur: () => void;
2121
clear: () => void;
22+
caretHidden: boolean;
2223
};
2324

25+
export type TextInputOTPProviderProps = PropsWithChildren<
26+
Pick<
27+
TextInputOTPProps,
28+
| 'autoFocus'
29+
| 'maxLength'
30+
| 'onChangeText'
31+
| 'onFilled'
32+
| 'value'
33+
| 'caretHidden'
34+
>
35+
>;
36+
2437
export type TextInputOTPGroupProps = {
2538
groupStyles?: StyleProp<ViewStyle>;
2639
} & Omit<ViewProps, 'style'>;

0 commit comments

Comments
 (0)