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.

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