UNPKG

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