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