react-native-autocomplete-dropdown

repository·main·Indexed 42 days ago

https://github.com/onmotion/react-native-autocomplete-dropdown

A highly customizable autocomplete dropdown component for React Native supporting local and remote datasets. Version 5.1.0 features include typeahead functionality, a controller for imperative methods (open, close, focus, toggle), and support for custom item rendering. Requires react-native-svg and the use of AutocompleteDropdownContextProvider for correct rendering, especially when used inside Modals or with navigation headers.

Tokens
10.1K
Snippets
15
Records
18
Agent score
54%

What's inside react-native-autocomplete-dropdown

  1. Set up AutocompleteDropdownContextProvider

    main

    To ensure the dropdown renders correctly, you must wrap your root component in AutocompleteDropdownContextProvider. The dropdown's position is relative to this provider, so it should be placed in a location that covers the entire screen or modal.

    If you are using a header (e.g., with React Navigation), you can pass a headerOffset to prevent the dropdown from being obscured by the header.

    import { AutocompleteDropdownContextProvider } from 'react-native-autocomplete-dropdown';
    import { useHeaderHeight } from '@react-navigation/elements';
    
    const headerHeight = useHeaderHeight();
    
    <AutocompleteDropdownContextProvider headerOffset={headerHeight}>
        <AppRootOrWhatever/>
    </AutocompleteDropdownContextProvider>
    <AutocompleteDropdownContextProvider>
        <AppRootOrWhatever/>
    </AutocompleteDropdownContextProvider>
  2. Use AutocompleteDropdown inside a Modal

    main

    When using the AutocompleteDropdown component inside a React Native Modal, you must wrap the dropdown (and its parent container within the modal) in an AutocompleteDropdownContextProvider. This ensures the dropdown's internal logic and context are correctly provided within the modal's view hierarchy.

    <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>
  3. How the AutocompleteDropdown filtering works

    main

    The component performs filtering on the dataSet based on the searchText. The logic is influenced by several props:

    1. Case Sensitivity: Controlled by caseSensitive. If false, both search text and item titles are converted to lowercase.
    2. Accents: If ignoreAccents is true, both search text and item titles are processed through a diacriticless function to remove accents.
    3. Trimming: If trimSearchText is true, the search text is trimmed before matching.
    4. Match Position: If matchFrom is set to 'start', the component uses .startsWith() to match. Otherwise, it uses .indexOf() !== -1 (contains) to match anywhere in the title.

    Note: If useFilter is set to false, the component will not perform this internal filtering logic.

  4. Use AutocompleteDropdown with a remote dataset

    main

    For remote data, use the onChangeText prop to trigger an API call. You can manage the loading state and the suggestions list in your component state.

    Key props for remote usage:

    • onChangeText: Callback triggered when the user types.
    • loading: Boolean to show a loading indicator.
    • dataSet: The state variable containing fetched items.
    • useFilter: Set to false when fetching from a remote source to prevent the component from filtering the results locally a second time.
    • controller: A callback to access the dropdown controller (e.g., for calling .toggle()).
    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()
        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
              }}
              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}
              onOpenSuggestionsList={onOpenSuggestionsList}
              loading={loading}
              useFilter={false}
              textInputProps={{
                placeholder: 'Type 3+ letters (dolo...)',
                autoCorrect: false,
                autoCapitalize: 'none',
                style: {
                  borderRadius: 25,
                  backgroundColor: '#383b42',
                  color: '#fff',
                  paddingLeft: 18,
                },
              }}
              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>}
              inputHeight={50}
              showChevron={false}
              closeOnBlur={false}
            />
            <Button title="Toggle" onPress={() => dropdownController.current.toggle()} />
          </View>
        </>
      )
    })
  5. Use AutocompleteDropdown with a local dataset

    main

    To use a static list of items, provide the array directly to the dataSet prop and handle selection via onSelectItem.

    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' },
      ]}
    />
    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' },
      ]}
    />;
  6. Configure theme colors for light and dark modes

    main

    The library provides predefined light and dark theme objects that can be used to style the autocomplete dropdown. These themes control the colors for the input field, placeholder text, suggestion list, separators, shadows, and list items. You can import these themes or use them as a reference to create your own custom theme object following the same structure.

    import { theme } from 'react-native-autocomplete-dropdown';
    
    // Accessing predefined themes
    const currentTheme = theme.light;
    // or
    const currentTheme = theme.dark;
    
    // Example of a custom theme structure
    const myCustomTheme = {
      inputBackgroundColor: '#e5ecf2',
      inputPlaceholderColor: '#00000066',
      inputTextColor: '#333',
      suggestionsListBackgroundColor: '#fff',
      itemSeparatorColor: '#ddd',
      shadowColor: '#00000099',
      listItemTextColor: '#333',
    };
  7. Reference the AutocompleteDropdown options

    main

    The AutocompleteDropdown component accepts a wide range of configuration options to control its behavior, appearance, and event handling. Key categories include:

    • Data & Filtering: dataSet (the list items), useFilter (toggle local filtering), matchFrom ('any' or 'start'), and caseSensitive.
    • Loading State: loading (boolean) and enableLoadingIndicator (boolean).
    • UI & Styling: theme ('light' or 'dark'), suggestionsListMaxHeight, containerStyle, suggestionsListContainerStyle, and suggestionsListTextStyle.
    • Interaction: closeOnBlur, closeOnSubmit, clearOnFocus, and debounce (ms delay before onChangeText).
    • Custom Components: renderItem (custom JSX for items), ChevronIconComponent, ClearIconComponent, EmptyResultComponent, and InputComponent.
    • Events: onChangeText, onSelectItem, onOpenSuggestionsList, onChevronPress, onClear, onSubmit, onBlur, and onFocus.
    | Option                         | Description                                                                                                      | Type                | Default                                  |
    |--------------------------------|------------------------------------------------------------------------------------------------------------------|---------------------|------------------------------------------|
    | `dataSet`                      | Set of list items                                                                                                | array               | null                                     |
    | `initialValue`                 | String (**id**) or object that contains **id**                                    | string \| object    | null                                     |
    | `loading`                      | Loading state                                                                                                    | bool                    | false                                    |
    | `enableLoadingIndicator`       | Whether to show activity indicator on loading                                                                     | bool                    | true                                     |
    | `useFilter`                    | Whether to 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                                     |
    | `caseSensitive`                | Whether to perform case-sensitive search                                                                         | bool                    | false                                    |
    | `ignoreAccents`                | Ignore diacritics                                                                                                | bool                    | true                                     |
    | `trimSearchText`               | Trim the searched text                                                                                           | bool                    | true                                     |
    | `editable`                     | Is textInput editable                                                                                            | 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                                        |
    | `theme`           | Color scheme. Possible values are "light" or "dark"  | string              |  OS's color scheme                                |
    | `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                           |
    | `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 `FlatList` component                                                                                   | FlatListProps       |                                          |
  8. Provide a custom item renderer

    main

    Use the renderItem prop to define how each suggestion in the list should look. The function receives the item and the current searchText (useful for highlighting). If you use a custom renderer, the component wraps your returned element in a TouchableOpacity to handle selection.

    <AutocompleteDropdown
      dataSet={dataSet}
      renderItem={({ item, searchText }) => (
        <View style={{ padding: 10 }}>
          <Text style={{ fontWeight: item.title === searchText ? 'bold' : 'normal' }}>
            {item.title}
          </Text>
        </View>
      )}
    />
  9. Use the AutocompleteDropdown component

    main

    The AutocompleteDropdown component is the primary entry point for creating an autocomplete input in React Native. It supports local datasets, remote data fetching via loading states, custom rendering, and theme customization.

    Key features include:

    • Filtering: Supports case-sensitive, accent-insensitive, and start-of-string matching.
    • Controller: Provides imperative methods (like open, close, focus) via a controller prop.
    • Customization: Allows overriding the InputComponent, rendering individual items, and providing custom icons.
    • Theming: Supports light and dark themes, or follows the system color scheme.
    import { AutocompleteDropdown } from 'react-native-autocomplete-dropdown';
    
    // Basic usage
    <AutocompleteDropdown
      dataSet={[{ id: '1', title: 'Apple' }, { id: '2', title: 'Banana' }]}
      onSelectItem={(item) => console.log(item)}
    />