├── .editorconfig ├── .gitattributes ├── .github ├── actions │ └── setup │ │ └── action.yml └── workflows │ └── ci.yml ├── .gitignore ├── .nvmrc ├── .watchmanconfig ├── .yarnrc ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── babel.config.js ├── example ├── App.js ├── app.json ├── assets │ ├── adaptive-icon.png │ ├── favicon.png │ ├── icon.png │ └── splash.png ├── babel.config.js ├── metro.config.js ├── package.json ├── src │ ├── App.tsx │ └── dropdown │ │ ├── CountrySelect1.tsx │ │ ├── CountrySelect2.tsx │ │ ├── Dropdown1.tsx │ │ ├── Dropdown2.tsx │ │ ├── DropdownLazyLoad.tsx │ │ ├── DropdownWithConfirm.tsx │ │ ├── Menu.tsx │ │ ├── MultiSelectAll.tsx │ │ └── MultiSelectWithConfirm.tsx ├── tsconfig.json ├── webpack.config.js └── yarn.lock ├── lefthook.yml ├── package.json ├── scripts └── bootstrap.js ├── src ├── __tests__ │ └── index.test.tsx ├── assets │ ├── close.png │ └── down.png ├── components │ ├── Dropdown │ │ ├── index.tsx │ │ ├── model.ts │ │ └── styles.ts │ ├── MultiSelect │ │ ├── index.tsx │ │ ├── model.ts │ │ └── styles.ts │ ├── SelectCountry │ │ ├── index.tsx │ │ ├── model.ts │ │ └── styles.ts │ └── TextInput │ │ ├── index.tsx │ │ ├── model.ts │ │ └── styles.ts ├── index.tsx ├── toolkits │ ├── index.ts │ └── model.ts └── useDeviceOrientation.ts ├── tsconfig.build.json ├── tsconfig.json └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | 9 | indent_style = space 10 | indent_size = 2 11 | 12 | end_of_line = lf 13 | charset = utf-8 14 | trim_trailing_whitespace = true 15 | insert_final_newline = true 16 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | # specific for windows script files 3 | *.bat text eol=crlf -------------------------------------------------------------------------------- /.github/actions/setup/action.yml: -------------------------------------------------------------------------------- 1 | name: Setup 2 | description: Setup Node.js and install dependencies 3 | 4 | runs: 5 | using: composite 6 | steps: 7 | - name: Setup Node.js 8 | uses: actions/setup-node@v3 9 | with: 10 | node-version-file: .nvmrc 11 | 12 | - name: Cache dependencies 13 | id: yarn-cache 14 | uses: actions/cache@v3 15 | with: 16 | path: | 17 | **/node_modules 18 | key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} 19 | restore-keys: | 20 | ${{ runner.os }}-yarn- 21 | 22 | - name: Install dependencies 23 | if: steps.yarn-cache.outputs.cache-hit != 'true' 24 | run: | 25 | yarn install --cwd example --frozen-lockfile 26 | yarn install --frozen-lockfile 27 | shell: bash 28 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | branches: 8 | - main 9 | 10 | jobs: 11 | lint: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Checkout 15 | uses: actions/checkout@v3 16 | 17 | - name: Setup 18 | uses: ./.github/actions/setup 19 | 20 | - name: Lint files 21 | run: yarn lint 22 | 23 | - name: Typecheck files 24 | run: yarn typecheck 25 | 26 | test: 27 | runs-on: ubuntu-latest 28 | steps: 29 | - name: Checkout 30 | uses: actions/checkout@v3 31 | 32 | - name: Setup 33 | uses: ./.github/actions/setup 34 | 35 | - name: Run unit tests 36 | run: yarn test --maxWorkers=2 --coverage 37 | 38 | build: 39 | runs-on: ubuntu-latest 40 | steps: 41 | - name: Checkout 42 | uses: actions/checkout@v3 43 | 44 | - name: Setup 45 | uses: ./.github/actions/setup 46 | 47 | - name: Build package 48 | run: yarn prepack 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # XDE 6 | .expo/ 7 | 8 | # VSCode 9 | .vscode/ 10 | jsconfig.json 11 | 12 | # Xcode 13 | # 14 | build/ 15 | *.pbxuser 16 | !default.pbxuser 17 | *.mode1v3 18 | !default.mode1v3 19 | *.mode2v3 20 | !default.mode2v3 21 | *.perspectivev3 22 | !default.perspectivev3 23 | xcuserdata 24 | *.xccheckout 25 | *.moved-aside 26 | DerivedData 27 | *.hmap 28 | *.ipa 29 | *.xcuserstate 30 | project.xcworkspace 31 | 32 | # Android/IJ 33 | # 34 | .classpath 35 | .cxx 36 | .gradle 37 | .idea 38 | .project 39 | .settings 40 | local.properties 41 | android.iml 42 | 43 | # Cocoapods 44 | # 45 | example/ios/Pods 46 | 47 | # Ruby 48 | example/vendor/ 49 | 50 | # node.js 51 | # 52 | node_modules/ 53 | npm-debug.log 54 | yarn-debug.log 55 | yarn-error.log 56 | 57 | # BUCK 58 | buck-out/ 59 | \.buckd/ 60 | android/app/libs 61 | android/keystores/debug.keystore 62 | 63 | # Expo 64 | .expo/ 65 | 66 | # Turborepo 67 | .turbo/ 68 | 69 | # generated by bob 70 | lib/ 71 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 16.18.1 2 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /.yarnrc: -------------------------------------------------------------------------------- 1 | # Override Yarn command so we can automatically setup the repo on running `yarn` 2 | 3 | yarn-path "scripts/bootstrap.js" 4 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | # Contributor Covenant Code of Conduct 3 | 4 | ## Our Pledge 5 | 6 | We as members, contributors, and leaders pledge to make participation in our 7 | community a harassment-free experience for everyone, regardless of age, body 8 | size, visible or invisible disability, ethnicity, sex characteristics, gender 9 | identity and expression, level of experience, education, socio-economic status, 10 | nationality, personal appearance, race, caste, color, religion, or sexual 11 | identity and orientation. 12 | 13 | We pledge to act and interact in ways that contribute to an open, welcoming, 14 | diverse, inclusive, and healthy community. 15 | 16 | ## Our Standards 17 | 18 | Examples of behavior that contributes to a positive environment for our 19 | community include: 20 | 21 | * Demonstrating empathy and kindness toward other people 22 | * Being respectful of differing opinions, viewpoints, and experiences 23 | * Giving and gracefully accepting constructive feedback 24 | * Accepting responsibility and apologizing to those affected by our mistakes, 25 | and learning from the experience 26 | * Focusing on what is best not just for us as individuals, but for the overall 27 | community 28 | 29 | Examples of unacceptable behavior include: 30 | 31 | * The use of sexualized language or imagery, and sexual attention or advances of 32 | any kind 33 | * Trolling, insulting or derogatory comments, and personal or political attacks 34 | * Public or private harassment 35 | * Publishing others' private information, such as a physical or email address, 36 | without their explicit permission 37 | * Other conduct which could reasonably be considered inappropriate in a 38 | professional setting 39 | 40 | ## Enforcement Responsibilities 41 | 42 | Community leaders are responsible for clarifying and enforcing our standards of 43 | acceptable behavior and will take appropriate and fair corrective action in 44 | response to any behavior that they deem inappropriate, threatening, offensive, 45 | or harmful. 46 | 47 | Community leaders have the right and responsibility to remove, edit, or reject 48 | comments, commits, code, wiki edits, issues, and other contributions that are 49 | not aligned to this Code of Conduct, and will communicate reasons for moderation 50 | decisions when appropriate. 51 | 52 | ## Scope 53 | 54 | This Code of Conduct applies within all community spaces, and also applies when 55 | an individual is officially representing the community in public spaces. 56 | Examples of representing our community include using an official e-mail address, 57 | posting via an official social media account, or acting as an appointed 58 | representative at an online or offline event. 59 | 60 | ## Enforcement 61 | 62 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 63 | reported to the community leaders responsible for enforcement at 64 | [INSERT CONTACT METHOD]. 65 | All complaints will be reviewed and investigated promptly and fairly. 66 | 67 | All community leaders are obligated to respect the privacy and security of the 68 | reporter of any incident. 69 | 70 | ## Enforcement Guidelines 71 | 72 | Community leaders will follow these Community Impact Guidelines in determining 73 | the consequences for any action they deem in violation of this Code of Conduct: 74 | 75 | ### 1. Correction 76 | 77 | **Community Impact**: Use of inappropriate language or other behavior deemed 78 | unprofessional or unwelcome in the community. 79 | 80 | **Consequence**: A private, written warning from community leaders, providing 81 | clarity around the nature of the violation and an explanation of why the 82 | behavior was inappropriate. A public apology may be requested. 83 | 84 | ### 2. Warning 85 | 86 | **Community Impact**: A violation through a single incident or series of 87 | actions. 88 | 89 | **Consequence**: A warning with consequences for continued behavior. No 90 | interaction with the people involved, including unsolicited interaction with 91 | those enforcing the Code of Conduct, for a specified period of time. This 92 | includes avoiding interactions in community spaces as well as external channels 93 | like social media. Violating these terms may lead to a temporary or permanent 94 | ban. 95 | 96 | ### 3. Temporary Ban 97 | 98 | **Community Impact**: A serious violation of community standards, including 99 | sustained inappropriate behavior. 100 | 101 | **Consequence**: A temporary ban from any sort of interaction or public 102 | communication with the community for a specified period of time. No public or 103 | private interaction with the people involved, including unsolicited interaction 104 | with those enforcing the Code of Conduct, is allowed during this period. 105 | Violating these terms may lead to a permanent ban. 106 | 107 | ### 4. Permanent Ban 108 | 109 | **Community Impact**: Demonstrating a pattern of violation of community 110 | standards, including sustained inappropriate behavior, harassment of an 111 | individual, or aggression toward or disparagement of classes of individuals. 112 | 113 | **Consequence**: A permanent ban from any sort of public interaction within the 114 | community. 115 | 116 | ## Attribution 117 | 118 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 119 | version 2.1, available at 120 | [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. 121 | 122 | Community Impact Guidelines were inspired by 123 | [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. 124 | 125 | For answers to common questions about this code of conduct, see the FAQ at 126 | [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at 127 | [https://www.contributor-covenant.org/translations][translations]. 128 | 129 | [homepage]: https://www.contributor-covenant.org 130 | [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html 131 | [Mozilla CoC]: https://github.com/mozilla/diversity 132 | [FAQ]: https://www.contributor-covenant.org/faq 133 | [translations]: https://www.contributor-covenant.org/translations 134 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions are always welcome, no matter how large or small! 4 | 5 | We want this community to be friendly and respectful to each other. Please follow it in all your interactions with the project. Before contributing, please read the [code of conduct](./CODE_OF_CONDUCT.md). 6 | 7 | ## Development workflow 8 | 9 | To get started with the project, run `yarn` in the root directory to install the required dependencies for each package: 10 | 11 | ```sh 12 | yarn 13 | ``` 14 | 15 | > While it's possible to use [`npm`](https://github.com/npm/cli), the tooling is built around [`yarn`](https://classic.yarnpkg.com/), so you'll have an easier time if you use `yarn` for development. 16 | 17 | While developing, you can run the [example app](/example/) to test your changes. Any changes you make in your library's JavaScript code will be reflected in the example app without a rebuild. If you change any native code, then you'll need to rebuild the example app. 18 | 19 | To start the packager: 20 | 21 | ```sh 22 | yarn example start 23 | ``` 24 | 25 | To run the example app on Android: 26 | 27 | ```sh 28 | yarn example android 29 | ``` 30 | 31 | To run the example app on iOS: 32 | 33 | ```sh 34 | yarn example ios 35 | ``` 36 | 37 | To run the example app on Web: 38 | 39 | ```sh 40 | yarn example web 41 | ``` 42 | 43 | Make sure your code passes TypeScript and ESLint. Run the following to verify: 44 | 45 | ```sh 46 | yarn typecheck 47 | yarn lint 48 | ``` 49 | 50 | To fix formatting errors, run the following: 51 | 52 | ```sh 53 | yarn lint --fix 54 | ``` 55 | 56 | Remember to add tests for your change if possible. Run the unit tests by: 57 | 58 | ```sh 59 | yarn test 60 | ``` 61 | 62 | 63 | ### Commit message convention 64 | 65 | We follow the [conventional commits specification](https://www.conventionalcommits.org/en) for our commit messages: 66 | 67 | - `fix`: bug fixes, e.g. fix crash due to deprecated method. 68 | - `feat`: new features, e.g. add new method to the module. 69 | - `refactor`: code refactor, e.g. migrate from class components to hooks. 70 | - `docs`: changes into documentation, e.g. add usage example for the module.. 71 | - `test`: adding or updating tests, e.g. add integration tests using detox. 72 | - `chore`: tooling changes, e.g. change CI config. 73 | 74 | Our pre-commit hooks verify that your commit message matches this format when committing. 75 | 76 | ### Linting and tests 77 | 78 | [ESLint](https://eslint.org/), [Prettier](https://prettier.io/), [TypeScript](https://www.typescriptlang.org/) 79 | 80 | We use [TypeScript](https://www.typescriptlang.org/) for type checking, [ESLint](https://eslint.org/) with [Prettier](https://prettier.io/) for linting and formatting the code, and [Jest](https://jestjs.io/) for testing. 81 | 82 | Our pre-commit hooks verify that the linter and tests pass when committing. 83 | 84 | ### Publishing to npm 85 | 86 | We use [release-it](https://github.com/release-it/release-it) to make it easier to publish new versions. It handles common tasks like bumping version based on semver, creating tags and releases etc. 87 | 88 | To publish new versions, run the following: 89 | 90 | ```sh 91 | yarn release 92 | ``` 93 | 94 | ### Scripts 95 | 96 | The `package.json` file contains various scripts for common tasks: 97 | 98 | - `yarn bootstrap`: setup project by installing all dependencies and pods. 99 | - `yarn typecheck`: type-check files with TypeScript. 100 | - `yarn lint`: lint files with ESLint. 101 | - `yarn test`: run unit tests with Jest. 102 | - `yarn example start`: start the Metro server for the example app. 103 | - `yarn example android`: run the example app on Android. 104 | - `yarn example ios`: run the example app on iOS. 105 | 106 | ### Sending a pull request 107 | 108 | > **Working on your first pull request?** You can learn how from this _free_ series: [How to Contribute to an Open Source Project on GitHub](https://app.egghead.io/playlists/how-to-contribute-to-an-open-source-project-on-github). 109 | 110 | When you're sending a pull request: 111 | 112 | - Prefer small pull requests focused on one change. 113 | - Verify that linters and tests are passing. 114 | - Review the documentation to make sure it looks good. 115 | - Follow the pull request template when opening a pull request. 116 | - For pull requests that change the API or implementation, discuss with maintainers first by opening an issue. 117 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Hoa Phan 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [](https://github.com/hoaphantn7604/file-upload/blob/master/document/dropdown/react-native-element-dropdown-demo.png) 2 | 3 | # react-native-element-dropdown 4 | React Native Element Dropdown is a library that provides a customizable dropdown component for React Native applications. This library simplifies the process of creating dropdown menus and provides a variety of options to customize the dropdown to match the design and functionality of your application. 5 | 6 | ## Features 7 | * Dropdown and Multiselect in one package 8 | * Easy to use 9 | * Consistent look and feel on iOS and Android 10 | * Customizable font size, colors and animation duration 11 | * Implemented with typescript 12 | 13 | ```js 14 | If you love this library, give us a star, you will be a ray of sunshine in our lives :) 15 | ``` 16 | 17 | ### Free React Native Boilerplate 18 | [React Native Template](https://github.com/hoaphantn7604/react-native-template-components) with a beautiful UI. 19 | 20 | ## Getting started 21 | ```js 22 | npm install react-native-element-dropdown --save 23 | ``` 24 | or 25 | 26 | ```js 27 | yarn add react-native-element-dropdown 28 | ``` 29 | ### Demo 30 | 31 | [](https://youtu.be/FhTDR_Ad_14) 32 | 33 | 34 |
35 | 36 | ![](https://github.com/hoaphantn7604/file-upload/blob/master/document/dropdown/react-native-drpdown.gif) 37 | ![](https://github.com/hoaphantn7604/file-upload/blob/master/document/dropdown/react-native-multiselect.gif) 38 | 39 | ### Dropdown Props 40 | | Props | Params | isRequire | Description | 41 | | ------------------ | ----------------------------------------------- | --------- | ------------------------------------------------------------------- | 42 | | mode | 'default' or 'modal' of 'auto' | No | Mode 'modal' is show the dropdown in the middle of the screen. | 43 | | data | Array | Yes | Data is a plain array | 44 | | labelField | String | Yes | Extract the label from the data item | 45 | | valueField | String | Yes | Extract the primary key from the data item | 46 | | searchField | String | No | Specify the field of data list you want to search | 47 | | onChange | (item: object) => void | Yes | Selection callback | 48 | | onChangeText | (search: string) => void | No | Callback that is called when the text input's text changes | 49 | | value | Item | No | Set default value | 50 | | placeholder | String | No | The string that will be rendered before dropdown has been selected | 51 | | placeholderStyle | TextStyle | No | Styling for text placeholder | 52 | | selectedTextStyle | TextStyle | No | Styling for selected text | 53 | | selectedTextProps | TextProps | No | Text Props for selected text. Ex: numberOfLines={1} | 54 | | style | ViewStyle | No | Styling for view container | 55 | | containerStyle | ViewStyle | No | Styling for list container | 56 | | maxHeight | Number | No | Customize max height for list container | 57 | | minHeight | Number | No | Customize min height for list container | 58 | | fontFamily | String | No | Customize font style | 59 | | iconStyle | ImageStyle | No | Styling for icon | 60 | | iconColor | String | No | Color of icons | 61 | | itemContainerStyle | TextStyle | No | Styling for item container in list | 62 | | itemTextStyle | TextStyle | No | Styling for text item in list | 63 | | activeColor | String | No | Background color for item selected in list container | 64 | | search | Boolean | No | Show or hide input search | 65 | | searchQuery | (keyword: string, labelValue: string) => Boolean| No | Callback used to filter the list of items | 66 | | inputSearchStyle | ViewStyle | No | Styling for input search | 67 | | searchPlaceholder | String | No | The string that will be rendered before text input has been entered | 68 | | searchPlaceholderTextColor | String | No | The text color of the placeholder string | 69 | | renderInputSearch | (onSearch: (text:string) => void) => JSX.Element| No | Customize TextInput search | 70 | | disable | Boolean | No | Specifies the disabled state of the Dropdown | 71 | | dropdownPosition | 'auto' or 'top' or 'bottom' | No | Dropdown list position. Default is 'auto' | 72 | | autoScroll | Boolean | No | Auto scroll to index item selected, default is true | 73 | | showsVerticalScrollIndicator | Boolean | No | When true, shows a vertical scroll indicator, default is true | 74 | | renderLeftIcon | (visible?: boolean) => JSX.Element | No | Customize left icon for dropdown | 75 | | renderRightIcon | (visible?: boolean) => JSX.Element | No | Customize right icon for dropdown | 76 | | renderItem | (item: object, selected: Boolean) => JSX.Element| No | Takes an item from data and renders it into the list | 77 | | flatListProps | FlatListProps | No | Customize FlatList element | 78 | | inverted | Boolean | No | Reverses the direction of scroll on top position mode. Default is true| 79 | | onFocus | () => void | No | Callback that is called when the dropdown is focused | 80 | | onBlur | () => void | No | Callback that is called when the dropdown is blurred | 81 | | keyboardAvoiding | Boolean | No | keyboardAvoiding default is true | 82 | | backgroundColor | String | No | Set background color | 83 | | confirmSelectItem | Boolean | No | Turn On confirm select item. Refer example/src/dropdown/example3 | 84 | | onConfirmSelectItem | (item: object) => void | No | Selection callback. Refer example/src/dropdown/example3 | 85 | | testID | String | No | Used to locate this view in end-to-end tests | 86 | | itemTestIDField | String | No | Add this field to the input data. Ex: DATA = [{itemTestIDField: '', label: '', value:: ''}]| 87 | | accessibilityLabel | String | No | Set an accessibilityLabel on the view, so that people who use VoiceOver know what element they have selected | 88 | | itemAccessibilityLabelField | String | No | Add this field to the input data. Ex: DATA = [{itemAccessibilityLabelField: '', label: '', value:: ''}]| 89 | | closeModalWhenSelectedItem | Boolean | No | By default, closeModalWhenSelectedItem is set to true. When closeModalWhenSelectedItem is set to false, the Modal won't close when an item is selected. | 90 | | excludeItems | Item[] | No | The array containing the items to be excluded. | 91 | | excludeSearchItems | Item[] | No | The array containing the items to be excluded. | 92 | 93 | 94 | 95 | ### MultiSelect Props 96 | | Props | Params | isRequire | Description | 97 | | ------------------ | -----------------------------------------------------| --------- | ------------------------------------------------------------------- | 98 | | mode | 'default' or 'modal' of 'auto' | No | Mode 'modal' is show the dropdown in the middle of the screen. | 99 | | data | Array | Yes | Data is a plain array | 100 | | labelField | String | Yes | Extract the label from the data item | 101 | | valueField | String | Yes | Extract the primary key from the data item | 102 | | searchField | String | No | Specify the field of data list you want to search | 103 | | onChange | (value[]) => void | Yes | Selection callback. A array containing the "valueField". | 104 | | onChangeText | (search: string) => void | No | Callback that is called when the text input's text changes | 105 | | value | Item[] | No | Set default value. A array containing the "valueField". | 106 | | placeholder | String | No | The string that will be rendered before dropdown has been selected | 107 | | placeholderStyle | TextStyle | No | Styling for text placeholder | 108 | | style | ViewStyle | No | Styling for view container | 109 | | containerStyle | ViewStyle | No | Styling for list container | 110 | | maxHeight | Number | No | Customize max height for list container | 111 | | minHeight | Number | No | Customize min height for list container | 112 | | maxSelect | Number | No | maximum number of items that can be selected | 113 | | fontFamily | String | No | Customize font style | 114 | | iconStyle | ImageStyle | No | Styling for icon | 115 | | iconColor | String | No | Color of icons | 116 | | activeColor | String | No | Background color for item selected in list container | 117 | | itemContainerStyle | TextStyle | No | Styling for item container in list | 118 | | itemTextStyle | TextStyle | No | Styling for text item in list | 119 | | selectedStyle | ViewStyle | No | Styling for selected view | 120 | | selectedTextStyle | TextStyle | No | Styling for selected text | 121 | | selectedTextProps | TextProps | No | Text Props for selected text. Ex: numberOfLines={1} | 122 | | renderSelectedItem | (item: object, unSelect?: () => void) => JSX.Element | No | Takes an item from data and renders it into the list selected | 123 | | alwaysRenderSelectedItem | Boolean | No | Always show the list of selected items | 124 | | visibleSelectedItem | Boolean | No | Option to hide selected item list, Ẽx: visibleSelectedItem={false} | 125 | | search | Boolean | No | Show or hide input search | 126 | | searchQuery | (keyword: string, labelValue: string) => Boolean | No | Callback used to filter the list of items | 127 | | inputSearchStyle | ViewStyle | No | Styling for input search | 128 | | searchPlaceholder | String | No | The string that will be rendered before text input has been entered | 129 | | searchPlaceholderTextColor | String | No | The text color of the placeholder string | 130 | | renderInputSearch | (onSearch: (text:string) => void) => JSX.Element | No | Customize TextInput search | 131 | | disable | Boolean | No | Specifies the disabled state of the Dropdown | 132 | | dropdownPosition | 'auto' or 'top' or 'bottom' | No | Dropdown list position. Default is 'auto' | 133 | | showsVerticalScrollIndicator | Boolean | No | When true, shows a vertical scroll indicator, default is true | 134 | | renderLeftIcon | (visible?: boolean) => JSX.Element | No | Customize left icon for dropdown | 135 | | renderRightIcon | (visible?: boolean) => JSX.Element | No | Customize right icon for dropdown | 136 | | renderItem | (item: object, selected: Boolean) => JSX.Element | No | Takes an item from data and renders it into the list | 137 | | flatListProps | FlatListProps | No | Customize FlatList element | 138 | | inverted | Boolean | No | Reverses the direction of scroll on top position mode. Default is true| 139 | | onFocus | () => void | No | Callback that is called when the dropdown is focused | 140 | | onBlur | () => void | No | Callback that is called when the dropdown is blurred | 141 | | keyboardAvoiding | Boolean | No | keyboardAvoiding default is true | 142 | | inside | Boolean | No | inside default is false | 143 | | backgroundColor | String | No | Set background color | 144 | | confirmSelectItem | Boolean | No | Turn On confirm select item. Refer example/src/dropdown/example7 | 145 | | confirmUnSelectItem | Boolean | No | Turn On confirm un-select item. Refer example/src/dropdown/example7 | 146 | | onConfirmSelectItem | (item: any) => void | No | Selection callback. Refer example/src/dropdown/example7 | 147 | | testID | String | No | Used to locate this view in end-to-end tests | 148 | | itemTestIDField | String | No | Add this field to the input data. Ex: DATA = [{itemTestIDField: '', label: '', value:: ''}]| 149 | | accessibilityLabel | String | No | Set an accessibilityLabel on the view, so that people who use VoiceOver know what element they have selected | 150 | | itemAccessibilityLabelField | String | No | Add this field to the input data. Ex: DATA = [{itemAccessibilityLabelField: '', label: '', value:: ''}]| 151 | | excludeItems | Item[] | No | The array containing the items to be excluded. | 152 | | excludeSearchItems | Item[] | No | The array containing the items to be excluded. | 153 | 154 | 155 | 156 | ### SelectCountry extends Dropdown 157 | | Props | Params | isRequire | Description | 158 | | ------------------ | -------------------- | --------- | ------------------------------------ | 159 | | imageField | String | Yes | Extract the image from the data item | 160 | | imageStyle | ImageStyle | No | Styling for image | 161 | 162 | 163 | ### Method 164 | | API | Params | Description | 165 | | ----------- | ------------| ---------------------| 166 | | open | () => void | Open dropdown list | 167 | | close | () => void | Close dropdown list | 168 | 169 | 170 | ### Dropdown example 171 | ![](https://github.com/hoaphantn7604/file-upload/blob/master/document/dropdown/react-native-dropdown-1.png) 172 | ```js 173 | import React, { useState } from 'react'; 174 | import { StyleSheet, Text, View } from 'react-native'; 175 | import { Dropdown } from 'react-native-element-dropdown'; 176 | import AntDesign from '@expo/vector-icons/AntDesign'; 177 | 178 | const data = [ 179 | { label: 'Item 1', value: '1' }, 180 | { label: 'Item 2', value: '2' }, 181 | { label: 'Item 3', value: '3' }, 182 | { label: 'Item 4', value: '4' }, 183 | { label: 'Item 5', value: '5' }, 184 | { label: 'Item 6', value: '6' }, 185 | { label: 'Item 7', value: '7' }, 186 | { label: 'Item 8', value: '8' }, 187 | ]; 188 | 189 | const DropdownComponent = () => { 190 | const [value, setValue] = useState(null); 191 | const [isFocus, setIsFocus] = useState(false); 192 | 193 | const renderLabel = () => { 194 | if (value || isFocus) { 195 | return ( 196 | 197 | Dropdown label 198 | 199 | ); 200 | } 201 | return null; 202 | }; 203 | 204 | return ( 205 | 206 | {renderLabel()} 207 | setIsFocus(true)} 222 | onBlur={() => setIsFocus(false)} 223 | onChange={item => { 224 | setValue(item.value); 225 | setIsFocus(false); 226 | }} 227 | renderLeftIcon={() => ( 228 | 234 | )} 235 | /> 236 | 237 | ); 238 | }; 239 | 240 | export default DropdownComponent; 241 | 242 | const styles = StyleSheet.create({ 243 | container: { 244 | backgroundColor: 'white', 245 | padding: 16, 246 | }, 247 | dropdown: { 248 | height: 50, 249 | borderColor: 'gray', 250 | borderWidth: 0.5, 251 | borderRadius: 8, 252 | paddingHorizontal: 8, 253 | }, 254 | icon: { 255 | marginRight: 5, 256 | }, 257 | label: { 258 | position: 'absolute', 259 | backgroundColor: 'white', 260 | left: 22, 261 | top: 8, 262 | zIndex: 999, 263 | paddingHorizontal: 8, 264 | fontSize: 14, 265 | }, 266 | placeholderStyle: { 267 | fontSize: 16, 268 | }, 269 | selectedTextStyle: { 270 | fontSize: 16, 271 | }, 272 | iconStyle: { 273 | width: 20, 274 | height: 20, 275 | }, 276 | inputSearchStyle: { 277 | height: 40, 278 | fontSize: 16, 279 | }, 280 | }); 281 | ``` 282 | 283 | ### Dropdown example 1 284 | ![](https://github.com/hoaphantn7604/file-upload/blob/master/document/dropdown/react-native-dropdown-2.png) 285 | ```javascript 286 | import React, { useState } from 'react'; 287 | import { StyleSheet } from 'react-native'; 288 | import { Dropdown } from 'react-native-element-dropdown'; 289 | import AntDesign from '@expo/vector-icons/AntDesign'; 290 | 291 | const data = [ 292 | { label: 'Item 1', value: '1' }, 293 | { label: 'Item 2', value: '2' }, 294 | { label: 'Item 3', value: '3' }, 295 | { label: 'Item 4', value: '4' }, 296 | { label: 'Item 5', value: '5' }, 297 | { label: 'Item 6', value: '6' }, 298 | { label: 'Item 7', value: '7' }, 299 | { label: 'Item 8', value: '8' }, 300 | ]; 301 | 302 | const DropdownComponent = () => { 303 | const [value, setValue] = useState(null); 304 | 305 | return ( 306 | { 321 | setValue(item.value); 322 | }} 323 | renderLeftIcon={() => ( 324 | 325 | )} 326 | /> 327 | ); 328 | }; 329 | 330 | export default DropdownComponent; 331 | 332 | const styles = StyleSheet.create({ 333 | dropdown: { 334 | margin: 16, 335 | height: 50, 336 | borderBottomColor: 'gray', 337 | borderBottomWidth: 0.5, 338 | }, 339 | icon: { 340 | marginRight: 5, 341 | }, 342 | placeholderStyle: { 343 | fontSize: 16, 344 | }, 345 | selectedTextStyle: { 346 | fontSize: 16, 347 | }, 348 | iconStyle: { 349 | width: 20, 350 | height: 20, 351 | }, 352 | inputSearchStyle: { 353 | height: 40, 354 | fontSize: 16, 355 | }, 356 | }); 357 | ``` 358 | 359 | ### Dropdown example 2 360 | ![](https://github.com/hoaphantn7604/file-upload/blob/master/document/dropdown/react-native-dropdown-3.png) 361 | ```javascript 362 | import React, { useState } from 'react'; 363 | import { StyleSheet, View, Text } from 'react-native'; 364 | import { Dropdown } from 'react-native-element-dropdown'; 365 | import AntDesign from '@expo/vector-icons/AntDesign'; 366 | 367 | const data = [ 368 | { label: 'Item 1', value: '1' }, 369 | { label: 'Item 2', value: '2' }, 370 | { label: 'Item 3', value: '3' }, 371 | { label: 'Item 4', value: '4' }, 372 | { label: 'Item 5', value: '5' }, 373 | { label: 'Item 6', value: '6' }, 374 | { label: 'Item 7', value: '7' }, 375 | { label: 'Item 8', value: '8' }, 376 | ]; 377 | 378 | const DropdownComponent = () => { 379 | const [value, setValue] = useState(null); 380 | 381 | const renderItem = item => { 382 | return ( 383 | 384 | {item.label} 385 | {item.value === value && ( 386 | 392 | )} 393 | 394 | ); 395 | }; 396 | 397 | return ( 398 | { 413 | setValue(item.value); 414 | }} 415 | renderLeftIcon={() => ( 416 | 417 | )} 418 | renderItem={renderItem} 419 | /> 420 | ); 421 | }; 422 | 423 | export default DropdownComponent; 424 | 425 | const styles = StyleSheet.create({ 426 | dropdown: { 427 | margin: 16, 428 | height: 50, 429 | backgroundColor: 'white', 430 | borderRadius: 12, 431 | padding: 12, 432 | shadowColor: '#000', 433 | shadowOffset: { 434 | width: 0, 435 | height: 1, 436 | }, 437 | shadowOpacity: 0.2, 438 | shadowRadius: 1.41, 439 | 440 | elevation: 2, 441 | }, 442 | icon: { 443 | marginRight: 5, 444 | }, 445 | item: { 446 | padding: 17, 447 | flexDirection: 'row', 448 | justifyContent: 'space-between', 449 | alignItems: 'center', 450 | }, 451 | textItem: { 452 | flex: 1, 453 | fontSize: 16, 454 | }, 455 | placeholderStyle: { 456 | fontSize: 16, 457 | }, 458 | selectedTextStyle: { 459 | fontSize: 16, 460 | }, 461 | iconStyle: { 462 | width: 20, 463 | height: 20, 464 | }, 465 | inputSearchStyle: { 466 | height: 40, 467 | fontSize: 16, 468 | }, 469 | }); 470 | ``` 471 | 472 | ### MultiSelect example 1 473 | ![](https://github.com/hoaphantn7604/file-upload/blob/master/document/dropdown/react-native-multiselect-1.png) 474 | ```js 475 | import React, { useState } from 'react'; 476 | import { StyleSheet, View } from 'react-native'; 477 | import { MultiSelect } from 'react-native-element-dropdown'; 478 | import AntDesign from '@expo/vector-icons/AntDesign'; 479 | 480 | const data = [ 481 | { label: 'Item 1', value: '1' }, 482 | { label: 'Item 2', value: '2' }, 483 | { label: 'Item 3', value: '3' }, 484 | { label: 'Item 4', value: '4' }, 485 | { label: 'Item 5', value: '5' }, 486 | { label: 'Item 6', value: '6' }, 487 | { label: 'Item 7', value: '7' }, 488 | { label: 'Item 8', value: '8' }, 489 | ]; 490 | 491 | const MultiSelectComponent = () => { 492 | const [selected, setSelected] = useState([]); 493 | 494 | return ( 495 | 496 | { 510 | setSelected(item); 511 | }} 512 | renderLeftIcon={() => ( 513 | 519 | )} 520 | selectedStyle={styles.selectedStyle} 521 | /> 522 | 523 | ); 524 | }; 525 | 526 | export default MultiSelectComponent; 527 | 528 | const styles = StyleSheet.create({ 529 | container: { padding: 16 }, 530 | dropdown: { 531 | height: 50, 532 | backgroundColor: 'transparent', 533 | borderBottomColor: 'gray', 534 | borderBottomWidth: 0.5, 535 | }, 536 | placeholderStyle: { 537 | fontSize: 16, 538 | }, 539 | selectedTextStyle: { 540 | fontSize: 14, 541 | }, 542 | iconStyle: { 543 | width: 20, 544 | height: 20, 545 | }, 546 | inputSearchStyle: { 547 | height: 40, 548 | fontSize: 16, 549 | }, 550 | icon: { 551 | marginRight: 5, 552 | }, 553 | selectedStyle: { 554 | borderRadius: 12, 555 | }, 556 | }); 557 | ``` 558 | 559 | ### MultiSelect example 2 560 | ![](https://github.com/hoaphantn7604/file-upload/blob/master/document/dropdown/react-native-multiselect-2.png) 561 | ```js 562 | import React, { useState } from 'react'; 563 | import { StyleSheet, View, TouchableOpacity, Text } from 'react-native'; 564 | import { MultiSelect } from 'react-native-element-dropdown'; 565 | import AntDesign from '@expo/vector-icons/AntDesign'; 566 | 567 | const data = [ 568 | { label: 'Item 1', value: '1' }, 569 | { label: 'Item 2', value: '2' }, 570 | { label: 'Item 3', value: '3' }, 571 | { label: 'Item 4', value: '4' }, 572 | { label: 'Item 5', value: '5' }, 573 | { label: 'Item 6', value: '6' }, 574 | { label: 'Item 7', value: '7' }, 575 | { label: 'Item 8', value: '8' }, 576 | ]; 577 | 578 | const MultiSelectComponent = () => { 579 | const [selected, setSelected] = useState([]); 580 | 581 | const renderItem = item => { 582 | return ( 583 | 584 | {item.label} 585 | 586 | 587 | ); 588 | }; 589 | 590 | return ( 591 | 592 | { 606 | setSelected(item); 607 | }} 608 | renderLeftIcon={() => ( 609 | 615 | )} 616 | renderItem={renderItem} 617 | renderSelectedItem={(item, unSelect) => ( 618 | unSelect && unSelect(item)}> 619 | 620 | {item.label} 621 | 622 | 623 | 624 | )} 625 | /> 626 | 627 | ); 628 | }; 629 | 630 | export default MultiSelectComponent; 631 | 632 | const styles = StyleSheet.create({ 633 | container: { padding: 16 }, 634 | dropdown: { 635 | height: 50, 636 | backgroundColor: 'white', 637 | borderRadius: 12, 638 | padding: 12, 639 | shadowColor: '#000', 640 | shadowOffset: { 641 | width: 0, 642 | height: 1, 643 | }, 644 | shadowOpacity: 0.2, 645 | shadowRadius: 1.41, 646 | 647 | elevation: 2, 648 | }, 649 | placeholderStyle: { 650 | fontSize: 16, 651 | }, 652 | selectedTextStyle: { 653 | fontSize: 14, 654 | }, 655 | iconStyle: { 656 | width: 20, 657 | height: 20, 658 | }, 659 | inputSearchStyle: { 660 | height: 40, 661 | fontSize: 16, 662 | }, 663 | icon: { 664 | marginRight: 5, 665 | }, 666 | item: { 667 | padding: 17, 668 | flexDirection: 'row', 669 | justifyContent: 'space-between', 670 | alignItems: 'center', 671 | }, 672 | selectedStyle: { 673 | flexDirection: 'row', 674 | justifyContent: 'center', 675 | alignItems: 'center', 676 | borderRadius: 14, 677 | backgroundColor: 'white', 678 | shadowColor: '#000', 679 | marginTop: 8, 680 | marginRight: 12, 681 | paddingHorizontal: 12, 682 | paddingVertical: 8, 683 | shadowOffset: { 684 | width: 0, 685 | height: 1, 686 | }, 687 | shadowOpacity: 0.2, 688 | shadowRadius: 1.41, 689 | 690 | elevation: 2, 691 | }, 692 | textSelectedStyle: { 693 | marginRight: 5, 694 | fontSize: 16, 695 | }, 696 | }); 697 | ``` 698 | 699 | ### SelectCountry example 1 700 | ![](https://github.com/hoaphantn7604/file-upload/blob/master/document/dropdown/react-native-dropdown-4.png) 701 | ```js 702 | import React, { useState } from 'react'; 703 | import { StyleSheet } from 'react-native'; 704 | import { SelectCountry } from 'react-native-element-dropdown'; 705 | 706 | const local_data = [ 707 | { 708 | value: '1', 709 | lable: 'Country 1', 710 | image: { 711 | uri: 'https://www.vigcenter.com/public/all/images/default-image.jpg', 712 | }, 713 | }, 714 | { 715 | value: '2', 716 | lable: 'Country 2', 717 | image: { 718 | uri: 'https://www.vigcenter.com/public/all/images/default-image.jpg', 719 | }, 720 | }, 721 | { 722 | value: '3', 723 | lable: 'Country 3', 724 | image: { 725 | uri: 'https://www.vigcenter.com/public/all/images/default-image.jpg', 726 | }, 727 | }, 728 | { 729 | value: '4', 730 | lable: 'Country 4', 731 | image: { 732 | uri: 'https://www.vigcenter.com/public/all/images/default-image.jpg', 733 | }, 734 | }, 735 | { 736 | value: '5', 737 | lable: 'Country 5', 738 | image: { 739 | uri: 'https://www.vigcenter.com/public/all/images/default-image.jpg', 740 | }, 741 | }, 742 | ]; 743 | 744 | const SelectCountryScreen = _props => { 745 | const [country, setCountry] = useState('1'); 746 | 747 | return ( 748 | { 765 | setCountry(e.value); 766 | }} 767 | /> 768 | ); 769 | }; 770 | 771 | export default SelectCountryScreen; 772 | 773 | const styles = StyleSheet.create({ 774 | dropdown: { 775 | margin: 16, 776 | height: 50, 777 | borderBottomColor: 'gray', 778 | borderBottomWidth: 0.5, 779 | }, 780 | imageStyle: { 781 | width: 24, 782 | height: 24, 783 | }, 784 | placeholderStyle: { 785 | fontSize: 16, 786 | }, 787 | selectedTextStyle: { 788 | fontSize: 16, 789 | marginLeft: 8, 790 | }, 791 | iconStyle: { 792 | width: 20, 793 | height: 20, 794 | }, 795 | inputSearchStyle: { 796 | height: 40, 797 | fontSize: 16, 798 | }, 799 | }); 800 | ``` 801 | 802 | ### SelectCountry example 2 803 | ![](https://github.com/hoaphantn7604/file-upload/blob/master/document/dropdown/react-native-dropdown-5.png) 804 | ```js 805 | import React, { useState } from 'react'; 806 | import { StyleSheet } from 'react-native'; 807 | import { SelectCountry } from 'react-native-element-dropdown'; 808 | 809 | const local_data = [ 810 | { 811 | value: '1', 812 | lable: 'Country 1', 813 | image: { 814 | uri: 'https://www.vigcenter.com/public/all/images/default-image.jpg', 815 | }, 816 | }, 817 | { 818 | value: '2', 819 | lable: 'Country 2', 820 | image: { 821 | uri: 'https://www.vigcenter.com/public/all/images/default-image.jpg', 822 | }, 823 | }, 824 | { 825 | value: '3', 826 | lable: 'Country 3', 827 | image: { 828 | uri: 'https://www.vigcenter.com/public/all/images/default-image.jpg', 829 | }, 830 | }, 831 | { 832 | value: '4', 833 | lable: 'Country 4', 834 | image: { 835 | uri: 'https://www.vigcenter.com/public/all/images/default-image.jpg', 836 | }, 837 | }, 838 | { 839 | value: '5', 840 | lable: 'Country 5', 841 | image: { 842 | uri: 'https://www.vigcenter.com/public/all/images/default-image.jpg', 843 | }, 844 | }, 845 | ]; 846 | 847 | const SelectCountryScreen = _props => { 848 | const [country, setCountry] = useState('1'); 849 | 850 | return ( 851 | { 866 | setCountry(e.value); 867 | }} 868 | /> 869 | ); 870 | }; 871 | 872 | export default SelectCountryScreen; 873 | 874 | const styles = StyleSheet.create({ 875 | dropdown: { 876 | margin: 16, 877 | height: 50, 878 | width: 150, 879 | backgroundColor: '#EEEEEE', 880 | borderRadius: 22, 881 | paddingHorizontal: 8, 882 | }, 883 | imageStyle: { 884 | width: 24, 885 | height: 24, 886 | borderRadius: 12, 887 | }, 888 | placeholderStyle: { 889 | fontSize: 16, 890 | }, 891 | selectedTextStyle: { 892 | fontSize: 16, 893 | marginLeft: 8, 894 | }, 895 | iconStyle: { 896 | width: 20, 897 | height: 20, 898 | }, 899 | }); 900 | ``` 901 | 902 |
903 | 904 | [](https://github.com/hoaphantn7604) 905 | 906 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /example/App.js: -------------------------------------------------------------------------------- 1 | export { default } from './src/App'; 2 | -------------------------------------------------------------------------------- /example/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "example", 4 | "slug": "example", 5 | "version": "1.0.0", 6 | "orientation": "portrait", 7 | "icon": "./assets/icon.png", 8 | "userInterfaceStyle": "light", 9 | "splash": { 10 | "image": "./assets/splash.png", 11 | "resizeMode": "contain", 12 | "backgroundColor": "#ffffff" 13 | }, 14 | "assetBundlePatterns": [ 15 | "**/*" 16 | ], 17 | "ios": { 18 | "supportsTablet": true 19 | }, 20 | "android": { 21 | "adaptiveIcon": { 22 | "foregroundImage": "./assets/adaptive-icon.png", 23 | "backgroundColor": "#ffffff" 24 | } 25 | }, 26 | "web": { 27 | "favicon": "./assets/favicon.png" 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /example/assets/adaptive-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoaphantn7604/react-native-element-dropdown/5787e1f33f7ca890322457b1ee2dcd2e68e78ed1/example/assets/adaptive-icon.png -------------------------------------------------------------------------------- /example/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoaphantn7604/react-native-element-dropdown/5787e1f33f7ca890322457b1ee2dcd2e68e78ed1/example/assets/favicon.png -------------------------------------------------------------------------------- /example/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoaphantn7604/react-native-element-dropdown/5787e1f33f7ca890322457b1ee2dcd2e68e78ed1/example/assets/icon.png -------------------------------------------------------------------------------- /example/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoaphantn7604/react-native-element-dropdown/5787e1f33f7ca890322457b1ee2dcd2e68e78ed1/example/assets/splash.png -------------------------------------------------------------------------------- /example/babel.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const pak = require('../package.json'); 3 | 4 | module.exports = function (api) { 5 | api.cache(true); 6 | 7 | return { 8 | presets: ['babel-preset-expo'], 9 | plugins: [ 10 | [ 11 | 'module-resolver', 12 | { 13 | extensions: ['.tsx', '.ts', '.js', '.json'], 14 | alias: { 15 | // For development, we want to alias the library to the source 16 | [pak.name]: path.join(__dirname, '..', pak.source), 17 | }, 18 | }, 19 | ], 20 | ], 21 | }; 22 | }; 23 | -------------------------------------------------------------------------------- /example/metro.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const escape = require('escape-string-regexp'); 3 | const { getDefaultConfig } = require('@expo/metro-config'); 4 | const exclusionList = require('metro-config/src/defaults/exclusionList'); 5 | const pak = require('../package.json'); 6 | 7 | const root = path.resolve(__dirname, '..'); 8 | 9 | const modules = Object.keys({ 10 | ...pak.peerDependencies, 11 | }); 12 | 13 | const defaultConfig = getDefaultConfig(__dirname); 14 | 15 | module.exports = { 16 | ...defaultConfig, 17 | 18 | projectRoot: __dirname, 19 | watchFolders: [root], 20 | 21 | // We need to make sure that only one version is loaded for peerDependencies 22 | // So we block them at the root, and alias them to the versions in example's node_modules 23 | resolver: { 24 | ...defaultConfig.resolver, 25 | 26 | blacklistRE: exclusionList( 27 | modules.map( 28 | (m) => 29 | new RegExp(`^${escape(path.join(root, 'node_modules', m))}\\/.*$`) 30 | ) 31 | ), 32 | 33 | extraNodeModules: modules.reduce((acc, name) => { 34 | acc[name] = path.join(__dirname, 'node_modules', name); 35 | return acc; 36 | }, {}), 37 | }, 38 | }; 39 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "1.0.0", 4 | "main": "node_modules/expo/AppEntry.js", 5 | "scripts": { 6 | "start": "expo start", 7 | "android": "expo start --android", 8 | "ios": "expo start --ios", 9 | "web": "expo start --web" 10 | }, 11 | "dependencies": { 12 | "@expo/vector-icons": "^13.0.0", 13 | "expo": "~48.0.6", 14 | "expo-status-bar": "~1.4.4", 15 | "react": "18.2.0", 16 | "react-dom": "18.2.0", 17 | "react-native": "0.71.3", 18 | "react-native-web": "~0.18.10" 19 | }, 20 | "devDependencies": { 21 | "@babel/core": "^7.20.0", 22 | "@expo/webpack-config": "^0.17.2", 23 | "babel-loader": "^8.1.0", 24 | "babel-plugin-module-resolver": "^4.1.0" 25 | }, 26 | "private": true 27 | } 28 | -------------------------------------------------------------------------------- /example/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, View, ScrollView } from 'react-native'; 3 | import DropdownExample1 from './dropdown/Dropdown1'; 4 | import DropdownExample2 from './dropdown/Dropdown2'; 5 | import Menu from './dropdown/Menu'; 6 | import DropdownWithConfirm from './dropdown/DropdownWithConfirm'; 7 | import CountrySelect1 from './dropdown/CountrySelect1'; 8 | import CountrySelect2 from './dropdown/CountrySelect2'; 9 | import MultiSelectAll from './dropdown/MultiSelectAll'; 10 | import MultiSelectWithConfirm from './dropdown/MultiSelectWithConfirm'; 11 | import DropdownLazyLoad from './dropdown/DropdownLazyLoad'; 12 | 13 | const DropdownScreen = (_props: any) => { 14 | return ( 15 | 16 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | ); 32 | }; 33 | 34 | export default DropdownScreen; 35 | 36 | const styles = StyleSheet.create({ 37 | container: { 38 | flex: 1, 39 | backgroundColor: 'white', 40 | paddingVertical: 50, 41 | }, 42 | }); 43 | -------------------------------------------------------------------------------- /example/src/dropdown/CountrySelect1.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { StyleSheet } from 'react-native'; 3 | import { SelectCountry } from 'react-native-element-dropdown'; 4 | 5 | const local_data = [ 6 | { 7 | value: '1', 8 | lable: 'Country 1', 9 | image: { 10 | uri: 'https://www.vigcenter.com/public/all/images/default-image.jpg', 11 | }, 12 | }, 13 | { 14 | value: '2', 15 | lable: 'Country 2', 16 | image: { 17 | uri: 'https://www.vigcenter.com/public/all/images/default-image.jpg', 18 | }, 19 | }, 20 | { 21 | value: '3', 22 | lable: 'Country 3', 23 | image: { 24 | uri: 'https://www.vigcenter.com/public/all/images/default-image.jpg', 25 | }, 26 | }, 27 | { 28 | value: '4', 29 | lable: 'Country 4', 30 | image: { 31 | uri: 'https://www.vigcenter.com/public/all/images/default-image.jpg', 32 | }, 33 | }, 34 | { 35 | value: '5', 36 | lable: 'Country 5', 37 | image: { 38 | uri: 'https://www.vigcenter.com/public/all/images/default-image.jpg', 39 | }, 40 | }, 41 | ]; 42 | 43 | const SelectCountryScreen = () => { 44 | const [country, setCountry] = useState(); 45 | 46 | return ( 47 | { 64 | setCountry(e.value); 65 | }} 66 | /> 67 | ); 68 | }; 69 | 70 | export default SelectCountryScreen; 71 | 72 | const styles = StyleSheet.create({ 73 | dropdown: { 74 | margin: 16, 75 | height: 50, 76 | borderBottomColor: 'gray', 77 | borderBottomWidth: 0.5, 78 | }, 79 | imageStyle: { 80 | width: 24, 81 | height: 24, 82 | }, 83 | placeholderStyle: { 84 | fontSize: 16, 85 | }, 86 | selectedTextStyle: { 87 | fontSize: 16, 88 | marginLeft: 8, 89 | }, 90 | iconStyle: { 91 | width: 20, 92 | height: 20, 93 | }, 94 | inputSearchStyle: { 95 | height: 40, 96 | fontSize: 16, 97 | }, 98 | }); 99 | -------------------------------------------------------------------------------- /example/src/dropdown/CountrySelect2.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { StyleSheet } from 'react-native'; 3 | import { SelectCountry } from 'react-native-element-dropdown'; 4 | 5 | const local_data = [ 6 | { 7 | value: '1', 8 | lable: 'Country 1', 9 | image: { 10 | uri: 'https://www.vigcenter.com/public/all/images/default-image.jpg', 11 | }, 12 | }, 13 | { 14 | value: '2', 15 | lable: 'Country 2', 16 | image: { 17 | uri: 'https://www.vigcenter.com/public/all/images/default-image.jpg', 18 | }, 19 | }, 20 | { 21 | value: '3', 22 | lable: 'Country 3', 23 | image: { 24 | uri: 'https://www.vigcenter.com/public/all/images/default-image.jpg', 25 | }, 26 | }, 27 | { 28 | value: '4', 29 | lable: 'Country 4', 30 | image: { 31 | uri: 'https://www.vigcenter.com/public/all/images/default-image.jpg', 32 | }, 33 | }, 34 | { 35 | value: '5', 36 | lable: 'Country 5', 37 | image: { 38 | uri: 'https://www.vigcenter.com/public/all/images/default-image.jpg', 39 | }, 40 | }, 41 | ]; 42 | 43 | const SelectCountryScreen = () => { 44 | const [country, setCountry] = useState(); 45 | 46 | return ( 47 | { 63 | setCountry(e.value); 64 | }} 65 | /> 66 | ); 67 | }; 68 | 69 | export default SelectCountryScreen; 70 | 71 | const styles = StyleSheet.create({ 72 | dropdown: { 73 | margin: 16, 74 | height: 50, 75 | width: 160, 76 | backgroundColor: '#EEEEEE', 77 | borderRadius: 22, 78 | paddingHorizontal: 8, 79 | }, 80 | imageStyle: { 81 | width: 24, 82 | height: 24, 83 | borderRadius: 12, 84 | }, 85 | placeholderStyle: { 86 | fontSize: 16, 87 | }, 88 | selectedTextStyle: { 89 | fontSize: 16, 90 | marginLeft: 8, 91 | }, 92 | iconStyle: { 93 | width: 20, 94 | height: 20, 95 | }, 96 | }); 97 | -------------------------------------------------------------------------------- /example/src/dropdown/Dropdown1.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable react-native/no-inline-styles */ 2 | import React, { useState } from 'react'; 3 | import { StyleSheet, Text, View } from 'react-native'; 4 | import { Dropdown } from 'react-native-element-dropdown'; 5 | import AntDesign from '@expo/vector-icons/AntDesign'; 6 | 7 | const data = [ 8 | { label: 'Item 1', value: '1', search: 'Item 1' }, 9 | { label: 'Item 2', value: '2', search: 'Item 2' }, 10 | { label: 'Item 3', value: '3', search: 'Item 3' }, 11 | { label: 'Item 4', value: '4', search: 'Item 4' }, 12 | { label: 'Item 5', value: '5', search: 'Item 5' }, 13 | { label: 'Item 6', value: '6', search: 'Item 6' }, 14 | { label: 'Item 7', value: '7', search: 'Item 7' }, 15 | { label: 'Item 8', value: '8', search: 'Item 8' }, 16 | ]; 17 | 18 | const excludeItem = [ 19 | { label: 'Item 7', value: '7', search: 'Item 7' }, 20 | { label: 'Item 8', value: '8', search: 'Item 8' }, 21 | ]; 22 | 23 | const DropdownComponent = () => { 24 | const [value, setValue] = useState(); 25 | const [isFocus, setIsFocus] = useState(false); 26 | 27 | const renderLabel = () => { 28 | if (value || isFocus) { 29 | return ( 30 | 31 | Dropdown label 32 | 33 | ); 34 | } 35 | return null; 36 | }; 37 | 38 | return ( 39 | 40 | {renderLabel()} 41 | setIsFocus(true)} 60 | onBlur={() => setIsFocus(false)} 61 | onChange={(item) => { 62 | setValue(item.value); 63 | setIsFocus(false); 64 | }} 65 | renderLeftIcon={() => ( 66 | 72 | )} 73 | /> 74 | 75 | ); 76 | }; 77 | 78 | export default DropdownComponent; 79 | 80 | const styles = StyleSheet.create({ 81 | container: { 82 | backgroundColor: 'white', 83 | padding: 16, 84 | }, 85 | dropdown: { 86 | height: 50, 87 | borderColor: 'gray', 88 | borderWidth: 0.5, 89 | borderRadius: 8, 90 | paddingHorizontal: 8, 91 | }, 92 | icon: { 93 | marginRight: 5, 94 | }, 95 | label: { 96 | position: 'absolute', 97 | backgroundColor: 'white', 98 | left: 22, 99 | top: 8, 100 | zIndex: 999, 101 | paddingHorizontal: 8, 102 | fontSize: 14, 103 | }, 104 | placeholderStyle: { 105 | fontSize: 16, 106 | }, 107 | selectedTextStyle: { 108 | fontSize: 16, 109 | }, 110 | iconStyle: { 111 | width: 20, 112 | height: 20, 113 | }, 114 | inputSearchStyle: { 115 | height: 40, 116 | fontSize: 16, 117 | }, 118 | }); 119 | -------------------------------------------------------------------------------- /example/src/dropdown/Dropdown2.tsx: -------------------------------------------------------------------------------- 1 | import React, { useRef, useState } from 'react'; 2 | import { Button, StyleSheet, View } from 'react-native'; 3 | import { Dropdown, IDropdownRef } from 'react-native-element-dropdown'; 4 | 5 | const data = [ 6 | { label: 'Item 1', value: '1' }, 7 | { label: 'Item 2', value: '2' }, 8 | { label: 'Item 3', value: '3' }, 9 | { label: 'Item 4', value: '4' }, 10 | { label: 'Item 5', value: '5' }, 11 | { label: 'Item 6', value: '6' }, 12 | { label: 'Item 7', value: '7' }, 13 | { label: 'Item 8', value: '8' }, 14 | ]; 15 | 16 | const DropdownComponent = () => { 17 | const [value, setValue] = useState(); 18 | const ref = useRef(null); 19 | 20 | return ( 21 | 22 | { 39 | setValue(item.value); 40 | }} 41 | onChangeText={() => {}} // Keep search keyword 42 | /> 43 | 44 |