Skip to content

Instantly share code, notes, and snippets.

@betiol
Created May 27, 2017 04:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save betiol/f5251ca90245c97055d8a1c19778e476 to your computer and use it in GitHub Desktop.
Save betiol/f5251ca90245c97055d8a1c19778e476 to your computer and use it in GitHub Desktop.
Lib Float Label
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