diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 12f5d8e20..000000000 --- a/.eslintignore +++ /dev/null @@ -1,16 +0,0 @@ -# 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/.eslintrc.yaml b/.eslintrc.yaml deleted file mode 100644 index 6386cc9af..000000000 --- a/.eslintrc.yaml +++ /dev/null @@ -1,109 +0,0 @@ ---- -# 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/eslint.config.js b/eslint.config.js new file mode 100644 index 000000000..7dfe0079a --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,109 @@ +import eslint from '@eslint/js'; +import prettier from 'eslint-config-prettier'; +import eslintComments from 'eslint-plugin-eslint-comments'; +import json from 'eslint-plugin-json'; +import jsxA11y from 'eslint-plugin-jsx-a11y'; +import react from 'eslint-plugin-react'; +import reactHooks from 'eslint-plugin-react-hooks'; +import reactNative from 'eslint-plugin-react-native'; +import simpleImportSort from 'eslint-plugin-simple-import-sort'; +import tseslint from 'typescript-eslint'; + +export default tseslint.config( + eslint.configs.recommended, + tseslint.configs.recommended, + tseslint.configs.stylistic, + { + ignores: [ + 'node_modules', + 'package-lock.json', + 'build', + 'dist', + '*.expo', + 'coverage', + '.github', + '.idea', + '.vscode', + '*.yaml', + '*.yml', + '*.md', + ], + plugins: { + react, + 'react-hooks': reactHooks, + 'react-native': reactNative, + 'jsx-a11y': jsxA11y, + '@typescript-eslint': tseslint.plugin, + 'eslint-comments': eslintComments, + json, + simpleImportSort, + }, + languageOptions: { + parser: tseslint.parser, + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + ecmaVersion: 'latest', + project: './tsconfig.json', + sourceType: 'module', + }, + globals: { + JSX: true, + require: true, + module: true, + __dirname: true, + setTimeout: true, + }, + }, + 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-require-imports': 'off', // diabling until typescript rewrite + '@typescript-eslint/no-shadow': 'error', + '@typescript-eslint/no-empty-function': 'off', // disabling due to lots of functions defaulting to empt@typescript-eslint/no-empty-functiony + '@typescript-eslint/no-unused-vars': [ + 'error', + { + caughtErrors: 'none', + }, + ], + 'no-underscore-dangle': 'off', + 'comma-dangle': ['error', 'always-multiline'], + 'comma-style': ['error', 'last'], + 'jsx-quotes': ['error', 'prefer-single'], + 'linebreak-style': ['error', 'unix'], + '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', + 'react-native/no-inline-styles': 'warn', + 'react/jsx-filename-extension': [ + 'error', + { + extensions: ['.ts', '.tsx', '.js', '.jsx'], + }, + ], + 'simpleImportSort/imports': ['error'], + 'react/prop-types': 'off', // Disabling until typescript rewrite + }, + }, + prettier, +); diff --git a/examples/App.tsx b/examples/App.tsx index b213fad08..ec92bb2bb 100644 --- a/examples/App.tsx +++ b/examples/App.tsx @@ -1,107 +1,123 @@ import React, { JSX } from 'react'; -import { StyleSheet, View, FlatList, useColorScheme } from 'react-native'; +import { FlatList, StyleSheet, useColorScheme, View } from 'react-native'; import { GestureHandlerRootView } from 'react-native-gesture-handler'; -import DropDownPickerExample, { ExampleProps } from './example-src-files/example'; -const EXAMPLES: ExampleProps[] = [{ - title: "Default Example", - description: "This is the default dropdown picker" -},{ - title: "Multiple Select", - description: "Multiple select example", - multiple: true -},{ - title: "Multiple Select Badge Mode", - description: "Multiple select example - with badges", - multiple: true, - dropdownProps: {mode: "BADGE", showBadgeDot: false}, -},{ - title: "Multiple Select Badge Mode with Dots", - description: "Multiple select example - with badges and dots", - multiple: true, - dropdownProps: {mode: "BADGE", showBadgeDot: true}, -},{ - title: "Customized Multiple Select Badge Mode", - description: "Multiple select example - with badges", - multiple: true, - dropdownProps: { - mode: "BADGE", - showBadgeDot: false, - badgeDotStyle: {}, - badgeColors: '#d5c4a1', // Badge Colors currentlly overwites badgeStyle background color - placeholderStyle: {color: '#83a598'}, - badgeStyle: { - // background: '#d5c4a1', - borderColor: '#282828', - borderWidth: 2, - borderStyle: 'solid', - }, - badgeTextStyle: { - color: '#282828' - }, - style: { - backgroundColor: '#fbf1c7', - borderColor: '#b16286', - cursor: 'pointer' - }, - customItemContainerStyle: { - }, - listItemContainerStyle: { - backgroundColor: '#fbf1c7', - borderColor: '#b16286' +import DropDownPickerExample, { + ExampleProps, +} from './example-src-files/example'; + +const EXAMPLES: Array = [ + { + title: 'Default Example', + description: 'This is the default dropdown picker', + }, + { + title: 'Multiple Select', + description: 'Multiple select example', + multiple: true, + }, + { + title: 'Multiple Select Badge Mode', + description: 'Multiple select example - with badges', + multiple: true, + dropdownProps: { mode: 'BADGE', showBadgeDot: false }, + }, + { + title: 'Multiple Select Badge Mode with Dots', + description: 'Multiple select example - with badges and dots', + multiple: true, + dropdownProps: { mode: 'BADGE', showBadgeDot: true }, + }, + { + title: 'Customized Multiple Select Badge Mode', + description: 'Multiple select example - with badges', + multiple: true, + dropdownProps: { + mode: 'BADGE', + showBadgeDot: false, + badgeDotStyle: {}, + badgeColors: '#d5c4a1', // Badge Colors currentlly overwites badgeStyle background color + placeholderStyle: { color: '#83a598' }, + badgeStyle: { + // background: '#d5c4a1', + borderColor: '#282828', + borderWidth: 2, + borderStyle: 'solid', + }, + badgeTextStyle: { + color: '#282828', + }, + style: { + backgroundColor: '#fbf1c7', + borderColor: '#b16286', + cursor: 'pointer', + }, + customItemContainerStyle: {}, + listItemContainerStyle: { + backgroundColor: '#fbf1c7', + borderColor: '#b16286', + }, + listItemLabelStyle: { + color: '#b16286', + }, }, - listItemLabelStyle: { - color: '#b16286' + }, + { + title: 'Autoscroll Example', + description: 'This is the default dropdown picker - with autoscroll', + dropdownProps: { autoScroll: true }, + }, + { + title: 'Searchable Example', + description: 'This is the default dropdown picker - with search', + dropdownProps: { searchable: true }, + }, + { + title: 'Multiple Search Example', + description: 'This is the default dropdown picker - with search', + multiple: true, + dropdownProps: { searchable: true }, + }, + { + title: 'Multiple Search Clear on Select Example', + description: 'This is the default dropdown picker - with search', + multiple: true, + dropdownProps: { + searchable: true, + clearSearchFieldOnSelect: true, + mode: 'BADGE', }, }, -},{ - title: "Autoscroll Example", - description: "This is the default dropdown picker - with autoscroll", - dropdownProps: {autoScroll: true}, -},{ - title: "Searchable Example", - description: "This is the default dropdown picker - with search", - dropdownProps: {searchable: true}, -},{ - title: "Multiple Search Example", - description: "This is the default dropdown picker - with search", - multiple: true, - dropdownProps: {searchable: true}, -},{ - title: "Multiple Search Clear on Select Example", - description: "This is the default dropdown picker - with search", - multiple: true, - dropdownProps: {searchable: true, clearSearchFieldOnSelect: true, mode: "BADGE"}, -},{ - title: "Modal Example", - description: "This is the default dropdown picker - with search", - multiple: true, - dropdownProps: {listMode: "MODAL"} -}] + { + title: 'Modal Example', + description: 'This is the default dropdown picker - with search', + multiple: true, + dropdownProps: { listMode: 'MODAL' }, + }, +]; export default function App(): JSX.Element { const colorScheme = useColorScheme(); const backgroundColor = colorScheme === 'dark' ? '#222' : '#fff'; - + const renderItem = ({ item }: { item: ExampleProps }) => ( - + ); return ( - - + + example.title} renderItem={renderItem} contentContainerStyle={styles.container} showsVerticalScrollIndicator={false} - CellRendererComponent={({ index, style, children }) => ( + CellRendererComponent={({ children }) => ( // Remove flatlsit view that wraps children for dropdown zIndex support <>{children} )} @@ -124,17 +140,17 @@ const styles = StyleSheet.create({ marginBottom: 64, padding: 3, maxWidth: 600, - minWidth: 400 + minWidth: 400, }, examplesContainer: { display: 'flex', flexDirection: 'column', justifyContent: 'flex-start', - gap: 32 + gap: 32, }, exampleCard: { - zIndex:0, + zIndex: 0, borderRadius: 8, - marginBottom: 48 - } + marginBottom: 48, + }, }); diff --git a/examples/example-src-files/example.tsx b/examples/example-src-files/example.tsx index a5a4a313d..06a6cec3a 100644 --- a/examples/example-src-files/example.tsx +++ b/examples/example-src-files/example.tsx @@ -1,17 +1,20 @@ -import React, { useState, JSX } from 'react'; -import { StyleSheet, Button, Text, View, useColorScheme } from 'react-native'; -import DropDownPicker, { ItemType,DropDownPickerProps } from 'react-native-dropdown-picker'; +import React, { JSX, useState } from 'react'; +import { Button, StyleSheet, Text, useColorScheme, View } from 'react-native'; +import DropDownPicker, { + DropDownPickerProps, + ItemType, +} from 'react-native-dropdown-picker'; -export type ExampleProps = { +export interface ExampleProps { multiple?: boolean; title: string; description?: string; placeholder?: string; multipleText?: string; // For the sake of keeping the examples simple for now - items?: ItemType[]; + items?: Array>; dropdownProps?: Partial>; -}; +} const DEFAULT_ITEMS = [ { label: 'Apple', value: 'apple' }, @@ -36,7 +39,7 @@ const styles = StyleSheet.create({ }, description: { fontSize: 12, - marginBottom: 16 + marginBottom: 16, }, body: { fontSize: 12, @@ -49,8 +52,8 @@ const styles = StyleSheet.create({ gap: 16, }, dropdownContainer: { - zIndex: 1 - } + zIndex: 1, + }, }); /** @@ -59,29 +62,30 @@ const styles = StyleSheet.create({ * @param props.multiple */ export default function DropDownPickerExample({ - multiple = false, - title, - description, - dropdownProps, - placeholder = 'Choose a fruit', - multipleText='You have chosen {count} fruits.', - items = DEFAULT_ITEMS, + multiple = false, + title, + description, + dropdownProps, + placeholder = 'Choose a fruit', + multipleText = 'You have chosen {count} fruits.', + items = DEFAULT_ITEMS, }: ExampleProps): JSX.Element { const [open, setOpen] = useState(false); const [singleValue, setSingleValue] = useState(null); const [multiValue, setMultiValue] = useState | null>(null); const colorScheme = useColorScheme(); const color = colorScheme === 'dark' ? '#fff' : '#222'; - const theme = colorScheme === 'dark' ? 'DARK' : 'LIGHT'; - + const theme = colorScheme === 'dark' ? 'DARK' : 'LIGHT'; + const [_items, setItems] = useState>>(items); - + return ( + // eslint-disable-next-line react-native/no-inline-styles - {title} + {title} {description && ( - {description} + {description} )} @@ -114,21 +118,19 @@ export default function DropDownPickerExample({ /> )} - - + + {multiple ? 'Fruits currently are: ' : 'Fruit currently is: '} - {multiple - ? JSON.stringify(multiValue) - : JSON.stringify(singleValue)} - + {multiple ? JSON.stringify(multiValue) : JSON.stringify(singleValue)} + -