UNPKG

4.51 kBJavaScriptView Raw
1import React from 'react';
2import PropTypes from 'prop-types';
3import {
4 Animated,
5 TextInput,
6 TouchableWithoutFeedback,
7 View,
8 StyleSheet,
9} from 'react-native';
10
11import BaseInput from './BaseInput';
12
13export default class Sae extends BaseInput {
14 static propTypes = {
15 height: PropTypes.number,
16 /*
17 * active border height
18 */
19 borderHeight: PropTypes.number,
20 /*
21 * This is the icon component you are importing from react-native-vector-icons.
22 * import FontAwesomeIcon from 'react-native-vector-icons/FontAwesome';
23 * iconClass={FontAwesomeIcon}
24 */
25 iconClass: PropTypes.func.isRequired,
26 /*
27 * Passed to react-native-vector-icons library as name prop
28 */
29 iconName: PropTypes.string,
30 /*
31 * Passed to react-native-vector-icons library as color prop.
32 * This is also used as border color.
33 */
34 iconColor: PropTypes.string,
35 inputPadding: PropTypes.number,
36 labelHeight: PropTypes.number,
37 };
38
39 static defaultProps = {
40 iconColor: 'white',
41 height: 48,
42 inputPadding: 16,
43 labelHeight: 24,
44 borderHeight: 2,
45 animationDuration: 300,
46 iconName: 'pencil',
47 };
48
49 render() {
50 const {
51 iconClass,
52 iconColor,
53 iconName,
54 label,
55 style: containerStyle,
56 height: inputHeight,
57 inputPadding,
58 labelHeight,
59 borderHeight,
60 inputStyle,
61 labelStyle,
62 } = this.props;
63 const { width, focusedAnim, value } = this.state;
64 const AnimatedIcon = Animated.createAnimatedComponent(iconClass);
65
66 return (
67 <View
68 style={[
69 styles.container,
70 containerStyle,
71 {
72 height: inputHeight + inputPadding,
73 },
74 ]}
75 onLayout={this._onLayout}
76 >
77 <TouchableWithoutFeedback onPress={this.focus}>
78 <Animated.View
79 style={{
80 position: 'absolute',
81 bottom: focusedAnim.interpolate({
82 inputRange: [0, 1],
83 outputRange: [0, labelHeight + inputPadding],
84 }),
85 }}
86 >
87 <Animated.Text
88 style={[
89 styles.label,
90 labelStyle,
91 {
92 fontSize: focusedAnim.interpolate({
93 inputRange: [0, 1],
94 outputRange: [18, 12],
95 }),
96 },
97 ]}
98 >
99 {label}
100 </Animated.Text>
101 </Animated.View>
102 </TouchableWithoutFeedback>
103 <TextInput
104 ref={this.input}
105 {...this.props}
106 style={[
107 styles.textInput,
108 inputStyle,
109 {
110 width,
111 height: inputHeight,
112 paddingTop: inputPadding / 2,
113 },
114 ]}
115 value={value}
116 onBlur={this._onBlur}
117 onChange={this._onChange}
118 onFocus={this._onFocus}
119 underlineColorAndroid={'transparent'}
120 />
121 <TouchableWithoutFeedback onPress={this.focus}>
122 <AnimatedIcon
123 name={iconName}
124 color={iconColor}
125 style={{
126 position: 'absolute',
127 bottom: 0,
128 right: focusedAnim.interpolate({
129 inputRange: [0, 1],
130 outputRange: [0, width + inputPadding],
131 }),
132 transform: [
133 {
134 rotate: focusedAnim.interpolate({
135 inputRange: [0, 1],
136 outputRange: ['0deg', '-90deg'],
137 }),
138 },
139 ],
140 fontSize: 20,
141 backgroundColor: 'transparent',
142 }}
143 />
144 </TouchableWithoutFeedback>
145 {/* bottom border */}
146 <Animated.View
147 style={{
148 position: 'absolute',
149 bottom: 0,
150 right: 0,
151 height: borderHeight,
152 width: focusedAnim.interpolate({
153 inputRange: [0, 1],
154 outputRange: [0, width],
155 }),
156 backgroundColor: iconColor,
157 }}
158 />
159 </View>
160 );
161 }
162}
163
164const styles = StyleSheet.create({
165 container: {
166 overflow: 'hidden',
167 },
168 label: {
169 backgroundColor: 'transparent',
170 fontWeight: 'bold',
171 color: '#7771ab',
172 },
173 textInput: {
174 position: 'absolute',
175 bottom: 0,
176 left: 0,
177 paddingLeft: 0,
178 color: 'white',
179 fontSize: 18,
180 },
181});