Skip to content

Commit 39c56e1

Browse files
committed
new: Library is here and ready to test
1 parent 0e5d4bd commit 39c56e1

File tree

5 files changed

+201
-42
lines changed

5 files changed

+201
-42
lines changed

example/App.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*/
1010

1111
import React from "react";
12-
import { SafeAreaView } from "react-native";
12+
import { Alert, SafeAreaView } from "react-native";
1313
import InteractiveTextInput from "./lib/InteractiveTextInput";
1414

1515
const App = () => {
@@ -22,7 +22,13 @@ const App = () => {
2222
}}
2323
>
2424
<InteractiveTextInput mainColor="red" />
25-
<InteractiveTextInput placeholder="Password" secureTextEntry enableIcon />
25+
<InteractiveTextInput
26+
placeholder="Password"
27+
secureTextEntry
28+
enableIcon
29+
iconImageSource={require("./assets/visibility-button.png")}
30+
onIconPress={() => Alert.alert("hello", "hello")}
31+
/>
2632
<InteractiveTextInput />
2733
</SafeAreaView>
2834
);

example/lib/InteractiveTextInput.style.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import { ViewStyle, Dimensions, StyleSheet } from "react-native";
2-
import { ImageStyle } from "react-native-fast-image";
1+
import { ViewStyle, Dimensions, ImageStyle, StyleSheet } from "react-native";
32
const { width: ScreenWidth } = Dimensions.get("screen");
43

54
interface Style {
65
container: ViewStyle;
6+
iconContainerStyle: ViewStyle;
7+
iconImageStyle: ImageStyle;
78
}
89

910
export const _textInputStyle = (borderColor: any): ViewStyle => ({
@@ -23,4 +24,13 @@ export default StyleSheet.create<Style>({
2324
flexDirection: "row",
2425
alignItems: "center",
2526
},
27+
iconContainerStyle: {
28+
right: 16,
29+
position: "absolute",
30+
},
31+
iconImageStyle: {
32+
height: 20,
33+
width: 20,
34+
tintColor: "#b5b9bb",
35+
},
2636
});

example/lib/InteractiveTextInput.tsx

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import {
99
TouchableOpacity,
1010
View,
1111
TextStyle,
12+
ImageStyle,
13+
ImageSourcePropType,
1214
} from "react-native";
1315
/**
1416
* ? Local Imports
@@ -25,10 +27,16 @@ const ANIMATED_VALUE = 1;
2527

2628
type CustomStyleProp = StyleProp<ViewStyle> | Array<StyleProp<ViewStyle>>;
2729
type CustomTextStyleProp = StyleProp<TextStyle> | Array<StyleProp<TextStyle>>;
30+
type CustomImageStyleProp =
31+
| StyleProp<ImageStyle>
32+
| Array<StyleProp<ImageStyle>>;
2833

2934
interface IInteractiveTextInputProps extends TextInputProps {
3035
style?: CustomStyleProp;
3136
textInputStyle?: CustomTextStyleProp;
37+
iconContainerStyle?: CustomStyleProp;
38+
iconImageStyle?: CustomImageStyleProp;
39+
iconImageSource?: ImageSourcePropType;
3240
ImageComponent?: any;
3341
IconComponent?: any;
3442
enableIcon?: boolean;
@@ -37,6 +45,7 @@ interface IInteractiveTextInputProps extends TextInputProps {
3745
animatedPlaceholderTextColor?: string;
3846
onFocus?: () => void;
3947
onBlur?: () => void;
48+
onIconPress?: () => void;
4049
}
4150

4251
interface IState {}
@@ -76,26 +85,24 @@ export default class InteractiveTextInput extends React.Component<
7685
renderIcon = () => {
7786
const {
7887
enableIcon,
88+
iconImageStyle,
89+
iconContainerStyle,
90+
iconImageSource,
91+
onIconPress,
7992
ImageComponent = Image,
8093
IconComponent = TouchableOpacity,
8194
} = this.props;
8295

8396
return (
8497
enableIcon && (
8598
<IconComponent
86-
style={{
87-
right: 16,
88-
position: "absolute",
89-
}}
99+
style={[styles.iconContainerStyle, iconContainerStyle]}
100+
onPress={onIconPress}
90101
>
91102
<ImageComponent
92103
resizeMode="contain"
93-
source={require("../assets/visibility-button.png")}
94-
style={{
95-
height: 20,
96-
width: 20,
97-
tintColor: "#b5b9bb",
98-
}}
104+
source={iconImageSource}
105+
style={[styles.iconImageStyle, iconImageStyle]}
99106
/>
100107
</IconComponent>
101108
)

lib/InteractiveTextInput.style.ts

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,36 @@
1-
import { ViewStyle, TextStyle, StyleSheet } from "react-native";
2-
import { ImageStyle } from "react-native-fast-image";
1+
import { ViewStyle, Dimensions, ImageStyle, StyleSheet } from "react-native";
2+
const { width: ScreenWidth } = Dimensions.get("screen");
33

44
interface Style {
55
container: ViewStyle;
6+
iconContainerStyle: ViewStyle;
7+
iconImageStyle: ImageStyle;
68
}
79

10+
export const _textInputStyle = (borderColor: any): ViewStyle => ({
11+
height: 50,
12+
width: ScreenWidth * 0.9,
13+
borderWidth: 1,
14+
paddingLeft: 16,
15+
borderRadius: 8,
16+
paddingRight: 16,
17+
borderColor: borderColor,
18+
justifyContent: "center",
19+
backgroundColor: "#eceef5",
20+
});
21+
822
export default StyleSheet.create<Style>({
9-
container: {},
23+
container: {
24+
flexDirection: "row",
25+
alignItems: "center",
26+
},
27+
iconContainerStyle: {
28+
right: 16,
29+
position: "absolute",
30+
},
31+
iconImageStyle: {
32+
height: 20,
33+
width: 20,
34+
tintColor: "#b5b9bb",
35+
},
1036
});

lib/InteractiveTextInput.tsx

Lines changed: 135 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,152 @@
1-
import React from "react";
1+
import * as React from "react";
22
import {
3-
View,
4-
Dimensions,
53
StyleProp,
64
TextInput,
75
TextInputProps,
86
ViewStyle,
7+
Animated,
8+
Image,
9+
TouchableOpacity,
10+
View,
11+
TextStyle,
12+
ImageStyle,
13+
ImageSourcePropType,
914
} from "react-native";
1015
/**
1116
* ? Local Imports
1217
*/
13-
import styles from "./InteractiveTextInput.style";
18+
import styles, { _textInputStyle } from "./InteractiveTextInput.style";
1419

15-
const { width: ScreenWidth, height: ScreenHeight } = Dimensions.get("screen");
20+
const AnimatedTextInput = Animated.createAnimatedComponent(TextInput);
21+
22+
const MAIN_COLOR = "#008FEB";
23+
const ORIGINAL_COLOR = "transparent";
24+
const PLACEHOLDER_COLOR = "#757575";
25+
const ORIGINAL_VALUE = 0;
26+
const ANIMATED_VALUE = 1;
1627

1728
type CustomStyleProp = StyleProp<ViewStyle> | Array<StyleProp<ViewStyle>>;
29+
type CustomTextStyleProp = StyleProp<TextStyle> | Array<StyleProp<TextStyle>>;
30+
type CustomImageStyleProp =
31+
| StyleProp<ImageStyle>
32+
| Array<StyleProp<ImageStyle>>;
1833

1934
interface IInteractiveTextInputProps extends TextInputProps {
2035
style?: CustomStyleProp;
36+
textInputStyle?: CustomTextStyleProp;
37+
iconContainerStyle?: CustomStyleProp;
38+
iconImageStyle?: CustomImageStyleProp;
39+
iconImageSource?: ImageSourcePropType;
40+
ImageComponent?: any;
41+
IconComponent?: any;
42+
enableIcon?: boolean;
43+
mainColor?: string;
44+
originalColor?: string;
45+
animatedPlaceholderTextColor?: string;
46+
onFocus?: () => void;
47+
onBlur?: () => void;
48+
onIconPress?: () => void;
2149
}
2250

23-
const InteractiveTextInput: React.FC<IInteractiveTextInputProps> = ({
24-
style,
25-
}) => {
26-
return (
27-
<TextInput
28-
style={{
29-
height: 50,
30-
width: ScreenWidth * 0.9,
31-
backgroundColor: "#f5f6f8",
32-
paddingLeft: 8,
33-
paddingRight: 8,
34-
borderRadius: 8,
35-
justifyContent: "center",
36-
}}
37-
placeholder="Email"
38-
/>
39-
);
40-
};
41-
42-
export default InteractiveTextInput;
51+
interface IState {}
52+
53+
export default class InteractiveTextInput extends React.Component<
54+
IInteractiveTextInputProps,
55+
IState
56+
> {
57+
interpolatedColor: Animated.Value;
58+
59+
constructor(props: IInteractiveTextInputProps) {
60+
super(props);
61+
this.interpolatedColor = new Animated.Value(ORIGINAL_VALUE);
62+
this.state = {};
63+
}
64+
65+
showOriginColor = () => {
66+
Animated.timing(this.interpolatedColor, {
67+
duration: 350,
68+
toValue: ORIGINAL_VALUE,
69+
useNativeDriver: false,
70+
}).start();
71+
};
72+
73+
showFocusColor = () => {
74+
Animated.timing(this.interpolatedColor, {
75+
duration: 450,
76+
toValue: ANIMATED_VALUE,
77+
useNativeDriver: false,
78+
}).start();
79+
};
80+
81+
/* -------------------------------------------------------------------------- */
82+
/* Render Methods */
83+
/* -------------------------------------------------------------------------- */
84+
85+
renderIcon = () => {
86+
const {
87+
enableIcon,
88+
iconImageStyle,
89+
iconContainerStyle,
90+
iconImageSource,
91+
onIconPress,
92+
ImageComponent = Image,
93+
IconComponent = TouchableOpacity,
94+
} = this.props;
95+
96+
return (
97+
enableIcon && (
98+
<IconComponent
99+
style={[styles.iconContainerStyle, iconContainerStyle]}
100+
onPress={onIconPress}
101+
>
102+
<ImageComponent
103+
resizeMode="contain"
104+
source={iconImageSource}
105+
style={[styles.iconImageStyle, iconImageStyle]}
106+
/>
107+
</IconComponent>
108+
)
109+
);
110+
};
111+
112+
renderAnimatedTextInput = () => {
113+
const mainColor = this.props.mainColor || MAIN_COLOR;
114+
const originalColor = this.props.originalColor || ORIGINAL_COLOR;
115+
const animatedPlaceholderTextColor =
116+
this.props.animatedPlaceholderTextColor || PLACEHOLDER_COLOR;
117+
118+
let borderColor = this.interpolatedColor.interpolate({
119+
inputRange: [ORIGINAL_VALUE, ANIMATED_VALUE],
120+
outputRange: [originalColor, mainColor],
121+
});
122+
let placeholderTextColor = this.interpolatedColor.interpolate({
123+
inputRange: [ORIGINAL_VALUE, ANIMATED_VALUE],
124+
outputRange: [animatedPlaceholderTextColor, mainColor],
125+
});
126+
return (
127+
<AnimatedTextInput
128+
placeholderTextColor={placeholderTextColor}
129+
placeholder="Email"
130+
{...this.props}
131+
style={[_textInputStyle(borderColor), this.props.textInputStyle]}
132+
onFocus={() => {
133+
this.showFocusColor();
134+
this.props.onFocus && this.props.onFocus();
135+
}}
136+
onBlur={() => {
137+
this.showOriginColor();
138+
this.props.onBlur && this.props.onBlur();
139+
}}
140+
/>
141+
);
142+
};
143+
144+
render() {
145+
return (
146+
<View style={styles.container}>
147+
{this.renderAnimatedTextInput()}
148+
{this.renderIcon()}
149+
</View>
150+
);
151+
}
152+
}

0 commit comments

Comments
 (0)