UNPKG

react-native-autocomplete-dropdown

Version:

Dropdown Item picker with search and autocomplete (typeahead) functionality for react native

296 lines (243 loc) 15.3 kB
# react-native-autocomplete-dropdown Dropdown Item picker with search and autocomplete (typeahead) functionality for react native [![license](https://img.shields.io/github/license/onmotion/react-native-autocomplete-dropdown)](https://img.shields.io/github/license/onmotion/react-native-autocomplete-dropdown) [![npm](https://img.shields.io/npm/v/react-native-autocomplete-dropdown.svg)](https://npmjs.com/package/react-native-autocomplete-dropdown) [![npm](https://img.shields.io/npm/dm/react-native-autocomplete-dropdown.svg)](https://npmjs.com/package/react-native-autocomplete-dropdown) > This is documentation for version 3.x, if you are looking docs for version 2.x, you can find it [here](https://github.com/onmotion/react-native-autocomplete-dropdown/blob/main/README%5E2.md) <p style="text-align: center;" align="center"> <img src="./screens/Example.png" width="500px" > </p> ## Demo <p style="text-align: center;" align="center"> <img src="./screens/android.gif" width="280px" > <img src="./screens/ios.gif" width="280px" > </p> > Run expo snack demo [@onmotion/react-native-autocomplete-dropdown](https://snack.expo.io/@onmotion/react-native-autocomplete-dropdown-v3) <img src="./screens/expo-qr.png" width="150"> ## Nav - [react-native-autocomplete-dropdown](#react-native-autocomplete-dropdown) - [Demo](#demo) - [Nav](#nav) - [Installation](#installation) - [Post-install Steps](#post-install-steps) - [iOS](#ios) - [Android](#android) - [Usage](#usage) - [Dataset item format](#dataset-item-format) - [Example with local Dataset](#example-with-local-dataset) - [Example with remote requested Dataset](#example-with-remote-requested-dataset) - [Options](#options) ## Installation Run: ```bash npm install --save react-native-autocomplete-dropdown ``` or ```bash yarn add react-native-autocomplete-dropdown ``` ## Post-install Steps Make sure **react-native-svg** is installed. Follow the guide <https://github.com/software-mansion/react-native-svg> ```bash yarn add react-native-svg ``` ### iOS Run: `npx pod-install` for install `react-native-svg` dependency (if not installed yet). ### Android No additional steps are necessary ## Usage Wrap your root component in `AutocompleteDropdownContextProvider` from `react-native-autocomplete-dropdown` as you can see in [example](https://github.com/onmotion/react-native-autocomplete-dropdown/blob/main/example/App.js) ```js <AutocompleteDropdownContextProvider> <AppRootOrWhatever/> </AutocompleteDropdownContextProvider> ``` If you have a header component, you can pass an offset. For example with react navigation ```js //... import { useHeaderHeight } from '@react-navigation/elements'; //... const headerHeight = useHeaderHeight(); //... <AutocompleteDropdownContextProvider headerOffset={headerHeight} > <AppRootOrWhatever/> </AutocompleteDropdownContextProvider> ``` import the package ```js import { AutocompleteDropdown } from 'react-native-autocomplete-dropdown'; ``` ### Dataset item format `dataSet` property must be an **array of objects** or **null**. Object required keys are: ```js { id: 'some uniq string id', title: 'list item title' } ``` ### Example with local Dataset ```js 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' }, ]} />; ``` ### Example with remote requested Dataset ```js 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> ## Playground ```bash cd example yarn install npx pod-install yarn ios ``` ## Options | **Option** | **Description** | **Type** | **Default** | |--- |-----------------------------------------------------------------------------------------------------------------|--- |-----------------------------------------------| | `dataSet` | set of list items | array | null | | `initialValue` | string (**id**) or object that contain **id** | string \| object | null | | `loading` | loading state | bool | false | | `useFilter` | whether use local filter by dataSet (useful set to false for remote filtering to prevent rerender twice) | bool | true | | `showClear` | show clear button | bool | true | | `showChevron` | show chevron (open/close) button | bool | true | | `closeOnBlur` | whether to close dropdown on blur | bool | false | | `closeOnSubmit` | whether to close dropdown on submit | bool | false | | `clearOnFocus` | whether to clear typed text on focus | bool | true | | `ignoreAccents` | ignore diacritics | bool | true | | `trimSearchText` | trim the searched text | bool | true | | `debounce` | wait **ms** before call `onChangeText` | number | 0 | | `suggestionsListMaxHeight` | max height of dropdown | number | 200 | | `direction` | "up" or "down" | string | down + auto calculate | | `matchFrom` | whether match suggestions from start of titles or anywhere in the title. Possible values are "any" or "start" | string | any | | `bottomOffset` | for calculate dropdown direction (e.g. tabbar) | number | 0 | | `onChangeText` | event textInput onChangeText | function | | | `onSelectItem` | event onSelectItem | function | | | `onOpenSuggestionsList` | event onOpenSuggestionsList | function | | | `onChevronPress` | event onChevronPress | function | | | `onClear` | event on clear button press | function | | | `onSubmit` | event on submit KB button press | function | | | `onBlur` | event fired on text input blur | function | | | `onFocus` | event on focus text input | function | | | `renderItem` | JSX for render item `(item, searchText) => JSX \| null` if return null then the element will not be displayed | function | item.title | | `controller` | return reference to module controller with methods **close, open, toggle, clear, setInputText, setItem** | function | | | `containerStyle` | | ViewStyle | | | `rightButtonsContainerStyle` | | ViewStyle | | | `suggestionsListContainerStyle` | | ViewStyle | | | `suggestionsListTextStyle` | | TextStyle | styles of suggestions list text items | | `ChevronIconComponent` | | React.Component | Feather chevron icon | | `ClearIconComponent` | | React.Component | Feather x icon | | ~~ScrollViewComponent~~ | removed in 2.0.0 based on FlatList | React.Component name | ScrollView that provide suggestions content | | `EmptyResultComponent` | replace the default `` Component on empty result | React.Component | | | `InputComponent` | input element component | React.ComponentType | TextInput | | `emptyResultText` | replace the default "Nothing found" text on empty result | string | "Nothing found" | | `textInputProps` | text input props | TextInputProps | | | `flatListProps` | props for \ component | FlatListProps\ | |