eslint-config-entva 1.2.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. package/eslint.config.js +3 -0
  2. package/index.js +526 -34
  3. package/package.json +16 -13
@@ -0,0 +1,3 @@
1
+ import mainConfig from './index.js';
2
+
3
+ export default mainConfig;
package/index.js CHANGED
@@ -1,35 +1,527 @@
1
- module.exports = {
2
- extends: [
3
- 'airbnb',
4
- 'airbnb/hooks',
5
- 'entva-base',
6
- ],
7
- rules: {
8
- 'react/jsx-props-no-spreading': 'off',
9
- 'react/forbid-prop-types': 'off',
10
- 'react/require-default-props': 'off',
11
- 'react/no-array-index-key': 'off',
12
- 'react/jsx-no-bind': 'off',
13
- 'react/prop-types': 'off',
14
- 'react/react-in-jsx-scope': 'off',
15
- 'react/function-component-definition': [2, { namedComponents: 'arrow-function' }],
16
- 'react/jsx-max-props-per-line': ['error', { maximum: 1, when: 'multiline' }],
17
- 'react/jsx-uses-react': 'off',
18
- 'react/no-unstable-nested-components': ['error', { allowAsProps: true }],
19
- 'react/no-unused-class-component-methods': 'off',
20
- 'react-hooks/exhaustive-deps': 'off',
21
- 'react/display-name': 'off',
22
- 'react/jsx-one-expression-per-line': 'off', // doesn't let write sentences in React
23
- 'jsx-quotes': ['error', 'prefer-double'],
24
-
25
- 'jsx-a11y/anchor-is-valid': 'off',
26
- 'jsx-a11y/anchor-has-content': 'off',
27
- 'jsx-a11y/no-static-element-interactions': 'off',
28
- 'jsx-a11y/click-events-have-key-events': 'off',
29
- 'jsx-a11y/media-has-caption': 'off',
30
- 'jsx-a11y/no-noninteractive-element-interactions': 'off',
31
- 'jsx-a11y/label-has-for': 'off',
32
- 'jsx-a11y/label-has-associated-control': 'off',
33
- 'jsx-a11y/control-has-associated-label': 'off',
1
+ import baseConfig from 'eslint-config-entva-base';
2
+ import react from 'eslint-plugin-react';
3
+ import jsxA11Y from 'eslint-plugin-jsx-a11y';
4
+ import reactHooks from 'eslint-plugin-react-hooks';
5
+ import importPlugin from 'eslint-plugin-import';
6
+ import globals from 'globals';
7
+
8
+ export default [
9
+ ...baseConfig,
10
+ {
11
+ files: [
12
+ '**/*.test.jsx',
13
+ '**/*.spec.jsx',
14
+ '**/__tests__/**',
15
+ ],
16
+ languageOptions: {
17
+ globals: {
18
+ ...globals.jest,
19
+ },
20
+ },
21
+ },
22
+ {
23
+ files: ['**/*.{js,mjs,cjs,jsx}'],
24
+ plugins: {
25
+ react,
26
+ 'jsx-a11y': jsxA11Y,
27
+ 'react-hooks': reactHooks,
28
+ import: importPlugin,
29
+ },
30
+
31
+ languageOptions: {
32
+ globals: {
33
+ ...globals.browser,
34
+ ...globals.node,
35
+ },
36
+
37
+ ecmaVersion: 'latest',
38
+ sourceType: 'module',
39
+
40
+ parserOptions: {
41
+ ecmaFeatures: {
42
+ generators: false,
43
+ objectLiteralDuplicateProperties: false,
44
+ jsx: true,
45
+ },
46
+ },
47
+ },
48
+
49
+ settings: {
50
+ 'import/resolver': {
51
+ node: {
52
+ extensions: ['.mjs', '.js', '.json', '.jsx'],
53
+ },
54
+ },
55
+
56
+ 'import/extensions': ['.mjs', '.js', '.json', '.jsx'],
57
+ 'import/core-modules': [],
58
+ 'import/ignore': ['node_modules', '\\.(coffee|scss|css|less|hbs|svg|json)$'],
59
+
60
+ react: {
61
+ pragma: 'React',
62
+ version: 'detect',
63
+ },
64
+
65
+ propWrapperFunctions: ['forbidExtraProps', 'exact', 'Object.freeze'],
66
+ },
67
+
68
+ rules: {
69
+ 'react/jsx-props-no-spreading': ['off', {
70
+ html: 'enforce',
71
+ custom: 'enforce',
72
+ explicitSpread: 'ignore',
73
+ exceptions: [],
74
+ }],
75
+
76
+ 'react/forbid-prop-types': ['off', {
77
+ forbid: ['any', 'array', 'object'],
78
+ checkContextTypes: true,
79
+ checkChildContextTypes: true,
80
+ }],
81
+
82
+ 'react/require-default-props': ['off', {
83
+ forbidDefaultForRequired: true,
84
+ }],
85
+
86
+ 'react/no-array-index-key': ['off'],
87
+
88
+ 'react/jsx-no-bind': ['off', {
89
+ ignoreRefs: true,
90
+ allowArrowFunctions: true,
91
+ allowFunctions: false,
92
+ allowBind: false,
93
+ ignoreDOMComponents: true,
94
+ }],
95
+
96
+ 'react/prop-types': ['off', {
97
+ ignore: [],
98
+ customValidators: [],
99
+ skipUndeclared: false,
100
+ }],
101
+
102
+ 'react/react-in-jsx-scope': ['off'],
103
+
104
+ 'react/function-component-definition': [2, {
105
+ namedComponents: 'arrow-function',
106
+ }],
107
+
108
+ 'react/jsx-max-props-per-line': ['error', {
109
+ maximum: 1,
110
+ when: 'multiline',
111
+ }],
112
+
113
+ 'react/jsx-uses-react': ['off'],
114
+
115
+ 'react/no-unstable-nested-components': ['error', {
116
+ allowAsProps: true,
117
+ }],
118
+
119
+ 'react/no-unused-class-component-methods': ['off'],
120
+ 'react-hooks/exhaustive-deps': 'off',
121
+
122
+ 'react/display-name': 'off',
123
+
124
+ 'react/jsx-one-expression-per-line': ['off', {
125
+ allow: 'single-child',
126
+ }],
127
+
128
+ 'jsx-a11y/anchor-is-valid': ['off', {
129
+ components: ['Link'],
130
+ specialLink: ['to'],
131
+ aspects: ['noHref', 'invalidHref', 'preferButton'],
132
+ }],
133
+
134
+ 'jsx-a11y/anchor-has-content': ['off', {
135
+ components: [],
136
+ }],
137
+
138
+ 'jsx-a11y/no-static-element-interactions': ['off', {
139
+ handlers: [
140
+ 'onClick',
141
+ 'onMouseDown',
142
+ 'onMouseUp',
143
+ 'onKeyPress',
144
+ 'onKeyDown',
145
+ 'onKeyUp',
146
+ ],
147
+ }],
148
+
149
+ 'jsx-a11y/click-events-have-key-events': ['off'],
150
+
151
+ 'jsx-a11y/media-has-caption': ['off', {
152
+ audio: [],
153
+ video: [],
154
+ track: [],
155
+ }],
156
+
157
+ 'jsx-a11y/no-noninteractive-element-interactions': ['off', {
158
+ handlers: [
159
+ 'onClick',
160
+ 'onMouseDown',
161
+ 'onMouseUp',
162
+ 'onKeyPress',
163
+ 'onKeyDown',
164
+ 'onKeyUp',
165
+ ],
166
+ }],
167
+
168
+ 'jsx-a11y/label-has-for': ['off', {
169
+ components: [],
170
+
171
+ required: {
172
+ every: ['nesting', 'id'],
173
+ },
174
+
175
+ allowChildren: false,
176
+ }],
177
+
178
+ 'jsx-a11y/label-has-associated-control': ['off', {
179
+ labelComponents: [],
180
+ labelAttributes: [],
181
+ controlComponents: [],
182
+ assert: 'both',
183
+ depth: 25,
184
+ }],
185
+
186
+ 'jsx-a11y/control-has-associated-label': ['off', {
187
+ labelAttributes: ['label'],
188
+ controlComponents: [],
189
+ ignoreElements: ['audio', 'canvas', 'embed', 'input', 'textarea', 'tr', 'video'],
190
+
191
+ ignoreRoles: [
192
+ 'grid',
193
+ 'listbox',
194
+ 'menu',
195
+ 'menubar',
196
+ 'radiogroup',
197
+ 'row',
198
+ 'tablist',
199
+ 'toolbar',
200
+ 'tree',
201
+ 'treegrid',
202
+ ],
203
+
204
+ depth: 5,
205
+ }],
206
+
207
+ 'react-hooks/rules-of-hooks': ['error'],
208
+ 'jsx-a11y/accessible-emoji': ['off'],
209
+
210
+ 'jsx-a11y/alt-text': 'off',
211
+
212
+ 'jsx-a11y/aria-activedescendant-has-tabindex': ['error'],
213
+ 'jsx-a11y/aria-props': ['error'],
214
+ 'jsx-a11y/aria-proptypes': ['error'],
215
+
216
+ 'jsx-a11y/aria-role': ['error', {
217
+ ignoreNonDOM: false,
218
+ }],
219
+
220
+ 'jsx-a11y/aria-unsupported-elements': ['error'],
221
+
222
+ 'jsx-a11y/autocomplete-valid': ['off', {
223
+ inputComponents: [],
224
+ }],
225
+
226
+ 'jsx-a11y/heading-has-content': ['error', {
227
+ components: [''],
228
+ }],
229
+
230
+ 'jsx-a11y/html-has-lang': ['error'],
231
+ 'jsx-a11y/iframe-has-title': ['error'],
232
+ 'jsx-a11y/img-redundant-alt': ['error'],
233
+ 'jsx-a11y/interactive-supports-focus': ['error'],
234
+ 'jsx-a11y/lang': ['error'],
235
+ 'jsx-a11y/mouse-events-have-key-events': ['error'],
236
+ 'jsx-a11y/no-access-key': ['error'],
237
+
238
+ 'jsx-a11y/no-autofocus': ['error', {
239
+ ignoreNonDOM: true,
240
+ }],
241
+
242
+ 'jsx-a11y/no-distracting-elements': ['error', {
243
+ elements: ['marquee', 'blink'],
244
+ }],
245
+
246
+ 'jsx-a11y/no-interactive-element-to-noninteractive-role': ['error', {
247
+ tr: ['none', 'presentation'],
248
+ }],
249
+
250
+ 'jsx-a11y/no-noninteractive-element-to-interactive-role': ['error', {
251
+ ul: ['listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'],
252
+ ol: ['listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'],
253
+ li: ['menuitem', 'option', 'row', 'tab', 'treeitem'],
254
+ table: ['grid'],
255
+ td: ['gridcell'],
256
+ }],
257
+
258
+ 'jsx-a11y/no-noninteractive-tabindex': ['error', {
259
+ tags: [],
260
+ roles: ['tabpanel'],
261
+ }],
262
+
263
+ 'jsx-a11y/no-onchange': ['off'],
264
+ 'jsx-a11y/no-redundant-roles': ['error'],
265
+ 'jsx-a11y/role-has-required-aria-props': ['error'],
266
+ 'jsx-a11y/role-supports-aria-props': ['error'],
267
+ 'jsx-a11y/scope': ['error'],
268
+ 'jsx-a11y/tabindex-no-positive': ['error'],
269
+
270
+ 'react/forbid-dom-props': ['off', {
271
+ forbid: [],
272
+ }],
273
+
274
+ 'react/jsx-boolean-value': ['error', 'never', {
275
+ always: [],
276
+ }],
277
+
278
+ 'react/jsx-closing-bracket-location': ['error', 'line-aligned'],
279
+ 'react/jsx-closing-tag-location': ['error'],
280
+
281
+ 'react/jsx-curly-spacing': ['error', 'never', {
282
+ allowMultiline: true,
283
+ }],
284
+
285
+ 'react/jsx-handler-names': ['off', {
286
+ eventHandlerPrefix: 'handle',
287
+ eventHandlerPropPrefix: 'on',
288
+ }],
289
+
290
+ 'react/jsx-indent-props': ['error', 2],
291
+ 'react/jsx-key': ['off'],
292
+
293
+ 'react/jsx-no-duplicate-props': ['error', {
294
+ ignoreCase: true,
295
+ }],
296
+
297
+ 'react/jsx-no-literals': ['off', {
298
+ noStrings: true,
299
+ }],
300
+
301
+ 'react/jsx-no-undef': ['error'],
302
+
303
+ 'react/jsx-pascal-case': ['error', {
304
+ allowAllCaps: true,
305
+ ignore: [],
306
+ }],
307
+
308
+ 'react/sort-prop-types': ['off', {
309
+ ignoreCase: true,
310
+ callbacksLast: false,
311
+ requiredFirst: false,
312
+ sortShapeProp: true,
313
+ }],
314
+
315
+ 'react/jsx-sort-prop-types': ['off'],
316
+
317
+ 'react/jsx-sort-props': ['off', {
318
+ ignoreCase: true,
319
+ callbacksLast: false,
320
+ shorthandFirst: false,
321
+ shorthandLast: false,
322
+ noSortAlphabetically: false,
323
+ reservedFirst: true,
324
+ }],
325
+
326
+ 'react/jsx-sort-default-props': ['off', {
327
+ ignoreCase: true,
328
+ }],
329
+
330
+ 'react/jsx-uses-vars': ['error'],
331
+ 'react/no-danger': ['warn'],
332
+ 'react/no-deprecated': ['error'],
333
+ 'react/no-did-mount-set-state': ['off'],
334
+ 'react/no-did-update-set-state': ['error'],
335
+ 'react/no-will-update-set-state': ['error'],
336
+ 'react/no-direct-mutation-state': ['off'],
337
+ 'react/no-is-mounted': ['error'],
338
+ 'react/no-multi-comp': ['off'],
339
+ 'react/no-set-state': ['off'],
340
+ 'react/no-string-refs': ['error'],
341
+ 'react/no-unknown-property': ['error'],
342
+ 'react/prefer-es6-class': ['error', 'always'],
343
+
344
+ 'react/prefer-stateless-function': ['error', {
345
+ ignorePureComponents: true,
346
+ }],
347
+
348
+ 'react/require-render-return': ['error'],
349
+ 'react/self-closing-comp': ['error'],
350
+
351
+ 'react/sort-comp': ['error', {
352
+ order: [
353
+ 'static-variables',
354
+ 'static-methods',
355
+ 'instance-variables',
356
+ 'lifecycle',
357
+ '/^handle.+$/',
358
+ '/^on.+$/',
359
+ 'getters',
360
+ 'setters',
361
+ '/^(get|set)(?!(InitialState$|DefaultProps$|ChildContext$)).+$/',
362
+ 'instance-methods',
363
+ 'everything-else',
364
+ 'rendering',
365
+ ],
366
+
367
+ groups: {
368
+ lifecycle: [
369
+ 'displayName',
370
+ 'propTypes',
371
+ 'contextTypes',
372
+ 'childContextTypes',
373
+ 'mixins',
374
+ 'statics',
375
+ 'defaultProps',
376
+ 'constructor',
377
+ 'getDefaultProps',
378
+ 'getInitialState',
379
+ 'state',
380
+ 'getChildContext',
381
+ 'getDerivedStateFromProps',
382
+ 'componentWillMount',
383
+ 'UNSAFE_componentWillMount',
384
+ 'componentDidMount',
385
+ 'componentWillReceiveProps',
386
+ 'UNSAFE_componentWillReceiveProps',
387
+ 'shouldComponentUpdate',
388
+ 'componentWillUpdate',
389
+ 'UNSAFE_componentWillUpdate',
390
+ 'getSnapshotBeforeUpdate',
391
+ 'componentDidUpdate',
392
+ 'componentDidCatch',
393
+ 'componentWillUnmount',
394
+ ],
395
+
396
+ rendering: ['/^render.+$/', 'render'],
397
+ },
398
+ }],
399
+
400
+ 'react/jsx-wrap-multilines': ['error', {
401
+ declaration: 'parens-new-line',
402
+ assignment: 'parens-new-line',
403
+ return: 'parens-new-line',
404
+ arrow: 'parens-new-line',
405
+ condition: 'parens-new-line',
406
+ logical: 'parens-new-line',
407
+ prop: 'parens-new-line',
408
+ }],
409
+
410
+ 'react/jsx-first-prop-new-line': ['error', 'multiline-multiprop'],
411
+ 'react/jsx-equals-spacing': ['error', 'never'],
412
+ 'react/jsx-indent': ['error', 2],
413
+
414
+ 'react/jsx-no-target-blank': ['error', {
415
+ enforceDynamicLinks: 'always',
416
+ links: true,
417
+ forms: false,
418
+ }],
419
+
420
+ 'react/jsx-filename-extension': ['error', {
421
+ extensions: ['.jsx'],
422
+ }],
423
+
424
+ 'react/jsx-no-comment-textnodes': ['error'],
425
+ 'react/no-render-return-value': ['error'],
426
+
427
+ 'react/require-optimization': ['off', {
428
+ allowDecorators: [],
429
+ }],
430
+
431
+ 'react/no-find-dom-node': ['error'],
432
+
433
+ 'react/forbid-component-props': ['off', {
434
+ forbid: [],
435
+ }],
436
+
437
+ 'react/forbid-elements': ['off', {
438
+ forbid: [],
439
+ }],
440
+
441
+ 'react/no-danger-with-children': ['error'],
442
+
443
+ 'react/no-unused-prop-types': ['error', {
444
+ customValidators: [],
445
+ skipShapeProps: true,
446
+ }],
447
+
448
+ 'react/style-prop-object': ['error'],
449
+ 'react/no-unescaped-entities': ['error'],
450
+ 'react/no-children-prop': ['error'],
451
+
452
+ 'react/jsx-tag-spacing': ['error', {
453
+ closingSlash: 'never',
454
+ beforeSelfClosing: 'always',
455
+ afterOpening: 'never',
456
+ beforeClosing: 'never',
457
+ }],
458
+
459
+ 'react/jsx-space-before-closing': ['off', 'always'],
460
+
461
+ 'react/forbid-foreign-prop-types': ['warn', {
462
+ allowInPropTypes: true,
463
+ }],
464
+
465
+ 'react/void-dom-elements-no-children': ['error'],
466
+
467
+ 'react/default-props-match-prop-types': ['error', {
468
+ allowRequiredDefaults: false,
469
+ }],
470
+
471
+ 'react/no-redundant-should-component-update': ['error'],
472
+ 'react/no-unused-state': ['error'],
473
+
474
+ 'react/boolean-prop-naming': ['off', {
475
+ propTypeNames: ['bool', 'mutuallyExclusiveTrueProps'],
476
+ rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+',
477
+ message: '',
478
+ }],
479
+
480
+ 'react/no-typos': ['error'],
481
+
482
+ 'react/jsx-curly-brace-presence': ['error', {
483
+ props: 'never',
484
+ children: 'never',
485
+ }],
486
+
487
+ 'react/destructuring-assignment': ['error', 'always'],
488
+ 'react/no-access-state-in-setstate': ['error'],
489
+
490
+ 'react/button-has-type': ['error', {
491
+ button: true,
492
+ submit: true,
493
+ reset: false,
494
+ }],
495
+
496
+ 'react/jsx-child-element-spacing': ['off'],
497
+ 'react/no-this-in-sfc': ['error'],
498
+ 'react/jsx-max-depth': ['off'],
499
+ 'react/jsx-props-no-multi-spaces': ['error'],
500
+ 'react/no-unsafe': ['off'],
501
+ 'react/jsx-fragments': ['error', 'syntax'],
502
+
503
+ 'react/jsx-curly-newline': ['error', {
504
+ multiline: 'consistent',
505
+ singleline: 'consistent',
506
+ }],
507
+
508
+ 'react/state-in-constructor': ['error', 'always'],
509
+ 'react/static-property-placement': ['error', 'property assignment'],
510
+ 'react/prefer-read-only-props': ['off'],
511
+
512
+ 'react/jsx-no-script-url': ['error', [{
513
+ name: 'Link',
514
+ props: ['to'],
515
+ }]],
516
+
517
+ 'react/jsx-no-useless-fragment': ['error'],
518
+ 'react/no-adjacent-inline-elements': ['off'],
519
+ 'react/jsx-newline': ['off'],
520
+ 'react/jsx-no-constructed-context-values': ['error'],
521
+ 'react/no-namespace': ['error'],
522
+ 'react/prefer-exact-props': ['error'],
523
+ 'react/no-arrow-function-lifecycle': ['error'],
524
+ 'react/no-invalid-html-attribute': ['error'],
525
+ },
34
526
  },
35
- };
527
+ ];
package/package.json CHANGED
@@ -4,36 +4,39 @@
4
4
  "author": "Max Degterev <max@degterev.me>",
5
5
  "license": "MIT",
6
6
  "readmeFilename": "README.md",
7
- "repository": "entva/styleguide",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/entva/styleguide"
10
+ },
8
11
  "bugs": "https://github.com/entva/styleguide/issues",
9
- "version": "1.2.0",
12
+ "version": "2.1.0",
10
13
  "keywords": [
11
14
  "linter",
12
15
  "config",
13
16
  "eslint",
14
17
  "react"
15
18
  ],
19
+ "type": "module",
16
20
  "main": "index.js",
17
21
  "scripts": {
18
22
  "reinstall": "rm -rf node_modules package-lock.json && npm install",
19
23
  "test": "node ../../../test ./test js jsx",
20
- "rules": "node_modules/.bin/eslint --print-config file.js > eslint-ruleset-output.json",
24
+ "rules": "eslint --print-config file.js > eslint-ruleset-output.json",
21
25
  "prepublishOnly": "npm test"
22
26
  },
23
27
  "devDependencies": {
24
- "eslint": "^8.57.0",
25
- "prop-types": "^15.8.1",
26
- "react": "^18.2.0"
28
+ "eslint": "^9.16.0",
29
+ "react": "^19.0.0"
27
30
  },
28
31
  "dependencies": {
29
- "eslint-config-airbnb": "^19.0.4",
30
- "eslint-config-entva-base": "^1.1.0",
31
- "eslint-plugin-import": "^2.29.1",
32
- "eslint-plugin-jsx-a11y": "^6.8.0",
33
- "eslint-plugin-react": "^7.34.1",
34
- "eslint-plugin-react-hooks": "^4.6.0"
32
+ "eslint-config-entva-base": "^2.3.0",
33
+ "eslint-plugin-import": "^2.31.0",
34
+ "eslint-plugin-jsx-a11y": "^6.10.2",
35
+ "eslint-plugin-react": "^7.37.2",
36
+ "eslint-plugin-react-hooks": "^5.1.0",
37
+ "globals": "^15.13.0"
35
38
  },
36
39
  "peerDependencies": {
37
- "eslint": "^8.x.x"
40
+ "eslint": "^9.x.x"
38
41
  }
39
42
  }