1- import reactX from '@eslint-react/eslint-plugin' ;
1+ import eslintReact from '@eslint-react/eslint-plugin' ;
22import markdown from '@eslint/markdown' ;
33import vitest from '@vitest/eslint-plugin' ;
44import jestDom from 'eslint-plugin-jest-dom' ;
5+ import reactDom from 'eslint-plugin-react-dom' ;
56import reactHooks from 'eslint-plugin-react-hooks' ;
7+ import reactNamingConvention from 'eslint-plugin-react-naming-convention' ;
8+ import reactRsc from 'eslint-plugin-react-rsc' ;
9+ import reactWebApi from 'eslint-plugin-react-web-api' ;
610import sonarjs from 'eslint-plugin-sonarjs' ;
711import testingLibrary from 'eslint-plugin-testing-library' ;
812import { defineConfig , globalIgnores } from 'eslint/config' ;
@@ -24,7 +28,11 @@ export default defineConfig([
2428 plugins : {
2529 // @ts -expect-error
2630 'react-hooks' : reactHooks ,
27- 'react-x' : reactX ,
31+ '@eslint-react' : eslintReact ,
32+ '@eslint-react/rsc' : reactRsc ,
33+ '@eslint-react/dom' : reactDom ,
34+ '@eslint-react/web-api' : reactWebApi ,
35+ '@eslint-react/naming-convention' : reactNamingConvention ,
2836 sonarjs,
2937 '@typescript-eslint' : tseslint . plugin
3038 } ,
@@ -276,12 +284,127 @@ export default defineConfig([
276284 'react-hooks/unsupported-syntax' : 1 ,
277285 'react-hooks/use-memo' : 1 ,
278286
279- // React Hooks Extra
280- // https://eslint-react.xyz/
281- 'react-x/no-unnecessary-use-callback' : 1 ,
282- 'react-x/no-unnecessary-use-memo' : 1 ,
283- 'react-x/no-unnecessary-use-prefix' : 1 ,
284- 'react-x/prefer-use-state-lazy-initialization' : 1 ,
287+ // ESLint React
288+ // https://www.eslint-react.xyz/docs/rules/overview
289+ /*
290+ // copy all the rules from the rules table for easy pasting
291+ function getRules(id, prefix) {
292+ return (
293+ Iterator.from(
294+ document
295+ // select rules table
296+ .querySelector(`#${id} ~ *:has(table) > table`)
297+ // select all rule links
298+ .querySelectorAll('tr a')
299+ )
300+ // map link to rule declaration
301+ .map((a) => `'@eslint-react/${prefix}${a.textContent}': 1,`)
302+ );
303+ }
304+ copy(
305+ Iterator.from([
306+ getRules('x-rules', ''),
307+ getRules('rsc-rules', 'rsc/'),
308+ getRules('dom-rules', 'dom/'),
309+ getRules('web-api-rules', 'web-api/'),
310+ getRules('naming-convention-rules', 'naming-convention/'),
311+ ])
312+ .flatMap((x) => x)
313+ .toArray()
314+ .join('\n')
315+ );
316+ */
317+ '@eslint-react/component-hook-factories' : 1 ,
318+ '@eslint-react/error-boundaries' : 1 ,
319+ '@eslint-react/exhaustive-deps' : 1 ,
320+ '@eslint-react/jsx-dollar' : 1 ,
321+ '@eslint-react/jsx-key-before-spread' : 1 ,
322+ '@eslint-react/jsx-no-comment-textnodes' : 1 ,
323+ '@eslint-react/jsx-no-duplicate-props' : 1 ,
324+ '@eslint-react/jsx-shorthand-boolean' : 1 ,
325+ '@eslint-react/jsx-shorthand-fragment' : 1 ,
326+ '@eslint-react/jsx-uses-react' : 1 ,
327+ '@eslint-react/jsx-uses-vars' : 1 ,
328+ '@eslint-react/no-access-state-in-setstate' : 1 ,
329+ '@eslint-react/no-array-index-key' : 0 ,
330+ '@eslint-react/no-children-count' : 1 ,
331+ '@eslint-react/no-children-for-each' : 1 ,
332+ '@eslint-react/no-children-map' : 1 ,
333+ '@eslint-react/no-children-only' : 1 ,
334+ '@eslint-react/no-children-prop' : 1 ,
335+ '@eslint-react/no-children-to-array' : 1 ,
336+ '@eslint-react/no-class-component' : 1 ,
337+ '@eslint-react/no-clone-element' : 1 ,
338+ '@eslint-react/no-component-will-mount' : 1 ,
339+ '@eslint-react/no-component-will-receive-props' : 1 ,
340+ '@eslint-react/no-component-will-update' : 1 ,
341+ '@eslint-react/no-context-provider' : 1 ,
342+ '@eslint-react/no-create-ref' : 1 ,
343+ '@eslint-react/no-direct-mutation-state' : 1 ,
344+ '@eslint-react/no-duplicate-key' : 1 ,
345+ '@eslint-react/no-forward-ref' : 1 ,
346+ '@eslint-react/no-implicit-key' : 1 ,
347+ '@eslint-react/no-leaked-conditional-rendering' : 1 ,
348+ '@eslint-react/no-missing-component-display-name' : 1 ,
349+ '@eslint-react/no-missing-context-display-name' : 1 ,
350+ '@eslint-react/no-missing-key' : 1 ,
351+ '@eslint-react/no-misused-capture-owner-stack' : 1 ,
352+ '@eslint-react/no-nested-component-definitions' : 1 ,
353+ '@eslint-react/no-nested-lazy-component-declarations' : 1 ,
354+ '@eslint-react/no-redundant-should-component-update' : 1 ,
355+ '@eslint-react/no-set-state-in-component-did-mount' : 1 ,
356+ '@eslint-react/no-set-state-in-component-did-update' : 1 ,
357+ '@eslint-react/no-set-state-in-component-will-update' : 1 ,
358+ '@eslint-react/no-unnecessary-use-callback' : 1 ,
359+ '@eslint-react/no-unnecessary-use-memo' : 1 ,
360+ '@eslint-react/no-unnecessary-use-prefix' : 1 ,
361+ '@eslint-react/no-unsafe-component-will-mount' : 1 ,
362+ '@eslint-react/no-unsafe-component-will-receive-props' : 1 ,
363+ '@eslint-react/no-unsafe-component-will-update' : 1 ,
364+ '@eslint-react/no-unstable-context-value' : 1 ,
365+ '@eslint-react/no-unstable-default-props' : 1 ,
366+ '@eslint-react/no-unused-class-component-members' : 1 ,
367+ '@eslint-react/no-unused-props' : 1 ,
368+ '@eslint-react/no-unused-state' : 1 ,
369+ '@eslint-react/no-use-context' : 1 ,
370+ '@eslint-react/no-useless-fragment' : [ 1 , { allowExpressions : false } ] ,
371+ '@eslint-react/prefer-destructuring-assignment' : 1 ,
372+ '@eslint-react/prefer-namespace-import' : 1 ,
373+ '@eslint-react/purity' : 1 ,
374+ '@eslint-react/refs' : 1 ,
375+ '@eslint-react/rules-of-hooks' : 1 ,
376+ '@eslint-react/set-state-in-effect' : 0 ,
377+ '@eslint-react/set-state-in-render' : 1 ,
378+ '@eslint-react/unsupported-syntax' : 1 ,
379+ '@eslint-react/use-memo' : 1 ,
380+ '@eslint-react/use-state' : 1 ,
381+ '@eslint-react/rsc/function-definition' : 1 ,
382+ '@eslint-react/dom/no-dangerously-set-innerhtml' : 1 ,
383+ '@eslint-react/dom/no-dangerously-set-innerhtml-with-children' : 1 ,
384+ '@eslint-react/dom/no-find-dom-node' : 1 ,
385+ '@eslint-react/dom/no-flush-sync' : 0 ,
386+ '@eslint-react/dom/no-hydrate' : 1 ,
387+ '@eslint-react/dom/no-missing-button-type' : 1 ,
388+ '@eslint-react/dom/no-missing-iframe-sandbox' : 1 ,
389+ '@eslint-react/dom/no-namespace' : 1 ,
390+ '@eslint-react/dom/no-render' : 1 ,
391+ '@eslint-react/dom/no-render-return-value' : 1 ,
392+ '@eslint-react/dom/no-script-url' : 1 ,
393+ '@eslint-react/dom/no-string-style-prop' : 1 ,
394+ '@eslint-react/dom/no-unknown-property' : 0 ,
395+ '@eslint-react/dom/no-unsafe-iframe-sandbox' : 1 ,
396+ '@eslint-react/dom/no-unsafe-target-blank' : 1 ,
397+ '@eslint-react/dom/no-use-form-state' : 1 ,
398+ '@eslint-react/dom/no-void-elements-with-children' : 1 ,
399+ '@eslint-react/dom/prefer-namespace-import' : 1 ,
400+ '@eslint-react/web-api/no-leaked-event-listener' : 1 ,
401+ '@eslint-react/web-api/no-leaked-interval' : 1 ,
402+ '@eslint-react/web-api/no-leaked-resize-observer' : 1 ,
403+ '@eslint-react/web-api/no-leaked-timeout' : 1 ,
404+ '@eslint-react/naming-convention/component-name' : 1 ,
405+ '@eslint-react/naming-convention/context-name' : 1 ,
406+ '@eslint-react/naming-convention/id-name' : 1 ,
407+ '@eslint-react/naming-convention/ref-name' : 1 ,
285408
286409 // SonarJS rules
287410 // https://github.com/SonarSource/SonarJS/blob/master/packages/jsts/src/rules/README.md#rules
@@ -290,7 +413,7 @@ export default defineConfig([
290413copy(
291414 Iterator.from(
292415 document
293- // selecto rules table
416+ // select rules table
294417 .querySelector('.markdown-heading:has(> a[href="#rules"]) ~ markdown-accessiblity-table')
295418 // select all rows with a rule
296419 .querySelectorAll('tr:has(a)')
@@ -438,7 +561,7 @@ copy(
438561 'sonarjs/no-identical-functions' : 1 ,
439562 'sonarjs/no-ignored-exceptions' : 1 ,
440563 'sonarjs/no-ignored-return' : 1 ,
441- 'sonarjs/no-implicit-dependencies' : 1 ,
564+ 'sonarjs/no-implicit-dependencies' : 0 ,
442565 'sonarjs/no-implicit-global' : 1 ,
443566 'sonarjs/no-in-misuse' : 1 ,
444567 'sonarjs/no-incomplete-assertions' : 1 ,
@@ -654,19 +777,7 @@ copy(
654777 '@typescript-eslint/no-redeclare' : 1 ,
655778 '@typescript-eslint/no-redundant-type-constituents' : 1 ,
656779 '@typescript-eslint/no-require-imports' : 1 ,
657- '@typescript-eslint/no-restricted-imports' : [
658- 1 ,
659- {
660- name : 'react' ,
661- importNames : [ 'default' ] ,
662- message : 'Use named imports instead.'
663- } ,
664- {
665- name : 'react-dom' ,
666- importNames : [ 'default' ] ,
667- message : 'Use named imports instead.'
668- }
669- ] ,
780+ '@typescript-eslint/no-restricted-imports' : 0 ,
670781 '@typescript-eslint/no-restricted-types' : 0 ,
671782 '@typescript-eslint/no-shadow' : 0 ,
672783 '@typescript-eslint/no-this-alias' : 1 ,
@@ -803,6 +914,9 @@ copy(
803914 rules : {
804915 '@typescript-eslint/no-floating-promises' : 1 ,
805916
917+ '@eslint-react/component-hook-factories' : 0 ,
918+ '@eslint-react/no-create-ref' : 0 ,
919+
806920 // https://github.com/vitest-dev/eslint-plugin-vitest#rules
807921 'vitest/consistent-each-for' : 1 ,
808922 'vitest/consistent-test-filename' : 0 ,
0 commit comments