Skip to content

Commit fa6d43e

Browse files
committed
feat: adding container style and animated props
1 parent bb2e0b7 commit fa6d43e

File tree

3 files changed

+178
-92
lines changed

3 files changed

+178
-92
lines changed

src/PinCodeKey.tsx

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import React from 'react';
22
import {
3-
type TextStyle,
3+
Animated,
44
type ColorValue,
5+
Easing,
6+
Pressable,
57
Text,
8+
type TextStyle,
69
TouchableOpacity,
710
} from 'react-native';
811
import type { NumberProp } from 'react-native-svg';
@@ -24,6 +27,8 @@ function PinCodeKey({
2427
bioMetricIconHeight,
2528
bioMetricIconWidth,
2629
disable = false,
30+
animated = false,
31+
animationProps
2732
}: {
2833
item: string | number;
2934
onKeyPress: (value: any) => void;
@@ -39,7 +44,44 @@ function PinCodeKey({
3944
bioMetricIconHeight: NumberProp;
4045
bioMetricIconWidth: NumberProp;
4146
disable?: boolean;
47+
animated?: boolean;
48+
animationProps?: {
49+
activeColor?: string;
50+
activeTextScale?: number;
51+
pressInDuration?: number
52+
pressOutDuration?: number
53+
}
4254
}) {
55+
// animations
56+
const AnimatedPressable = Animated.createAnimatedComponent(Pressable);
57+
const anim = React.useRef(new Animated.Value(0)).current;
58+
59+
const bgColor = anim.interpolate({
60+
inputRange: [0, 1],
61+
outputRange: ['transparent', animationProps?.activeColor ?? 'rgba(255, 255, 255, 0.24)'],
62+
});
63+
const textScale = anim.interpolate({
64+
inputRange: [0, 1],
65+
outputRange: [1, animationProps?.activeTextScale ?? 0.85],
66+
});
67+
68+
const pressIn = () => {
69+
Animated.timing(anim, {
70+
toValue: 1,
71+
duration: animationProps?.pressInDuration ?? 150,
72+
easing: Easing.out(Easing.quad),
73+
useNativeDriver: true,
74+
}).start();
75+
};
76+
77+
const pressOut = () => {
78+
Animated.timing(anim, {
79+
toValue: 0,
80+
duration: animationProps?.pressOutDuration ?? 250,
81+
easing: Easing.inOut(Easing.quad),
82+
useNativeDriver: true,
83+
}).start();
84+
};
4385
// ---------------------------------------------------
4486
// @ Helper Functions
4587
// ---------------------------------------------------
@@ -74,6 +116,13 @@ function PinCodeKey({
74116
</>
75117
);
76118
}
119+
if (animated === true) {
120+
return (
121+
<Animated.View style={[{ transform: [{ scale: textScale }] }]}>
122+
<Text style={textStyle}>{item}</Text>
123+
</Animated.View>
124+
);
125+
}
77126
return <Text style={textStyle}>{item}</Text>;
78127
};
79128

@@ -87,6 +136,27 @@ function PinCodeKey({
87136
// ---------------------------------------------------
88137
// @ Main View
89138
// ---------------------------------------------------
139+
if (animated) {
140+
return (
141+
<AnimatedPressable
142+
onPress={() => getOnPress()}
143+
onPressIn={pressIn}
144+
onPressOut={pressOut}
145+
style={[
146+
{
147+
justifyContent: 'center',
148+
alignItems: 'center',
149+
flex: 1,
150+
borderRadius: 12,
151+
backgroundColor: bgColor,
152+
},
153+
]}
154+
disabled={disable}
155+
>
156+
{getContent()}
157+
</AnimatedPressable>
158+
);
159+
}
90160
return (
91161
<TouchableOpacity
92162
onPress={() => getOnPress()}

src/PinCodeRow.tsx

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,27 @@
1-
import React from 'react';
2-
import type { PropsWithChildren } from 'react';
3-
import { View } from 'react-native';
1+
import type { PropsWithChildren } from "react";
2+
import React from "react";
3+
import { type StyleProp, View, type ViewStyle } from "react-native";
44

55
function PinCodeRow({
6-
rowReverse = false,
7-
children,
8-
}: PropsWithChildren<{ rowReverse: boolean }>) {
9-
return (
10-
<View
11-
style={{
12-
flexDirection: rowReverse ? 'row-reverse' : 'row',
13-
width: '100%',
14-
minHeight: '11%',
15-
paddingHorizontal: 2,
16-
}}
17-
>
18-
{children}
19-
</View>
20-
);
6+
rowReverse = false,
7+
children,
8+
style,
9+
}: PropsWithChildren<{ rowReverse: boolean; style?: StyleProp<ViewStyle> }>) {
10+
return (
11+
<View
12+
style={[
13+
{
14+
flexDirection: rowReverse ? "row-reverse" : "row",
15+
width: "100%",
16+
minHeight: "11%",
17+
paddingHorizontal: 2,
18+
},
19+
style,
20+
]}
21+
>
22+
{children}
23+
</View>
24+
);
2125
}
2226

2327
export default PinCodeRow;

src/keypad.tsx

Lines changed: 85 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,93 @@
1-
import React from 'react';
2-
import { type TextStyle, type ColorValue } from 'react-native';
3-
import type { NumberProp } from 'react-native-svg';
4-
import PinCodeRow from './PinCodeRow';
5-
import PinCodeKey from './PinCodeKey';
1+
import React, { type ComponentProps } from "react";
2+
import type { ColorValue, StyleProp, TextStyle, ViewStyle } from "react-native";
3+
import type { NumberProp } from "react-native-svg";
4+
import PinCodeKey from "./PinCodeKey";
5+
import PinCodeRow from "./PinCodeRow";
66

77
export const Keypad = ({
8-
onKeyPress,
9-
textStyle = {},
10-
backspaceIcon,
11-
bioMetricAuthIcon,
12-
rowReverse = false,
13-
backspaceIconFillColor = '#000000',
14-
backspaceIconStrokeColor = '#FFFFFF',
15-
bioMetricFillColor = '#000000',
16-
backspaceIconHeight = 24,
17-
backspaceIconWidth = 33,
18-
bioMetricIconHeight = 28,
19-
bioMetricIconWidth = 28,
20-
onBioAuthPress,
21-
disable = false,
8+
onKeyPress,
9+
textStyle = {},
10+
backspaceIcon,
11+
bioMetricAuthIcon,
12+
rowReverse = false,
13+
backspaceIconFillColor = "#000000",
14+
backspaceIconStrokeColor = "#FFFFFF",
15+
bioMetricFillColor = "#000000",
16+
backspaceIconHeight = 24,
17+
backspaceIconWidth = 33,
18+
bioMetricIconHeight = 28,
19+
bioMetricIconWidth = 28,
20+
onBioAuthPress,
21+
disable = false,
22+
animated = false,
23+
rowStyle,
24+
animationProps,
2225
}: {
23-
onKeyPress: (value: any) => void;
24-
textStyle?: TextStyle;
25-
rowReverse?: boolean;
26-
backspaceIcon?: JSX.Element;
27-
bioMetricAuthIcon?: JSX.Element;
28-
backspaceIconFillColor?: ColorValue;
29-
backspaceIconStrokeColor?: ColorValue;
30-
bioMetricFillColor?: ColorValue;
31-
backspaceIconHeight?: NumberProp;
32-
backspaceIconWidth?: NumberProp;
33-
bioMetricIconHeight?: NumberProp;
34-
bioMetricIconWidth?: NumberProp;
35-
onBioAuthPress?: () => void;
36-
disable?: boolean;
26+
onKeyPress: (value: any) => void;
27+
textStyle?: TextStyle;
28+
rowReverse?: boolean;
29+
backspaceIcon?: JSX.Element;
30+
bioMetricAuthIcon?: JSX.Element;
31+
backspaceIconFillColor?: ColorValue;
32+
backspaceIconStrokeColor?: ColorValue;
33+
bioMetricFillColor?: ColorValue;
34+
backspaceIconHeight?: NumberProp;
35+
backspaceIconWidth?: NumberProp;
36+
bioMetricIconHeight?: NumberProp;
37+
bioMetricIconWidth?: NumberProp;
38+
onBioAuthPress?: () => void;
39+
disable?: boolean;
40+
animated?: boolean;
41+
rowStyle?: StyleProp<ViewStyle>;
42+
animationProps?: ComponentProps<typeof PinCodeKey>["animationProps"];
3743
}) => {
38-
// ---------------------------------------------------
39-
// @ Defaults
40-
// ---------------------------------------------------
41-
const keys = [
42-
[1, 2, 3],
43-
[4, 5, 6],
44-
[7, 8, 9],
45-
['auth', 0, 'delete'],
46-
];
44+
// ---------------------------------------------------
45+
// @ Defaults
46+
// ---------------------------------------------------
47+
const keys = [
48+
[1, 2, 3],
49+
[4, 5, 6],
50+
[7, 8, 9],
51+
["auth", 0, "delete"],
52+
];
4753

48-
// ---------------------------------------------------
49-
// @ Main View
50-
// ---------------------------------------------------
51-
return (
52-
<>
53-
{keys.map((list: any, index: number) => (
54-
// eslint-disable-next-line react/no-array-index-key
55-
<PinCodeRow rowReverse={rowReverse} key={`${index}-keypad-row`}>
56-
{list.map((item: string | number) => (
57-
<PinCodeKey
58-
key={`${item}-keypad-key`}
59-
item={item}
60-
textStyle={textStyle}
61-
backspaceIconFillColor={backspaceIconFillColor}
62-
backspaceIconStrokeColor={backspaceIconStrokeColor}
63-
bioMetricFillColor={bioMetricFillColor}
64-
backspaceIconHeight={backspaceIconHeight}
65-
backspaceIconWidth={backspaceIconWidth}
66-
bioMetricIconHeight={bioMetricIconHeight}
67-
bioMetricIconWidth={bioMetricIconWidth}
68-
backspaceIcon={backspaceIcon}
69-
bioMetricAuthIcon={bioMetricAuthIcon}
70-
onKeyPress={onKeyPress}
71-
onBioAuthPress={onBioAuthPress}
72-
disable={disable}
73-
/>
74-
))}
75-
</PinCodeRow>
76-
))}
77-
</>
78-
);
54+
// ---------------------------------------------------
55+
// @ Main View
56+
// ---------------------------------------------------
57+
return (
58+
<>
59+
{keys.map((list: any, index: number) => (
60+
// eslint-disable-next-line react/no-array-index-key
61+
<PinCodeRow
62+
rowReverse={rowReverse}
63+
key={`${index}-keypad-row`}
64+
style={rowStyle}
65+
>
66+
{list.map((item: string | number) => (
67+
<PinCodeKey
68+
key={`${item}-keypad-key`}
69+
item={item}
70+
textStyle={textStyle}
71+
backspaceIconFillColor={backspaceIconFillColor}
72+
backspaceIconStrokeColor={backspaceIconStrokeColor}
73+
bioMetricFillColor={bioMetricFillColor}
74+
backspaceIconHeight={backspaceIconHeight}
75+
backspaceIconWidth={backspaceIconWidth}
76+
bioMetricIconHeight={bioMetricIconHeight}
77+
bioMetricIconWidth={bioMetricIconWidth}
78+
backspaceIcon={backspaceIcon}
79+
bioMetricAuthIcon={bioMetricAuthIcon}
80+
onKeyPress={onKeyPress}
81+
onBioAuthPress={onBioAuthPress}
82+
disable={disable}
83+
animated={animated}
84+
animationProps={animationProps}
85+
/>
86+
))}
87+
</PinCodeRow>
88+
))}
89+
</>
90+
);
7991
};
8092

8193
export default Keypad;

0 commit comments

Comments
 (0)