diff --git a/package.json b/package.json
index 2a66fc1..44dd857 100644
--- a/package.json
+++ b/package.json
@@ -5,14 +5,17 @@
"main": "dist",
"dependencies": {
"babel-runtime": "^6.23.0",
+ "lodash": "^4.17.11",
"moment": "^2.18.1",
+ "npm": "^6.9.0",
"prop-types": "^15.5.8",
- "react": "15.x.x",
- "react-native": ">=0.40.0",
+ "react": "^16.6.x",
+ "react-dom": "^16.6.x",
+ "react-native": "0.55.x",
"react-native-elements": "^0.11.2",
"react-native-linear-gradient": "^2.0.0",
"react-native-looped-carousel": "^0.1.7",
- "react-native-vector-icons": "^4.0.0",
+ "react-native-vector-icons": "^6.2.0",
"react-slick": "^0.14.11",
"slick-carousel": "^1.6.0"
},
@@ -23,12 +26,9 @@
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-react-native": "^1.9.1",
"json-loader": "^0.5.4",
- "react": "15.x.x",
- "react-dom": "15.x.x",
- "react-native-web": "0.0.94"
+ "react-native-web": "^0.9.x"
},
"scripts": {
- "prepublish": ". ./scripts/transpile.sh",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
diff --git a/src/AutoComplete/index.android.js b/src/AutoComplete/index.android.js
new file mode 100644
index 0000000..b88b9d0
--- /dev/null
+++ b/src/AutoComplete/index.android.js
@@ -0,0 +1,247 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import _ from 'lodash'
+import {
+ Keyboard,
+ VirtualizedList,
+ Text,
+ Platform,
+ StyleSheet,
+ TextInput,
+ TouchableOpacity,
+ View
+} from 'react-native';
+
+const inbuiltStyles = StyleSheet.create({
+ container: {
+ width: '100%',
+ ...Platform.select({
+ web: {
+ zIndex: 999,
+ }
+ })
+ // flexDirection:'row'
+ }
+});
+
+export default class AutoComplete extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ cursor: 0,
+ counter: 0,
+ allData: props.list,
+ fullData: props.list,
+ data: props.list,
+ query: '',
+ showList: false,
+ };
+ }
+
+
+ ////////////////////////////////////////////////////
+ handleSearch = (text) => {
+ const data = _.filter(this.state.fullData, user => {
+ return this.containsQuery(user, text);
+ });
+ this.setState({query: text, value: text, data, showList: true})
+ };
+
+ containsQuery = ({name}, query) => {
+ if (name.toLowerCase().includes(query.toLowerCase())) {
+ return true;
+ } else {
+ return false;
+ }
+ };
+ /////////////////////////////////////////////////////
+
+
+ // arrow up/down button should select next/previous list element and enter key press should simulate item selection
+ handleKeyDown(e) {
+ e.persist();
+ const {cursor, data} = this.state
+ if (e.keyCode === 38 && cursor > 0) {
+ let counter = this.state.counter
+ --counter;
+ let c = this.state.cursor;
+ --c;
+ this.setState({cursor: c, counter}, () => this.handleScroll('up'))
+ } else if (e.keyCode === 40 && cursor <= data.length - 1) {
+ let counter = this.state.counter
+ ++counter;
+ let c = this.state.cursor;
+ ++c;
+ this.setState({cursor: c, counter}, () => this.handleScroll('down'))
+ } else {
+ if (e.key === 'Enter') {
+ if (this.state.cursor !== 0) {
+ if (this.props.onItemSelected)
+ {
+ this.props.onItemSelected(this.VTListRef.props.data[--this.state.cursor])
+ this.setState({value: this.VTListRef.props.data[this.state.cursor][this.props.searchQuery]})
+ }
+
+ /*const eventItemName = e.target.nextElementSibling.children[0].children[0].getElementsByClassName('active')[0].children[0].innerText
+ this.setState({
+ showList: false,
+ }, () => {
+ this.props.list.map(item => {
+ if (item[this.props.searchQuery] === eventItemName) {
+ if (this.props.onItemSelected) {
+ this.props.onItemSelected(item);
+ this.setState({value: item[this.props.searchQuery]})
+ }
+ }
+ })
+ });*/
+ }
+ }
+ }
+ }
+
+ handleScroll = (scrollType) => {
+ if (scrollType === 'down') {
+ if (this.state.counter % Math.floor(this.state.listContainerHeight / this.props.listItemStyle.height) === 0 && this.state.cursor > 0)
+ this.VTListRef.scrollToIndex({index: this.state.cursor - 1})
+ } else if (this.state.cursor > 0)
+ this.VTListRef.scrollToIndex({index: this.state.cursor - 1})
+ }
+
+
+ render() {
+ let index = 0;
+ const {cursor} = this.state
+ const propStyles = this.props;
+ return (
+
+ {
+ this.setState({
+ showList: false,
+ cursor: 0,
+ counter: 0
+ })
+ }}
+ onChangeText={value => this.handleSearch(value)}
+ onKeyPress={(e) => this.handleKeyDown(e)}
+ />
+ {this.state.showList ?
+ {
+ let {height} = event.nativeEvent.layout
+ this.setState({listContainerHeight: height})
+ }}
+ style={[{position: 'absolute', zIndex: 999, marginTop: 40, backgroundColor: '#fff'}
+ , propStyles.listContainerStyle]}>
+ data.length}
+ ref={(ref) => {
+ this.VTListRef = ref;
+ }}
+ keyboardShouldPersistTaps='handled'
+ getItem={(data, index) => data[index]}
+ keyExtractor={(item, index) => item.name}
+ renderItem={
+ (rowData, key) => (
+ {
+ let {height} = event.nativeEvent.layout
+ this.setState({listItemHeight: height})
+ }}
+ style={{backgroundColor: cursor === index ? 'rgba(1, 140, 207, 0.46)' : null}}>
+ {
+ this.setState({
+ showList: false,
+ query: rowData.item,
+ value: rowData.item[this.props.searchQuery]
+ }, () => {
+ Keyboard.dismiss()
+ if (this.props.onItemSelected)
+ this.props.onItemSelected(this.state.query);
+ });
+ }}>
+
+ {rowData.item[this.props.searchQuery]}
+
+
+
+ )
+ }
+ />
+
+ : null
+ }
+
+ )
+ }
+
+}
+
+AutoComplete.defaultProps = {
+ ignoreCase: false,
+ searchQuery: 'name',
+ list: [{
+ name: 'React',
+ email: 'react@gmail.com'
+ },
+ {
+ name: 'Redux',
+ email: 'Redux@gmail.com'
+ },
+ {
+ name: 'CSS',
+ email: 'css3@gmail.com'
+ },
+ {
+ name: "React Native",
+ email: 'RN@gmail.com'
+ },
+ {
+ name: 'GraphQL',
+ email: 'GraphQL@gmail.com'
+ },
+ {
+ name: 'python',
+ email: 'python@gmail.com'
+ },
+ {
+ name: 'django',
+ email: 'django@gmail.com'
+ },
+ {
+ name: 'JavaScript',
+ email: 'javascript@gmail.com'
+ },
+ {
+ name: 'Java',
+ email: 'oracle@gmail.com'
+ }
+ ]
+};
+
+AutoComplete.propTypes = {
+ placeholder: PropTypes.string,
+ searchQuery: PropTypes.string,
+ listContainerStyle: PropTypes.object,
+ listItemStyle: PropTypes.object,
+ autoCompleteInputStyle: PropTypes.object,
+ list: PropTypes.array.isRequired,
+ ignoreCase: PropTypes.bool,
+ onItemSelected: PropTypes.func,
+};
diff --git a/src/AutoComplete/index.ios.js b/src/AutoComplete/index.ios.js
new file mode 100644
index 0000000..b88b9d0
--- /dev/null
+++ b/src/AutoComplete/index.ios.js
@@ -0,0 +1,247 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import _ from 'lodash'
+import {
+ Keyboard,
+ VirtualizedList,
+ Text,
+ Platform,
+ StyleSheet,
+ TextInput,
+ TouchableOpacity,
+ View
+} from 'react-native';
+
+const inbuiltStyles = StyleSheet.create({
+ container: {
+ width: '100%',
+ ...Platform.select({
+ web: {
+ zIndex: 999,
+ }
+ })
+ // flexDirection:'row'
+ }
+});
+
+export default class AutoComplete extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ cursor: 0,
+ counter: 0,
+ allData: props.list,
+ fullData: props.list,
+ data: props.list,
+ query: '',
+ showList: false,
+ };
+ }
+
+
+ ////////////////////////////////////////////////////
+ handleSearch = (text) => {
+ const data = _.filter(this.state.fullData, user => {
+ return this.containsQuery(user, text);
+ });
+ this.setState({query: text, value: text, data, showList: true})
+ };
+
+ containsQuery = ({name}, query) => {
+ if (name.toLowerCase().includes(query.toLowerCase())) {
+ return true;
+ } else {
+ return false;
+ }
+ };
+ /////////////////////////////////////////////////////
+
+
+ // arrow up/down button should select next/previous list element and enter key press should simulate item selection
+ handleKeyDown(e) {
+ e.persist();
+ const {cursor, data} = this.state
+ if (e.keyCode === 38 && cursor > 0) {
+ let counter = this.state.counter
+ --counter;
+ let c = this.state.cursor;
+ --c;
+ this.setState({cursor: c, counter}, () => this.handleScroll('up'))
+ } else if (e.keyCode === 40 && cursor <= data.length - 1) {
+ let counter = this.state.counter
+ ++counter;
+ let c = this.state.cursor;
+ ++c;
+ this.setState({cursor: c, counter}, () => this.handleScroll('down'))
+ } else {
+ if (e.key === 'Enter') {
+ if (this.state.cursor !== 0) {
+ if (this.props.onItemSelected)
+ {
+ this.props.onItemSelected(this.VTListRef.props.data[--this.state.cursor])
+ this.setState({value: this.VTListRef.props.data[this.state.cursor][this.props.searchQuery]})
+ }
+
+ /*const eventItemName = e.target.nextElementSibling.children[0].children[0].getElementsByClassName('active')[0].children[0].innerText
+ this.setState({
+ showList: false,
+ }, () => {
+ this.props.list.map(item => {
+ if (item[this.props.searchQuery] === eventItemName) {
+ if (this.props.onItemSelected) {
+ this.props.onItemSelected(item);
+ this.setState({value: item[this.props.searchQuery]})
+ }
+ }
+ })
+ });*/
+ }
+ }
+ }
+ }
+
+ handleScroll = (scrollType) => {
+ if (scrollType === 'down') {
+ if (this.state.counter % Math.floor(this.state.listContainerHeight / this.props.listItemStyle.height) === 0 && this.state.cursor > 0)
+ this.VTListRef.scrollToIndex({index: this.state.cursor - 1})
+ } else if (this.state.cursor > 0)
+ this.VTListRef.scrollToIndex({index: this.state.cursor - 1})
+ }
+
+
+ render() {
+ let index = 0;
+ const {cursor} = this.state
+ const propStyles = this.props;
+ return (
+
+ {
+ this.setState({
+ showList: false,
+ cursor: 0,
+ counter: 0
+ })
+ }}
+ onChangeText={value => this.handleSearch(value)}
+ onKeyPress={(e) => this.handleKeyDown(e)}
+ />
+ {this.state.showList ?
+ {
+ let {height} = event.nativeEvent.layout
+ this.setState({listContainerHeight: height})
+ }}
+ style={[{position: 'absolute', zIndex: 999, marginTop: 40, backgroundColor: '#fff'}
+ , propStyles.listContainerStyle]}>
+ data.length}
+ ref={(ref) => {
+ this.VTListRef = ref;
+ }}
+ keyboardShouldPersistTaps='handled'
+ getItem={(data, index) => data[index]}
+ keyExtractor={(item, index) => item.name}
+ renderItem={
+ (rowData, key) => (
+ {
+ let {height} = event.nativeEvent.layout
+ this.setState({listItemHeight: height})
+ }}
+ style={{backgroundColor: cursor === index ? 'rgba(1, 140, 207, 0.46)' : null}}>
+ {
+ this.setState({
+ showList: false,
+ query: rowData.item,
+ value: rowData.item[this.props.searchQuery]
+ }, () => {
+ Keyboard.dismiss()
+ if (this.props.onItemSelected)
+ this.props.onItemSelected(this.state.query);
+ });
+ }}>
+
+ {rowData.item[this.props.searchQuery]}
+
+
+
+ )
+ }
+ />
+
+ : null
+ }
+
+ )
+ }
+
+}
+
+AutoComplete.defaultProps = {
+ ignoreCase: false,
+ searchQuery: 'name',
+ list: [{
+ name: 'React',
+ email: 'react@gmail.com'
+ },
+ {
+ name: 'Redux',
+ email: 'Redux@gmail.com'
+ },
+ {
+ name: 'CSS',
+ email: 'css3@gmail.com'
+ },
+ {
+ name: "React Native",
+ email: 'RN@gmail.com'
+ },
+ {
+ name: 'GraphQL',
+ email: 'GraphQL@gmail.com'
+ },
+ {
+ name: 'python',
+ email: 'python@gmail.com'
+ },
+ {
+ name: 'django',
+ email: 'django@gmail.com'
+ },
+ {
+ name: 'JavaScript',
+ email: 'javascript@gmail.com'
+ },
+ {
+ name: 'Java',
+ email: 'oracle@gmail.com'
+ }
+ ]
+};
+
+AutoComplete.propTypes = {
+ placeholder: PropTypes.string,
+ searchQuery: PropTypes.string,
+ listContainerStyle: PropTypes.object,
+ listItemStyle: PropTypes.object,
+ autoCompleteInputStyle: PropTypes.object,
+ list: PropTypes.array.isRequired,
+ ignoreCase: PropTypes.bool,
+ onItemSelected: PropTypes.func,
+};
diff --git a/src/AutoComplete/index.js b/src/AutoComplete/index.js
index 5abd8bc..b88b9d0 100644
--- a/src/AutoComplete/index.js
+++ b/src/AutoComplete/index.js
@@ -1,114 +1,246 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { ListView, Text, TextInput, TouchableOpacity, View } from 'react-native';
+import _ from 'lodash'
+import {
+ Keyboard,
+ VirtualizedList,
+ Text,
+ Platform,
+ StyleSheet,
+ TextInput,
+ TouchableOpacity,
+ View
+} from 'react-native';
-const styles = {
+const inbuiltStyles = StyleSheet.create({
container: {
- width: 200,
- },
- autoCompleteInput: {
- width: 200,
- height: 40,
- },
- listContainer: {
- zIndex: 1,
- position: 'absolute',
- marginTop: 40,
- backgroundColor: '#FFF',
- width: 'inherit'
- },
- listItem: {
- height: 40,
- justifyContent: 'center',
- borderWidth: 2,
- borderStyle: 'solid',
- borderColor: '#e0e0e0',
- borderTopWidth: 0,
- },
-};
+ width: '100%',
+ ...Platform.select({
+ web: {
+ zIndex: 999,
+ }
+ })
+ // flexDirection:'row'
+ }
+});
export default class AutoComplete extends React.Component {
constructor(props) {
super(props);
-
- const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
+ cursor: 0,
+ counter: 0,
allData: props.list,
- dataSource: ds.cloneWithRows([]),
+ fullData: props.list,
+ data: props.list,
query: '',
showList: false,
};
}
+
+ ////////////////////////////////////////////////////
+ handleSearch = (text) => {
+ const data = _.filter(this.state.fullData, user => {
+ return this.containsQuery(user, text);
+ });
+ this.setState({query: text, value: text, data, showList: true})
+ };
+
+ containsQuery = ({name}, query) => {
+ if (name.toLowerCase().includes(query.toLowerCase())) {
+ return true;
+ } else {
+ return false;
+ }
+ };
+ /////////////////////////////////////////////////////
+
+
+ // arrow up/down button should select next/previous list element and enter key press should simulate item selection
+ handleKeyDown(e) {
+ e.persist();
+ const {cursor, data} = this.state
+ if (e.keyCode === 38 && cursor > 0) {
+ let counter = this.state.counter
+ --counter;
+ let c = this.state.cursor;
+ --c;
+ this.setState({cursor: c, counter}, () => this.handleScroll('up'))
+ } else if (e.keyCode === 40 && cursor <= data.length - 1) {
+ let counter = this.state.counter
+ ++counter;
+ let c = this.state.cursor;
+ ++c;
+ this.setState({cursor: c, counter}, () => this.handleScroll('down'))
+ } else {
+ if (e.key === 'Enter') {
+ if (this.state.cursor !== 0) {
+ if (this.props.onItemSelected)
+ {
+ this.props.onItemSelected(this.VTListRef.props.data[--this.state.cursor])
+ this.setState({value: this.VTListRef.props.data[this.state.cursor][this.props.searchQuery]})
+ }
+
+ /*const eventItemName = e.target.nextElementSibling.children[0].children[0].getElementsByClassName('active')[0].children[0].innerText
+ this.setState({
+ showList: false,
+ }, () => {
+ this.props.list.map(item => {
+ if (item[this.props.searchQuery] === eventItemName) {
+ if (this.props.onItemSelected) {
+ this.props.onItemSelected(item);
+ this.setState({value: item[this.props.searchQuery]})
+ }
+ }
+ })
+ });*/
+ }
+ }
+ }
+ }
+
+ handleScroll = (scrollType) => {
+ if (scrollType === 'down') {
+ if (this.state.counter % Math.floor(this.state.listContainerHeight / this.props.listItemStyle.height) === 0 && this.state.cursor > 0)
+ this.VTListRef.scrollToIndex({index: this.state.cursor - 1})
+ } else if (this.state.cursor > 0)
+ this.VTListRef.scrollToIndex({index: this.state.cursor - 1})
+ }
+
+
render() {
+ let index = 0;
+ const {cursor} = this.state
+ const propStyles = this.props;
return (
-
-
+ this.setState({showList: false})}
- onChangeText={this.onQueryChange}/>
- {this.state.showList
- &&
-
- (
- {
- this.setState({
- showList: false, query: rowData
- }, () => {
- if (this.props.onItemSelected)
- this.props.onItemSelected(this.state.query);
- });
- }}>
-
- {rowData}
-
-
- )
- }
- />
-
+ value={this.state.value}
+ underlineColorAndroid={'transparent'}
+ onBlur={() => {
+ this.setState({
+ showList: false,
+ cursor: 0,
+ counter: 0
+ })
+ }}
+ onChangeText={value => this.handleSearch(value)}
+ onKeyPress={(e) => this.handleKeyDown(e)}
+ />
+ {this.state.showList ?
+ {
+ let {height} = event.nativeEvent.layout
+ this.setState({listContainerHeight: height})
+ }}
+ style={[{position: 'absolute', zIndex: 999, marginTop: 40, backgroundColor: '#fff'}
+ , propStyles.listContainerStyle]}>
+ data.length}
+ ref={(ref) => {
+ this.VTListRef = ref;
+ }}
+ keyboardShouldPersistTaps='handled'
+ getItem={(data, index) => data[index]}
+ keyExtractor={(item, index) => item.name}
+ renderItem={
+ (rowData, key) => (
+ {
+ let {height} = event.nativeEvent.layout
+ this.setState({listItemHeight: height})
+ }}
+ style={{backgroundColor: cursor === index ? 'rgba(1, 140, 207, 0.46)' : null}}>
+ {
+ this.setState({
+ showList: false,
+ query: rowData.item,
+ value: rowData.item[this.props.searchQuery]
+ }, () => {
+ Keyboard.dismiss()
+ if (this.props.onItemSelected)
+ this.props.onItemSelected(this.state.query);
+ });
+ }}>
+
+ {rowData.item[this.props.searchQuery]}
+
+
+
+ )
+ }
+ />
+
+ : null
}
)
}
- onQueryChange = (value) => {
- this.setState({query: value});
- this.filter(value);
- };
-
- filter = (query) => {
- query = query.trim();
- let filteredData = this.state.allData.filter((item) => {
- if (this.props.ignoreCase)
- return item.toLowerCase().includes(query.toLowerCase());
-
- return item.includes(query);
- });
-
- const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
- this.setState({
- dataSource: ds.cloneWithRows(filteredData),
- showList: true
- }
- );
- };
}
AutoComplete.defaultProps = {
ignoreCase: false,
+ searchQuery: 'name',
+ list: [{
+ name: 'React',
+ email: 'react@gmail.com'
+ },
+ {
+ name: 'Redux',
+ email: 'Redux@gmail.com'
+ },
+ {
+ name: 'CSS',
+ email: 'css3@gmail.com'
+ },
+ {
+ name: "React Native",
+ email: 'RN@gmail.com'
+ },
+ {
+ name: 'GraphQL',
+ email: 'GraphQL@gmail.com'
+ },
+ {
+ name: 'python',
+ email: 'python@gmail.com'
+ },
+ {
+ name: 'django',
+ email: 'django@gmail.com'
+ },
+ {
+ name: 'JavaScript',
+ email: 'javascript@gmail.com'
+ },
+ {
+ name: 'Java',
+ email: 'oracle@gmail.com'
+ }
+ ]
};
AutoComplete.propTypes = {
placeholder: PropTypes.string,
+ searchQuery: PropTypes.string,
+ listContainerStyle: PropTypes.object,
+ listItemStyle: PropTypes.object,
+ autoCompleteInputStyle: PropTypes.object,
list: PropTypes.array.isRequired,
ignoreCase: PropTypes.bool,
onItemSelected: PropTypes.func,