Skip to content

Instantly share code, notes, and snippets.

@rohozhnikoff
Created November 14, 2017 17:11
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rohozhnikoff/b0e8868c7dfb440ffd43266688a05ad1 to your computer and use it in GitHub Desktop.
Save rohozhnikoff/b0e8868c7dfb440ffd43266688a05ad1 to your computer and use it in GitHub Desktop.
my autosuggest for react-native, api-compatible with react-autosuggest
import React, { Component } from "react";
import PropTypes from "prop-types";
import {
View,
Text,
TextInput,
TouchableOpacity,
ScrollView,
} from "react-native";
import { Modal } from "react-native";
import Styler from "@styler";
import _ from "lodash";
import Field from "../../components/Field";
import Btn from "../../components/Button";
import { ModalHeader } from "../Modal";
import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view";
const styles = Styler.create(({ $components }) => ({
scroll: {},
scroll__container: {
paddingHorizontal: 10,
},
suggestions: {
// flex: 1,
// alignSelf:'stretch',
// marginHorizontal: 20,
// minHeight: (40 + 80 + 2 + 3),
},
"suggestions-input-withscroll": {
borderTopLeftRadius: 3,
borderTopRightRadius: 3,
borderBottomLeftRadius: 0,
borderBottomRightRadius: 0,
},
"suggestions-input": {
borderWidth: 1,
// borderColor: 'red',
paddingHorizontal: 15,
borderTopLeftRadius: 3,
borderTopRightRadius: 3,
borderBottomLeftRadius: 3,
borderBottomRightRadius: 3,
marginTop: 5,
backgroundColor: "#fff",
},
"suggestions-scroll": {
// position: 'absolute',
// top: 40 + 7 + 3,
// left: 0, right: 0,
// overflow: 'hidden',
},
suggest: {
// borderColor: '#c3c3c3',
// borderWidth: 1,
// borderTopWidth: 0,
// padding: 5,
// backgroundColor: '#fff',
borderColor: "#d7dae0",
borderBottomWidth: 1,
// borderWidth: 1,
paddingHorizontal: 15,
paddingVertical: 12,
backgroundColor: "#fff",
// borderRadiusLeftBottom: 3,
// borderRadiusRightBottom: 3,
},
suggestions_btn: {},
suggestions_btn_wrapper: {
...$components.btnWrapper,
},
suggestions_scroll_wrapper: {
flex: 1,
flexDirection: "column",
paddingHorizontal: 10,
},
suggestions_scroll_view: {
justifyContent: "space-between",
alignItems: "stretch",
},
}));
export default class Autosuggest extends Component {
constructor(props) {
super(props);
this.state = {
focused: false,
suggestions: this.props.suggestions || [],
inputValue: this.props.defaultValue || "",
};
}
componentWillReceiveProps(nextProps) {
if (!_.isEqual(nextProps.suggestions, this.props.suggestions)) {
this.setState({ suggestions: nextProps.suggestions });
}
}
onSuggestionSelected(suggestion) {
const suggestionValue = this.props.getSuggestionValue(suggestion);
typeof this.props.onSuggestionSelected === "function" &&
this.props.onSuggestionSelected(
{},
{
suggestion,
suggestionValue,
}
);
// this.setState({
// inputValue: suggestionValue,
// })
this.close();
}
onChangeText = text => {
this.props.inputProps.onChangeText &&
this.props.inputProps.onChangeText(text);
if (text.length === 0) {
this.props.onSuggestionsClearRequested();
} else {
this.props.onSuggestionsFetchRequested({ value: text });
}
this.setState({
inputValue: text,
});
};
getField(optionalProps) {
const { inputProps } = this.props;
return (
<Field
value={this.state.inputValue}
{...inputProps}
textInputStyle={styles.$("suggestions-input", {
"suggestions-input-withscroll":
this.state.suggestions.length > 0,
})}
onChangeText={this.onChangeText}
autoCapitalize="none"
autoCorrect={false}
maxLength={255}
label={
typeof inputProps.label === "undefined"
? inputProps.placeholder
: inputProps.label
}
placeholder={inputProps.placeholder}
style={{
marginBottom: 0,
height: 60,
}}
{...optionalProps}
/>
);
}
close = () => {
this.setState({ focused: false });
};
render() {
const { childKey, title } = this.props;
return (
<View style={styles["suggestions"]}>
{this.getField({
onFocus: () => this.setState({ focused: true }),
})}
<Modal
animationType={"slide"}
visible={this.state.focused}
onRequestClose={this.props.onRequestClose}
>
<View style={{ flex: 1 }}>
<ModalHeader
title={
this.props.suggestionLoading
? title + "..."
: title
}
onBack={this.close}
/>
<KeyboardAwareScrollView
keyboardShouldPersistTaps="handled"
style={styles.scroll}
contentContainerStyle={styles.scroll__container}
extraHeight={20}
enableOnAndroid={true}
>
{this.getField({
autoFocus: true,
label: null,
})}
{this.state.suggestions.map((suggest, i) => (
<TouchableOpacity
style={styles["suggest"]}
onPress={ev => {
this.onSuggestionSelected(suggest);
}}
key={childKey ? suggest[childKey] : i}
>
{this.props.renderSuggestion(suggest)}
</TouchableOpacity>
))}
{/*<View style={styles.suggestions_btn_wrapper}>
<Btn
style={styles.suggestions_btn}
disabled={this.state.inputValue.length < 2}
onPress={this.close}>Обрати</Btn>
</View>*/}
</KeyboardAwareScrollView>
</View>
</Modal>
</View>
);
}
}
Autosuggest.defaultProps = {
inputProps: {},
shouldRenderSuggestions: value => value.trim().length >= 1,
onRequestClose: () => console.log("onRequestClose"),
childKey: null,
};
Autosuggest.propTypes = {
onSuggestionsFetchRequested: PropTypes.func.isRequired,
onSuggestionsClearRequested: PropTypes.func.isRequired,
getSuggestionValue: PropTypes.func.isRequired,
renderSuggestion: PropTypes.func.isRequired,
suggestions: PropTypes.array.isRequired,
shouldRenderSuggestions: PropTypes.func,
inputProps: PropTypes.object,
childKey: PropTypes.string,
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment