const confusingBrowserGlobals = require('confusing-browser-globals'); const path = require('path'); module.exports = { root: true, // So parent files don't get applied globals: { preval: false, // Used in the documentation }, env: { es6: true, browser: true, node: true, }, extends: ['plugin:import/recommended', 'airbnb', 'prettier', 'prettier/react'], parser: 'babel-eslint', parserOptions: { ecmaVersion: 7, sourceType: 'module', }, plugins: ['babel', 'material-ui', 'react-hooks'], settings: { 'import/resolver': { webpack: { config: path.join(__dirname, './docs/webpackBaseConfig.js'), }, }, }, /** * Sorted alphanumerically within each group. built-in and each plugin form * their own groups. */ rules: { 'consistent-this': ['error', 'self'], 'linebreak-style': 'off', // Doesn't play nicely with Windows // just as bad as "max components per file" 'max-classes-per-file': 'off', 'no-alert': 'error', // Strict, airbnb is using warn; allow warn and error for dev environments 'no-console': ['error', { allow: ['warn', 'error'] }], 'no-constant-condition': 'error', // Airbnb use error 'no-param-reassign': 'off', 'no-prototype-builtins': 'off', 'no-restricted-imports': [ 'error', { patterns: [ '@material-ui/*/*/*', '!@material-ui/core/test-utils/*', '!@material-ui/utils/macros/*.macro', ], }, ], 'nonblock-statement-body-position': 'error', // Airbnb restricts isNaN and isFinite which are necessary for IE 11 // we have to be disciplined about the usage and ensure the Number type for its // arguments 'no-restricted-globals': ['error'].concat(confusingBrowserGlobals), 'no-underscore-dangle': 'error', 'prefer-arrow-callback': ['error', { allowNamedFunctions: true }], 'prefer-destructuring': 'off', // Destructuring harm grep potential. 'jsx-a11y/label-has-associated-control': 'off', 'jsx-a11y/label-has-for': 'off', // deprecated 'jsx-a11y/no-autofocus': 'off', // We are a library, people do what they want. 'material-ui/docgen-ignore-before-comment': 'error', // This rule is great for raising people awareness of what a key is and how it works. 'react/no-array-index-key': 'off', 'react/destructuring-assignment': 'off', // It's buggy 'react/forbid-prop-types': 'off', 'react/jsx-curly-brace-presence': 'off', // prefer over <>. The former allows `key` while the latter doesn't 'react/jsx-fragments': ['error', 'element'], 'react/jsx-filename-extension': ['error', { extensions: ['.js'] }], // airbnb is using .jsx 'react/jsx-handler-names': [ 'error', { // airbnb is disabling this rule eventHandlerPrefix: 'handle', eventHandlerPropPrefix: 'on', }, ], // not a good rule for components close to the DOM 'react/jsx-props-no-spreading': 'off', 'react/no-danger': 'error', // Strict, airbnb is using off 'react/no-direct-mutation-state': 'error', 'react/no-find-dom-node': 'off', 'react/no-multi-comp': 'off', 'react/require-default-props': 'off', 'react/sort-prop-types': 'error', // This depends entirely on what you're doing. There's no universal pattern 'react/state-in-constructor': 'off', // stylistic opinion. For conditional assignment we want it outside, otherwise as static 'react/static-property-placement': 'off', 'import/no-extraneous-dependencies': 'off', // It would be better to enable this rule. 'import/namespace': ['error', { allowComputed: true }], 'import/order': [ 'error', { groups: [['index', 'sibling', 'parent', 'internal', 'external', 'builtin']], 'newlines-between': 'never', }, ], 'react-hooks/rules-of-hooks': 'error', 'react-hooks/exhaustive-deps': ['error', { additionalHooks: 'useEnhancedEffect' }], }, overrides: [ { files: [ '**/test-utils/**/*.js', // matching the pattern of the test runner '*.test.js', ], env: { mocha: true, }, extends: ['plugin:mocha/recommended'], rules: { // does not work with wildcard imports. Mistakes will throw at runtime anyway 'import/named': 'off', // 'no-restricted-imports': [ 'error', { paths: [ { name: '@material-ui/core/test-utils', importNames: ['createMount'], message: "Please use `import createMount from 'test/utils/createMount'` instead. `createMount` from /core has cleanup issues that require breaking changes.", }, ], }, ], 'material-ui/disallow-active-element-as-key-event-target': 'error', // upgraded level from recommended 'mocha/no-exclusive-tests': 'error', 'mocha/no-skipped-tests': 'error', // no rationale provided in /recommended 'mocha/no-mocha-arrows': 'off', // definitely a useful rule but too many false positives // due to `describeConformance` // "If you're using dynamically generated tests, you should disable this rule."" 'mocha/no-setup-in-describe': 'off', // `beforeEach` for a single case is optimized for change // when we add a test we don't have to refactor the existing // test to `beforeEach`. // `beforeEach`+`afterEach` also means that the `beforeEach` // is cleaned up in `afterEach` if the test causes a crash 'mocha/no-hooks-for-single-case': 'off', // disable eslint-plugin-jsx-a11y // tests are not driven by assistive technology // add `jsx-a11y` rules once you encounter them in tests 'jsx-a11y/click-events-have-key-events': 'off', 'jsx-a11y/control-has-associated-label': 'off', 'jsx-a11y/iframe-has-title': 'off', 'jsx-a11y/mouse-events-have-key-events': 'off', 'jsx-a11y/no-noninteractive-tabindex': 'off', 'jsx-a11y/no-static-element-interactions': 'off', 'jsx-a11y/tabindex-no-positive': 'off', // In tests this is generally intended. 'react/button-has-type': 'off', // They are accessed to test custom validator implementation with PropTypes.checkPropTypes 'react/forbid-foreign-prop-types': 'off', // components that are defined in test are isolated enough // that they don't need type-checking 'react/prop-types': 'off', }, }, { files: ['docs/src/modules/components/**/*.js'], rules: { 'material-ui/no-hardcoded-labels': [ 'error', { allow: ['Material-UI', 'Twitter', 'GitHub', 'StackOverflow'] }, ], }, }, { files: ['docs/pages/**/*.js'], rules: { 'react/prop-types': 'off', }, }, ], };