@tb-dev/eslint-config 6.0.6 → 6.1.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/README.md CHANGED
@@ -1,6 +1,3 @@
1
1
  # @tb-dev/eslint-config
2
2
 
3
3
  Opinionated config for ESLint.
4
-
5
- - TypeScript only.
6
- - Optional Vue support.
package/dist/index.cjs CHANGED
@@ -39,6 +39,12 @@ function isEnabled(config, feature) {
39
39
  switch (feature) {
40
40
  case "perfectionist":
41
41
  return config?.perfectionist ?? true;
42
+ case "react":
43
+ return config?.react ?? false;
44
+ case "reactCompiler":
45
+ return config?.reactCompiler ?? config?.react ?? false;
46
+ case "reactHooks":
47
+ return config?.reactHooks ?? config?.react ?? false;
42
48
  case "svelte":
43
49
  return config?.svelte ?? false;
44
50
  case "tailwind":
@@ -287,6 +293,55 @@ async function vue(options) {
287
293
  ];
288
294
  }
289
295
 
296
+ async function react(options) {
297
+ if (!isEnabled(options.features, "react")) return {};
298
+ const plugin = await interopDefault(import('eslint-plugin-react'));
299
+ return {
300
+ plugins: { react: plugin },
301
+ rules: {
302
+ "react/button-has-type": "error",
303
+ "react/function-component-definition": [
304
+ "error",
305
+ {
306
+ namedComponents: "function-expression",
307
+ unnamedComponents: "function-expression"
308
+ }
309
+ ],
310
+ "react/hook-use-state": ["error", { allowDestructuredState: true }],
311
+ "react/jsx-boolean-value": ["error", "never", { assumeUndefinedIsFalse: true }],
312
+ "react/jsx-key": [
313
+ "error",
314
+ {
315
+ checkFragmentShorthand: true,
316
+ checkKeyMustBeforeSpread: false,
317
+ warnOnDuplicates: true
318
+ }
319
+ ],
320
+ "react/jsx-no-script-url": "error",
321
+ "react/jsx-no-useless-fragment": "error",
322
+ "react/jsx-pascal-case": [
323
+ "error",
324
+ {
325
+ allowAllCaps: false,
326
+ allowNamespace: true,
327
+ allowLeadingUnderscore: false
328
+ }
329
+ ],
330
+ "react/jsx-props-no-spread-multi": "error",
331
+ "react/no-access-state-in-setstate": "error",
332
+ "react/no-array-index-key": "error",
333
+ "react/no-danger": "error",
334
+ "react/no-deprecated": "error",
335
+ "react/no-direct-mutation-state": "error",
336
+ "react/no-find-dom-node": "error",
337
+ "react/no-is-mounted": "error",
338
+ "react/no-render-return-value": "error",
339
+ "react/no-unsafe": "error",
340
+ ...options.overrides?.react
341
+ }
342
+ };
343
+ }
344
+
290
345
  async function svelte(options) {
291
346
  if (!isEnabled(options.features, "svelte")) return [];
292
347
  const [sveltePlugin, svelteParser, tsParser] = await Promise.all([
@@ -427,6 +482,11 @@ function javascript(options) {
427
482
  languageOptions: {
428
483
  ecmaVersion: "latest",
429
484
  sourceType: "module",
485
+ parserOptions: {
486
+ ecmaFeatures: {
487
+ jsx: isEnabled(options.features, "react")
488
+ }
489
+ },
430
490
  globals: {
431
491
  ...globals.browser,
432
492
  ...globals.es2021,
@@ -850,7 +910,10 @@ async function typescript(options) {
850
910
  parserOptions: {
851
911
  project: options.project,
852
912
  tsconfigRootDir: process.cwd(),
853
- extraFileExtensions
913
+ extraFileExtensions,
914
+ ecmaFeatures: {
915
+ jsx: isEnabled(options.features, "react")
916
+ }
854
917
  }
855
918
  },
856
919
  plugins: { "@typescript-eslint": tsPlugin },
@@ -967,6 +1030,7 @@ async function defineConfig(options) {
967
1030
  typescript(options),
968
1031
  ...await vue(options),
969
1032
  ...await svelte(options),
1033
+ react(options),
970
1034
  perfectionist(options),
971
1035
  unicorn(options),
972
1036
  tailwind(options),
package/dist/index.d.ts CHANGED
@@ -22,6 +22,9 @@ declare interface ConfigOptions {
22
22
  overrides?: {
23
23
  javascript?: Rules;
24
24
  perfectionist?: Rules;
25
+ react?: Rules;
26
+ reactCompiler?: Rules;
27
+ reactHooks?: Rules;
25
28
  svelte?: Rules;
26
29
  tailwind?: Rules;
27
30
  typescript?: Rules;
@@ -38,6 +41,12 @@ declare interface FeaturesObject {
38
41
  /** @default true */
39
42
  perfectionist?: boolean;
40
43
  /** @default false */
44
+ react?: boolean;
45
+ /** @default false */
46
+ reactCompiler?: boolean;
47
+ /** @default false */
48
+ reactHooks?: boolean;
49
+ /** @default false */
41
50
  svelte?: boolean;
42
51
  /** @default false */
43
52
  tailwind?: boolean;
package/dist/index.js CHANGED
@@ -35,6 +35,12 @@ function isEnabled(config, feature) {
35
35
  switch (feature) {
36
36
  case "perfectionist":
37
37
  return config?.perfectionist ?? true;
38
+ case "react":
39
+ return config?.react ?? false;
40
+ case "reactCompiler":
41
+ return config?.reactCompiler ?? config?.react ?? false;
42
+ case "reactHooks":
43
+ return config?.reactHooks ?? config?.react ?? false;
38
44
  case "svelte":
39
45
  return config?.svelte ?? false;
40
46
  case "tailwind":
@@ -283,6 +289,55 @@ async function vue(options) {
283
289
  ];
284
290
  }
285
291
 
292
+ async function react(options) {
293
+ if (!isEnabled(options.features, "react")) return {};
294
+ const plugin = await interopDefault(import('eslint-plugin-react'));
295
+ return {
296
+ plugins: { react: plugin },
297
+ rules: {
298
+ "react/button-has-type": "error",
299
+ "react/function-component-definition": [
300
+ "error",
301
+ {
302
+ namedComponents: "function-expression",
303
+ unnamedComponents: "function-expression"
304
+ }
305
+ ],
306
+ "react/hook-use-state": ["error", { allowDestructuredState: true }],
307
+ "react/jsx-boolean-value": ["error", "never", { assumeUndefinedIsFalse: true }],
308
+ "react/jsx-key": [
309
+ "error",
310
+ {
311
+ checkFragmentShorthand: true,
312
+ checkKeyMustBeforeSpread: false,
313
+ warnOnDuplicates: true
314
+ }
315
+ ],
316
+ "react/jsx-no-script-url": "error",
317
+ "react/jsx-no-useless-fragment": "error",
318
+ "react/jsx-pascal-case": [
319
+ "error",
320
+ {
321
+ allowAllCaps: false,
322
+ allowNamespace: true,
323
+ allowLeadingUnderscore: false
324
+ }
325
+ ],
326
+ "react/jsx-props-no-spread-multi": "error",
327
+ "react/no-access-state-in-setstate": "error",
328
+ "react/no-array-index-key": "error",
329
+ "react/no-danger": "error",
330
+ "react/no-deprecated": "error",
331
+ "react/no-direct-mutation-state": "error",
332
+ "react/no-find-dom-node": "error",
333
+ "react/no-is-mounted": "error",
334
+ "react/no-render-return-value": "error",
335
+ "react/no-unsafe": "error",
336
+ ...options.overrides?.react
337
+ }
338
+ };
339
+ }
340
+
286
341
  async function svelte(options) {
287
342
  if (!isEnabled(options.features, "svelte")) return [];
288
343
  const [sveltePlugin, svelteParser, tsParser] = await Promise.all([
@@ -423,6 +478,11 @@ function javascript(options) {
423
478
  languageOptions: {
424
479
  ecmaVersion: "latest",
425
480
  sourceType: "module",
481
+ parserOptions: {
482
+ ecmaFeatures: {
483
+ jsx: isEnabled(options.features, "react")
484
+ }
485
+ },
426
486
  globals: {
427
487
  ...globals.browser,
428
488
  ...globals.es2021,
@@ -846,7 +906,10 @@ async function typescript(options) {
846
906
  parserOptions: {
847
907
  project: options.project,
848
908
  tsconfigRootDir: process.cwd(),
849
- extraFileExtensions
909
+ extraFileExtensions,
910
+ ecmaFeatures: {
911
+ jsx: isEnabled(options.features, "react")
912
+ }
850
913
  }
851
914
  },
852
915
  plugins: { "@typescript-eslint": tsPlugin },
@@ -963,6 +1026,7 @@ async function defineConfig(options) {
963
1026
  typescript(options),
964
1027
  ...await vue(options),
965
1028
  ...await svelte(options),
1029
+ react(options),
966
1030
  perfectionist(options),
967
1031
  unicorn(options),
968
1032
  tailwind(options),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tb-dev/eslint-config",
3
- "version": "6.0.6",
3
+ "version": "6.1.0",
4
4
  "description": "ESLint config",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -17,18 +17,23 @@
17
17
  "eslint",
18
18
  "eslint-config",
19
19
  "typescript",
20
+ "react",
21
+ "svelte",
20
22
  "vue"
21
23
  ],
22
24
  "dependencies": {
23
25
  "@typescript-eslint/eslint-plugin": "^8.19.1",
24
26
  "@typescript-eslint/parser": "^8.19.1",
25
27
  "eslint-plugin-perfectionist": "^4.6.0",
28
+ "eslint-plugin-react": "^7.37.3",
29
+ "eslint-plugin-react-compiler": "19.0.0-beta-63e3235-20250105",
30
+ "eslint-plugin-react-hooks": "^5.1.0",
26
31
  "eslint-plugin-svelte": "^3.0.0-next.10",
27
32
  "eslint-plugin-tailwindcss": "^3.17.5",
28
33
  "eslint-plugin-unicorn": "^56.0.1",
29
34
  "eslint-plugin-vue": "^9.32.0",
30
35
  "globals": "^15.14.0",
31
- "svelte": "^5.16.4",
36
+ "svelte": "^5.16.5",
32
37
  "svelte-eslint-parser": "^1.0.0-next.6",
33
38
  "vue-eslint-parser": "^9.4.3"
34
39
  },