From e98556a29f72679344637bc500ec4e048de6c553 Mon Sep 17 00:00:00 2001 From: Drl Khr Date: Mon, 25 Jul 2022 13:55:13 +0800 Subject: [PATCH 1/3] add textStyles props --- README.md | 158 +++++++++-------- index.tsx | 494 ++++++++++++++++++++++++++++-------------------------- 2 files changed, 331 insertions(+), 321 deletions(-) diff --git a/README.md b/README.md index a5e594fc..c15e5126 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ - -

🚩React Native Dropdown Select List

@@ -23,22 +21,16 @@

Light weight and Easy to use dropdown select list.

-- Style it your way with style props of every view. -- Smooth performance on all platforms IOS, Android and Web. -- Change Font Family Easily which community picker lacks. -- Zero dependencies - - +- Style it your way with style props of every view. +- Smooth performance on all platforms IOS, Android and Web. +- Change Font Family Easily which community picker lacks. +- Zero dependencies # Compatibility - -| iOS | Android | Web | Expo | ---------|---------|-----|------| -| βœ… | βœ… | βœ… | βœ… | - - - +| iOS | Android | Web | Expo | +| --- | ------- | --- | ---- | +| βœ… | βœ… | βœ… | βœ… | # πŸ”Œ Installation @@ -53,108 +45,114 @@ OR $ yarn add react-native-dropdown-select-list ``` - # 😎 Usage + ```jsx -import SelectList from 'react-native-dropdown-select-list' +import SelectList from "react-native-dropdown-select-list"; const App = () => { - const [selected, setSelected] = React.useState(""); - - const data = [{key:'1',value:'Jammu & Kashmir'}]; - return( - alert(selected)} /> - ) + const data = [{ key: "1", value: "Jammu & Kashmir" }]; + return ( + alert(selected)} + /> + ); }; ``` For Live `Demo` [(Expo Snack)](https://snack.expo.dev/@danish1658/react-native-dropdown-select-list) # ⭐ Props -| Name | Type | Description | -| ---- | ---- | ----------- | -| onSelect| Function | Pass any function that you want to trigger immediately after a value is selected -| placeholder | String | Placeholder text that will be displayed in the select box -| search | boolean | set to false if you dont want to use search functionality -| boxStyles| Object| Additional styles for select box -| inputStyles| Object| Additional styles for text of select box -| dropdownStyles| Object| Additional styles for dropdown scrollview -| dropdownItemStyles| Object| Additional styles for dropdown list item -| dropdownTextStyles| Object| Additional styles for list items text -| maxHeight| Number | Maximum height of the dropdown wrapper to occupy -| data| array or array[object]| Data which will be iterated as options of select list -| setSelected| Function | For Setting the option value which will be stored in your local state -| searchicon| JSX Element | Pass any JSX to this prop like Text, Image or Icon to show instead of search icon -| arrowicon| JSX Element | Pass any JSX to this prop like Text, Image or Icon to show instead of chevron icon +| Name | Type | Description | +| ------------------ | ---------------------- | ---------------------------------------------------------------------------------- | +| onSelect | Function | Pass any function that you want to trigger immediately after a value is selected | +| placeholder | String | Placeholder text that will be displayed in the select box | +| search | boolean | set to false if you dont want to use search functionality | +| boxStyles | Object | Additional styles for select box | +| inputStyles | Object | Additional styles for textinput of select box | +| textStyles | Object | Additional styles for text of select box | +| dropdownStyles | Object | Additional styles for dropdown scrollview | +| dropdownItemStyles | Object | Additional styles for dropdown list item | +| dropdownTextStyles | Object | Additional styles for list items text | +| maxHeight | Number | Maximum height of the dropdown wrapper to occupy | +| data | array or array[object] | Data which will be iterated as options of select list | +| setSelected | Function | For Setting the option value which will be stored in your local state | +| searchicon | JSX Element | Pass any JSX to this prop like Text, Image or Icon to show instead of search icon | +| arrowicon | JSX Element | Pass any JSX to this prop like Text, Image or Icon to show instead of chevron icon | # 😎 Advanced Usage + ```jsx -import SelectList from 'react-native-dropdown-select-list' +import SelectList from "react-native-dropdown-select-list"; const App = () => { - const [selected, setSelected] = React.useState(""); - + const data = [ - {key:'1',value:'Jammu & Kashmir'}, - {key:'2',value:'Gujrat'}, - {key:'3',value:'Maharashtra'}, - {key:'4',value:'Goa'}, + { key: "1", value: "Jammu & Kashmir" }, + { key: "2", value: "Gujrat" }, + { key: "3", value: "Maharashtra" }, + { key: "4", value: "Goa" }, ]; - return( - alert(selected)} - setSelected={setSelected} - data={data} - arrowicon={} - searchicon={} - search={false} - boxStyles={{borderRadius:0}} //override default styles + setSelected={setSelected} + data={data} + arrowicon={} + searchicon={} + search={false} + boxStyles={{ borderRadius: 0 }} //override default styles /> - ) - + ); }; ``` - # 😎 Getting Options From Database + ```jsx -import SelectList from 'react-native-dropdown-select-list' +import SelectList from "react-native-dropdown-select-list"; const App = () => { - const [selected, setSelected] = React.useState(""); - const [data,setData] = React.useState([]); - - React.useEffect(() => - //Get Values from database - axios.get('https://jsonplaceholder.typicode.com/users') - .then((response) => { - // Store Values in Temporary Array - let newArray = response.data.map((item) => { - return {key: item.id, value: item.name} + const [data, setData] = React.useState([]); + + React.useEffect( + () => + //Get Values from database + axios + .get("https://jsonplaceholder.typicode.com/users") + .then((response) => { + // Store Values in Temporary Array + let newArray = response.data.map((item) => { + return { key: item.id, value: item.name }; + }); + //Set Data Variable + setData(newArray); }) - //Set Data Variable - setData(newArray) - }) - .catch((e) => { - console.log(e) - }) - ,[]) - - return( - alert(selected)} /> - ) - + .catch((e) => { + console.log(e); + }), + [] + ); + + return ( + alert(selected)} + /> + ); }; ``` - # ▢️ Watch Video [![Watch the video](https://i.imgur.com/K8Lt2h4.png)](https://www.youtube.com/watch?v=J9raEY-1KPQ&t=499s) diff --git a/index.tsx b/index.tsx index 59373408..582f256f 100644 --- a/index.tsx +++ b/index.tsx @@ -1,253 +1,265 @@ -import React,{JSXElementConstructor} from 'react'; +import React, { JSXElementConstructor } from "react"; import { - View, - Text, - StyleSheet, - Image, - TouchableOpacity, - ScrollView, - Animated, - TextInput, - ViewStyle} from 'react-native'; - -interface SelectListProps { - /** - * Fn to set Selected option value which will be stored in your local state - */ - setSelected: React.Dispatch>, - - /** - * Placeholder text that will be displayed in the select box - */ - placeholder?: string, - - /** - * Additional styles for select box - */ - boxStyles?: ViewStyle, - - /** - * Additional styles for text of select box - */ - inputStyles?: ViewStyle, - - /** - * Additional styles for dropdown scrollview - */ - dropdownStyles?:ViewStyle, - - /** - * Additional styles for dropdown list item - */ - dropdownItemStyles?: ViewStyle, - - /** - * Additional styles for list items text - */ - dropdownTextStyles?: ViewStyle, - - /** - * Maximum height of the dropdown wrapper to occupy - */ - maxHeight?: number, - - /** - * Data which will be iterated as options of select list - */ - data: Array<{}>, - - /** - * Pass any JSX to this prop like Text, Image or Icon to show instead of search icon - */ - searchicon?: JSX.Element, - - /** - * Pass any JSX to this prop like Text, Image or Icon to show instead of chevron icon - */ - arrowicon?: JSX.Element, - - /** - * set to false if you dont want to use search functionality - */ - search?: boolean - - /** - * Trigger an action when option is selected - */ - onSelect?: () => void + View, + Text, + StyleSheet, + Image, + TouchableOpacity, + ScrollView, + Animated, + TextInput, + ViewStyle, +} from "react-native"; +interface SelectListProps { + /** + * Fn to set Selected option value which will be stored in your local state + */ + setSelected: React.Dispatch>; + + /** + * Placeholder text that will be displayed in the select box + */ + placeholder?: string; + + /** + * Additional styles for select box + */ + boxStyles?: ViewStyle; + + /** + * Additional styles for textinput of select box + */ + inputStyles?: ViewStyle; + + /** + * Additional styles for text of select box + */ + textStyles?: ViewStyle; + + /** + * Additional styles for dropdown scrollview + */ + dropdownStyles?: ViewStyle; + + /** + * Additional styles for dropdown list item + */ + dropdownItemStyles?: ViewStyle; + + /** + * Additional styles for list items text + */ + dropdownTextStyles?: ViewStyle; + + /** + * Maximum height of the dropdown wrapper to occupy + */ + maxHeight?: number; + + /** + * Data which will be iterated as options of select list + */ + data: Array<{}>; + + /** + * Pass any JSX to this prop like Text, Image or Icon to show instead of search icon + */ + searchicon?: JSX.Element; + + /** + * Pass any JSX to this prop like Text, Image or Icon to show instead of chevron icon + */ + arrowicon?: JSX.Element; + + /** + * set to false if you dont want to use search functionality + */ + search?: boolean; + + /** + * Trigger an action when option is selected + */ + onSelect?: () => void; } const SelectList: React.FC = ({ - setSelected, - placeholder, - boxStyles, - inputStyles, - dropdownStyles, - dropdownItemStyles, - dropdownTextStyles, - maxHeight, - data, - searchicon = false, - arrowicon = false, - search = true, - onSelect = () => {}, - }) => { - - - const [_firstRender,_setFirstRender] = React.useState(true); - const [dropdown, setDropdown] = React.useState(false); - const [selectedval, setSelectedVal] = React.useState(""); - const [height,setHeight] = React.useState(200) - const animatedvalue = React.useRef(new Animated.Value(0)).current; - const [filtereddata,setFilteredData] = React.useState(data) - - - const slidedown = () => { - setDropdown(true) - Animated.timing(animatedvalue,{ - toValue:height, - duration:500, - useNativeDriver:false, - - }).start() - } - const slideup = () => { - - Animated.timing(animatedvalue,{ - toValue:0, - duration:500, - useNativeDriver:false, - - }).start(() => setDropdown(false)) + setSelected, + placeholder, + boxStyles, + inputStyles, + textStyles, + dropdownStyles, + dropdownItemStyles, + dropdownTextStyles, + maxHeight, + data, + searchicon = false, + arrowicon = false, + search = true, + onSelect = () => {}, +}) => { + const [_firstRender, _setFirstRender] = React.useState(true); + const [dropdown, setDropdown] = React.useState(false); + const [selectedval, setSelectedVal] = React.useState(""); + const [height, setHeight] = React.useState(200); + const animatedvalue = React.useRef(new Animated.Value(0)).current; + const [filtereddata, setFilteredData] = React.useState(data); + + const slidedown = () => { + setDropdown(true); + Animated.timing(animatedvalue, { + toValue: height, + duration: 500, + useNativeDriver: false, + }).start(); + }; + const slideup = () => { + Animated.timing(animatedvalue, { + toValue: 0, + duration: 500, + useNativeDriver: false, + }).start(() => setDropdown(false)); + }; + + React.useEffect(() => { + if (maxHeight) setHeight(maxHeight); + }, [maxHeight]); + + React.useEffect(() => { + setFilteredData(data); + }, [data]); + + React.useEffect(() => { + if (_firstRender) { + _setFirstRender(false); + return; } + onSelect(); + }, [selectedval]); - React.useEffect( () => { - if(maxHeight) - setHeight(maxHeight) - },[maxHeight]) - - - React.useEffect(() => { - setFilteredData(data); - },[data]) - - - React.useEffect(() => { - if(_firstRender){ - _setFirstRender(false); - return; - } - onSelect() - },[selectedval]) - - - return( - - { - (dropdown && search) - ? - - - { - (!searchicon) - ? - - : - searchicon - } - - { - let result = data.filter((item) => { - val.toLowerCase(); - let row = item.value.toLowerCase() - return row.search(val.toLowerCase()) > -1; - }); - setFilteredData(result) - }} - style={[{padding:0,height:20,width:'80%'},inputStyles]} - /> - - - - - : - { if(!dropdown){ slidedown() }else{ slideup() } }}> - { (selectedval == "") ? (placeholder) ? placeholder : 'Select option' : selectedval } - { - (!arrowicon) - ? - - : - arrowicon - } - - - } - - { - (dropdown) - ? - - - - { - (filtereddata.length >= 1) - ? - filtereddata.map((item,index) => { - let key = item.key ?? item.value ?? item; - let value = item.value ?? item; - return( - { - setSelected(key) - setSelectedVal(value) - slideup() - setTimeout(() => setFilteredData(data), 800) - - }}> - {value} - - ) - }) - : - { - setSelected("") - setSelectedVal("") - slideup() - setTimeout(() => setFilteredData(data), 800) - - }}> - No data found - - } - - - - - - : - null - } - - + return ( + + {dropdown && search ? ( + + + {!searchicon ? ( + + ) : ( + searchicon + )} + + { + let result = data.filter((item) => { + val.toLowerCase(); + let row = item.value.toLowerCase(); + return row.search(val.toLowerCase()) > -1; + }); + setFilteredData(result); + }} + style={[{ padding: 0, height: 20, width: "80%" }, inputStyles]} + /> + - ) -} + ) : ( + { + if (!dropdown) { + slidedown(); + } else { + slideup(); + } + }} + > + + {selectedval == "" + ? placeholder + ? placeholder + : "Select option" + : selectedval} + + {!arrowicon ? ( + + ) : ( + arrowicon + )} + + )} + + {dropdown ? ( + + + {filtereddata.length >= 1 ? ( + filtereddata.map((item, index) => { + let key = item.key ?? item.value ?? item; + let value = item.value ?? item; + return ( + { + setSelected(key); + setSelectedVal(value); + slideup(); + setTimeout(() => setFilteredData(data), 800); + }} + > + {value} + + ); + }) + ) : ( + { + setSelected(""); + setSelectedVal(""); + slideup(); + setTimeout(() => setFilteredData(data), 800); + }} + > + No data found + + )} + + + ) : null} + + ); +}; export default SelectList; const styles = StyleSheet.create({ - wrapper:{ borderWidth:1,borderRadius:10,borderColor:'gray',paddingHorizontal:20,paddingVertical:12,flexDirection:'row',justifyContent:'space-between' }, - dropdown:{ borderWidth:1,borderRadius:10,borderColor:'gray',marginTop:10}, - option:{ paddingHorizontal:20,paddingVertical:8 } -}) \ No newline at end of file + wrapper: { + borderWidth: 1, + borderRadius: 10, + borderColor: "gray", + paddingHorizontal: 20, + paddingVertical: 12, + flexDirection: "row", + justifyContent: "space-between", + }, + dropdown: { + borderWidth: 1, + borderRadius: 10, + borderColor: "gray", + marginTop: 10, + }, + option: { paddingHorizontal: 20, paddingVertical: 8 }, +}); From 3c74d72ca2b28f0de8a7aa95af76fdd0da7d0030 Mon Sep 17 00:00:00 2001 From: Drl Khr Date: Tue, 26 Jul 2022 09:26:54 +0800 Subject: [PATCH 2/3] add placeholderSearch props --- README.md | 1 + index.tsx | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c15e5126..6ad0e6ff 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ For Live `Demo` [(Expo Snack)](https://snack.expo.dev/@danish1658/react-native-d | ------------------ | ---------------------- | ---------------------------------------------------------------------------------- | | onSelect | Function | Pass any function that you want to trigger immediately after a value is selected | | placeholder | String | Placeholder text that will be displayed in the select box | +| placeholderSearch | String | Placeholder text that will be displayed in the search textinput | | search | boolean | set to false if you dont want to use search functionality | | boxStyles | Object | Additional styles for select box | | inputStyles | Object | Additional styles for textinput of select box | diff --git a/index.tsx b/index.tsx index 582f256f..d1bf8a31 100644 --- a/index.tsx +++ b/index.tsx @@ -22,6 +22,11 @@ interface SelectListProps { */ placeholder?: string; + /** + * Placeholder text that will be displayed in the search textinput + */ + placeholderSearch?: string; + /** * Additional styles for select box */ @@ -86,6 +91,7 @@ interface SelectListProps { const SelectList: React.FC = ({ setSelected, placeholder, + placeholderSearch, boxStyles, inputStyles, textStyles, @@ -154,7 +160,7 @@ const SelectList: React.FC = ({ )} { let result = data.filter((item) => { val.toLowerCase(); From 99565762eff46ba7105a8a0f68b3a8ce636c462e Mon Sep 17 00:00:00 2001 From: Drl Khr Date: Wed, 27 Jul 2022 11:44:28 +0800 Subject: [PATCH 3/3] add numberOfLines props --- README.md | 1 + index.tsx | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6ad0e6ff..722f47cd 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ For Live `Demo` [(Expo Snack)](https://snack.expo.dev/@danish1658/react-native-d | dropdownItemStyles | Object | Additional styles for dropdown list item | | dropdownTextStyles | Object | Additional styles for list items text | | maxHeight | Number | Maximum height of the dropdown wrapper to occupy | +| numberOfLines | Number | Number of lines text | | data | array or array[object] | Data which will be iterated as options of select list | | setSelected | Function | For Setting the option value which will be stored in your local state | | searchicon | JSX Element | Pass any JSX to this prop like Text, Image or Icon to show instead of search icon | diff --git a/index.tsx b/index.tsx index d1bf8a31..eaaeb0ab 100644 --- a/index.tsx +++ b/index.tsx @@ -62,6 +62,11 @@ interface SelectListProps { */ maxHeight?: number; + /** + * Number of lines text + */ + numberOfLines?: number; + /** * Data which will be iterated as options of select list */ @@ -99,6 +104,7 @@ const SelectList: React.FC = ({ dropdownItemStyles, dropdownTextStyles, maxHeight, + numberOfLines, data, searchicon = false, arrowicon = false, @@ -184,7 +190,7 @@ const SelectList: React.FC = ({ } }} > - + {selectedval == "" ? placeholder ? placeholder