UNPKG

4.24 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 Madoka extends BaseInput {
14 static propTypes = {
15 /*
16 * this is applied as active border and label color
17 */
18 borderColor: PropTypes.string,
19 labelHeight: PropTypes.number,
20 inputPadding: PropTypes.number,
21 height: PropTypes.number,
22 };
23
24 static defaultProps = {
25 borderColor: '#7A7593',
26 animationDuration: 250,
27 labelHeight: 24,
28 inputPadding: 16,
29 height: 48,
30 };
31
32 render() {
33 const {
34 label,
35 style: containerStyle,
36 height: inputHeight,
37 inputPadding,
38 labelHeight,
39 inputStyle,
40 labelStyle,
41 borderColor,
42 } = this.props;
43 const {
44 width,
45 focusedAnim,
46 value,
47 } = this.state;
48
49 return (
50 <View
51 style={[containerStyle, { height: inputHeight + labelHeight + 8 }]}
52 onLayout={this._onLayout}
53 >
54 <View
55 style={[styles.inputContainer, { borderBottomColor: borderColor }]}
56 >
57 <TextInput
58 ref={this.input}
59 {...this.props}
60 style={[
61 styles.textInput,
62 inputStyle,
63 {
64 width,
65 height: inputHeight,
66 paddingHorizontal: inputPadding,
67 },
68 ]}
69 value={value}
70 onBlur={this._onBlur}
71 onChange={this._onChange}
72 onFocus={this._onFocus}
73 underlineColorAndroid={'transparent'}
74 />
75 {/* right border */}
76 <Animated.View
77 style={{
78 position: 'absolute',
79 right: 0,
80 bottom: 0,
81 width: 2,
82 height: focusedAnim.interpolate({
83 inputRange: [0, 0.2, 1],
84 outputRange: [0, inputHeight, inputHeight],
85 }),
86 backgroundColor: borderColor,
87 }}
88 />
89 {/* top border */}
90 <Animated.View
91 style={{
92 position: 'absolute',
93 right: 0,
94 top: 0,
95 height: 2,
96 width: focusedAnim.interpolate({
97 inputRange: [0, 0.2, 0.8, 1],
98 outputRange: [0, 0, width, width],
99 }),
100 backgroundColor: borderColor,
101 }}
102 />
103 {/* left border */}
104 <Animated.View
105 style={{
106 position: 'absolute',
107 left: 0,
108 top: 0,
109 width: 2,
110 height: focusedAnim.interpolate({
111 inputRange: [0, 0.8, 1],
112 outputRange: [0, 0, inputHeight],
113 }),
114 backgroundColor: borderColor,
115 }}
116 />
117 </View>
118 <TouchableWithoutFeedback onPress={this.focus}>
119 <Animated.View
120 style={[
121 styles.labelContainer,
122 {
123 width,
124 height: labelHeight,
125 bottom: focusedAnim.interpolate({
126 inputRange: [0, 1],
127 outputRange: [labelHeight + inputPadding, 0],
128 }),
129 left: inputPadding,
130 },
131 ]}
132 >
133 <Animated.Text
134 style={[
135 styles.label,
136 labelStyle,
137 {
138 fontSize: focusedAnim.interpolate({
139 inputRange: [0, 1],
140 outputRange: [18, 14],
141 }),
142 },
143 ]}
144 >
145 {label}
146 </Animated.Text>
147 </Animated.View>
148 </TouchableWithoutFeedback>
149 </View>
150 );
151 }
152}
153
154const styles = StyleSheet.create({
155 inputContainer: {
156 borderBottomWidth: 2,
157 },
158 labelContainer: {
159 position: 'absolute',
160 },
161 label: {
162 backgroundColor: 'transparent',
163 fontWeight: 'bold',
164 color: '#6a7989',
165 },
166 textInput: {
167 paddingVertical: 0,
168 color: 'black',
169 fontSize: 18,
170 fontWeight: 'bold',
171 },
172});