UNPKG

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