Created
May 27, 2017 04:53
-
-
Save betiol/f5251ca90245c97055d8a1c19778e476 to your computer and use it in GitHub Desktop.
Lib Float Label
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react'; | |
import { | |
StyleSheet, | |
Text, | |
View, | |
TextInput, | |
Animated, | |
Platform | |
} from 'react-native' | |
class FloatingLabel extends Component { | |
constructor(props) { | |
super(props); | |
let initialPadding = 1; | |
let initialOpacity = 0; | |
if (this.props.visible) { | |
initialPadding = 1; | |
initialOpacity = 1; | |
} | |
this.state = { | |
paddingAnim: new Animated.Value(initialPadding), | |
opacityAnim: new Animated.Value(initialOpacity) | |
} | |
} | |
componentWillReceiveProps(newProps) { | |
Animated.timing(this.state.paddingAnim, { | |
toValue: newProps.visible ? 5 : 9, | |
duration: 230 | |
}).start(); | |
return Animated.timing(this.state.opacityAnim, { | |
toValue: newProps.visible ? 1 : 0, | |
duration: 230 | |
}).start(); | |
} | |
render() { | |
return ( | |
<Animated.View style={[styles.floatingLabel, { paddingTop: this.state.paddingAnim, opacity: this.state.opacityAnim }]}> | |
{this.props.children} | |
</Animated.View> | |
); | |
} | |
} | |
class TextFieldHolder extends Component { | |
constructor(props) { | |
super(props); | |
this.state = { | |
marginAnim: new Animated.Value(this.props.withValue ? 10 : 0) | |
} | |
} | |
componentWillReceiveProps(newProps) { | |
return Animated.timing(this.state.marginAnim, { | |
toValue: newProps.withValue ? 10 : 0, | |
duration: 230 | |
}).start(); | |
} | |
render() { | |
return ( | |
<Animated.View style={{ marginTop: this.state.marginAnim }}> | |
{this.props.children} | |
</Animated.View> | |
); | |
} | |
} | |
class FloatLabelTextField extends Component { | |
constructor(props) { | |
super(props); | |
this.state = { | |
focused: false, | |
text: this.props.value | |
}; | |
} | |
componentWillReceiveProps(newProps) { | |
if (newProps.hasOwnProperty('value') && newProps.value !== this.state.text) { | |
this.setState({ text: newProps.value }) | |
} | |
} | |
withBorder() { | |
if (!this.props.noBorder) { | |
return styles.withBorder; | |
} | |
} | |
render() { | |
return ( | |
<View style={styles.container}> | |
<View style={styles.viewContainer}> | |
<View style={styles.paddingView} /> | |
<View style={[styles.fieldContainer, this.withBorder()]}> | |
<FloatingLabel visible={this.state.text}> | |
<Text style={[styles.fieldLabel, this.labelStyle()]}>{this.placeholderValue()}</Text> | |
</FloatingLabel> | |
<TextFieldHolder withValue={this.state.text}> | |
<TextInput {...this.props} | |
ref='input' | |
placeholderTextColor={"rgba(236,240,241,0.25)"} | |
underlineColorAndroid="transparent" | |
style={[styles.valueText, styles.input]} | |
defaultValue={this.props.defaultValue} | |
value={this.state.text} | |
maxLength={this.props.maxLength} | |
onFocus={() => this.setFocus()} | |
onBlur={() => this.unsetFocus()} | |
onChangeText={(value) => this.setText(value)} | |
/> | |
</TextFieldHolder> | |
</View> | |
</View> | |
</View> | |
); | |
} | |
inputRef() { | |
return this.refs.input; | |
} | |
focus() { | |
this.inputRef().focus(); | |
} | |
blur() { | |
this.inputRef().blur(); | |
} | |
isFocused() { | |
return this.inputRef().isFocused(); | |
} | |
clear() { | |
this.inputRef().clear(); | |
} | |
setFocus() { | |
this.setState({ | |
focused: true | |
}); | |
try { | |
return this.props.onFocus(); | |
} catch (_error) { } | |
} | |
unsetFocus() { | |
this.setState({ | |
focused: false | |
}); | |
try { | |
return this.props.onBlur(); | |
} catch (_error) { } | |
} | |
labelStyle() { | |
if (this.state.focused) { | |
return styles.focused; | |
} | |
} | |
placeholderValue() { | |
if (this.state.text) { | |
return this.props.placeholder; | |
} | |
} | |
setText(value) { | |
this.setState({ | |
text: value | |
}); | |
try { | |
return this.props.onChangeTextValue(value); | |
} catch (_error) { } | |
} | |
} | |
const styles = StyleSheet.create({ | |
container: { | |
flex: 1, | |
backgroundColor: '#0277bd', | |
justifyContent: 'center', | |
}, | |
viewContainer: { | |
flexDirection: 'row', | |
}, | |
paddingView: { | |
width: 8, | |
}, | |
floatingLabel: { | |
position: 'absolute', | |
top: 0, | |
left: 0, | |
}, | |
fieldLabel: { | |
height: 15, | |
fontSize: 10, | |
paddingTop: 3, | |
color: '#bdc3c7' | |
}, | |
fieldContainer: { | |
flex: 1, | |
justifyContent: 'center', | |
position: 'relative' | |
}, | |
withBorder: { | |
borderBottomWidth: 1 / 2, | |
borderColor: '#0277bd', | |
}, | |
valueText: { | |
height: (Platform.OS == 'ios' ? 20 : 60), | |
fontSize: 14, | |
color: '#fff' | |
}, | |
focused: { | |
color: "rgba(236,240,241,0.25)", | |
} | |
}); | |
export default FloatLabelTextField; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment