module.exports = { env: { browser: true, es2021: true, }, parser: '@typescript-eslint/parser', parserOptions: { ecmaFeatures: { jsx: true }, ecmaVersion: 12, project: ['./tsconfig.json'], sourceType: 'module', }, extends: [ 'plugin:@typescript-eslint/recommended', 'plugin:@typescript-eslint/recommended-requiring-type-checking', 'plugin:jsx-a11y/recommended', 'plugin:react/recommended', 'airbnb', ], plugins: [ '@typescript-eslint', 'import', 'jsx-a11y', 'react', 'react-hooks', ], rules: { '@typescript-eslint/brace-style': ['error'], '@typescript-eslint/comma-dangle': ['error', 'always-multiline'], '@typescript-eslint/consistent-type-definitions': ['error', 'interface'], '@typescript-eslint/keyword-spacing': ['error'], '@typescript-eslint/member-delimiter-style': ['error'], '@typescript-eslint/method-signature-style': ['warn', 'method'], '@typescript-eslint/naming-convention': [ 'warn', { selector: 'default', format: ['camelCase', 'PascalCase'], leadingUnderscore: 'forbid', trailingUnderscore: 'forbid', filter: { // skip names requiring quotes, e.g. HTTP headers regex: '[- ]', match: false, }, }, { selector: ['enumMember'], format: ['UPPER_CASE'], }, { selector: ['property', 'parameter', 'parameterProperty'], format: ['camelCase', 'PascalCase'], leadingUnderscore: 'allow', trailingUnderscore: 'forbid', filter: { // skip names requiring quotes, e.g. HTTP headers regex: '[- ]', match: false, }, }, { selector: 'typeLike', format: ['PascalCase'], }, ], '@typescript-eslint/no-duplicate-imports': ['error'], '@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/no-floating-promises': ['error'], '@typescript-eslint/no-misused-promises': ['error'], '@typescript-eslint/no-non-null-assertion': 'off', '@typescript-eslint/no-shadow': ['error'], '@typescript-eslint/no-unnecessary-condition': ['error', { allowConstantLoopConditions: true }], '@typescript-eslint/no-unnecessary-boolean-literal-compare': ['error'], '@typescript-eslint/no-unused-expressions': ['error'], '@typescript-eslint/no-unused-vars': ['error'], '@typescript-eslint/no-use-before-define': ['error'], '@typescript-eslint/prefer-nullish-coalescing': ['warn'], '@typescript-eslint/quotes': ['error', 'single', { avoidEscape: true }], '@typescript-eslint/semi': ['error'], '@typescript-eslint/space-before-function-paren': ['error', { anonymous: 'never', named: 'never', asyncArrow: 'always', }], '@typescript-eslint/switch-exhaustiveness-check': ['error'], '@typescript-eslint/type-annotation-spacing': ['warn', { before: false, after: true, overrides: { arrow: { before: true }, }, }], 'brace-style': 'off', camelcase: 'off', 'class-methods-use-this': 'off', 'comma-dangle': 'off', 'keyword-spacing': 'off', 'no-duplicate-imports': 'off', 'no-shadow': 'off', 'no-unused-expressions': 'off', 'no-unused-vars': 'off', 'no-use-before-define': 'off', quotes: 'off', semi: 'off', 'space-before-function-paren': 'off', 'implicit-arrow-linebreak': 'off', 'import/extensions': [ 'error', 'ignorePackages', { js: 'never', jsx: 'never', ts: 'never', tsx: 'never', }, ], indent: ['error', 2, { CallExpression: { arguments: 'first' }, FunctionDeclaration: { parameters: 'first' }, FunctionExpression: { parameters: 'first' }, SwitchCase: 1, VariableDeclarator: 'first', offsetTernaryExpressions: true, }], 'jsx-a11y/label-has-associated-control': ['warn', { assert: 'either', }], 'max-classes-per-file': 'off', 'max-len': ['warn', { code: 100, tabWidth: 2 }], 'no-console': 'off', 'no-underscore-dangle': 'off', 'prefer-arrow-callback': ['error'], 'react/function-component-definition': ['error', { namedComponents: 'arrow-function', unnamedComponents: 'arrow-function', }], 'react/jsx-curly-newline': ['error', { multiline: 'forbid', singleline: 'forbid' }], 'react/jsx-filename-extension': ['error', { extensions: ['.jsx', '.tsx'] }], 'react/jsx-first-prop-new-line': ['error', 'multiline'], 'react/jsx-fragments': 'off', 'react/jsx-indent': ['error', 2, { checkAttributes: true, indentLogicalExpressions: true }], 'react/jsx-indent-props': ['error', 2], 'react/jsx-key': ['error', { checkFragmentShorthand: true }], 'react/jsx-max-props-per-line': ['error', { maximum: 3, when: 'always' }], 'react/jsx-no-target-blank': ['error'], 'react/jsx-wrap-multilines': ['error', { declaration: 'parens-new-line', assignment: 'parens-new-line', return: 'parens-new-line', arrow: 'parens-new-line', condition: 'parens-new-line', logical: 'parens-new-line', prop: 'parens-new-line', }], 'react/prop-types': 'off', 'react/no-deprecated': ['error'], 'react/no-multi-comp': ['error'], 'react/no-unused-prop-types': ['error'], 'react/prefer-stateless-function': ['error'], 'react/react-in-jsx-scope': 'off', 'react-hooks/rules-of-hooks': ['error'], 'react-hooks/exhaustive-deps': ['warn'], }, settings: { 'import/resolver': { node: { extensions: ['.js', '.jsx', '.ts', '.tsx'] }, }, }, };