Skip to content

Instantly share code, notes, and snippets.

@xmanemran
Created February 13, 2019 07:25
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 xmanemran/f80e89e5d25a97b6c96c665e201c1f3d to your computer and use it in GitHub Desktop.
Save xmanemran/f80e89e5d25a97b6c96c665e201c1f3d to your computer and use it in GitHub Desktop.
import * as React from 'react';
import {
StyleSheet,
TextInput,
View,
TouchableOpacity,
Keyboard,
Animated
} from 'react-native';
import * as PropTypes from 'prop-types';
import FontAwesome5Pro from 'react-native-vector-icons/FontAwesome5Pro';
import { translation, color } from '../config';
const DURATION = 200;
class SearchBar extends React.Component {
constructor(props) {
super(props);
const { onFocus, searchText } = props;
this.state = {
onFocus,
searchText
};
this.animationValue = new Animated.Value(0);
}
componentDidMount() {
Keyboard.addListener('keyboardDidHide', this.onKeyboardDidHide);
Keyboard.addListener('keyboardDidShow', this.onKeyboardDidShow);
}
componentWillUnmount() {
Keyboard.removeListener('keyboardDidHide', this.onKeyboardDidHide);
Keyboard.addListener('keyboardDidShow', this.onKeyboardDidShow);
}
callFocusAndAnimation(focusState) {
const { onFocus } = this.props;
this.animation();
if (onFocus) {
onFocus(focusState);
}
}
onKeyboardDidHide = () => {
this.setState({ onFocus: false }, () => this.callFocusAndAnimation(false));
};
onKeyboardDidShow = () => {
this.setState({ onFocus: true }, () => this.callFocusAndAnimation(true));
};
render() {
return (
<View style={styles.searchBar}>
{this.leftIcon()}
{this.searchContent()}
{this.rightIcon()}
</View>
);
}
searchContent() {
const { disable } = this.props;
const { searchText } = this.state;
return (
<TextInput
returnKeyType={'search'}
style={styles.textInput}
value={searchText}
editable={!disable}
placeholder={translation('search_something')}
onChangeText={this.onChangeTextHandle}
onSubmitEditing={this.onSubmit}
onFocus={this.onFocus}
/>
);
}
onChangeTextHandle = searchText => {
this.setState({ searchText });
};
animation = () => {
const { onFocus, searchText } = this.state;
const visibility = onFocus || searchText;
Animated.timing(this.animationValue, {
toValue: visibility ? 1 : 0.0001,
duration: DURATION,
useNativeDriver: true
}).start();
};
onSubmit = () => {
const { onSubmit } = this.props;
const { searchText } = this.state;
this.setState({ onFocus: false }, () => {
this.animation();
onSubmit(searchText);
});
};
onFocus = () => {
this.setState({ onFocus: true }, () => this.callFocusAndAnimation(true));
};
leftIcon() {
return (
<View style={styles.iconRoot}>
<FontAwesome5Pro name={'search'} size={24} style={styles.icon} />
</View>
);
}
rightIcon() {
return (
<Animated.View
style={[styles.iconRoot, { opacity: this.animationValue }]}
>
<TouchableOpacity onPress={this.resetSearch}>
<FontAwesome5Pro name={'times'} light size={28} style={styles.icon} />
</TouchableOpacity>
</Animated.View>
);
}
resetSearch = () => {
this.setState(
{
onFocus: false,
searchText: ''
},
this.postReset
);
};
postReset = () => {
const { onSubmit } = this.props;
console.log(this.state.searchText);
this.animation();
Keyboard.dismiss();
onSubmit(searchText);
};
}
SearchBar.defaultProps = {
onFocus: false,
searchText: ''
};
SearchBar.propTypes = {
onFocus: PropTypes.bool,
searchText: PropTypes.string,
onSubmit: PropTypes.func.isRequired
};
export default SearchBar;
const styles = StyleSheet.create({
searchBar: {
height: 70,
padding: 10,
alignItems: 'center',
backgroundColor: color.WHITE,
elevation: 0,
justifyContent: 'center',
flexDirection: 'row',
shadowColor: color.WHITE,
borderBottomColor: '#EEE',
borderBottomWidth: 1
},
iconRoot: {
height: 48,
width: 48,
justifyContent: 'center',
alignItems: 'center'
},
textInput: {
height: 48,
fontSize: 18,
fontWeight: '100',
color: color.BLACK,
flex: 1
},
icon: {
color: '#b7b7b7'
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment