diff --git a/.eslintignore b/.eslintignore index f00c85966..12f5d8e20 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,6 +1,16 @@ # don't ever lint node_modules node_modules -# don't lint build output (make sure it's set to your correct build folder name) +package-lock.json +# don't lint build output +build dist -# don't lint nyc coverage output -coverage \ No newline at end of file +# don't lint coverage output +coverage +# don't lint workflows etc +.github +.idea +.vscode +# unsupported file types +*.yaml +*.yml +*.md \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index c020106d3..000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,87 +0,0 @@ -module.exports = { - root: true, - parser: '@typescript-eslint/parser', - plugins: [ - '@typescript-eslint', - 'react', - "react-hooks", - "react-native", - "prettier", - "jsx-a11y", - "eslint-comments", - "import" - ], - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - 'airbnb-typescript', - "airbnb", - "airbnb/hooks", - "plugin:react/recommended", - "plugin:react-hooks/recommended", - "plugin:react-native/all", - "prettier", - "plugin:prettier/recommended", - "plugin:jsx-a11y/recommended", - "plugin:eslint-comments/recommended", - "plugin:import/errors", - "plugin:import/errors", - "plugin:import/warnings", - "plugin:import/typescript" - ], - env: { - node: true, - "react-native/react-native": true - }, - "parserOptions": { - "ecmaFeatures": { - "jsx": true - }, - "ecmaVersion": 2020, - "sourceType": "module", - "project": "./tsconfig.json" - }, - "rules": { - "@typescript-eslint/no-explicit-any": ["error", { "ignoreRestArgs": false, "fixToUnknown": false }], - "import/no-unresolved": 0, - "react/jsx-filename-extension": [1, { - "extensions": [ - ".ts", - ".tsx", - ".js", - ".jsx" - ] - }], - "prettier/prettier": [ - "error", - { - // documented at: https://prettier.io/docs/en/configuration.html - "printWidth": 80, - "tabWidth": 2, - "useTabs": false, - "semi": true, - "singleQuote": true, - "quoteProps": "consistent", - "jsxSingleQuote": true, - "trailingComma": "all", - "bracketSpacing": true, - "jsxBracketSameLine": true, - "arrowParens": "always", - "requirePragma": false, - "insertPragma": false, - "proseWrap": "preserve", - "htmlWhitespaceSensitivity": "css", - "endOfLine": "lf", - "embeddedLanguageFormatting": "auto" - } - ], - "no-use-before-define": "off", - "@typescript-eslint/no-use-before-define": ["error"], - "import/extensions": ["error", "never"], - "react/prop-types": 0, - "no-shadow": "off", - "@typescript-eslint/no-shadow": ["error"], - "no-undef": "off" - }, - "ignorePatterns": [".eslintrc.js"] -}; diff --git a/.eslintrc.yaml b/.eslintrc.yaml new file mode 100644 index 000000000..6386cc9af --- /dev/null +++ b/.eslintrc.yaml @@ -0,0 +1,109 @@ +--- +# docs at: https://eslint.org/docs/latest/use/configure/configuration-files +env: + browser: true + es2021: true + react-native/react-native: true +extends: + - airbnb + - airbnb-typescript + - airbnb/hooks + - eslint:recommended + - plugin:@typescript-eslint/recommended + - plugin:@typescript-eslint/stylistic + - plugin:eslint-comments/recommended + - plugin:import/errors + - plugin:import/recommended + - plugin:import/typescript + - plugin:import/warnings + - plugin:jsdoc/recommended + - plugin:json/recommended + - plugin:jsx-a11y/recommended + - plugin:react-hooks/recommended + - plugin:react-native/all + - plugin:react/recommended + - prettier +globals: + JSX: true +parser: '@typescript-eslint/parser' +parserOptions: + ecmaFeatures: + jsx: true + ecmaVersion: latest + project: ./tsconfig.json + sourceType: module +plugins: + - '@typescript-eslint' + - eslint-comments + - eslint-plugin-json + - import + - jsdoc + - jsx-a11y + - react + - react-hooks + - react-native +rules: + '@typescript-eslint/array-type': + - error + - default: 'generic' + readonly: 'generic' + '@typescript-eslint/explicit-function-return-type': error + '@typescript-eslint/explicit-module-boundary-types': error + '@typescript-eslint/no-explicit-any': + - error + - fixToUnknown: false + ignoreRestArgs: false + '@typescript-eslint/no-shadow': error + '@typescript-eslint/no-use-before-define': error + camelcase: error + comma-dangle: + - error + - always-multiline + comma-style: + - error + - last + import/extensions: + - error + - never + import/no-unresolved: error + jsdoc/check-indentation: error + jsdoc/no-bad-blocks: error + jsdoc/require-description: error + jsdoc/require-file-overview: error + jsdoc/require-throws: error + jsx-quotes: + - error + - prefer-single + linebreak-style: + - error + - unix + max-lines: + - error + - 300 + max-lines-per-function: + - warn + - max: 20 + no-console: error + no-duplicate-imports: error + no-multi-spaces: error + no-shadow: error + no-template-curly-in-string: error + no-trailing-spaces: error + no-undef: error + no-use-before-define: warn + react-native/no-inline-styles: warn + react/jsx-filename-extension: + - error + - extensions: + - .ts + - .tsx + - .js + - .jsx + react/prop-types: error + sort-imports: warn + sort-keys: + - error + - asc + - caseSensitive: true + minKeys: 2 + natural: true diff --git a/.github/assets/images/screenshots/badges.png b/.github/assets/images/screenshots/badges.png new file mode 100644 index 000000000..009c01f55 Binary files /dev/null and b/.github/assets/images/screenshots/badges.png differ diff --git a/.github/assets/images/screenshots/badges_full.png b/.github/assets/images/screenshots/badges_full.png new file mode 100644 index 000000000..129731ef4 Binary files /dev/null and b/.github/assets/images/screenshots/badges_full.png differ diff --git a/.github/assets/images/screenshots/basic.png b/.github/assets/images/screenshots/basic.png new file mode 100644 index 000000000..c6bef60f4 Binary files /dev/null and b/.github/assets/images/screenshots/basic.png differ diff --git a/.github/assets/images/screenshots/basic_full.png b/.github/assets/images/screenshots/basic_full.png new file mode 100644 index 000000000..92927ccf4 Binary files /dev/null and b/.github/assets/images/screenshots/basic_full.png differ diff --git a/.github/assets/images/screenshots/dark_theme_parent_items.png b/.github/assets/images/screenshots/dark_theme_parent_items.png new file mode 100644 index 000000000..919239a96 Binary files /dev/null and b/.github/assets/images/screenshots/dark_theme_parent_items.png differ diff --git a/.github/assets/images/screenshots/dark_theme_parent_items_full.png b/.github/assets/images/screenshots/dark_theme_parent_items_full.png new file mode 100644 index 000000000..00e5e55bd Binary files /dev/null and b/.github/assets/images/screenshots/dark_theme_parent_items_full.png differ diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 000000000..d9edc018b --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,130 @@ +--- +# file format documented at: +# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions +name: CI + +on: [push, pull_request] + +jobs: + # TODO: check project builds/compiles correctly? maybe with tsc? + # TODO: add tests including coverage (jest and mocha/chai?) + + lint_src_files: + name: Lint source files + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v3 + with: + node-version: 18 + - run: npm ci + - name: Lint source files with Prettier + run: > + npx prettier --check + . + --config + .prettierrc.yaml + --ignore-path + .prettierignore + - name: Lint source files with ESLint + run: > + npx eslint + . + --config + .eslintrc.yaml + --ignore-path + .eslintignore + + check-npm-dependencies: + name: Check npm dependencies + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v3 + with: + node-version: 18 + - run: npm ci + - name: Scan for known vulnerabilities in dependencies with npm audit + run: > + npm audit + --audit-level + critical + - name: Check for unused and missing dependencies with depcheck + run: > + npx depcheck + --ignores + typescript,prettier + - name: Check for outdated packages with npm outdated + run: npm outdated + - name: Check for outdated packages with npm-check-updates + run: npx npm-check-updates + + find_todos: + name: Search for TODOs etc + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Search for TODO, FIXME, and BUG statements in source files + run: > + if grep + --recursive + --extended-regexp + --with-filename + --line-number + --color=always + "TODO|FIXME|BUG" + ./src; + then exit 1; + else + echo "No TODO, FIXME, or BUG statements found in source files."; + fi + + typos_spell_check: + name: Check spelling with typos + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Check spelling with typos + uses: crate-ci/typos@master + with: + config: .typos.toml + + lint_markdown_files: + name: Lint Markdown files + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: articulate/actions-markdownlint@v1 + with: + files: '*.md' + ignore: '**/node_modules' + + lint_yaml_files: + name: Lint YAML files + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ibiqlik/action-yamllint@v3 + + lint_shell_script_files: + name: Lint shell scripts + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: azohra/shell-linter@latest + + commitlint: + name: Enforce Conventional Commits + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: > + Check the commits conform to the Conventional + Commits specification with commitlint + uses: wagoid/commitlint-github-action@v5 + +# TODO: check PRs have all changes (squashed) in(to) 1 commit +# TODO: make semver automatically bump version num and update changelog +# TODO: publish new release if version num bumped and CI passes diff --git a/.github/workflows/publish-beta.yml-disabled b/.github/workflows/publish-beta.yaml-disabled similarity index 100% rename from .github/workflows/publish-beta.yml-disabled rename to .github/workflows/publish-beta.yaml-disabled diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yaml similarity index 83% rename from .github/workflows/publish.yml rename to .github/workflows/publish.yaml index b5c7c0c6a..680d8faba 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yaml @@ -1,3 +1,4 @@ +--- name: "🚀 publish" on: @@ -15,4 +16,4 @@ jobs: registry-url: https://registry.npmjs.org/ - run: npm publish env: - NODE_AUTH_TOKEN: ${{secrets.NPM_ACCESS_TOKEN}} \ No newline at end of file + NODE_AUTH_TOKEN: ${{secrets.NPM_ACCESS_TOKEN}} diff --git a/.gitignore b/.gitignore index ca3143ee8..8d54c735b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ node_modules - -package-lock.json -.vscode/* \ No newline at end of file +#package-lock.json +# package-lock.json should be in source control. +# see here: https://stackoverflow.com/questions/44206782/do-i-commit-the-package-lock-json-file-created-by-npm-5 +.vscode/* +.idea \ No newline at end of file diff --git a/.npmignore b/.npmignore index 960e504f3..375e7d7f3 100644 --- a/.npmignore +++ b/.npmignore @@ -1,4 +1,4 @@ .github/ node_modules/ - +examples package-lock.json \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..12f5d8e20 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,16 @@ +# don't ever lint node_modules +node_modules +package-lock.json +# don't lint build output +build +dist +# don't lint coverage output +coverage +# don't lint workflows etc +.github +.idea +.vscode +# unsupported file types +*.yaml +*.yml +*.md \ No newline at end of file diff --git a/.prettierrc.yaml b/.prettierrc.yaml new file mode 100644 index 000000000..ebd0116e4 --- /dev/null +++ b/.prettierrc.yaml @@ -0,0 +1,19 @@ +--- +# docs at: https://prettier.io/docs/en/configuration.html +arrowParens: always +bracketSameLine: true +bracketSpacing: true +embeddedLanguageFormatting: auto +endOfLine: lf +htmlWhitespaceSensitivity: css +insertPragma: false +jsxSingleQuote: true +printWidth: 80 +proseWrap: preserve +quoteProps: consistent +requirePragma: false +semi: true +singleQuote: true +tabWidth: 2 +trailingComma: all +useTabs: false diff --git a/.typos.toml b/.typos.toml new file mode 100644 index 000000000..c3da8ec1e --- /dev/null +++ b/.typos.toml @@ -0,0 +1,19 @@ +# docs at: https://github.com/crate-ci/typos/blob/master/docs/reference.md + +files.extend-exclude = [ + ".typos.toml" +] + +default.extend-ignore-re = [ + # false positives + "alguns itens selecionados", + "elementi sono stati selezionati", + "Nada a ser mostrado", + "prevProps", + "prevState", +] + +default.locale = "en-us" + +# note: add false negatives with corrections in default.extend-identifiers or default.extend-words +# todo: check mistakes over multiple words, e.g. "the the" instead of "the" \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..ba250f086 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,146 @@ +# 💖 Contributing to [React Native Dropdown Picker](https://github.com/hossein-zare/react-native-dropdown-picker) + +Thank you for considering contributing to this library! This guide will walk you +through how to do so successfully 😃 + +## 🤔 Overview + +### 🌍 General guidance + +You should +read [GitHub's general guidance on contributing to projects](https://docs.github.com/en/get-started/quickstart/contributing-to-projects) +and [guidance on collaborating with pull requests](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests). + +### 📄 Documentation + +Good and thorough documentation is important to enabling people to use a +library. Therefore, it would be greatly appreciated if +you [contributed to this library's documentation](https://github.com/hossein-zare/react-native-dropdown-picker-website). + +### 🧪 Experimenting + +To easily and quickly test changes before needing to add them to version +control or submit them for acceptance into this library, you can +use [patch-package](https://www.npmjs.com/package/patch-package). It will let +you edit this library in your own project's npm dependencies to see which +changes work. + +## 🛠️ How to contribute changes + +### ✅ Sensibility + +Read [this library's docs](https://hossein-zare.github.io/react-native-dropdown-picker-website/docs) +and +search [its GitHub issues](https://github.com/hossein-zare/react-native-dropdown-picker/issues) +to ensure your intended changes make sense. + +### 🚩 Make an issue + +Before submitting any changes, document them +in [an issue](https://github.com/hossein-zare/react-native-dropdown-picker/issues/new/choose). +For example, this might be a feature request issue for the feature you will +create or a bug report for the bug you will fix. If the issue already exists, +e.g. a bug report for the same bug you'll fix or a feature request for the same +feature you're building, skip this step. Don't make a duplicate issue. + +### 🍴 Forking + +To start work on your changes to be +submitted, [fork and clone](https://docs.github.com/en/get-started/quickstart/fork-a-repo) +this library. You should +then [create a new branch](https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging) +on your fork dedicated to the changes you're making. You should +read [GitHub's docs about branches](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-branches). +Make sure you use a separate branch (⇒ PR) for each atomic change (e.g. adding +one feature or fixing one bug) you are making. If you want to make multiple, do +so in separate branches, and submit them in separate PRs. Otherwise, your PRs +will bloat, and it will be hard to review, manage, and keep track of them. + +### 👩🏾‍💻 Make changes + +Make the changes you require to this library in your fork. Test them +with `npm pack`. It will let you build this library as if for release on npm +locally, so you can include it as a dependency in another npm package to test +it. +Read [this article](https://dev.to/scooperdev/use-npm-pack-to-test-your-packages-locally-486e) +for more information on how to use `npm pack` to test your changed version of +this library locally. + +Once you have ensured your changes work as +required, [commit your changes](https://git-scm.com/docs/git-commit) +and [push them to your fork](https://docs.github.com/en/get-started/using-git/pushing-commits-to-a-remote-repository). +Then ensure that your changes pass +our [continuous integration (CI) workflow](https://docs.github.com/en/actions/automating-builds-and-tests/about-continuous-integration). +They will show up to you +as [status checks](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/about-status-checks). +To do this, you may need +to [fix ESLint issues](https://eslint.org/docs/latest/use/command-line-interface#--fix) +and [reformat your code with Prettier](https://prettier.io/docs/en/cli#--write). + +Use the script `update_reformat.sh` to automatically update this library's +dependencies and reformat its code. This will help you pass our CI checks. + +Whenever applicable, add or update automated tests to check your changes work +and that they will continue to do so in the future. You +should [squash the commits you made](https://www.geeksforgeeks.org/git-squash/) +containing your changes into one single commit that conforms +to [the Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/#summary). + +Ensure your changes are up-to-date with those in the `dev-5.x` (default) branch. +This will mean your commit will come immediately after the last one in +the `dev-5.x` (default) branch if you +run [git log](https://git-scm.com/docs/git-log). +Read [GitHub's guidance on keeping your pull request in sync with the base branch](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/keeping-your-pull-request-in-sync-with-the-base-branch). +Doing this will prevent merge conflicts that will stop your changes being able +to be merged. + +Once you've done all this, you're ready to submit a Pull Request (PR). + +### 🚀 Make a Pull Request + +To submit your changes for review and to have them added to this library, you +must make +a [pull request (PR)](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests). +You will be ready to do so after following the instructions in the "Make +changes" section. + +You can make a PR into this +library [here](https://github.com/hossein-zare/react-native-dropdown-picker/compare). +Ensure +you [link the issue you made earlier (and any others that are relevant) to your PR](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#manually-linking-a-pull-request-to-an-issue-using-the-pull-request-sidebar). + +PRs should be made against and merged into +the [`dev-5.x`](https://github.com/hossein-zare/react-native-dropdown-picker) +branch, which is set as the `default` branch on GitHub. + +You can also make +a [draft PR](https://github.blog/2019-02-14-introducing-draft-pull-requests/) +before the changes are completely finished as per the "Make changes" section. +This might be useful if you need feedback on your changes early on and before +finalizing for merging. + +Once you have made a PR, you will then get feedback from the maintainers of the +repo. This will help ensure your changes are ready to be merged. + +If required, make a separate +PR [in the docs](https://github.com/hossein-zare/react-native-dropdown-picker-website) +if your changes make its contents incorrect or if information regarding your +changes is missing from them altogether. + +## 🏁 Release process + +Releases are currently made from +the [`5.x`](https://github.com/hossein-zare/react-native-dropdown-picker/tree/5.x) +branch. To make a new release, follow these steps: + +1. Verify the development branch has all the changes desired in the release and + works well +2. Make and merge a final PR into the development branch that increments the + version number in `package.json` +3. Make and merge a PR from the development branch to the release branch +4. Using the GitHub web UI, draft a new release using the tag name `vx.x.x` + (replace the `x` values as appropriate). Use the release branch as the + target, with the release name being `vx.x.x` (again, with appropriate + numbers in place of `x`) +5. Verify in the GitHub Actions panel for the repository that `npm publish` + succeeded diff --git a/README.md b/README.md index 1377973d5..4ac7c9344 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,103 @@ -# React Native Dropdown Picker 5.x +# React Native Dropdown Picker -

- Screenshot - Screenshot - Screenshot -

+[![GitHub repo](https://img.shields.io/badge/GitHub_repo-grey?logo=github)](https://github.com/hossein-zare/react-native-dropdown-picker) +[![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Fhossein-zare%2Freact-native-dropdown-picker%2Fbadge%3Fref%3Ddev-5.x&style=flat)](https://actions-badge.atrox.dev/hossein-zare/react-native-dropdown-picker/goto?ref=dev-5.x) +[![PRs welcome](https://img.shields.io/badge/PRs-welcome-brightgreen)](https://github.com/hossein-zare/react-native-dropdown-picker/blob/dev-5.x/CONTRIBUTING.md) +[![react-native-dropdown-picker is released under the MIT license.](https://img.shields.io/github/license/hossein-zare/react-native-dropdown-picker)](https://github.com/hossein-zare/react-native-dropdown-picker/blob/dev-5.x/LICENSE) +[![Current npm package version.](https://img.shields.io/npm/v/react-native-dropdown-picker?color=brightgreen&label=npm%20package)](https://www.npmjs.org/package/react-native-dropdown-picker) +[![Weekly npm downloads](https://img.shields.io/npm/dw/react-native-dropdown-picker)](https://www.npmjs.org/package/react-native-dropdown-picker) +[![Documentation](https://img.shields.io/badge/Documentation-grey)](https://hossein-zare.github.io/react-native-dropdown-picker-website/docs) -The example in the screenshots: https://snack.expo.dev/8mHmLfcZf +--- -# Documentation -**Visit https://hossein-zare.github.io/react-native-dropdown-picker-website/** +## 📱 Screenshots -# Merge and Release Process +[![Screenshot showing basic dropdown](.github/assets/images/screenshots/basic.png)](https://raw.githubusercontent.com/hossein-zare/react-native-dropdown-picker/dev-5.x/.github/assets/images/screenshots/basic_full.png) +[![Screenshot showing badges](.github/assets/images/screenshots/badges.png)](https://raw.githubusercontent.com/hossein-zare/react-native-dropdown-picker/dev-5.x/.github/assets/images/screenshots/badges_full.png) +[![Screenshot showing dark theme and parent items](.github/assets/images/screenshots/dark_theme_parent_items.png)](https://raw.githubusercontent.com/hossein-zare/react-native-dropdown-picker/dev-5.x/.github/assets/images/screenshots/dark_theme_parent_items_full.png) -## Branches in use +The above screenshots were taken +from [this example](https://snack.expo.dev/8mHmLfcZf). -### Development +## 👋 Usage -PRs should be made against and merged into the [`dev-5.x`](https://github.com/hossein-zare/react-native-dropdown-picker) branch, which is set as the `default` branch on github. +### Basic usage -### Release +The following code shows basic usage of this library: -Releases are currently made from the [`5.x`](https://github.com/hossein-zare/react-native-dropdown-picker/tree/5.x) branch. +```javascript +import React, {useState} from 'react'; +import {View, Text} from 'react-native'; +import DropDownPicker from 'react-native-dropdown-picker'; -## Release Process +export default function App() { + const [open, setOpen] = useState(false); + const [value, setValue] = useState(null); + const [items, setItems] = useState([ + {label: 'Apple', value: 'apple'}, + {label: 'Banana', value: 'banana'}, + {label: 'Pear', value: 'pear'}, + ]); -To make a new release, follow these steps: + return ( + + + + -* Verify the development branch has all the changes desired in a release and works well -* Make and merge a final PR into development branch that increments the version number in `package.json` -* Make and merge a PR from the development branch to the release branch -* Using the GitHub web UI, draft a new release using tag name `vx.x.x` (replace the `x` values as appropriate of course), with the release branch as the target, with release name `vx.x.x` (again, with appropriate numbers in place of `x` of course) -* Verify in the GitHub Actions panel for the repository that NPM publish succeeded + + Chosen fruit: {value === null ? 'none' : value} + + + ); +} +``` + +### Further information on usage + +You can find more examples in the `examples` subdirectory. This subdirectory is +a working [Expo](https://github.com/expo/expo) project demonstrating this +library. It shows how to use this library with class components as well as with +function components, and in TypeScript as well as in JavaScript. Navigate into +the `examples` subdirectory, run `npm install`, and then run `npx expo start` to +see the examples working. + +For further information on how to use this library, +read [the usage documentation](https://hossein-zare.github.io/react-native-dropdown-picker-website/docs/usage). + +## 📄 Further documentation + +The docs can be read +at: [https://hossein-zare.github.io/react-native-dropdown-picker-website](https://hossein-zare.github.io/react-native-dropdown-picker-website) + +The docs can be edited +at: [https://github.com/hossein-zare/react-native-dropdown-picker-website](https://github.com/hossein-zare/react-native-dropdown-picker-website) + +## 😕 Support and issues + +If you have questions or need help, you +can [ask a question on Stack Overflow](https://stackoverflow.com/questions/tagged/react-native-dropdown-picker) +or [make a GitHub issue](https://github.com/hossein-zare/react-native-dropdown-picker/issues/new/choose). +You can also make a GitHub issue to report a bug or make a feature request. + +## 🚀️ Contributing + +See [CONTRIBUTING.md](https://github.com/hossein-zare/react-native-dropdown-picker/blob/dev-5.x/CONTRIBUTING.md). diff --git a/examples/.gitignore b/examples/.gitignore new file mode 100644 index 000000000..05647d55c --- /dev/null +++ b/examples/.gitignore @@ -0,0 +1,35 @@ +# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files + +# dependencies +node_modules/ + +# Expo +.expo/ +dist/ +web-build/ + +# Native +*.orig.* +*.jks +*.p8 +*.p12 +*.key +*.mobileprovision + +# Metro +.metro-health-check* + +# debug +npm-debug.* +yarn-debug.* +yarn-error.* + +# macOS +.DS_Store +*.pem + +# local env files +.env*.local + +# typescript +*.tsbuildinfo diff --git a/examples/App.tsx b/examples/App.tsx new file mode 100644 index 000000000..3773bc9f4 --- /dev/null +++ b/examples/App.tsx @@ -0,0 +1,160 @@ +import React, { JSX } from 'react'; +import { StyleSheet, Text, View } from 'react-native'; +import DropDownPicker, { ItemType } from 'react-native-dropdown-picker'; +import JavascriptClassExample from './example-src-files/javascript-class-example'; +import JavascriptFunctionExample from './example-src-files/javascript-function-example'; +import TypescriptClassExample from './example-src-files/typescript-class-example'; +import TypescriptFunctionExample from './example-src-files/typescript-function-example'; + +enum ExampleComponent { + JavaScriptClassSingleValue, + JavaScriptClassMultiValue, + JavaScriptFunctionSingleValue, + JavaScriptFunctionMultiValue, + TypeScriptClassSingleValue, + TypeScriptClassMultiValue, + TypeScriptFunctionSingleValue, + TypeScriptFunctionMultiValue, +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + // backgroundColor: "#fff", + // alignItems: "center", + // justifyContent: "center", + flexDirection: 'column', + margin: 3, + marginTop: 20, + padding: 3, + }, +}); + +const EXAMPLE_COMPONENT_ITEMS: Array> = [ + { + label: 'JavaScript; class component; single-item', + value: ExampleComponent.JavaScriptClassSingleValue, + }, + { + label: 'JavaScript; class component; multiple-item', + value: ExampleComponent.JavaScriptClassMultiValue, + }, + { + label: 'JavaScript; function component; single-item', + value: ExampleComponent.JavaScriptFunctionSingleValue, + }, + { + label: 'JavaScript; function component; multiple-item', + value: ExampleComponent.JavaScriptFunctionMultiValue, + }, + { + label: 'TypeScript; class component; single-item', + value: ExampleComponent.TypeScriptClassSingleValue, + }, + { + label: 'TypeScript; class component; multiple-item', + value: ExampleComponent.TypeScriptClassMultiValue, + }, + { + label: 'TypeScript; function component; single-item', + value: ExampleComponent.TypeScriptFunctionSingleValue, + }, + { + label: 'TypeScript; function component; multiple-item', + value: ExampleComponent.TypeScriptFunctionMultiValue, + }, +]; + +type Props = Record; + +interface State { + currentExample: ExampleComponent; + examplePickerOpen: boolean; + exampleComponents: Array>; +} + +export default class App extends React.Component { + constructor(props: Readonly) { + super(props); + this.state = { + currentExample: ExampleComponent.JavaScriptClassSingleValue, + exampleComponents: EXAMPLE_COMPONENT_ITEMS, + examplePickerOpen: false, + }; + + this.setOpen = this.setOpen.bind(this); + this.setCurrentExample = this.setCurrentExample.bind(this); + } + + private static getExample(egComponent: ExampleComponent): JSX.Element { + switch (egComponent) { + case ExampleComponent.JavaScriptClassSingleValue: + return ; + case ExampleComponent.JavaScriptClassMultiValue: + return ; + case ExampleComponent.JavaScriptFunctionSingleValue: + return ; + case ExampleComponent.JavaScriptFunctionMultiValue: + return ; + case ExampleComponent.TypeScriptClassSingleValue: + return ; + case ExampleComponent.TypeScriptClassMultiValue: + return ; + case ExampleComponent.TypeScriptFunctionSingleValue: + return ; + case ExampleComponent.TypeScriptFunctionMultiValue: + return ; + default: + throw new Error( + "couldn't match example component in getExample() in App.tsx. egComponent was: ", + egComponent, + ); + } + } + + setOpen(examplePickerOpen: boolean): void { + this.setState({ examplePickerOpen }); + } + + setCurrentExample( + callback: (prevState: ExampleComponent | null) => ExampleComponent | null, + ): void { + this.setState((state: Readonly) => ({ + currentExample: callback(state.currentExample), + })); + } + + // todo: fix picker items being under text + + render(): JSX.Element { + const { currentExample, examplePickerOpen, exampleComponents } = this.state; + + return ( + + + + Choose example: + + + + + + + + + + Example: + + + {App.getExample(currentExample)} + + + ); + } +} diff --git a/examples/app.json b/examples/app.json new file mode 100644 index 000000000..b5e52fc05 --- /dev/null +++ b/examples/app.json @@ -0,0 +1,28 @@ +{ + "expo": { + "name": "examples", + "slug": "examples", + "version": "1.0.0", + "orientation": "portrait", + "icon": "./assets/icon.png", + "userInterfaceStyle": "light", + "splash": { + "image": "./assets/splash.png", + "resizeMode": "contain", + "backgroundColor": "#ffffff" + }, + "assetBundlePatterns": ["**/*"], + "ios": { + "supportsTablet": true + }, + "android": { + "adaptiveIcon": { + "foregroundImage": "./assets/adaptive-icon.png", + "backgroundColor": "#ffffff" + } + }, + "web": { + "favicon": "./assets/favicon.png" + } + } +} diff --git a/examples/assets/adaptive-icon.png b/examples/assets/adaptive-icon.png new file mode 100644 index 000000000..03d6f6b6c Binary files /dev/null and b/examples/assets/adaptive-icon.png differ diff --git a/examples/assets/favicon.png b/examples/assets/favicon.png new file mode 100644 index 000000000..e75f697b1 Binary files /dev/null and b/examples/assets/favicon.png differ diff --git a/examples/assets/icon.png b/examples/assets/icon.png new file mode 100644 index 000000000..a0b1526fc Binary files /dev/null and b/examples/assets/icon.png differ diff --git a/examples/assets/splash.png b/examples/assets/splash.png new file mode 100644 index 000000000..0e89705a9 Binary files /dev/null and b/examples/assets/splash.png differ diff --git a/examples/babel.config.js b/examples/babel.config.js new file mode 100644 index 000000000..9d89e1311 --- /dev/null +++ b/examples/babel.config.js @@ -0,0 +1,6 @@ +module.exports = function (api) { + api.cache(true); + return { + presets: ['babel-preset-expo'], + }; +}; diff --git a/examples/example-src-files/javascript-class-example.jsx b/examples/example-src-files/javascript-class-example.jsx new file mode 100644 index 000000000..b5fd06ea6 --- /dev/null +++ b/examples/example-src-files/javascript-class-example.jsx @@ -0,0 +1,116 @@ +import React, { Component } from 'react'; +import { Button, Text, View } from 'react-native'; +import DropDownPicker from 'react-native-dropdown-picker'; + +export default class JavascriptClassExample extends Component { + constructor(props) { + super(props); + + this.state = { + items: [ + { label: 'Bert', value: 'Bert' }, + { label: 'Darius', value: 'Darius' }, + { label: 'Maggie', value: 'Maggie' }, + { label: 'Rebecca', value: 'Rebecca' }, + { label: 'Ruby', value: 'Ruby' }, + { label: 'Trent', value: 'Trent' }, + ], + multiValue: null, + open: false, + singleValue: null, + }; + + this.setOpen = this.setOpen.bind(this); + this.setSingleValue = this.setSingleValue.bind(this); + this.setMultiValue = this.setMultiValue.bind(this); + this.setItems = this.setItems.bind(this); + } + + setOpen(open) { + this.setState({ + open, + }); + } + + setSingleValue(callback) { + this.setState((state) => ({ + singleValue: callback(state.singleValue), + })); + } + + setMultiValue(callback) { + this.setState((state) => ({ + multiValue: callback(state.multiValue), + })); + } + + setItems(callback) { + this.setState((state) => ({ + items: callback(state.items), + })); + } + + render() { + const { multiple } = this.props; + const { open, singleValue, multiValue, items } = this.state; + + return ( + + + + Choose a name (javascript class,{' '} + {multiple ? 'multiple-item' : 'single-item'}): + + + + + {multiple ? ( + + ) : ( + + )} + + + + + + {multiple ? 'Names currently are: ' : 'Name currently is: '} + {multiple + ? JSON.stringify(multiValue) + : JSON.stringify(singleValue)} + + + + +