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 Akira 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 | height: 48,
|
29 | animationDuration: 200,
|
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 style={containerStyle} onLayout={this._onLayout}>
|
49 | <TouchableWithoutFeedback onPress={this._focus}>
|
50 | <Animated.View style={{
|
51 | width,
|
52 | height: LABEL_HEIGHT,
|
53 | transform: [{
|
54 | translateY: focusedAnim.interpolate({
|
55 | inputRange: [0, 1],
|
56 | outputRange: [LABEL_HEIGHT + PADDING, 0],
|
57 | }),
|
58 | }],
|
59 | }}>
|
60 | <Text style={[styles.label, labelStyle]}>
|
61 | {label}
|
62 | </Text>
|
63 | </Animated.View>
|
64 | </TouchableWithoutFeedback>
|
65 | <TextInput
|
66 | ref="input"
|
67 | {...this.props}
|
68 | style={[styles.textInput, inputStyle, {
|
69 | width,
|
70 | height: inputHeight,
|
71 | }]}
|
72 | value={value}
|
73 | onBlur={this._onBlur}
|
74 | onChange={this._onChange}
|
75 | onFocus={this._onFocus}
|
76 | underlineColorAndroid={'transparent'}
|
77 | />
|
78 | {}
|
79 | <Animated.View
|
80 | style={{
|
81 | position: 'absolute',
|
82 | left: 0,
|
83 | bottom: 0,
|
84 | height: inputHeight,
|
85 | width: focusedAnim.interpolate({
|
86 | inputRange: [0, 1],
|
87 | outputRange: [6, 1],
|
88 | }),
|
89 | backgroundColor: borderColor,
|
90 | }}
|
91 | />
|
92 | {}
|
93 | <Animated.View
|
94 | style={{
|
95 | position: 'absolute',
|
96 | top: LABEL_HEIGHT,
|
97 | width,
|
98 | height: focusedAnim.interpolate({
|
99 | inputRange: [0, 1],
|
100 | outputRange: [6, 1],
|
101 | }),
|
102 | backgroundColor: borderColor,
|
103 | }}
|
104 | />
|
105 | {}
|
106 | <Animated.View
|
107 | style={{
|
108 | position: 'absolute',
|
109 | right: 0,
|
110 | bottom: 0,
|
111 | height: inputHeight,
|
112 | width: focusedAnim.interpolate({
|
113 | inputRange: [0, 1],
|
114 | outputRange: [6, 1],
|
115 | }),
|
116 | backgroundColor: borderColor,
|
117 | }}
|
118 | />
|
119 | {}
|
120 | <Animated.View
|
121 | style={{
|
122 | position: 'absolute',
|
123 | bottom: 0,
|
124 | height: focusedAnim.interpolate({
|
125 | inputRange: [0, 1],
|
126 | outputRange: [6, 1],
|
127 | }),
|
128 | width,
|
129 | backgroundColor: borderColor,
|
130 | }}
|
131 | />
|
132 | </View>
|
133 | );
|
134 | }
|
135 | }
|
136 |
|
137 | const styles = StyleSheet.create({
|
138 | label: {
|
139 | backgroundColor: 'transparent',
|
140 | fontFamily: 'Arial',
|
141 | fontSize: 14,
|
142 | fontWeight: 'bold',
|
143 | color: '#cc6055',
|
144 | textAlign: 'center',
|
145 | },
|
146 | textInput: {
|
147 | paddingHorizontal: PADDING,
|
148 | padding: 0,
|
149 | color: 'black',
|
150 | fontSize: 18,
|
151 | textAlign: 'center',
|
152 | },
|
153 | });
|