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