You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

217 lines
5.1 KiB

  1. module.exports = {
  2. root: true,
  3. extends: [
  4. 'eslint:recommended',
  5. 'plugin:react/recommended',
  6. 'plugin:jsx-a11y/recommended',
  7. 'plugin:import/recommended',
  8. 'plugin:promise/recommended',
  9. ],
  10. env: {
  11. browser: true,
  12. node: true,
  13. es6: true,
  14. jest: true,
  15. },
  16. globals: {
  17. ATTACHMENT_HOST: false,
  18. },
  19. parser: '@babel/eslint-parser',
  20. plugins: [
  21. 'react',
  22. 'jsx-a11y',
  23. 'import',
  24. 'promise',
  25. ],
  26. parserOptions: {
  27. sourceType: 'module',
  28. ecmaFeatures: {
  29. experimentalObjectRestSpread: true,
  30. jsx: true,
  31. },
  32. ecmaVersion: 2021,
  33. },
  34. settings: {
  35. react: {
  36. version: 'detect',
  37. },
  38. 'import/extensions': [
  39. '.js', '.jsx',
  40. ],
  41. 'import/ignore': [
  42. 'node_modules',
  43. '\\.(css|scss|json)$',
  44. ],
  45. 'import/resolver': {
  46. node: {
  47. paths: ['app/javascript'],
  48. extensions: ['.js', '.jsx'],
  49. },
  50. },
  51. },
  52. rules: {
  53. 'brace-style': 'warn',
  54. 'comma-dangle': ['error', 'always-multiline'],
  55. 'comma-spacing': [
  56. 'warn',
  57. {
  58. before: false,
  59. after: true,
  60. },
  61. ],
  62. 'comma-style': ['warn', 'last'],
  63. 'consistent-return': 'error',
  64. 'dot-notation': 'error',
  65. eqeqeq: 'error',
  66. indent: ['warn', 2],
  67. 'jsx-quotes': ['error', 'prefer-single'],
  68. 'no-case-declarations': 'off',
  69. 'no-catch-shadow': 'error',
  70. 'no-console': [
  71. 'warn',
  72. {
  73. allow: [
  74. 'error',
  75. 'warn',
  76. ],
  77. },
  78. ],
  79. 'no-empty': 'off',
  80. 'no-restricted-properties': [
  81. 'error',
  82. { property: 'substring', message: 'Use .slice instead of .substring.' },
  83. { property: 'substr', message: 'Use .slice instead of .substr.' },
  84. ],
  85. 'no-self-assign': 'off',
  86. 'no-trailing-spaces': 'warn',
  87. 'no-unused-expressions': 'error',
  88. 'no-unused-vars': [
  89. 'error',
  90. {
  91. vars: 'all',
  92. args: 'after-used',
  93. ignoreRestSiblings: true,
  94. },
  95. ],
  96. 'object-curly-spacing': ['error', 'always'],
  97. 'padded-blocks': [
  98. 'error',
  99. {
  100. classes: 'always',
  101. },
  102. ],
  103. quotes: ['error', 'single'],
  104. semi: 'error',
  105. 'valid-typeof': 'error',
  106. 'react/jsx-filename-extension': ['error', { 'allow': 'as-needed' }],
  107. 'react/jsx-boolean-value': 'error',
  108. 'react/jsx-closing-bracket-location': ['error', 'line-aligned'],
  109. 'react/jsx-curly-spacing': 'error',
  110. 'react/display-name': 'off',
  111. 'react/jsx-equals-spacing': 'error',
  112. 'react/jsx-first-prop-new-line': ['error', 'multiline-multiprop'],
  113. 'react/jsx-indent': ['error', 2],
  114. 'react/jsx-no-bind': 'error',
  115. 'react/jsx-no-target-blank': 'off',
  116. 'react/jsx-tag-spacing': 'error',
  117. 'react/jsx-wrap-multilines': 'error',
  118. 'react/no-deprecated': 'off',
  119. 'react/no-unknown-property': 'off',
  120. 'react/self-closing-comp': 'error',
  121. // recommended values found in https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/src/index.js
  122. 'jsx-a11y/accessible-emoji': 'warn',
  123. 'jsx-a11y/click-events-have-key-events': 'off',
  124. 'jsx-a11y/label-has-associated-control': 'off',
  125. 'jsx-a11y/media-has-caption': 'off',
  126. 'jsx-a11y/no-autofocus': 'off',
  127. // recommended rule is:
  128. // 'jsx-a11y/no-interactive-element-to-noninteractive-role': [
  129. // 'error',
  130. // {
  131. // tr: ['none', 'presentation'],
  132. // canvas: ['img'],
  133. // },
  134. // ],
  135. 'jsx-a11y/no-interactive-element-to-noninteractive-role': 'off',
  136. // recommended rule is:
  137. // 'jsx-a11y/no-noninteractive-element-interactions': [
  138. // 'error',
  139. // {
  140. // body: ['onError', 'onLoad'],
  141. // iframe: ['onError', 'onLoad'],
  142. // img: ['onError', 'onLoad'],
  143. // },
  144. // ],
  145. 'jsx-a11y/no-noninteractive-element-interactions': [
  146. 'warn',
  147. {
  148. handlers: [
  149. 'onClick',
  150. ],
  151. },
  152. ],
  153. // recommended rule is:
  154. // 'jsx-a11y/no-noninteractive-tabindex': [
  155. // 'error',
  156. // {
  157. // tags: [],
  158. // roles: ['tabpanel'],
  159. // allowExpressionValues: true,
  160. // },
  161. // ],
  162. 'jsx-a11y/no-noninteractive-tabindex': 'off',
  163. 'jsx-a11y/no-onchange': 'warn',
  164. // recommended is full 'error'
  165. 'jsx-a11y/no-static-element-interactions': [
  166. 'warn',
  167. {
  168. handlers: [
  169. 'onClick',
  170. ],
  171. },
  172. ],
  173. // See https://github.com/import-js/eslint-plugin-import/blob/main/config/recommended.js
  174. 'import/extensions': [
  175. 'error',
  176. 'always',
  177. {
  178. js: 'never',
  179. jsx: 'never',
  180. },
  181. ],
  182. 'import/newline-after-import': 'error',
  183. 'import/no-extraneous-dependencies': [
  184. 'error',
  185. {
  186. devDependencies: [
  187. 'config/webpack/**',
  188. 'app/javascript/mastodon/test_setup.js',
  189. 'app/javascript/**/__tests__/**',
  190. ],
  191. },
  192. ],
  193. 'import/no-webpack-loader-syntax': 'error',
  194. 'promise/always-return': 'off',
  195. 'promise/catch-or-return': [
  196. 'error',
  197. {
  198. allowFinally: true,
  199. },
  200. ],
  201. 'promise/no-callback-in-promise': 'off',
  202. 'promise/no-nesting': 'off',
  203. 'promise/no-promise-in-callback': 'off',
  204. },
  205. };