UNPKG

4.11 kBJavaScriptView Raw
1import React, { PropTypes, Component } from 'react';
2import {
3 Animated,
4 Text,
5 TextInput,
6 TouchableWithoutFeedback,
7 View,
8 StyleSheet,
9} from 'react-native';
10
11import BaseInput from './BaseInput';
12
13const PADDING = 16;
14const ICON_WIDTH = 40;
15
16export default class Fumi extends BaseInput {
17
18 static propTypes = {
19 /*
20 * This is the icon component you are importing from react-native-vector-icons.
21 * import FontAwesomeIcon from 'react-native-vector-icons/FontAwesome';
22 * iconClass={FontAwesomeIcon}
23 */
24 iconClass: PropTypes.func.isRequired,
25 /*
26 * Passed to react-native-vector-icons library as name prop
27 */
28 iconName: PropTypes.string.isRequired,
29 /*
30 * Passed to react-native-vector-icons library as color prop.
31 * Also used as textInput color.
32 */
33 iconColor: PropTypes.string,
34 height: PropTypes.number,
35 };
36
37 static defaultProps = {
38 height: 48,
39 iconColor: '#00aeef',
40 animationDuration: 300,
41 };
42
43 render() {
44 const {
45 iconClass,
46 iconColor,
47 iconName,
48 label,
49 style: containerStyle,
50 inputStyle,
51 height: inputHeight,
52 labelStyle,
53 } = this.props;
54 const { focusedAnim, value } = this.state;
55 const AnimatedIcon = Animated.createAnimatedComponent(iconClass);
56 const ANIM_PATH = PADDING + inputHeight;
57 const NEGATIVE_ANIM_PATH = ANIM_PATH * -1;
58
59 return (
60 <View style={[containerStyle, styles.container]} onLayout={this._onLayout}>
61 <TouchableWithoutFeedback onPress={this._focus}>
62 <AnimatedIcon
63 name={iconName}
64 color={iconColor}
65 size={20}
66 style={{
67 position: 'absolute',
68 left: PADDING,
69 bottom: focusedAnim.interpolate({
70 inputRange: [0, 0.5, 0.51, 0.7, 1],
71 outputRange: [24, ANIM_PATH, NEGATIVE_ANIM_PATH, NEGATIVE_ANIM_PATH, 24],
72 }),
73 color: focusedAnim.interpolate({
74 inputRange: [0, 0.5, 1],
75 outputRange: ['#a3a3a3', iconColor, iconColor],
76 }),
77 }}
78 />
79 </TouchableWithoutFeedback>
80 <View
81 style={[styles.separator, {
82 height: inputHeight,
83 left: ICON_WIDTH + 8,
84 }]}
85 />
86 <TouchableWithoutFeedback onPress={this._focus}>
87 <Animated.View style={{
88 position: 'absolute',
89 left: ICON_WIDTH + PADDING,
90 height: inputHeight,
91 top: focusedAnim.interpolate({
92 inputRange: [0, 0.5, 0.51, 0.7, 1],
93 outputRange: [24, ANIM_PATH, NEGATIVE_ANIM_PATH, NEGATIVE_ANIM_PATH, PADDING / 2],
94 }),
95 }}>
96 <Animated.Text style={[styles.label, labelStyle, {
97 fontSize: focusedAnim.interpolate({
98 inputRange: [0, 0.7, 0.71, 1],
99 outputRange: [16, 16, 12, 12],
100 }),
101 color: focusedAnim.interpolate({
102 inputRange: [0, 0.7],
103 outputRange: ['#696969', '#a3a3a3'],
104 }),
105 }]}>
106 {label}
107 </Animated.Text>
108 </Animated.View>
109 </TouchableWithoutFeedback>
110 <TextInput
111 ref="input"
112 {...this.props}
113 style={[styles.textInput, inputStyle, {
114 marginLeft: ICON_WIDTH + PADDING,
115 color: iconColor,
116 }]}
117 value={value}
118 onBlur={this._onBlur}
119 onFocus={this._onFocus}
120 onChange={this._onChange}
121 underlineColorAndroid={'transparent'}
122 />
123 </View>
124 );
125 }
126}
127
128const styles = StyleSheet.create({
129 container: {
130 overflow: 'hidden',
131 paddingTop: 16,
132 backgroundColor: 'white',
133 },
134 label: {
135 fontSize: 18,
136 fontFamily: 'Arial',
137 fontWeight: 'bold',
138 },
139 textInput: {
140 flex: 1,
141 color: 'black',
142 fontSize: 18,
143 padding: 7,
144 paddingLeft: 0,
145 },
146 separator: {
147 position: 'absolute',
148 width: 1,
149 backgroundColor: '#f0f0f0',
150 marginTop: -8,
151 },
152});