Skip to content

Commit 3d1b556

Browse files
committed
feat: add caretColor prop to TextInputOTP component
- remove animated-caret.tsx and replace with simpler caret component - extract color constants to constants.ts - use constants for slot dimensions and colors - update imports and component usage accordingly
1 parent ec64358 commit 3d1b556

7 files changed

+33
-9
lines changed

src/components/animated-caret.tsx renamed to src/components/caret.tsx

+12-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import { useEffect } from 'react';
22
import { StyleSheet, Animated, useAnimatedValue } from 'react-native';
3+
import { DEFAULT_DARK_COLOR } from '../constants';
4+
import { useTextInputOTP } from '../hooks/use-text-input-otp';
35

4-
export function AnimatedCaret() {
6+
export function Caret() {
57
const opacity = useAnimatedValue(0);
8+
const { caretColor } = useTextInputOTP();
69

710
useEffect(() => {
811
Animated.loop(
@@ -21,14 +24,20 @@ export function AnimatedCaret() {
2124
).start();
2225
}, [opacity]);
2326

24-
return <Animated.View style={[styles.caret, { opacity }]} />;
27+
return (
28+
<Animated.View
29+
style={[
30+
styles.caret,
31+
{ opacity, backgroundColor: caretColor ?? DEFAULT_DARK_COLOR },
32+
]}
33+
/>
34+
);
2535
}
2636

2737
const styles = StyleSheet.create({
2838
caret: {
2939
width: 2,
3040
height: 16,
3141
borderRadius: 16,
32-
backgroundColor: '#030712',
3342
},
3443
});

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { View, StyleSheet } from 'react-native';
2+
import { DEFAULT_DARK_COLOR } from '../constants';
23
import type { TextInputOTPSeparatorProps } from '../types';
34

45
export function TextInputOTPSeparator({
@@ -13,7 +14,7 @@ const styles = StyleSheet.create({
1314
separator: {
1415
width: 10,
1516
height: 4,
16-
backgroundColor: '#030712',
17+
backgroundColor: DEFAULT_DARK_COLOR,
1718
borderRadius: 15,
1819
},
1920
});

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { memo } from 'react';
22
import { Pressable, Text, StyleSheet } from 'react-native';
3-
import { AnimatedCaret } from './animated-caret';
3+
import { Caret } from './caret';
44
import { useTextInputOTP } from '../hooks/use-text-input-otp';
55
import { useSlotBorderStyles } from '../hooks/use-slot-border-styles';
66
import { SLOT_HEIGHT, SLOT_WIDTH } from '../constants';
@@ -45,7 +45,7 @@ function TextInputOTPSlotComponent({
4545
</Text>
4646
)}
4747

48-
{shouldRenderCaret && <AnimatedCaret />}
48+
{shouldRenderCaret && <Caret />}
4949
</Pressable>
5050
);
5151
}

src/constants.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1-
export const BACKSPACE_KEY = 'Backspace';
21
export const SLOT_WIDTH = 50;
32
export const SLOT_HEIGHT = 50;
3+
export const FOCUSED_SLOT_HEIGHT = 54;
4+
export const DEFAULT_DARK_COLOR = '#030712';
5+
export const DEFAULT_LIGHT_COLOR = '#E4E7EC';

src/hooks/use-slot-border-styles.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
import {
2+
DEFAULT_DARK_COLOR,
3+
DEFAULT_LIGHT_COLOR,
4+
FOCUSED_SLOT_HEIGHT,
5+
SLOT_HEIGHT,
6+
} from '../constants';
17
import type { UseSlotBorderStylesProps } from '../types';
28

39
export function useSlotBorderStyles({
@@ -6,8 +12,8 @@ export function useSlotBorderStyles({
612
isLast,
713
}: UseSlotBorderStylesProps) {
814
return {
9-
height: isFocused ? 54 : 50,
10-
borderColor: isFocused ? '#030712' : '#E4E7EC',
15+
height: isFocused ? FOCUSED_SLOT_HEIGHT : SLOT_HEIGHT,
16+
borderColor: isFocused ? DEFAULT_DARK_COLOR : DEFAULT_LIGHT_COLOR,
1117
borderTopWidth: 2,
1218
borderBottomWidth: 2,
1319
borderLeftWidth: isFocused || isFirst ? 2 : 1,

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

+3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export function TextInputOTPProvider({
3232
onFilled,
3333
onChangeText,
3434
caretHidden = false,
35+
caretColor,
3536
children,
3637
}: TextInputOTPProviderProps) {
3738
const [code, setCode] = useState(value);
@@ -98,6 +99,7 @@ export function TextInputOTPProvider({
9899
blur,
99100
clear,
100101
caretHidden,
102+
caretColor,
101103
}),
102104
[
103105
clear,
@@ -108,6 +110,7 @@ export function TextInputOTPProvider({
108110
setValue,
109111
value,
110112
caretHidden,
113+
caretColor,
111114
]
112115
);
113116

src/types.ts

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export type TextInputOTPContextProps = {
2020
blur: () => void;
2121
clear: () => void;
2222
caretHidden: boolean;
23+
caretColor?: string;
2324
};
2425

2526
export type TextInputOTPProviderProps = PropsWithChildren<
@@ -31,6 +32,7 @@ export type TextInputOTPProviderProps = PropsWithChildren<
3132
| 'onFilled'
3233
| 'value'
3334
| 'caretHidden'
35+
| 'caretColor'
3436
>
3537
>;
3638

@@ -74,4 +76,5 @@ export type TextInputOTPProps = {
7476
maxLength: number;
7577
onFilled?: (text: string) => void;
7678
containerStyles?: StyleProp<ViewStyle>;
79+
caretColor?: string;
7780
} & Omit<TextInputProps, 'style'>;

0 commit comments

Comments
 (0)