Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
MaterialTextInput
// @flow
import React from 'react';
import { View, TextInput, Animated } from 'react-native';
type Props = {
placeholder: string,
focusColor: string,
unfocusColor: string,
secureTextEntry?: boolean,
textColor: string,
fontSize: number,
}
type State = {
animated: any,
text: string,
formHeight: number,
}
class MaterialTextInput extends React.Component<void, Props, State> {
state: State = {
animated: new Animated.Value(0),
text: '',
formHeight: 0,
}
startFocusInAnimation() {
Animated.timing(this.state.animated, {
toValue: 1,
duration: 200,
}).start();
}
startFocusOutAnimation() {
Animated.timing(this.state.animated, {
toValue: 0,
duration: 200,
}).start();
}
render() {
const existText = !!this.state.text;
return (
<View style={{ paddingVertical: 8 }}>
<View style={{ height: 20 }} />
<View style={{ justifyContent: 'center' }}>
<Animated.Text
style={{
position: 'absolute',
left: 0,
lineHeight: this.props.fontSize + 4,
margin: 0,
bottom: this.state.animated.interpolate({ inputRange: [0, 1], outputRange: [existText ? this.state.formHeight : 8, this.state.formHeight] }),
color: this.state.animated.interpolate({ inputRange: [0, 1], outputRange: [this.props.unfocusColor, this.props.focusColor] }),
backgroundColor: '#00000000',
fontSize: this.state.animated.interpolate({ inputRange: [0, 1], outputRange: [existText ? 12 : this.props.fontSize, 12] }),
}}
>{this.props.placeholder}</Animated.Text>
<TextInput
onLayout={({ nativeEvent: { layout: { height } } }) => this.setState({ formHeight: height })}
onChangeText={text => this.setState({ text })}
onEndEditing={() => this.startFocusOutAnimation()}
onFocus={() => this.startFocusInAnimation()}
underlineColorAndroid="#00000000"
selectionColor={this.props.focusColor}
secureTextEntry={this.props.secureTextEntry}
style={{
backgroundColor: '#00000000',
paddingTop: 8,
paddingBottom: 6,
paddingHorizontal: 0,
width: '100%',
fontSize: this.props.fontSize,
color: this.props.textColor,
}}
/>
</View>
<Animated.View
style={{
height: 2,
backgroundColor: this.state.animated.interpolate({ inputRange: [0, 1], outputRange: [this.props.unfocusColor, this.props.focusColor] }),
width: '100%',
opacity: this.state.animated.interpolate({ inputRange: [0, 1], outputRange: [0.7, 1] }),
transform: [
{ scaleY: this.state.animated.interpolate({ inputRange: [0, 1], outputRange: [0.6, 1] }) },
],
}}
/>
</View >
);
}
}
export default MaterialTextInput;
@ryohlan

This comment has been minimized.

Copy link
Owner Author

commented Sep 21, 2017

iOS
https://gyazo.com/7bf7d4237f42dd5630fd1af83e062c6d

Android
https://gyazo.com/30cae3cc29b82110079f65e1a1d71413

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.