diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..c18ed01 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,2 @@ +node_modules/ +lib/ \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js index 9e4157c..6cf0608 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,42 +1,69 @@ module.exports = { root: true, - extends: ['@react-native', 'plugin:prettier/recommended', 'prettier'], - plugins: ['react', 'unused-imports', 'prettier'], + extends: ['plugin:prettier/recommended', '@react-native'], + parser: '@typescript-eslint/parser', + plugins: ['react-native', 'prettier', '@typescript-eslint', 'unused-imports', 'simple-import-sort', 'import'], + env: { + 'react-native/react-native': true, + }, parserOptions: { ecmaFeatures: { - jsx: true + jsx: true, }, - requireConfigFile: false + }, + settings: { + 'react-native/style-sheet-object-names': ['ScaledSheet'], }, rules: { + 'react-native/no-unused-styles': 2, '@typescript-eslint/no-unused-vars': 'off', // or "no-unused-vars": "off", 'unused-imports/no-unused-imports': 'error', - 'unused-imports/no-unused-vars': [ - 'warn', - { - vars: 'all', - varsIgnorePattern: '^_', - args: 'after-used', - argsIgnorePattern: '^_' - } - ], + 'unused-imports/no-unused-vars': 0, + semi: ['warn', 'never'], 'prettier/prettier': [ 'error', { - printWidth: 110, + singleQuote: true, + semi: false, arrowParens: 'avoid', bracketSameLine: true, bracketSpacing: true, - singleQuote: true, - trailingComma: 'none', - tabWidth: 2, - useTabs: false, - semi: false - } + trailingComma: 'all', + printWidth: 120, + }, ], - semi: 'off', - 'comma-dangle': ['warn', 'never'], - 'react-native/no-inline-styles': 'off', - 'react-hooks/exhaustive-deps': 'off' - } + 'comma-dangle': 0, + 'simple-import-sort/imports': 'off', + 'simple-import-sort/exports': 'error', + 'import/order': [ + 'error', + { + pathGroups: [ + { + pattern: 'react', + group: 'builtin', + position: 'before', + }, + ], + pathGroupsExcludedImportTypes: ['react'], + }, + ], + 'import/first': 'error', + 'import/newline-after-import': 'off', + 'import/no-duplicates': 'error', + 'react/display-name': 'off', + '@typescript-eslint/consistent-type-imports': 'error', + }, + overrides: [ + { + files: ['*.ts', '*.tsx'], + rules: { + '@typescript-eslint/no-shadow': ['error'], + 'no-shadow': 'off', + 'no-undef': 'off', + 'react-hooks/exhaustive-deps': 'warn', + 'react-native/no-unused-styles': 'warn', + }, + }, + ], } diff --git a/.gitignore b/.gitignore index d43f98f..d3b53df 100644 --- a/.gitignore +++ b/.gitignore @@ -1,363 +1,78 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. -## -## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore - +# OSX +# .DS_Store -# User-specific files -*.rsuser -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs -.vscode - -# Mono auto generated files -mono_crash.* - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -[Aa][Rr][Mm]/ -[Aa][Rr][Mm]64/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ -[Ll]ogs/ - -# Visual Studio 2015/2017 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# Visual Studio 2017 auto generated files -Generated\ Files/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUnit -*.VisualState.xml -TestResult.xml -nunit-*.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# Benchmark Results -BenchmarkDotNet.Artifacts/ - -# .NET Core -project.lock.json -project.fragment.lock.json -artifacts/ - -# StyleCop -StyleCopReport.xml - -# Files built by Visual Studio -*_i.c -*_p.c -*_h.h -*.ilk -*.meta -*.obj -*.iobj -*.pch -*.pdb -*.ipdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*_wpftmp.csproj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# Visual Studio Trace Files -*.e2e - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# AxoCover is a Code Coverage Tool -.axoCover/* -!.axoCover/settings.json - -# Visual Studio code coverage results -*.coverage -*.coveragexml - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# Note: Comment the next line if you want to checkin your web deploy settings, -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# NuGet Symbol Packages -*.snupkg -# The packages folder can be ignored because of Package Restore -**/[Pp]ackages/* -# except build/, which is used as an MSBuild target. -!**/[Pp]ackages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/[Pp]ackages/repositories.config -# NuGet v3's project.json files produces more ignorable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt -*.appx -*.appxbundle -*.appxupload - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!?*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -orleans.codegen.cs - -# Including strong name files can present a security risk -# (https://github.com/github/gitignore/pull/2483#issue-259490424) -#*.snk - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm -ServiceFabricBackup/ -*.rptproj.bak - -# SQL Server files -*.mdf -*.ldf -*.ndf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings -*.rptproj.rsuser -*- [Bb]ackup.rdl -*- [Bb]ackup ([0-9]).rdl -*- [Bb]ackup ([0-9][0-9]).rdl +# XDE +.expo/ + +# VSCode +.vscode/ +jsconfig.json + +# Xcode +# +build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +*.xccheckout +*.moved-aside +DerivedData +*.hmap +*.ipa +*.xcuserstate +project.xcworkspace + +# Android/IJ +# +.classpath +.cxx +.gradle +.idea +.project +.settings +local.properties +android.iml -# Microsoft Fakes -FakesAssemblies/ +# Cocoapods +# +example/ios/Pods -# GhostDoc plugin setting file -*.GhostDoc.xml +# Ruby +example/vendor/ -# Node.js Tools for Visual Studio -.ntvs_analysis.dat +# node.js +# node_modules/ - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) -*.vbw - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# CodeRush personal settings -.cr/personal - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc - -# Cake - Uncomment if you are using it -# tools/** -# !tools/packages.config - -# Tabs Studio -*.tss - -# Telerik's JustMock configuration file -*.jmconfig - -# BizTalk build output -*.btp.cs -*.btm.cs -*.odx.cs -*.xsd.cs - -# OpenCover UI analysis results -OpenCover/ - -# Azure Stream Analytics local run output -ASALocalRun/ - -# MSBuild Binary and Structured Log -*.binlog - -# NVidia Nsight GPU debugger configuration file -*.nvuser - -# MFractors (Xamarin productivity tool) working folder -.mfractor/ - -# Local History for Visual Studio -.localhistory/ - -# BeatPulse healthcheck temp database -healthchecksdb - -# Backup folder for Package Reference Convert tool in Visual Studio 2017 -MigrationBackup/ - -# Ionide (cross platform F# VS Code tools) working folder -.ionide/ - -# macOS -.DS_Store - -#windows -desktop.ini - -# .idea -/.idea -.idea +npm-debug.log +yarn-debug.log +yarn-error.log + +# BUCK +buck-out/ +\.buckd/ +android/app/libs +android/keystores/debug.keystore + +# Yarn +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/sdks +!.yarn/versions + +# Expo +.expo/ + +# Turborepo +.turbo/ + +# generated by bob +lib/ diff --git a/.vscode/settings.json b/.vscode/settings.json index 03560de..3886e86 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -19,7 +19,7 @@ "tsx", "ts" ], - "jest.autoRun": "off", + "jest.runMode": "deferred", "prettier.requireConfig": true, "prettier.semi": false, "prettier.trailingComma": "none", diff --git a/.watchmanconfig b/.watchmanconfig new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/.watchmanconfig @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/.yarnrc b/.yarnrc new file mode 100644 index 0000000..7767fb7 --- /dev/null +++ b/.yarnrc @@ -0,0 +1,5 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +yarn-path ".yarn/releases/yarn-1.22.22.js" diff --git a/.yarnrc.yml b/.yarnrc.yml new file mode 100644 index 0000000..b44f21e --- /dev/null +++ b/.yarnrc.yml @@ -0,0 +1,3 @@ +nodeLinker: node-modules +nmHoistingLimits: workspaces + diff --git a/README.md b/README.md index 0b77b61..ba2abe0 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Dropdown Item picker with search and autocomplete (typeahead) functionality for [![npm](https://img.shields.io/npm/v/react-native-autocomplete-dropdown.svg)](https://npmjs.com/package/react-native-autocomplete-dropdown) [![npm](https://img.shields.io/npm/dm/react-native-autocomplete-dropdown.svg)](https://npmjs.com/package/react-native-autocomplete-dropdown) -> This is documentation for version 3.x, if you are looking docs for version 2.x, you can find it [here](https://github.com/onmotion/react-native-autocomplete-dropdown/blob/main/README%5E2.md) +> This is documentation for version 4.x, if you are looking docs for version 3.x, you can find it [here](https://github.com/onmotion/react-native-autocomplete-dropdown/blob/main/README%5E3.md)

@@ -249,12 +249,15 @@ More examples see at This is documentation for version 3.x, if you are looking docs for version 2.x, you can find it [here](https://github.com/onmotion/react-native-autocomplete-dropdown/blob/main/README%5E2.md) + +

+ +

+ +## Demo + +

+ + +

+ +> Run expo snack demo [@onmotion/react-native-autocomplete-dropdown](https://snack.expo.io/@onmotion/react-native-autocomplete-dropdown-v3) + + + +## Nav + +- [react-native-autocomplete-dropdown](#react-native-autocomplete-dropdown) + - [Demo](#demo) + - [Nav](#nav) + - [Installation](#installation) + - [Post-install Steps](#post-install-steps) + - [iOS](#ios) + - [Android](#android) + - [Usage](#usage) + - [Dataset item format](#dataset-item-format) + - [Example with local Dataset](#example-with-local-dataset) + - [Example with remote requested Dataset](#example-with-remote-requested-dataset) + - [Options](#options) + +## Installation + +Run: + +```bash +npm install --save react-native-autocomplete-dropdown +``` + + or + + ```bash + yarn add react-native-autocomplete-dropdown + ``` + +## Post-install Steps + +Make sure **react-native-svg** is installed. Follow the guide + + +```bash +yarn add react-native-svg +``` + +### iOS + +Run: `npx pod-install` for install `react-native-svg` dependency (if not installed yet). + +### Android + +No additional steps are necessary + +## Usage + +Wrap your root component in `AutocompleteDropdownContextProvider` from `react-native-autocomplete-dropdown` as you can see in [example](https://github.com/onmotion/react-native-autocomplete-dropdown/blob/main/example/App.js) + +```js + + + +``` + +If you have a header component, you can pass an offset. For example with react navigation + +```js +//... +import { useHeaderHeight } from '@react-navigation/elements'; +//... +const headerHeight = useHeaderHeight(); +//... + + + + +``` + +import the package + +```js +import { AutocompleteDropdown } from 'react-native-autocomplete-dropdown'; +``` + +### Dataset item format + +`dataSet` property must be an **array of objects** or **null**. Object required keys are: + +```js +{ + id: 'some uniq string id', + title: 'list item title' +} +``` + +### Example with local Dataset + +```js +const [selectedItem, setSelectedItem] = useState(null); + +; +``` + +### Example with remote requested Dataset + +```js +import React, { memo, useCallback, useRef, useState } from 'react' +import { Button, Dimensions, Text, View, Platform } from 'react-native' +import { AutocompleteDropdown } from 'react-native-autocomplete-dropdown' + +export const RemoteDataSetExample2 = memo(() => { + const [loading, setLoading] = useState(false) + const [suggestionsList, setSuggestionsList] = useState(null) + const [selectedItem, setSelectedItem] = useState(null) + const dropdownController = useRef(null) + + const searchRef = useRef(null) + + const getSuggestions = useCallback(async q => { + const filterToken = q.toLowerCase() + console.log('getSuggestions', q) + if (typeof q !== 'string' || q.length < 3) { + setSuggestionsList(null) + return + } + setLoading(true) + const response = await fetch('https://jsonplaceholder.typicode.com/posts') + const items = await response.json() + const suggestions = items + .filter(item => item.title.toLowerCase().includes(filterToken)) + .map(item => ({ + id: item.id, + title: item.title, + })) + setSuggestionsList(suggestions) + setLoading(false) + }, []) + + const onClearPress = useCallback(() => { + setSuggestionsList(null) + }, []) + + const onOpenSuggestionsList = useCallback(isOpened => {}, []) + + return ( + <> + + { + dropdownController.current = controller + }} + // initialValue={'1'} + direction={Platform.select({ ios: 'down' })} + dataSet={suggestionsList} + onChangeText={getSuggestions} + onSelectItem={item => { + item && setSelectedItem(item.id) + }} + debounce={600} + suggestionsListMaxHeight={Dimensions.get('window').height * 0.4} + onClear={onClearPress} + // onSubmit={(e) => onSubmitSearch(e.nativeEvent.text)} + onOpenSuggestionsList={onOpenSuggestionsList} + loading={loading} + useFilter={false} // set false to prevent rerender twice + textInputProps={{ + placeholder: 'Type 3+ letters (dolo...)', + autoCorrect: false, + autoCapitalize: 'none', + style: { + borderRadius: 25, + backgroundColor: '#383b42', + color: '#fff', + paddingLeft: 18, + }, + }} + rightButtonsContainerStyle={{ + right: 8, + height: 30, + + alignSelf: 'center', + }} + inputContainerStyle={{ + backgroundColor: '#383b42', + borderRadius: 25, + }} + suggestionsListContainerStyle={{ + backgroundColor: '#383b42', + }} + containerStyle={{ flexGrow: 1, flexShrink: 1 }} + renderItem={(item, text) => {item.title}} + // ChevronIconComponent={} + // ClearIconComponent={} + inputHeight={50} + showChevron={false} + closeOnBlur={false} + // showClear={false} + /> + +