UNPKG

@cfx-dev/eslint-config-ui

Version:

cfx-dev's ESLint config, following our styleguide

233 lines (225 loc) 7.6 kB
import { FlatCompat } from '@eslint/eslintrc'; import stylistic from '@stylistic/eslint-plugin'; import globals from 'globals'; import noRelativeImportPaths from 'eslint-plugin-no-relative-import-paths'; import reactCompiler from 'eslint-plugin-react-compiler'; import reactHooks from 'eslint-plugin-react-hooks'; import react from 'eslint-plugin-react'; import jsxA11y from 'eslint-plugin-jsx-a11y'; import eslint from '@eslint/js'; import tseslint from 'typescript-eslint'; import path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const compat = new FlatCompat({ baseDirectory: __dirname, // optional; default: process.cwd() resolvePluginsRelativeTo: __dirname, // optional recommendedConfig: eslint.configs.recommended, // optional unless you're using 'eslint:recommended' allConfig: eslint.configs.all, // optional unless you're using 'eslint:all' }); export default tseslint.config([ eslint.configs.recommended, tseslint.configs.recommended, // Unused because we use airbnb config // importPlagin.flatConfigs.recommended, ...compat.extends( 'airbnb', 'airbnb/hooks', ), stylistic.configs.customize({ indent: 2, quotes: 'single', semi: true, jsx: true, arrowParens: true, }), { files: ['src/**/*.{ts,tsx}', 'lib/**/*.{ts,tsx}'], ...react.configs.flat.recommended, ...jsxA11y.flatConfigs.recommended, languageOptions: { ecmaVersion: 'latest', sourceType: 'module', ...react.configs.flat.recommended.languageOptions, ...jsxA11y.flatConfigs.recommended.languageOptions, globals: { ...globals.serviceworker, ...globals.browser, }, }, plugins: { react, 'react-hooks': reactHooks, 'jsx-a11y': jsxA11y, '@stylistic': stylistic, 'no-relative-import-paths': noRelativeImportPaths, }, settings: { react: { version: 'detect', }, 'import/parsers': { '@typescript-eslint/parser': ['.ts', '.tsx'], }, 'import/resolver': { typescript: { project: './' }, }, }, rules: { // Start - Disable rules that are not needed or conflict with stylistic rules 'quote-props': 'off', 'space-before-function-paren': 'off', 'react/jsx-indent': 'off', 'indent': 'off', // End 'react-hooks/rules-of-hooks': 'error', 'react-hooks/exhaustive-deps': 'error', 'jsx-a11y/alt-text': 'error', 'jsx-a11y/label-has-associated-control': [ 'error', { 'labelComponents': [ 'Label', ], 'controlComponents': [ 'Input', 'Input*', '*Input', 'Select', 'Textarea', 'Checkbox', 'Radio', 'DropdownSelect', 'Switch', 'ToggleGroup', ], 'depth': 3, }], // stylistic rules start '@stylistic/jsx-wrap-multilines': ['error', { declaration: 'parens', assignment: 'parens', return: 'parens', arrow: 'parens', condition: 'parens', logical: 'parens', prop: 'parens', propertyValue: 'parens', }], '@stylistic/jsx-one-expression-per-line': 'off', '@stylistic/quote-props': ['error', 'as-needed', { numbers: true }], 'max-len': 'off', '@stylistic/max-len': ['error', { code: 120, ignoreComments: true }], '@stylistic/multiline-ternary': ['error', 'always'], 'brace-style': 'off', '@stylistic/brace-style': ['error', '1tbs'], '@stylistic/object-curly-newline': ['error', { ObjectExpression: { consistent: true }, ObjectPattern: 'always', ImportDeclaration: { consistent: true }, ExportDeclaration: { multiline: true, minProperties: 3 }, }], '@stylistic/object-property-newline': 'error', // stylistic rules end 'prefer-arrow-callback': 'off', 'linebreak-style': ['error', 'unix'], 'consistent-return': 'off', 'class-methods-use-this': 'off', 'grouped-accessor-pairs': 'error', 'padding-line-between-statements': [ 'error', { blankLine: 'always', prev: '*', next: 'try' }, { blankLine: 'always', prev: '*', next: 'if' }, { blankLine: 'always', prev: '*', next: 'for' }, { blankLine: 'always', prev: '*', next: 'return' }, { blankLine: 'always', prev: '*', next: 'switch' }, { blankLine: 'always', prev: '*', next: 'while' }, ], // Enforce consistent brace style curly: ['error', 'all'], 'import/prefer-default-export': 'off', // Will allow devDependencies import in test files 'import/no-extraneous-dependencies': [ 'error', { devDependencies: ['**/*{.,_}{test,spec,stories}.{ts,tsx}'], }, ], // Allow spreding in props like: { prop1, ...restProps } 'react/jsx-props-no-spreading': 'off', 'no-shadow': 'off', '@typescript-eslint/no-shadow': ['error'], // Very useful exemption when you need to omit some props 'no-unused-vars': 'off', '@typescript-eslint/no-unused-vars': [ 'error', { ignoreRestSiblings: true, destructuredArrayIgnorePattern: '^_', argsIgnorePattern: '^_', }, ], // Turn off default react rule that don't useful in ts 'react/require-default-props': 'off', // We don't need to import React in each jsx file 'react/react-in-jsx-scope': 'off', 'import/no-unresolved': 'error', // Ignore specific extensions 'import/extensions': [ 'error', 'ignorePackages', { js: 'never', jsx: 'never', ts: 'never', tsx: 'never', }, ], 'react/jsx-filename-extension': [ 1, { extensions: ['.tsx'], }, ], // more options for import/order can be found in documentation // https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/order.md 'import/order': [ 'error', { // add new line between groups 'newlines-between': 'always', // ['ignore', 'always', 'always-and-inside-groups', 'never'] // main grouping pattern for imports groups: [ 'builtin', // node 'builtin' modules 'external', // 'external' modules 'internal', // 'internal' modules 'type', // 'type' imports 'object', // 'object'-imports (only available in TypeScript) 'unknown', // special group for unknowns ['sibling', 'parent'], // modules from a 'parent' directory or from the same or a sibling's directory 'index', // 'index' of the current directory ], // add new line fore pathGroups distinctGroup: true, // group imports by pattern pathGroups: [ { pattern: './*.module.scss', group: 'index', position: 'after', }, ], // sorting options for imports inside of the group alphabetize: { order: 'asc', caseInsensitive: true, }, }, ], 'no-relative-import-paths/no-relative-import-paths': [ 'error', { allowSameFolder: true }, ], }, }, reactCompiler.configs.recommended, ]);