Skip to content

Commit 0e5d4bd

Browse files
committed
new: Animated colors are customizable now
1 parent aa268ff commit 0e5d4bd

File tree

4 files changed

+120
-28
lines changed

4 files changed

+120
-28
lines changed

example/.eslintrc.js

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,77 @@
11
module.exports = {
22
root: true,
3-
extends: '@react-native-community',
3+
extends: "@react-native-community",
4+
parser: "@typescript-eslint/parser",
5+
plugins: ["import", "eslint-plugin-import", "@typescript-eslint"],
6+
settings: {
7+
"import/resolver": {
8+
node: {
9+
extensions: [
10+
".js",
11+
".jsx",
12+
".ts",
13+
".tsx",
14+
".d.ts",
15+
".android.js",
16+
".android.jsx",
17+
".android.ts",
18+
".android.tsx",
19+
".ios.js",
20+
".ios.jsx",
21+
".ios.ts",
22+
".ios.tsx",
23+
".web.js",
24+
".web.jsx",
25+
".web.ts",
26+
".web.tsx",
27+
],
28+
},
29+
},
30+
},
31+
rules: {
32+
quotes: [
33+
"error",
34+
"double",
35+
{
36+
avoidEscape: true,
37+
},
38+
],
39+
"max-len": ["error", 120],
40+
"@typescript-eslint/ban-ts-comment": 2,
41+
"@typescript-eslint/no-explicit-any": 2,
42+
"@typescript-eslint/explicit-module-boundary-types": 0,
43+
"react/jsx-filename-extension": ["error", { extensions: [".tsx"] }],
44+
"react-native/no-unused-styles": 2,
45+
"react-native/split-platform-components": 2,
46+
"react-native/no-inline-styles": 0,
47+
"react-native/no-color-literals": 0,
48+
"react-native/no-raw-text": 0,
49+
"import/no-extraneous-dependencies": 2,
50+
"import/extensions": ["error", "never", { svg: "always" }],
51+
"import/no-named-as-default-member": 2,
52+
"import/order": ["error", { "newlines-between": "always" }],
53+
"import/no-duplicates": 2,
54+
"import/no-useless-path-segments": 2,
55+
"import/no-cycle": 2,
56+
"import/prefer-default-export": 0,
57+
"import/no-anonymous-default-export": 0,
58+
"import/named": 0,
59+
"@typescript-eslint/no-empty-interface": 0,
60+
"import/namespace": 0,
61+
"import/default": 0,
62+
"import/no-named-as-default": 0,
63+
"import/no-unused-modules": 0,
64+
"import/no-deprecated": 0,
65+
"@typescript-eslint/indent": 0,
66+
"react-hooks/rules-of-hooks": 2,
67+
"react-hooks/exhaustive-deps": [
68+
"error",
69+
{ additionalHooks: "(useMemoOne)" },
70+
],
71+
"jest/no-identical-title": 2,
72+
"jest/valid-expect": 2,
73+
camelcase: 2,
74+
"prefer-destructuring": 2,
75+
"no-nested-ternary": 2,
76+
},
477
};

example/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const App = () => {
2121
justifyContent: "space-evenly",
2222
}}
2323
>
24-
<InteractiveTextInput />
24+
<InteractiveTextInput mainColor="red" />
2525
<InteractiveTextInput placeholder="Password" secureTextEntry enableIcon />
2626
<InteractiveTextInput />
2727
</SafeAreaView>
Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,26 @@
1-
import { ViewStyle, TextStyle, StyleSheet } from "react-native";
1+
import { ViewStyle, Dimensions, StyleSheet } from "react-native";
22
import { ImageStyle } from "react-native-fast-image";
3+
const { width: ScreenWidth } = Dimensions.get("screen");
34

45
interface Style {
56
container: ViewStyle;
67
}
78

9+
export const _textInputStyle = (borderColor: any): ViewStyle => ({
10+
height: 50,
11+
width: ScreenWidth * 0.9,
12+
borderWidth: 1,
13+
paddingLeft: 16,
14+
borderRadius: 8,
15+
paddingRight: 16,
16+
borderColor: borderColor,
17+
justifyContent: "center",
18+
backgroundColor: "#eceef5",
19+
});
20+
821
export default StyleSheet.create<Style>({
9-
container: {},
22+
container: {
23+
flexDirection: "row",
24+
alignItems: "center",
25+
},
1026
});

example/lib/InteractiveTextInput.tsx

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import * as React from "react";
22
import {
3-
Dimensions,
43
StyleProp,
54
TextInput,
65
TextInputProps,
@@ -9,28 +8,35 @@ import {
98
Image,
109
TouchableOpacity,
1110
View,
11+
TextStyle,
1212
} from "react-native";
1313
/**
1414
* ? Local Imports
1515
*/
16-
import styles from "./InteractiveTextInput.style";
16+
import styles, { _textInputStyle } from "./InteractiveTextInput.style";
1717

18-
const { width: ScreenWidth } = Dimensions.get("screen");
1918
const AnimatedTextInput = Animated.createAnimatedComponent(TextInput);
2019

21-
const SUCCESS_COLOR = "#008FEB";
20+
const MAIN_COLOR = "#008FEB";
2221
const ORIGINAL_COLOR = "transparent";
23-
const ORIGINAL_VALUE = 0;
24-
const SUCCESS_VALUE = 1;
2522
const PLACEHOLDER_COLOR = "#757575";
23+
const ORIGINAL_VALUE = 0;
24+
const ANIMATED_VALUE = 1;
2625

2726
type CustomStyleProp = StyleProp<ViewStyle> | Array<StyleProp<ViewStyle>>;
27+
type CustomTextStyleProp = StyleProp<TextStyle> | Array<StyleProp<TextStyle>>;
2828

2929
interface IInteractiveTextInputProps extends TextInputProps {
3030
style?: CustomStyleProp;
31+
textInputStyle?: CustomTextStyleProp;
3132
ImageComponent?: any;
3233
IconComponent?: any;
3334
enableIcon?: boolean;
35+
mainColor?: string;
36+
originalColor?: string;
37+
animatedPlaceholderTextColor?: string;
38+
onFocus?: () => void;
39+
onBlur?: () => void;
3440
}
3541

3642
interface IState {}
@@ -58,7 +64,7 @@ export default class InteractiveTextInput extends React.Component<
5864
showFocusColor = () => {
5965
Animated.timing(this.interpolatedColor, {
6066
duration: 450,
61-
toValue: SUCCESS_VALUE,
67+
toValue: ANIMATED_VALUE,
6268
useNativeDriver: false,
6369
}).start();
6470
};
@@ -97,43 +103,40 @@ export default class InteractiveTextInput extends React.Component<
97103
};
98104

99105
renderAnimatedTextInput = () => {
106+
const mainColor = this.props.mainColor || MAIN_COLOR;
107+
const originalColor = this.props.originalColor || ORIGINAL_COLOR;
108+
const animatedPlaceholderTextColor =
109+
this.props.animatedPlaceholderTextColor || PLACEHOLDER_COLOR;
110+
100111
let borderColor = this.interpolatedColor.interpolate({
101-
inputRange: [ORIGINAL_VALUE, SUCCESS_VALUE],
102-
outputRange: [ORIGINAL_COLOR, SUCCESS_COLOR],
112+
inputRange: [ORIGINAL_VALUE, ANIMATED_VALUE],
113+
outputRange: [originalColor, mainColor],
103114
});
104115
let placeholderTextColor = this.interpolatedColor.interpolate({
105-
inputRange: [ORIGINAL_VALUE, SUCCESS_VALUE],
106-
outputRange: [PLACEHOLDER_COLOR, SUCCESS_COLOR],
116+
inputRange: [ORIGINAL_VALUE, ANIMATED_VALUE],
117+
outputRange: [animatedPlaceholderTextColor, mainColor],
107118
});
108119
return (
109120
<AnimatedTextInput
110-
style={{
111-
height: 50,
112-
width: ScreenWidth * 0.9,
113-
backgroundColor: "#eceef5",
114-
paddingLeft: 16,
115-
paddingRight: 16,
116-
borderRadius: 8,
117-
justifyContent: "center",
118-
borderWidth: 1,
119-
borderColor: borderColor,
120-
}}
121121
placeholderTextColor={placeholderTextColor}
122122
placeholder="Email"
123+
{...this.props}
124+
style={[_textInputStyle(borderColor), this.props.textInputStyle]}
123125
onFocus={() => {
124126
this.showFocusColor();
127+
this.props.onFocus && this.props.onFocus();
125128
}}
126129
onBlur={() => {
127130
this.showOriginColor();
131+
this.props.onBlur && this.props.onBlur();
128132
}}
129-
{...this.props}
130133
/>
131134
);
132135
};
133136

134137
render() {
135138
return (
136-
<View style={{ flexDirection: "row", alignItems: "center" }}>
139+
<View style={styles.container}>
137140
{this.renderAnimatedTextInput()}
138141
{this.renderIcon()}
139142
</View>

0 commit comments

Comments
 (0)