├── .gitignore ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── assets └── images │ ├── check.png │ ├── chevron.png │ ├── close.png │ └── search.png ├── components ├── MultipleSelectList.tsx └── SelectList.tsx ├── index.d.ts ├── index.ts └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.fontFamily": "'JetBrains Mono'", 3 | "workbench.colorTheme": "GitHub Dark Default", 4 | "workbench.preferredDarkColorTheme": "Default Dark+", 5 | "workbench.preferredHighContrastColorTheme": "Default High Contrast" 6 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 danish1658 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | | | | | | | 2 | | --------------------------------------- | -------- | ---------- |---------- |---------- | 3 | | ![NPM VERSION](https://img.shields.io/npm/v/react-native-dropdown-select-list?style=for-the-badge) | ![NPM WEEKLY DOWNLOADS](https://img.shields.io/npm/dw/react-native-dropdown-select-list?color=%232CA215&label=WEEKLY%20DOWNLOADS&style=for-the-badge) | ![GITHUB STAR](https://img.shields.io/github/stars/danish1658/react-native-dropdown-select-list?label=Give%20Us%20A%20Star&style=for-the-badge) | ![YOUTUBE VIEWS](https://img.shields.io/youtube/channel/views/UCEbbpzmnbRiNVhJ3ElABbMQ?label=YOUTUBE%20VIEWS&style=for-the-badge) | ![NPM LIFETIME DOWNLOADS](https://img.shields.io/npm/dt/react-native-dropdown-select-list?color=%232CA215&style=for-the-badge) 4 | 5 |
6 |

7 | ⭐ React Native Dropdown Select List

8 | 9 |
10 | 11 | React Native Select List Equivalent to Html's Select " 12 | 13 |
14 | 15 |

16 |

17 | 18 | Multiple Select List | Select List 19 | :-------------------------:|:-------------------------: 20 | ![](https://i.imgur.com/EAT81Nz.gif) | ![](https://i.imgur.com/qmHreFH.gif) 21 | 22 |
23 |
24 | 25 |

26 |
27 | 28 |

Light weight and Easy to use dropdown select list.

29 | 30 | - Style it your way with style props of every view. 31 | - Smooth performance on all platforms IOS, Android and Web. 32 | - Change Font Family Easily which community picker lacks. 33 | - Zero dependencies 34 | 35 |
36 | 37 | # Compatibility 38 | 39 |
40 | 41 | | iOS | Android | Web | Expo | 42 | --------|---------|-----|------| 43 | | ✅ | ✅ | ✅ | ✅ | 44 | 45 | 46 |
47 | 48 | # 🔌 Installation 49 | 50 | ```sh 51 | $ npm install react-native-dropdown-select-list 52 | 53 | ``` 54 | 55 | OR 56 | 57 | ```sh 58 | $ yarn add react-native-dropdown-select-list 59 | ``` 60 | 61 |
62 | 63 | # 😎 Basic Usage for SelectList 64 | ```jsx 65 | import { SelectList } from 'react-native-dropdown-select-list' 66 | 67 | const App = () => { 68 | 69 | const [selected, setSelected] = React.useState(""); 70 | 71 | const data = [ 72 | {key:'1', value:'Mobiles', disabled:true}, 73 | {key:'2', value:'Appliances'}, 74 | {key:'3', value:'Cameras'}, 75 | {key:'4', value:'Computers', disabled:true}, 76 | {key:'5', value:'Vegetables'}, 77 | {key:'6', value:'Diary Products'}, 78 | {key:'7', value:'Drinks'}, 79 | ] 80 | 81 | return( 82 | setSelected(val)} 84 | data={data} 85 | save="value" 86 | /> 87 | ) 88 | 89 | }; 90 | ``` 91 |
92 | 93 | # 😎 Basic Usage for MultipleSelectList 94 | ```jsx 95 | import { MultipleSelectList } from 'react-native-dropdown-select-list' 96 | 97 | const App = () => { 98 | 99 | const [selected, setSelected] = React.useState([]); 100 | 101 | const data = [ 102 | {key:'1', value:'Mobiles', disabled:true}, 103 | {key:'2', value:'Appliances'}, 104 | {key:'3', value:'Cameras'}, 105 | {key:'4', value:'Computers', disabled:true}, 106 | {key:'5', value:'Vegetables'}, 107 | {key:'6', value:'Diary Products'}, 108 | {key:'7', value:'Drinks'}, 109 | ] 110 | 111 | return( 112 | setSelected(val)} 114 | data={data} 115 | save="value" 116 | onSelect={() => alert(selected)} 117 | label="Categories" 118 | /> 119 | ) 120 | 121 | }; 122 | ``` 123 | 124 |
125 | 126 | 127 | For Live `Demo` [(Expo Snack)](https://snack.expo.dev/@danish1658/react-native-dropdown-select-list) 128 | 129 |
130 | 131 | # 🔧 General Props 132 | Applicable on both SelectList & MultipleSelectList Components 133 | 134 | | Name | Type | Description | 135 | | ---- | ---- | ----------- | 136 | | save| string | Pass ('key' or 'value') to save data of your choice in your local state variable 137 | | onSelect| Function | Pass any function that you want to trigger immediately after a value is selected 138 | | placeholder | String | Placeholder text that will be displayed in the select box 139 | | search | boolean | set to false if you dont want to use search functionality 140 | | maxHeight| Number | Maximum height of the dropdown wrapper to occupy 141 | | data| array or array[object]| Data which will be iterated as options of select list 142 | | setSelected| Function | For Setting the option value which will be stored in your local state 143 | | searchicon| JSX Element | Pass any JSX to this prop like Text, Image or Icon to show instead of search icon 144 | | arrowicon| JSX Element | Pass any JSX to this prop like Text, Image or Icon to show instead of chevron icon 145 | | closeicon| JSX Element | Pass any JSX to this prop like Text, Image or Icon to show instead of close icon 146 | | searchPlaceholder| String | Custom placeholder text for search TextInput 147 | | defaultOption| Object | Pass default selected option in key value pair 148 | | fontFamily| string | Pass font name to apply globally on each text field of component 149 | | notFoundText| string | Pass your custom message if any search result returns empty 150 | | dropdownShown| boolean | Control your dropdown ( on & off ) state by changing its value to true or false 151 | 152 |
153 | 154 | # 🔧 General Style Props 155 | Applicable on both SelectList & MultipleSelectList Components 156 | 157 | | Name | Type | Description | 158 | | ---- | ---- | ----------- | 159 | | boxStyles| Object| Additional styles for select box parent wrapper 160 | | inputStyles| Object| Additional styles for text of selection box 161 | | dropdownStyles| Object| Additional styles for dropdown scrollview 162 | | dropdownItemStyles| Object| Additional styles for dropdown single list item 163 | | dropdownTextStyles| Object| Additional styles for dropdown list items text 164 | | disabledItemStyles| Object| Additional styles for disabled dropdown list item 165 | | disabledTextStyles| Object| Additional styles for disabled dropdown list items text 166 | 167 |
168 | 169 | # 😎 Advanced Usage 170 | ```jsx 171 | import { SelectList } from 'react-native-dropdown-select-list' 172 | 173 | const App = () => { 174 | 175 | const [selected, setSelected] = React.useState(""); 176 | 177 | const data = [ 178 | {key:'1',value:'Jammu & Kashmir'}, 179 | {key:'2',value:'Gujrat'}, 180 | {key:'3',value:'Maharashtra'}, 181 | {key:'4',value:'Goa'}, 182 | ]; 183 | 184 | return( 185 | alert(selected)} 187 | setSelected={setSelected} 188 | fontFamily='lato' 189 | data={data} 190 | arrowicon={} 191 | searchicon={} 192 | search={false} 193 | boxStyles={{borderRadius:0}} //override default styles 194 | defaultOption={{ key:'1', value:'Jammu & Kashmir' }} //default selected option 195 | /> 196 | ) 197 | 198 | }; 199 | ``` 200 | 201 |
202 | 203 | # 😎 Getting Options From Database 204 | ```jsx 205 | import { SelectList } from 'react-native-dropdown-select-list' 206 | 207 | const App = () => { 208 | 209 | const [selected, setSelected] = React.useState(""); 210 | const [data,setData] = React.useState([]); 211 | 212 | React.useEffect(() => 213 | //Get Values from database 214 | axios.get('https://jsonplaceholder.typicode.com/users') 215 | .then((response) => { 216 | // Store Values in Temporary Array 217 | let newArray = response.data.map((item) => { 218 | return {key: item.id, value: item.name} 219 | }) 220 | //Set Data Variable 221 | setData(newArray) 222 | }) 223 | .catch((e) => { 224 | console.log(e) 225 | }) 226 | ,[]) 227 | 228 | return( 229 | alert(selected)} /> 230 | ) 231 | 232 | }; 233 | ``` 234 | 235 |
236 | 237 | # 🔧 Additional Props 238 | Applicable on MultipleSelectList Only 239 | 240 | | Name | Type | Description | 241 | | ---- | ---- | ----------- | 242 | | label| string| Pass any string to be placed instead of default label 243 | 244 | 245 |
246 | 247 | # 🔧 Additional Style Props 248 | Applicable on MultipleSelectList Only 249 | 250 | | Name | Type | Description | 251 | | ---- | ---- | ----------- | 252 | | disabledCheckBoxStyles| Object| Additional styles disabled checkbox inside dropdown 253 | | checkBoxStyles| Object| Additional styles for active checkbox 254 | | badgeStyles| Object| Additional styles for badges of selected values 255 | | badgeTextStyles| Object| Additional styles for Text of badges of selected values 256 | | labelStyles| Object| Additional styles for label of multiple select list 257 | 258 |
259 | 260 | 261 | # ▶️ Watch Video 262 | 263 | [![Watch the video](https://i.imgur.com/K8Lt2h4.png)](https://www.youtube.com/watch?v=J9raEY-1KPQ&t=499s) 264 | 265 |
266 | 267 | # 💲 Would you like to support me? 268 | 269 | If you would like me come up with similar packages, buy me a cup of coffee to boost my energy. 270 |

271 | [![Paypal](https://www.paypalobjects.com/webstatic/mktg/Logo/pp-logo-100px.png)](https://paypal.me/danishamindar) 272 |

273 | For Live `Demo` [(Expo Snack)](https://snack.expo.dev/@danish1658/react-native-dropdown-select-list) 274 | 275 |
276 | -------------------------------------------------------------------------------- /assets/images/check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danish1658/react-native-dropdown-select-list/f4f01abcb80708adb5575b67f635f521b9d0b03c/assets/images/check.png -------------------------------------------------------------------------------- /assets/images/chevron.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danish1658/react-native-dropdown-select-list/f4f01abcb80708adb5575b67f635f521b9d0b03c/assets/images/chevron.png -------------------------------------------------------------------------------- /assets/images/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danish1658/react-native-dropdown-select-list/f4f01abcb80708adb5575b67f635f521b9d0b03c/assets/images/close.png -------------------------------------------------------------------------------- /assets/images/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danish1658/react-native-dropdown-select-list/f4f01abcb80708adb5575b67f635f521b9d0b03c/assets/images/search.png -------------------------------------------------------------------------------- /components/MultipleSelectList.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | View, 4 | Text, 5 | StyleSheet, 6 | Image, 7 | TouchableOpacity, 8 | ScrollView, 9 | Animated, 10 | TextInput, 11 | ViewStyle, 12 | Pressable, 13 | Keyboard 14 | } from 'react-native'; 15 | 16 | import { MultipleSelectListProps } from '..'; 17 | 18 | type L1Keys = { key?: any; value?: any; disabled?: boolean | undefined } 19 | 20 | const MultipleSelectList: React.FC = ({ 21 | fontFamily, 22 | setSelected, 23 | placeholder, 24 | boxStyles, 25 | inputStyles, 26 | dropdownStyles, 27 | dropdownItemStyles, 28 | dropdownTextStyles, 29 | maxHeight, 30 | data, 31 | searchicon = false, 32 | arrowicon = false, 33 | closeicon = false, 34 | search = true, 35 | searchPlaceholder = "search", 36 | onSelect = () => {}, 37 | label, 38 | notFoundText = "No data found", 39 | disabledItemStyles, 40 | disabledTextStyles, 41 | disabledCheckBoxStyles, 42 | labelStyles, 43 | badgeStyles, 44 | badgeTextStyles, 45 | checkBoxStyles, 46 | save = 'key', 47 | dropdownShown = false 48 | }) => { 49 | 50 | const oldOption = React.useRef(null) 51 | const [_firstRender,_setFirstRender] = React.useState(true); 52 | const [dropdown, setDropdown] = React.useState(dropdownShown); 53 | const [selectedval, setSelectedVal] = React.useState([]); 54 | const [height,setHeight] = React.useState(350) 55 | const animatedvalue = React.useRef(new Animated.Value(0)).current; 56 | const [filtereddata,setFilteredData] = React.useState(data); 57 | 58 | 59 | const slidedown = () => { 60 | setDropdown(true) 61 | 62 | Animated.timing(animatedvalue,{ 63 | toValue:height, 64 | duration:500, 65 | useNativeDriver:false, 66 | 67 | }).start() 68 | } 69 | const slideup = () => { 70 | 71 | Animated.timing(animatedvalue,{ 72 | toValue:0, 73 | duration:500, 74 | useNativeDriver:false, 75 | 76 | }).start(() => setDropdown(false)) 77 | } 78 | 79 | React.useEffect( () => { 80 | if(maxHeight) 81 | setHeight(maxHeight) 82 | },[maxHeight]) 83 | 84 | 85 | React.useEffect(() => { 86 | setFilteredData(data); 87 | },[data]) 88 | 89 | 90 | React.useEffect(() => { 91 | if(_firstRender){ 92 | _setFirstRender(false); 93 | return; 94 | } 95 | onSelect() 96 | 97 | },[selectedval]) 98 | 99 | React.useEffect(() => { 100 | if(!_firstRender){ 101 | if(dropdownShown) 102 | slidedown(); 103 | else 104 | slideup(); 105 | 106 | } 107 | 108 | },[dropdownShown]) 109 | 110 | 111 | 112 | 113 | 114 | 115 | return( 116 | 117 | { 118 | (dropdown && search) 119 | ? 120 | 121 | 122 | { 123 | (!searchicon) 124 | ? 125 | 130 | : 131 | searchicon 132 | } 133 | 134 | { 137 | let result = data.filter((item: L1Keys) => { 138 | val.toLowerCase(); 139 | let row = item.value.toLowerCase() 140 | return row.search(val.toLowerCase()) > -1; 141 | }); 142 | setFilteredData(result) 143 | }} 144 | style={[{padding:0,height:20,flex:1,fontFamily},inputStyles]} 145 | /> 146 | { 147 | slideup() 148 | // setTimeout(() => setFilteredData(data), 800) 149 | }} > 150 | { 151 | (!closeicon) 152 | ? 153 | 158 | : 159 | closeicon 160 | } 161 | 162 | 163 | 164 | 165 | 166 | 167 | : 168 | 169 | (selectedval?.length > 0 ) 170 | 171 | ? 172 | { if(!dropdown){ Keyboard.dismiss(); slidedown() }else{ slideup() } }} > 173 | 174 | { label } 175 | 176 | { 177 | selectedval?.map((item,index) => { 178 | return ( 179 | 180 | {item} 181 | 182 | ) 183 | }) 184 | } 185 | 186 | 187 | 188 | : 189 | { if(!dropdown){ Keyboard.dismiss(); slidedown() }else{ slideup() } }}> 190 | { (selectedval == "") ? (placeholder) ? placeholder : 'Select option' : selectedval } 191 | { 192 | (!arrowicon) 193 | ? 194 | 199 | : 200 | arrowicon 201 | } 202 | 203 | 204 | } 205 | 206 | { 207 | (dropdown) 208 | ? 209 | 210 | 211 | 212 | 213 | { 214 | (filtereddata.length >= 1) 215 | ? 216 | filtereddata.map((item: L1Keys,index: number) => { 217 | let key = item.key ?? item.value ?? item; 218 | let value = item.value ?? item; 219 | let disabled = item.disabled ?? false; 220 | if(disabled){ 221 | return( 222 | 223 | 224 | 225 | { 226 | (selectedval?.includes(value)) 227 | ? 228 | 229 | 235 | 236 | : 237 | null 238 | 239 | } 240 | 241 | {value} 242 | 243 | ) 244 | }else{ 245 | return( 246 | { 247 | 248 | 249 | let existing = selectedval?.indexOf(value) 250 | 251 | 252 | // console.log(existing); 253 | 254 | if(existing != -1 && existing != undefined){ 255 | 256 | let sv = [...selectedval]; 257 | sv.splice(existing,1) 258 | setSelectedVal(sv); 259 | 260 | 261 | setSelected((val: any) => { 262 | let temp = [...val]; 263 | temp.splice(existing,1) 264 | return temp; 265 | }); 266 | 267 | // onSelect() 268 | }else{ 269 | if(save === 'value'){ 270 | setSelected((val: any) => { 271 | let temp = [...new Set([...val,value])]; 272 | return temp; 273 | }) 274 | }else{ 275 | setSelected((val: any) => { 276 | let temp = [...new Set([...val,key])]; 277 | return temp; 278 | }) 279 | } 280 | 281 | setSelectedVal((val: any )=> { 282 | let temp = [...new Set([...val,value])]; 283 | return temp; 284 | }) 285 | 286 | 287 | // onSelect() 288 | } 289 | 290 | 291 | 292 | }}> 293 | 294 | 295 | { 296 | (selectedval?.includes(value)) 297 | ? 298 | 299 | 305 | 306 | : 307 | null 308 | 309 | } 310 | 311 | 312 | 313 | 314 | 315 | {value} 316 | 317 | ) 318 | } 319 | 320 | }) 321 | : 322 | { 323 | setSelected(undefined) 324 | setSelectedVal("") 325 | slideup() 326 | setTimeout(() => setFilteredData(data), 800) 327 | }}> 328 | {notFoundText} 329 | 330 | } 331 | 332 | 333 | 334 | 335 | 336 | { 337 | (selectedval?.length > 0) 338 | ? 339 | 340 | 341 | Selected 342 | 343 | 344 | 345 | 346 | { 347 | selectedval?.map((item,index) => { 348 | return ( 349 | 350 | {item} 351 | 352 | ) 353 | }) 354 | } 355 | 356 | 357 | 358 | : 359 | null 360 | } 361 | 362 | 363 | 364 | 365 | 366 | 367 | : 368 | null 369 | } 370 | 371 | 372 | 373 | ) 374 | } 375 | 376 | export default MultipleSelectList; 377 | 378 | const styles = StyleSheet.create({ 379 | wrapper:{ borderWidth:1,borderRadius:10,borderColor:'gray',paddingHorizontal:20,paddingVertical:12,flexDirection:'row',justifyContent:'space-between',marginBottom:10 }, 380 | dropdown:{ borderWidth:1,borderRadius:10,borderColor:'gray',overflow:'hidden'}, 381 | option:{ paddingHorizontal:20,paddingVertical:8,flexDirection:'row',alignItems:'center'}, 382 | disabledoption:{ paddingHorizontal:20,paddingVertical:8,flexDirection:'row',alignItems:'center', backgroundColor:'whitesmoke'} 383 | 384 | }) 385 | -------------------------------------------------------------------------------- /components/SelectList.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | View, 4 | Text, 5 | StyleSheet, 6 | Image, 7 | TouchableOpacity, 8 | ScrollView, 9 | Animated, 10 | TextInput, 11 | Keyboard 12 | } from 'react-native'; 13 | 14 | import { SelectListProps } from '..'; 15 | 16 | type L1Keys = { key?: any; value?: any; disabled?: boolean | undefined } 17 | 18 | const SelectList: React.FC = ({ 19 | setSelected, 20 | placeholder, 21 | boxStyles, 22 | inputStyles, 23 | dropdownStyles, 24 | dropdownItemStyles, 25 | dropdownTextStyles, 26 | maxHeight, 27 | data, 28 | defaultOption, 29 | searchicon = false, 30 | arrowicon = false, 31 | closeicon = false, 32 | search = true, 33 | searchPlaceholder = "search", 34 | notFoundText = "No data found", 35 | disabledItemStyles, 36 | disabledTextStyles, 37 | onSelect = () => {}, 38 | save = 'key', 39 | dropdownShown = false, 40 | fontFamily 41 | }) => { 42 | 43 | const oldOption = React.useRef(null) 44 | const [_firstRender,_setFirstRender] = React.useState(true); 45 | const [dropdown, setDropdown] = React.useState(dropdownShown); 46 | const [selectedval, setSelectedVal] = React.useState(""); 47 | const [height,setHeight] = React.useState(200) 48 | const animatedvalue = React.useRef(new Animated.Value(0)).current; 49 | const [filtereddata,setFilteredData] = React.useState(data) 50 | 51 | 52 | const slidedown = () => { 53 | setDropdown(true) 54 | Animated.timing(animatedvalue,{ 55 | toValue:height, 56 | duration:500, 57 | useNativeDriver:false, 58 | 59 | }).start() 60 | } 61 | const slideup = () => { 62 | 63 | Animated.timing(animatedvalue,{ 64 | toValue:0, 65 | duration:500, 66 | useNativeDriver:false, 67 | 68 | }).start(() => setDropdown(false)) 69 | } 70 | 71 | React.useEffect( () => { 72 | if(maxHeight) 73 | setHeight(maxHeight) 74 | },[maxHeight]) 75 | 76 | 77 | React.useEffect(() => { 78 | setFilteredData(data); 79 | },[data]) 80 | 81 | 82 | React.useEffect(() => { 83 | if(_firstRender){ 84 | _setFirstRender(false); 85 | return; 86 | } 87 | onSelect() 88 | },[selectedval]) 89 | 90 | 91 | React.useEffect(() => { 92 | if(!_firstRender && defaultOption && oldOption.current != defaultOption.key ){ 93 | // oldOption.current != null 94 | oldOption.current = defaultOption.key 95 | setSelected(defaultOption.key); 96 | setSelectedVal(defaultOption.value); 97 | } 98 | if(defaultOption && _firstRender && defaultOption.key != undefined){ 99 | 100 | oldOption.current = defaultOption.key 101 | setSelected(defaultOption.key); 102 | setSelectedVal(defaultOption.value); 103 | } 104 | 105 | },[defaultOption]) 106 | 107 | React.useEffect(() => { 108 | if(!_firstRender){ 109 | if(dropdownShown) 110 | slidedown(); 111 | else 112 | slideup(); 113 | 114 | } 115 | 116 | },[dropdownShown]) 117 | 118 | 119 | 120 | return( 121 | 122 | { 123 | (dropdown && search) 124 | ? 125 | 126 | 127 | { 128 | (!searchicon) 129 | ? 130 | 135 | : 136 | searchicon 137 | } 138 | 139 | { 142 | let result = data.filter((item: L1Keys) => { 143 | val.toLowerCase(); 144 | let row = item.value.toLowerCase() 145 | return row.search(val.toLowerCase()) > -1; 146 | }); 147 | setFilteredData(result) 148 | }} 149 | style={[{padding:0,height:20,flex:1,fontFamily},inputStyles]} 150 | /> 151 | slideup()} > 152 | 153 | { 154 | (!closeicon) 155 | ? 156 | 161 | : 162 | closeicon 163 | } 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | : 172 | { if(!dropdown){ Keyboard.dismiss(); slidedown() }else{ slideup() } }}> 173 | { (selectedval == "") ? (placeholder) ? placeholder : 'Select option' : selectedval } 174 | { 175 | (!arrowicon) 176 | ? 177 | 182 | : 183 | arrowicon 184 | } 185 | 186 | 187 | } 188 | 189 | { 190 | (dropdown) 191 | ? 192 | 193 | 194 | 195 | { 196 | (filtereddata.length >= 1) 197 | ? 198 | filtereddata.map((item: L1Keys,index: number) => { 199 | let key = item.key ?? item.value ?? item; 200 | let value = item.value ?? item; 201 | let disabled = item.disabled ?? false; 202 | if(disabled){ 203 | return( 204 | {}}> 205 | {value} 206 | 207 | ) 208 | }else{ 209 | return( 210 | { 211 | if(save === 'value'){ 212 | setSelected(value); 213 | }else{ 214 | setSelected(key) 215 | } 216 | 217 | setSelectedVal(value) 218 | slideup() 219 | setTimeout(() => {setFilteredData(data)}, 800) 220 | 221 | }}> 222 | {value} 223 | 224 | ) 225 | } 226 | 227 | }) 228 | : 229 | { 230 | setSelected(undefined) 231 | setSelectedVal("") 232 | slideup() 233 | setTimeout(() => setFilteredData(data), 800) 234 | 235 | }}> 236 | {notFoundText} 237 | 238 | } 239 | 240 | 241 | 242 | 243 | 244 | : 245 | null 246 | } 247 | 248 | 249 | 250 | ) 251 | } 252 | 253 | 254 | export default SelectList; 255 | 256 | 257 | const styles = StyleSheet.create({ 258 | wrapper:{ borderWidth:1,borderRadius:10,borderColor:'gray',paddingHorizontal:20,paddingVertical:12,flexDirection:'row',justifyContent:'space-between' }, 259 | dropdown:{ borderWidth:1,borderRadius:10,borderColor:'gray',marginTop:10,overflow:'hidden'}, 260 | option:{ paddingHorizontal:20,paddingVertical:8,overflow:'hidden' }, 261 | disabledoption:{ paddingHorizontal:20,paddingVertical:8,flexDirection:'row',alignItems:'center', backgroundColor:'whitesmoke',opacity:0.9} 262 | 263 | }) 264 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | 2 | import type * as React from "react"; 3 | import { ViewStyle, TextStyle } from 'react-native'; 4 | 5 | export interface SelectListProps { 6 | /** 7 | * Fn to set Selected option value which will be stored in your local state 8 | */ 9 | setSelected: Function, 10 | 11 | /** 12 | * Placeholder text that will be displayed in the select box 13 | */ 14 | placeholder?: string, 15 | 16 | /** 17 | * Additional styles for select box 18 | */ 19 | boxStyles?: ViewStyle, 20 | 21 | /** 22 | * Additional styles for text of select box 23 | */ 24 | inputStyles?: TextStyle, 25 | 26 | /** 27 | * Additional styles for dropdown scrollview 28 | */ 29 | dropdownStyles?:ViewStyle, 30 | 31 | /** 32 | * Additional styles for dropdown list item 33 | */ 34 | dropdownItemStyles?: ViewStyle, 35 | 36 | /** 37 | * Additional styles for list items text 38 | */ 39 | dropdownTextStyles?: TextStyle, 40 | 41 | /** 42 | * Maximum height of the dropdown wrapper to occupy 43 | */ 44 | maxHeight?: number, 45 | 46 | /** 47 | * Data which will be iterated as options of select list 48 | */ 49 | data: Array<{}>, 50 | 51 | /** 52 | * The default option of the select list 53 | */ 54 | defaultOption?: { key: any, value: any }, 55 | 56 | /** 57 | * Pass any JSX to this prop like Text, Image or Icon to show instead of search icon 58 | */ 59 | searchicon?: JSX.Element, 60 | 61 | /** 62 | * Pass any JSX to this prop like Text, Image or Icon to show instead of chevron icon 63 | */ 64 | arrowicon?: JSX.Element, 65 | 66 | /** 67 | * set to false if you dont want to use search functionality 68 | */ 69 | search?: boolean, 70 | 71 | /** 72 | * set to false if you dont want to use search functionality 73 | */ 74 | searchPlaceholder?: string, 75 | 76 | /** 77 | * Trigger an action when option is selected 78 | */ 79 | onSelect?: () => void, 80 | 81 | /** 82 | * set fontFamily of whole component Text 83 | */ 84 | fontFamily?: string, 85 | 86 | /** 87 | * set this to change the default search failure text 88 | */ 89 | notFoundText?: string, 90 | 91 | /** 92 | * Additional styles for disabled list item 93 | */ 94 | disabledItemStyles?: ViewStyle, 95 | 96 | /** 97 | * Additional styles for disabled list items text 98 | */ 99 | disabledTextStyles?: TextStyle, 100 | 101 | /** 102 | * What to store inside your local state (key or value) 103 | */ 104 | save?: 'key' | 'value', 105 | 106 | /** 107 | * Control the dropdown with this prop 108 | */ 109 | dropdownShown?: boolean, 110 | 111 | /** 112 | * Pass any JSX to this prop like Text, Image or Icon to show instead of close icon 113 | */ 114 | closeicon?: JSX.Element, 115 | } 116 | 117 | 118 | export interface MultipleSelectListProps { 119 | /** 120 | * Fn to set Selected option value which will be stored in your local state 121 | */ 122 | setSelected: Function, 123 | 124 | /** 125 | * Placeholder text that will be displayed in the select box 126 | */ 127 | placeholder?: string, 128 | 129 | /** 130 | * Additional styles for select box 131 | */ 132 | boxStyles?: ViewStyle, 133 | 134 | /** 135 | * Additional styles for text of select box 136 | */ 137 | inputStyles?: TextStyle, 138 | 139 | /** 140 | * Additional styles for dropdown scrollview 141 | */ 142 | dropdownStyles?:ViewStyle, 143 | 144 | /** 145 | * Additional styles for dropdown list item 146 | */ 147 | dropdownItemStyles?: ViewStyle, 148 | 149 | /** 150 | * Additional styles for list items text 151 | */ 152 | dropdownTextStyles?: TextStyle, 153 | 154 | /** 155 | * Maximum height of the dropdown wrapper to occupy 156 | */ 157 | maxHeight?: number, 158 | 159 | /** 160 | * Data which will be iterated as options of select list 161 | */ 162 | data: Array<{}>, 163 | 164 | /** 165 | * The default option of the select list 166 | */ 167 | defaultOption?: { key: any, value: any }, 168 | 169 | /** 170 | * Pass any JSX to this prop like Text, Image or Icon to show instead of search icon 171 | */ 172 | searchicon?: JSX.Element, 173 | 174 | /** 175 | * Pass any JSX to this prop like Text, Image or Icon to show instead of chevron icon 176 | */ 177 | arrowicon?: JSX.Element, 178 | 179 | /** 180 | * set to false if you dont want to use search functionality 181 | */ 182 | search?: boolean, 183 | 184 | /** 185 | * set to false if you dont want to use search functionality 186 | */ 187 | searchPlaceholder?: string, 188 | 189 | /** 190 | * Trigger an action when option is selected 191 | */ 192 | onSelect?: () => void, 193 | 194 | /** 195 | * set text of label which appears soon after multiple values are selected 196 | */ 197 | label?: string, 198 | 199 | /** 200 | * set fontFamily of whole component Text 201 | */ 202 | fontFamily?: string, 203 | 204 | /** 205 | * set this to change the default search failure text 206 | */ 207 | notFoundText?: string, 208 | 209 | /** 210 | * Additional styles for disabled list item 211 | */ 212 | disabledItemStyles?: ViewStyle, 213 | 214 | /** 215 | * Additional styles for disabled list items text 216 | */ 217 | disabledTextStyles?: TextStyle, 218 | 219 | 220 | /** 221 | * Additional styles for disabled checkbox 222 | */ 223 | disabledCheckBoxStyles?: ViewStyle, 224 | 225 | /** 226 | * Additional styles for checkbox 227 | */ 228 | checkBoxStyles?: ViewStyle, 229 | 230 | /** 231 | * What to store inside your local state (key or value) 232 | */ 233 | save?: 'key' | 'value', 234 | 235 | /** 236 | * Control the dropdown with this prop 237 | */ 238 | dropdownShown?: boolean, 239 | 240 | /** 241 | * Pass any JSX to this prop like Text, Image or Icon to show instead of close icon 242 | */ 243 | closeicon?: JSX.Element, 244 | 245 | 246 | /** 247 | * Additional styles for multiselect badge 248 | */ 249 | badgeStyles?: ViewStyle, 250 | 251 | /** 252 | * Additional styles for multiselect badge text 253 | */ 254 | badgeTextStyles?: ViewStyle, 255 | 256 | /** 257 | * Additional styles for label 258 | */ 259 | labelStyles?: TextStyle, 260 | } 261 | 262 | declare class MultipleSelectList extends React.Component {} 263 | 264 | declare class SelectList extends React.Component {} 265 | 266 | export { 267 | MultipleSelectList, 268 | SelectList 269 | }; -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | import SelectList from './components/SelectList'; 2 | import MultipleSelectList from './components/MultipleSelectList'; 3 | export { SelectList, MultipleSelectList }; 4 | 5 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-dropdown-select-list", 3 | "version": "2.0.3", 4 | "description": "⭐ React Native Select List Equivalent to Html's Select with options\"", 5 | "main": "index.ts", 6 | "types": "index.d.ts", 7 | "scripts": { 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/danish1658/react-native-dropdown-select-list.git" 13 | }, 14 | "keywords": [ 15 | "picker", 16 | "select", 17 | "dropdown", 18 | "android", 19 | "ios", 20 | "selectlist", 21 | "searchable", 22 | "list", 23 | "dropdown-picker", 24 | "react", 25 | "react native", 26 | "react-native", 27 | "reactnative", 28 | "selectlist", 29 | "expo", 30 | "easy", 31 | "menu", 32 | "tag", 33 | "chooser", 34 | "multiple", 35 | "multi" 36 | ], 37 | "devDependencies": { 38 | "react": "17.0.2", 39 | "react-native": "0.68.2", 40 | "@types/react": "^18.0.25", 41 | "@types/react-native": "^0.70.6", 42 | "typescript": "^4.8.4" 43 | }, 44 | "author": "Danish Amin Dar", 45 | "license": "MIT", 46 | "bugs": { 47 | "url": "https://github.com/danish1658/react-native-dropdown-select-list/issues" 48 | }, 49 | "homepage": "https://github.com/danish1658/react-native-dropdown-select-list#readme" 50 | } 51 | --------------------------------------------------------------------------------