Dropdown Item picker with search and autocomplete (typeahead) functionality for react native
This is documentation for version 4.x, if you are looking docs for version 3.x, you can find it here
Run expo snack demo @onmotion/react-native-autocomplete-dropdown
or download the Expo Go app and scan the QR code below
- react-native-autocomplete-dropdown - Demo - Nav - Installation - Post-install Steps - iOS - Android - Usage - Dataset item format - Example with local Dataset - Example with remote requested Dataset - Playground - Options - Usage with a Modal
Run:
or
yarn add react-native-autocomplete-dropdownor for v3.x
yarn add react-native-autocomplete-dropdown@3.1.5Make sure react-native-svg is installed. Follow the guide https://github.com/software-mansion/react-native-svg
yarn add react-native-svgRun: npx pod-install for install react-native-svg dependency (if not installed yet).
No additional steps are necessary
Wrap your root component in AutocompleteDropdownContextProvider from react-native-autocomplete-dropdown as you can see in example
<AutocompleteDropdownContextProvider>
<AppRootOrWhatever/>
</AutocompleteDropdownContextProvider>The dropdown position is relative to the AutocompleteDropdownContextProvider, so put this in the right place, it should cover all the screen/modal.
If you have a header component, you can pass an offset. For example with react navigation
//...
import { useHeaderHeight } from '@react-navigation/elements';
//...
const headerHeight = useHeaderHeight();
//...
<AutocompleteDropdownContextProvider headerOffset={headerHeight} >
<AppRootOrWhatever/>
</AutocompleteDropdownContextProvider>import the package
import { AutocompleteDropdown } from 'react-native-autocomplete-dropdown';dataSet property must be an array of objects or null. Object required keys are:
{
id: 'some uniq string id',
title: 'list item title'
}const [selectedItem, setSelectedItem] = useState(null);
<AutocompleteDropdown
clearOnFocus={false}
closeOnBlur={true}
closeOnSubmit={false}
initialValue={{ id: '2' }} // or just '2'
onSelectItem={setSelectedItem}
dataSet={[
{ id: '1', title: 'Alpha' },
{ id: '2', title: 'Beta' },
{ id: '3', title: 'Gamma' },
]}
/>;import React, { memo, useCallback, useRef, useState } from 'react'
import { Button, Dimensions, Text, View, Platform } from 'react-native'
import { AutocompleteDropdown } from 'react-native-autocomplete-dropdown'
export const RemoteDataSetExample2 = memo(() => {
const [loading, setLoading] = useState(false)
const [suggestionsList, setSuggestionsList] = useState(null)
const [selectedItem, setSelectedItem] = useState(null)
const dropdownController = useRef(null)
const searchRef = useRef(null)
const getSuggestions = useCallback(async q => {
const filterToken = q.toLowerCase()
console.log('getSuggestions', q)
if (typeof q !== 'string' || q.length < 3) {
setSuggestionsList(null)
return
}
setLoading(true)
const response = await fetch('https://jsonplaceholder.typicode.com/posts')
const items = await response.json()
const suggestions = items
.filter(item => item.title.toLowerCase().includes(filterToken))
.map(item => ({
id: item.id,
title: item.title,
}))
setSuggestionsList(suggestions)
setLoading(false)
}, [])
const onClearPress = useCallback(() => {
setSuggestionsList(null)
}, [])
const onOpenSuggestionsList = useCallback(isOpened => {}, [])
return (
<>
<View
style={[
{ flex: 1, flexDirection: 'row', alignItems: 'center' },
Platform.select({ ios: { zIndex: 1 } }),
]}>
<AutocompleteDropdown
ref={searchRef}
controller={controller => {
dropdownController.current = controller
}}
// initialValue={'1'}
direction={Platform.select({ ios: 'down' })}
dataSet={suggestionsList}
onChangeText={getSuggestions}
onSelectItem={item => {
item && setSelectedItem(item.id)
}}
debounce={600}
suggestionsListMaxHeight={Dimensions.get('window').height * 0.4}
onClear={onClearPress}
// onSubmit={(e) => onSubmitSearch(e.nativeEvent.text)}
onOpenSuggestionsList={onOpenSuggestionsList}
loading={loading}
useFilter={false} // set false to prevent rerender twice
textInputProps={{
placeholder: 'Type 3+ letters (dolo...)',
autoCorrect: false,
autoCapitalize: 'none',
style: {
borderRadius: 25,
backgroundColor: '#383b42',
color: '#fff',
paddingLeft: 18,
},
}}
rightButtonsContainerStyle={{
right: 8,
height: 30,
alignSelf: 'center',
}}
inputContainerStyle={{
backgroundColor: '#383b42',
borderRadius: 25,
}}
suggestionsListContainerStyle={{
backgroundColor: '#383b42',
}}
containerStyle={{ flexGrow: 1, flexShrink: 1 }}
renderItem={(item, text) => <Text style={{ color: '#fff', padding: 15 }}>{item.title}</Text>}
// ChevronIconComponent={<Feather name="chevron-down" size={20} color="#fff" />}
// ClearIconComponent={<Feather name="x-circle" size={18} color="#fff" />}
inputHeight={50}
showChevron={false}
closeOnBlur={false}
// showClear={false}
/>
<View style={{ width: 10 }} />
<Button style={{ flexGrow: 0 }} title="Toggle" onPress={() => dropdownController.current.toggle()} />
</View>
<Text style={{ color: '#668', fontSize: 13 }}>Selected item id: {JSON.stringify(selectedItem)}</Text>
</>
)
})More examples see at https://github.com/onmotion/react-native-autocomplete-dropdown/tree/main/example
To play around with the examples, you can run the following commands
cd example
yarn install
yarn pods
yarn ios
yarn androidif you want to use the dropdown in a modal, you need to wrap the dropdown in another AutocompleteDropdownContextProvider inside the modal component
<Modal
visible={opened}
presentationStyle="formSheet"
animationType="slide"
onRequestClose={() => setOpened(false)}>
<SafeAreaView style={{ flex: 1, backgroundColor: 'transparent' }}>
<AutocompleteDropdownContextProvider>
<View style={{ paddingHorizontal: 20, flex: 1, paddingTop: 20 }}>
<AutocompleteDropdown {...props}/>
</View>
</AutocompleteDropdownContextProvider>
</SafeAreaView>
</Modal>



