@fullstacksjs/eslint-config 15.2.0 → 15.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fullstacksjs/eslint-config",
3
- "version": "15.2.0",
3
+ "version": "15.3.0",
4
4
  "description": "fullstacks eslint config",
5
5
  "license": "MIT",
6
6
  "author": "fullstacks <fullstacksjs@gmail.com>",
@@ -32,47 +32,48 @@
32
32
  "check:rules": "node scripts/check-missing-rules.mjs"
33
33
  },
34
34
  "dependencies": {
35
- "@eslint-react/eslint-plugin": "5.18.7",
36
- "@eslint/compat": "2.1.1",
37
- "@next/eslint-plugin-next": "16.3.4",
35
+ "@eslint-react/eslint-plugin": "5.20.2",
36
+ "@eslint/config-helpers": "0.7.0",
37
+ "@next/eslint-plugin-next": "16.3.5",
38
38
  "@stylistic/eslint-plugin": "5.10.0",
39
39
  "@vitest/eslint-plugin": "1.6.27",
40
40
  "deepmerge": "4.3.1",
41
41
  "eslint-flat-config-utils": "3.2.0",
42
42
  "eslint-plugin-better-tailwindcss": "4.7.0",
43
- "eslint-plugin-cypress": "7.0.1",
43
+ "eslint-plugin-cypress": "7.0.2",
44
44
  "eslint-plugin-import-x": "4.17.1",
45
45
  "eslint-plugin-jest": "29.16.6",
46
- "eslint-plugin-jsx-a11y": "6.10.2",
46
+ "eslint-plugin-jsx-a11y-x": "0.2.0",
47
47
  "eslint-plugin-n": "18.3.0",
48
- "eslint-plugin-perfectionist": "5.11.0",
49
- "eslint-plugin-playwright": "2.11.0",
48
+ "eslint-plugin-perfectionist": "5.11.1",
49
+ "eslint-plugin-playwright": "2.12.0",
50
50
  "eslint-plugin-prettier": "5.5.6",
51
51
  "eslint-plugin-promise": "7.3.0",
52
- "eslint-plugin-react-refresh": "0.5.6",
53
- "eslint-plugin-regexp": "3.3.0",
52
+ "eslint-plugin-react-refresh": "0.5.7",
53
+ "eslint-plugin-regexp": "3.3.1",
54
54
  "eslint-plugin-storybook": "10.6.0",
55
55
  "globals": "17.12.0",
56
56
  "local-pkg": "1.2.1",
57
- "typescript-eslint": "8.69.0"
57
+ "typescript-eslint": "8.70.0"
58
58
  },
59
59
  "devDependencies": {
60
60
  "@eslint/eslintrc": "3.3.7",
61
61
  "@eslint/js": "10.0.1",
62
+ "@semantic-release/git": "11.0.1",
62
63
  "@semantic-release/github": "12.0.9",
63
64
  "@semantic-release/npm": "13.1.5",
64
65
  "@semantic-release/release-notes-generator": "14.1.1",
65
66
  "@types/eslint": "9.6.1",
66
- "cspell": "10.2.2",
67
- "eslint": "10.10.0",
68
- "jest": "30.5.1",
67
+ "cspell": "10.3.3",
68
+ "eslint": "10.11.0",
69
+ "jest": "30.5.2",
69
70
  "pinst": "3.0.0",
70
- "prettier": "3.9.6",
71
+ "prettier": "3.9.8",
71
72
  "semantic-release": "25.0.9",
72
73
  "storybook": "10.6.0",
73
74
  "typescript": "6.0.3",
74
- "vite-plus": "0.3.0",
75
- "vitest": "4.1.10"
75
+ "vite-plus": "0.3.3",
76
+ "vitest": "5.0.1"
76
77
  },
77
78
  "peerDependencies": {
78
79
  "cypress": ">=15",
@@ -106,8 +107,5 @@
106
107
  "onFail": "download"
107
108
  }
108
109
  },
109
- "packageManager": "npm@12.0.2",
110
- "inlinedDependencies": {
111
- "@eslint/config-helpers": "0.7.0"
112
- }
110
+ "packageManager": "npm@12.0.2"
113
111
  }
@@ -35,10 +35,16 @@ function base(options = {}) {
35
35
  rules: {
36
36
  'accessor-pairs': 'error',
37
37
  'array-callback-return': 'error',
38
+ 'arrow-body-style': 'off',
38
39
  'block-scoped-var': 'error',
39
40
  'camelcase': ['warn', { properties: 'always' }],
41
+ 'capitalized-comments': 'off',
42
+ 'class-methods-use-this': 'off',
40
43
  'complexity': ['error', 14],
44
+ 'consistent-return': 'off',
45
+ 'consistent-this': 'off',
41
46
  'constructor-super': 'error',
47
+ 'curly': 'off',
42
48
  'default-case-last': 'error',
43
49
  'default-case': 'error',
44
50
  'default-param-last': 'warn',
@@ -47,14 +53,22 @@ function base(options = {}) {
47
53
  'for-direction': 'error',
48
54
  'func-name-matching': 'error',
49
55
  'func-names': 'error',
56
+ 'func-style': 'off',
50
57
  'getter-return': ['error', { allowImplicit: true }],
51
58
  'guard-for-in': 'error',
59
+ 'id-denylist': 'off',
60
+ 'id-length': 'off',
61
+ 'id-match': 'off',
62
+ 'init-declarations': 'off',
63
+ 'logical-assignment-operators': 'off',
64
+ 'max-classes-per-file': 'off',
52
65
  'max-depth': ['error', 4],
53
66
  'max-lines-per-function': ['error', 150],
54
67
  'max-lines': ['error', { max: 2500, skipBlankLines: false, skipComments: false }],
55
68
  'max-nested-callbacks': ['error', 7],
56
69
  'max-params': ['error', 3],
57
70
  'max-statements': ['error', 40],
71
+ 'new-cap': 'off',
58
72
  'no-alert': 'error',
59
73
  'no-array-constructor': 'error',
60
74
  'no-await-in-loop': 'error',
@@ -68,6 +82,7 @@ function base(options = {}) {
68
82
  'no-constant-binary-expression': 'warn',
69
83
  'no-constant-condition': 'error',
70
84
  'no-constructor-return': 'error',
85
+ 'no-continue': 'off',
71
86
  'no-control-regex': 'error',
72
87
  'no-debugger': 'error',
73
88
  'no-delete-var': 'error',
@@ -78,11 +93,13 @@ function base(options = {}) {
78
93
  'no-dupe-keys': 'error',
79
94
  'no-duplicate-case': 'error',
80
95
  'no-duplicate-imports': 'error',
96
+ 'no-else-return': 'warn',
81
97
  'no-empty-character-class': 'error',
82
98
  'no-empty-function': 'warn',
83
99
  'no-empty-pattern': 'error',
84
100
  'no-empty-static-block': 'warn',
85
101
  'no-empty': 'error',
102
+ 'no-eq-null': 'off',
86
103
  'no-eval': 'error',
87
104
  'no-ex-assign': 'error',
88
105
  'no-extend-native': 'error',
@@ -91,9 +108,11 @@ function base(options = {}) {
91
108
  'no-fallthrough': ['error', { allowEmptyCase: true }],
92
109
  'no-func-assign': 'error',
93
110
  'no-global-assign': 'error',
111
+ 'no-implicit-coercion': 'off',
94
112
  'no-implicit-globals': 'error',
95
113
  'no-implied-eval': 'error',
96
114
  'no-import-assign': 'error',
115
+ 'no-inline-comments': 'off',
97
116
  'no-inner-declarations': 'error',
98
117
  'no-invalid-regexp': 'error',
99
118
  'no-invalid-this': 'warn',
@@ -105,9 +124,12 @@ function base(options = {}) {
105
124
  'no-lonely-if': 'error',
106
125
  'no-loop-func': 'error',
107
126
  'no-loss-of-precision': 'warn',
127
+ 'no-magic-numbers': 'off',
108
128
  'no-misleading-character-class': ['error', { allowEscape: true }],
109
129
  'no-multi-assign': 'error',
110
130
  'no-multi-str': 'error',
131
+ 'no-negated-condition': 'off',
132
+ 'no-nested-ternary': 'warn',
111
133
  'no-new-func': 'error',
112
134
  'no-new-native-nonconstructor': 'error',
113
135
  'no-new-wrappers': 'error',
@@ -119,9 +141,13 @@ function base(options = {}) {
119
141
  'no-octal': 'error',
120
142
  'no-promise-executor-return': 'error',
121
143
  'no-proto': 'error',
144
+ 'no-prototype-builtins': 'off', // Annoying
122
145
  'no-redeclare': 'error',
123
146
  'no-regex-spaces': 'error',
147
+ 'no-restricted-exports': 'off',
124
148
  'no-restricted-globals': ['error', { name: 'event', message: 'Use local parameter instead.' }],
149
+ 'no-restricted-imports': 'off',
150
+ 'no-restricted-properties': 'off',
125
151
  'no-restricted-syntax': ['error', 'WithStatement'],
126
152
  'no-return-assign': 'error',
127
153
  'no-script-url': 'error',
@@ -132,10 +158,15 @@ function base(options = {}) {
132
158
  'no-shadow-restricted-names': 'error',
133
159
  'no-shadow': 'error',
134
160
  'no-sparse-arrays': 'error',
161
+ 'no-template-curly-in-string': 'warn',
162
+ 'no-ternary': 'off',
135
163
  'no-this-before-super': 'error',
136
164
  'no-throw-literal': 'error',
165
+ 'no-unassigned-vars': 'error',
137
166
  'no-undef-init': 'error',
138
167
  'no-undef': 'error',
168
+ 'no-undefined': 'off',
169
+ 'no-underscore-dangle': 'off',
139
170
  'no-unexpected-multiline': 'error',
140
171
  'no-unmodified-loop-condition': 'error',
141
172
  'no-unneeded-ternary': 'error',
@@ -144,6 +175,7 @@ function base(options = {}) {
144
175
  'no-unsafe-finally': 'error',
145
176
  'no-unsafe-negation': 'error',
146
177
  'no-unsafe-optional-chaining': 'error',
178
+ 'no-unused-expressions': 'error',
147
179
  'no-unused-labels': 'error',
148
180
  'no-unused-private-class-members': 'warn',
149
181
  'no-unused-vars': [
@@ -167,18 +199,23 @@ function base(options = {}) {
167
199
  'no-useless-rename': 'error',
168
200
  'no-useless-return': 'error',
169
201
  'no-var': 'warn',
202
+ 'no-void': 'off',
170
203
  'no-warning-comments': ['warn', { terms: ['fixme'], location: 'anywhere' }],
204
+ 'no-with': 'error',
171
205
  'object-shorthand': ['error', 'properties'],
172
206
  'one-var': ['error', { uninitialized: 'never', initialized: 'never' }],
207
+ 'operator-assignment': 'off',
173
208
  'prefer-arrow-callback': ['warn', { allowNamedFunctions: true, allowUnboundThis: true }],
174
209
  'prefer-const': 'warn',
210
+ 'prefer-named-capture-group': 'off',
211
+ 'prefer-object-spread': 'warn',
175
212
  'preserve-caught-error': strict(options, [
176
213
  'warn',
177
214
  {
178
215
  requireCatchParameter: true,
179
216
  },
180
217
  ]),
181
- 'prefer-destructuring': ['warn', { object: true, array: false }],
218
+ 'prefer-destructuring': 'off', // Annoying
182
219
  'prefer-exponentiation-operator': 'warn',
183
220
  'prefer-numeric-literals': 'error',
184
221
  'prefer-object-has-own': 'warn',
@@ -188,9 +225,14 @@ function base(options = {}) {
188
225
  'prefer-promise-reject-errors': 'warn',
189
226
  'radix': 'error',
190
227
  'require-await': 'error',
228
+ 'require-unicode-regexp': 'off',
191
229
  'require-yield': 'error',
230
+ 'sort-imports': 'off',
231
+ 'sort-keys': 'off',
232
+ 'sort-vars': 'off',
192
233
  'strict': 'error',
193
234
  'symbol-description': 'error',
235
+ 'unicode-bom': 'off',
194
236
  'use-isnan': 'error',
195
237
  'valid-typeof': 'error',
196
238
  'vars-on-top': 'error',
@@ -19,7 +19,10 @@ function cypress(options = {}) {
19
19
  rules: {
20
20
  'cypress/assertion-before-screenshot': 'warn',
21
21
  'cypress/no-assigning-return-values': 'error',
22
+ 'cypress/no-and': 'off',
22
23
  'cypress/no-async-tests': 'error',
24
+ 'cypress/no-async-before': 'error',
25
+ 'cypress/no-debug': 'warn',
23
26
  'cypress/no-force': 'warn',
24
27
  'cypress/no-pause': 'error',
25
28
  'cypress/no-unnecessary-waiting': 'error',
@@ -64,6 +64,7 @@ function imports(options = {}) {
64
64
  'import/no-named-as-default': 'error',
65
65
  'import/no-named-default': 'error',
66
66
  'import/no-relative-packages': 'error',
67
+ 'import/no-rename-default': 'off',
67
68
  'import/no-self-import': 'error',
68
69
  'import/no-unresolved': ['error', { caseSensitiveStrict: true }],
69
70
  'import/no-useless-path-segments': 'warn',
@@ -98,6 +99,7 @@ function imports(options = {}) {
98
99
  'import/no-unassigned-import': 'off',
99
100
  'import/no-unused-modules': 'off',
100
101
  'import/prefer-default-export': 'off',
102
+ 'import/prefer-namespace-import': 'off',
101
103
  'import/unambiguous': 'off',
102
104
 
103
105
  ...predicate(options.typescript, {
@@ -26,19 +26,23 @@ function jest(options = {}) {
26
26
  rules: {
27
27
  'jest/consistent-test-it': 'off',
28
28
  'jest/expect-expect': 'off',
29
- 'jest/lowercase-name': 'off',
30
29
  'jest/max-nested-describe': ['error', { max: 2 }],
30
+ 'jest/max-expects': 'off',
31
31
  'jest/no-alias-methods': 'error',
32
32
  'jest/no-commented-out-tests': 'warn',
33
33
  'jest/no-conditional-expect': 'error',
34
34
  'jest/no-conditional-in-test': 'error',
35
35
  'jest/no-confusing-set-timeout': 'warn',
36
+ 'jest/no-disabled-tests': 'warn',
37
+ 'jest/no-duplicate-hooks': 'error',
36
38
  'jest/no-done-callback': 'warn',
37
- 'jest/no-expect-resolves': 'off',
38
39
  'jest/no-export': 'error',
40
+ 'jest/no-focused-tests': 'error',
41
+ 'jest/no-identical-title': 'error',
39
42
  ...predicate(projectService, {
40
43
  'jest/no-error-equal': 'error',
41
44
  'jest/no-unnecessary-assertion': 'warn',
45
+ 'jest/valid-expect-with-promise': 'error',
42
46
  }),
43
47
  'jest/no-hooks': 'off',
44
48
  'jest/no-interpolation-in-snapshots': 'error',
@@ -48,27 +52,38 @@ function jest(options = {}) {
48
52
  'jest/no-restricted-jest-methods': 'off',
49
53
  'jest/no-restricted-matchers': 'error',
50
54
  'jest/no-standalone-expect': 'off',
51
- 'jest/no-test-callback': 'off',
52
55
  'jest/no-test-prefixes': 'error',
53
56
  'jest/no-test-return-statement': 'off',
54
57
  'jest/no-unneeded-async-expect-function': 'warn',
55
- 'jest/no-truthy-falsy': 'off',
58
+ 'jest/padding-around-after-all-blocks': 'off',
59
+ 'jest/padding-around-after-each-blocks': 'off',
60
+ 'jest/padding-around-all': 'off',
61
+ 'jest/padding-around-before-all-blocks': 'off',
62
+ 'jest/padding-around-before-each-blocks': 'off',
63
+ 'jest/padding-around-describe-blocks': 'off',
64
+ 'jest/padding-around-expect-groups': 'off',
65
+ 'jest/padding-around-test-blocks': 'off',
56
66
  'jest/prefer-called-with': 'error',
67
+ 'jest/prefer-comparison-matcher': 'warn',
68
+ 'jest/prefer-ending-with-an-expect': 'off',
69
+ 'jest/prefer-equality-matcher': 'warn',
57
70
  'jest/prefer-each': 'warn',
58
71
  'jest/prefer-expect-assertions': 'off',
59
72
  'jest/prefer-expect-resolves': 'warn',
60
73
  'jest/prefer-hooks-on-top': 'error',
61
- 'jest/prefer-inline-snapshots': 'off',
74
+ 'jest/prefer-hooks-in-order': 'warn',
75
+ 'jest/prefer-importing-jest-globals': 'off',
76
+ 'jest/prefer-jest-mocked': 'warn',
62
77
  'jest/prefer-lowercase-title': 'off',
63
78
  'jest/prefer-mock-promise-shorthand': 'warn',
64
79
  'jest/prefer-mock-return-shorthand': 'warn',
65
80
  'jest/prefer-snapshot-hint': 'warn',
66
81
  'jest/prefer-spy-on': 'off',
67
82
  'jest/prefer-strict-equal': 'off',
68
- 'jest/prefer-to-be-null': 'off',
69
- 'jest/prefer-to-be-undefined': 'off',
70
83
  'jest/prefer-to-be': 'warn',
71
84
  'jest/prefer-to-contain': 'warn',
85
+ 'jest/prefer-to-have-been-called': 'warn',
86
+ 'jest/prefer-to-have-been-called-times': 'warn',
72
87
  'jest/prefer-to-have-length': 'warn',
73
88
  'jest/prefer-todo': 'warn',
74
89
  'jest/require-hook': 'off',
@@ -29,6 +29,7 @@ function next(options = {}) {
29
29
  'next/no-head-import-in-document': 'warn',
30
30
  'next/no-html-link-for-pages': 'warn',
31
31
  'next/no-img-element': 'warn',
32
+ 'next/no-location-assign-relative-destination': 'error',
32
33
  'next/no-page-custom-font': 'warn',
33
34
  'next/no-script-component-in-head': 'warn',
34
35
  'next/no-styled-jsx-in-document': 'warn',
@@ -47,7 +47,7 @@ function node(options = {}) {
47
47
  'n/prefer-global/timers': 'warn',
48
48
  'n/prefer-global/url-search-params': 'warn',
49
49
  'n/prefer-global/url': 'warn',
50
- '/prefer-import/assert-strict': 'warn',
50
+ 'n/prefer-import/assert-strict': 'warn',
51
51
  'n/prefer-node-protocol': 'warn',
52
52
  'n/prefer-process-get-builtin-module': 'warn',
53
53
  'n/prefer-promises/dns': 'warn',
@@ -22,6 +22,7 @@ function playwright(options = {}) {
22
22
  'playwright/max-expects': 'off',
23
23
  'playwright/max-nested-describe': ['warn', { max: 5 }],
24
24
  'playwright/missing-playwright-await': 'error',
25
+ 'playwright/no-action-timeout': 'warn',
25
26
  'playwright/no-commented-out-tests': 'warn',
26
27
  'playwright/no-conditional-expect': 'warn',
27
28
  'playwright/no-conditional-in-test': 'warn',
@@ -29,10 +30,13 @@ function playwright(options = {}) {
29
30
  'playwright/no-duplicate-slow': 'off',
30
31
  'playwright/no-element-handle': 'warn',
31
32
  'playwright/no-eval': 'warn',
33
+ 'playwright/no-export': 'warn',
32
34
  'playwright/no-focused-test': 'warn',
33
35
  'playwright/no-force-option': 'warn',
34
36
  'playwright/no-get-by-title': 'off',
35
37
  'playwright/no-hooks': 'off',
38
+ 'playwright/no-identical-title': 'error',
39
+ 'playwright/no-magic-timeouts': 'off',
36
40
  'playwright/no-nested-step': 'warn',
37
41
  'playwright/no-networkidle': 'warn',
38
42
  'playwright/no-nth-methods': 'off',
@@ -44,6 +48,9 @@ function playwright(options = {}) {
44
48
  'playwright/no-skipped-test': 'warn',
45
49
  'playwright/no-slowed-test': 'warn',
46
50
  'playwright/no-standalone-expect': 'warn',
51
+ 'playwright/no-template-literal-title': 'off',
52
+ 'playwright/no-test-return-statement': 'warn',
53
+ 'playwright/no-unnecessary-assertions': 'warn',
47
54
  'playwright/no-unsafe-references': 'warn',
48
55
  'playwright/no-unused-locators': 'warn',
49
56
  'playwright/no-useless-await': 'error',
@@ -52,6 +59,7 @@ function playwright(options = {}) {
52
59
  'playwright/no-wait-for-selector': 'warn',
53
60
  'playwright/no-wait-for-timeout': 'warn',
54
61
  'playwright/prefer-comparison-matcher': 'off',
62
+ 'playwright/prefer-ending-with-an-expect': 'off',
55
63
  'playwright/prefer-equality-matcher': 'off',
56
64
  'playwright/prefer-hooks-in-order': 'off',
57
65
  'playwright/prefer-hooks-on-top': 'off',
@@ -64,6 +72,7 @@ function playwright(options = {}) {
64
72
  'playwright/prefer-to-have-count': 'off',
65
73
  'playwright/prefer-to-have-length': 'off',
66
74
  'playwright/prefer-web-first-assertions': 'warn',
75
+ 'playwright/require-annotation-reason': 'off',
67
76
  'playwright/require-hook': 'off',
68
77
  'playwright/require-soft-assertions': 'off',
69
78
  'playwright/require-tags': 'off',
@@ -1,6 +1,6 @@
1
1
  import reactPlugin from '@eslint-react/eslint-plugin';
2
2
  import { mergeConfigs } from 'eslint-flat-config-utils';
3
- import a11yPlugin from 'eslint-plugin-jsx-a11y';
3
+ import jsxA11yX from 'eslint-plugin-jsx-a11y-x';
4
4
  import { reactRefresh } from 'eslint-plugin-react-refresh';
5
5
  import { isPackageExists } from 'local-pkg';
6
6
  import { parser } from 'typescript-eslint';
@@ -25,7 +25,7 @@ function react(options = {}) {
25
25
  files: [globs.js, globs.jsx, globs.ts, globs.tsx],
26
26
  plugins: {
27
27
  ...reactPlugin.configs.all.plugins,
28
- 'jsx-a11y': a11yPlugin,
28
+ 'jsx-a11y-x': jsxA11yX,
29
29
  'react-refresh': reactRefresh.plugin,
30
30
  },
31
31
  ...predicate(projectService, {
@@ -60,14 +60,10 @@ function react(options = {}) {
60
60
  '@eslint-react/dom-no-void-elements-with-children': 'warn',
61
61
  '@eslint-react/dom-no-dangerously-set-innerhtml-with-children': 'error',
62
62
  '@eslint-react/dom-no-dangerously-set-innerhtml': 'off',
63
- '@eslint-react/dom-no-find-dom-node': 'error',
64
63
  '@eslint-react/dom-no-flush-sync': 'off',
65
- '@eslint-react/dom-no-use-form-state': 'warn',
66
- '@eslint-react/dom-no-hydrate': 'warn',
67
64
  '@eslint-react/dom-no-missing-button-type': 'warn',
68
65
  '@eslint-react/dom-no-missing-iframe-sandbox': 'warn',
69
66
  '@eslint-react/dom-no-render-return-value': 'error',
70
- '@eslint-react/dom-no-render': 'warn',
71
67
  '@eslint-react/dom-no-script-url': 'warn',
72
68
  '@eslint-react/dom-no-string-style-prop': 'error',
73
69
  '@eslint-react/dom-no-unknown-property': 'off',
@@ -92,16 +88,11 @@ function react(options = {}) {
92
88
  '@eslint-react/no-children-to-array': 'warn',
93
89
  '@eslint-react/no-class-component': 'off',
94
90
  '@eslint-react/no-clone-element': 'warn',
95
- '@eslint-react/no-component-will-mount': 'error',
96
- '@eslint-react/no-component-will-receive-props': 'error',
97
- '@eslint-react/no-component-will-update': 'error',
98
91
  '@eslint-react/no-context-provider': 'warn',
99
92
 
100
- '@eslint-react/no-create-ref': 'error',
101
93
  '@eslint-react/no-direct-mutation-state': 'error',
102
94
  '@eslint-react/no-duplicate-key': 'error',
103
95
  '@eslint-react/no-forward-ref': 'warn',
104
- '@eslint-react/no-leaked-conditional-rendering': 'error',
105
96
  '@eslint-react/no-missing-component-display-name': 'off',
106
97
  '@eslint-react/no-missing-context-display-name': 'warn',
107
98
  '@eslint-react/no-missing-key': 'error',
@@ -157,42 +148,50 @@ function react(options = {}) {
157
148
  '@eslint-react/unsupported-syntax': 'error',
158
149
  '@eslint-react/use-memo': 'error',
159
150
 
160
- 'jsx-a11y/alt-text': 'warn',
161
- 'jsx-a11y/anchor-has-content': 'error',
162
- 'jsx-a11y/anchor-is-valid': 'error',
163
- 'jsx-a11y/aria-activedescendant-has-tabindex': 'error',
164
- 'jsx-a11y/aria-props': 'error',
165
- 'jsx-a11y/aria-proptypes': 'error',
166
- 'jsx-a11y/aria-role': 'error',
167
- 'jsx-a11y/aria-unsupported-elements': 'error',
168
- 'jsx-a11y/autocomplete-valid': 'off',
169
- 'jsx-a11y/click-events-have-key-events': 'error',
170
- 'jsx-a11y/control-has-associated-label': 'off',
171
- 'jsx-a11y/heading-has-content': 'error',
172
- 'jsx-a11y/html-has-lang': 'error',
173
- 'jsx-a11y/iframe-has-title': 'error',
174
- 'jsx-a11y/img-redundant-alt': 'error',
175
- 'jsx-a11y/interactive-supports-focus': 'warn',
176
- 'jsx-a11y/label-has-associated-control': 'error',
177
- 'jsx-a11y/lang': 'error',
178
- 'jsx-a11y/media-has-caption': 'warn',
179
- 'jsx-a11y/mouse-events-have-key-events': 'error',
180
- 'jsx-a11y/no-access-key': 'error',
181
- 'jsx-a11y/no-aria-hidden-on-focusable': 'warn',
182
- 'jsx-a11y/no-autofocus': 'off',
183
- 'jsx-a11y/no-distracting-elements': 'error',
184
- 'jsx-a11y/no-interactive-element-to-noninteractive-role': 'warn',
185
- 'jsx-a11y/no-noninteractive-element-interactions': 'warn',
186
- 'jsx-a11y/no-noninteractive-element-to-interactive-role': 'warn',
187
- 'jsx-a11y/no-noninteractive-tabindex': 'off',
188
- 'jsx-a11y/no-redundant-roles': 'error',
189
- 'jsx-a11y/no-static-element-interactions': 'off',
190
- 'jsx-a11y/role-has-required-aria-props': 'error',
191
- 'jsx-a11y/role-supports-aria-props': 'error',
192
- 'jsx-a11y/scope': 'error',
193
- 'jsx-a11y/tabindex-no-positive': 'warn',
194
- 'jsx-a11y/anchor-ambiguous-text': 'off',
195
- 'jsx-a11y/prefer-tag-over-role': 'off',
151
+ ...predicate(projectService, {
152
+ '@eslint-react/no-implicit-children': 'warn',
153
+ '@eslint-react/no-implicit-key': 'warn',
154
+ '@eslint-react/no-implicit-ref': 'warn',
155
+ '@eslint-react/no-leaked-conditional-rendering': 'error',
156
+ '@eslint-react/no-unused-props': 'warn',
157
+ }),
158
+
159
+ 'jsx-a11y-x/alt-text': 'warn',
160
+ 'jsx-a11y-x/anchor-has-content': 'error',
161
+ 'jsx-a11y-x/anchor-is-valid': 'error',
162
+ 'jsx-a11y-x/aria-activedescendant-has-tabindex': 'error',
163
+ 'jsx-a11y-x/aria-props': 'error',
164
+ 'jsx-a11y-x/aria-proptypes': 'error',
165
+ 'jsx-a11y-x/aria-role': 'error',
166
+ 'jsx-a11y-x/aria-unsupported-elements': 'error',
167
+ 'jsx-a11y-x/autocomplete-valid': 'off',
168
+ 'jsx-a11y-x/click-events-have-key-events': 'error',
169
+ 'jsx-a11y-x/control-has-associated-label': 'off',
170
+ 'jsx-a11y-x/heading-has-content': 'error',
171
+ 'jsx-a11y-x/html-has-lang': 'error',
172
+ 'jsx-a11y-x/iframe-has-title': 'error',
173
+ 'jsx-a11y-x/img-redundant-alt': 'error',
174
+ 'jsx-a11y-x/interactive-supports-focus': 'warn',
175
+ 'jsx-a11y-x/label-has-associated-control': 'error',
176
+ 'jsx-a11y-x/lang': 'error',
177
+ 'jsx-a11y-x/media-has-caption': 'warn',
178
+ 'jsx-a11y-x/mouse-events-have-key-events': 'error',
179
+ 'jsx-a11y-x/no-access-key': 'error',
180
+ 'jsx-a11y-x/no-aria-hidden-on-focusable': 'warn',
181
+ 'jsx-a11y-x/no-autofocus': 'off',
182
+ 'jsx-a11y-x/no-distracting-elements': 'error',
183
+ 'jsx-a11y-x/no-interactive-element-to-noninteractive-role': 'warn',
184
+ 'jsx-a11y-x/no-noninteractive-element-interactions': 'warn',
185
+ 'jsx-a11y-x/no-noninteractive-element-to-interactive-role': 'warn',
186
+ 'jsx-a11y-x/no-noninteractive-tabindex': 'off',
187
+ 'jsx-a11y-x/no-redundant-roles': 'error',
188
+ 'jsx-a11y-x/no-static-element-interactions': 'off',
189
+ 'jsx-a11y-x/role-has-required-aria-props': 'error',
190
+ 'jsx-a11y-x/role-supports-aria-props': 'error',
191
+ 'jsx-a11y-x/scope': 'error',
192
+ 'jsx-a11y-x/tabindex-no-positive': 'warn',
193
+ 'jsx-a11y-x/anchor-ambiguous-text': 'off',
194
+ 'jsx-a11y-x/prefer-tag-over-role': 'off',
196
195
 
197
196
  'react-refresh/only-export-components': [
198
197
  'error',
@@ -200,6 +199,8 @@ function react(options = {}) {
200
199
  allowExportNames: isPackageExists('next') ? nextAllowExportNames : [],
201
200
 
202
201
  allowConstantExport: isPackageExists('vite'),
202
+
203
+ allowCompoundComponents: isPackageExists('vite'),
203
204
  },
204
205
  ],
205
206
  },
@@ -37,7 +37,7 @@ function storybook(options = {}) {
37
37
 
38
38
  // Conflicts
39
39
  '@typescript-eslint/no-confusing-void-expression': 'off',
40
- '@eslint-react/no-useless-fragment': 'off',
40
+ '@eslint-react/jsx-no-useless-fragment': 'off',
41
41
  'react-hooks/rules-of-hooks': 'off',
42
42
  },
43
43
  };