@luxass/eslint-config 4.0.0-beta.4 → 4.0.0-beta.5

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,8 +1,8 @@
1
1
  # @luxass/eslint-config
2
2
 
3
3
  > [!IMPORTANT]
4
- > The configuration is not currently finished, and the old config should be used. You can find it [here](https://github.com/luxass/eslint-config-legacy)
5
-
4
+ > The configuration is not currently finished.
5
+ > I could change at any moment.
6
6
 
7
7
  ## ✨ Features
8
8
 
@@ -0,0 +1,277 @@
1
+ import {
2
+ GLOB_JSX
3
+ } from "./chunk-YPPGNIVG.mjs";
4
+ import {
5
+ interop
6
+ } from "./chunk-4VUK6ART.mjs";
7
+
8
+ // src/configs/react.ts
9
+ async function react(options) {
10
+ const [
11
+ pluginReact,
12
+ pluginReactHooks,
13
+ pluginReactRefresh,
14
+ pluginA11y
15
+ ] = await Promise.all([
16
+ interop(import("eslint-plugin-react")),
17
+ interop(import("eslint-plugin-react-hooks")),
18
+ interop(import("eslint-plugin-react-refresh")),
19
+ ...options.a11y ? [interop(import("eslint-plugin-jsx-a11y"))] : []
20
+ ]);
21
+ const {
22
+ a11y = false,
23
+ overrides = {},
24
+ typescript = true
25
+ } = options;
26
+ return [
27
+ {
28
+ name: "luxass:react:setup",
29
+ plugins: {
30
+ "react": pluginReact,
31
+ "react-hooks": pluginReactHooks,
32
+ "react-refresh": pluginReactRefresh,
33
+ ...a11y ? { "jsx-a11y": pluginA11y } : {}
34
+ }
35
+ },
36
+ {
37
+ files: [GLOB_JSX],
38
+ languageOptions: {
39
+ parserOptions: {
40
+ ecmaFeatures: {
41
+ jsx: true
42
+ }
43
+ }
44
+ },
45
+ name: "luxass:react:rules",
46
+ rules: {
47
+ // recommended rules for jsx-a11y
48
+ "jsx-a11y/alt-text": "error",
49
+ "jsx-a11y/anchor-ambiguous-text": "off",
50
+ "jsx-a11y/anchor-has-content": "error",
51
+ "jsx-a11y/anchor-is-valid": "error",
52
+ "jsx-a11y/aria-activedescendant-has-tabindex": "error",
53
+ "jsx-a11y/aria-props": "error",
54
+ "jsx-a11y/aria-proptypes": "error",
55
+ "jsx-a11y/aria-role": "error",
56
+ "jsx-a11y/aria-unsupported-elements": "error",
57
+ "jsx-a11y/autocomplete-valid": "error",
58
+ "jsx-a11y/click-events-have-key-events": "error",
59
+ "jsx-a11y/control-has-associated-label": [
60
+ "off",
61
+ {
62
+ ignoreElements: [
63
+ "audio",
64
+ "canvas",
65
+ "embed",
66
+ "input",
67
+ "textarea",
68
+ "tr",
69
+ "video"
70
+ ],
71
+ ignoreRoles: [
72
+ "grid",
73
+ "listbox",
74
+ "menu",
75
+ "menubar",
76
+ "radiogroup",
77
+ "row",
78
+ "tablist",
79
+ "toolbar",
80
+ "tree",
81
+ "treegrid"
82
+ ],
83
+ includeRoles: [
84
+ "alert",
85
+ "dialog"
86
+ ]
87
+ }
88
+ ],
89
+ "jsx-a11y/heading-has-content": "error",
90
+ "jsx-a11y/html-has-lang": "error",
91
+ "jsx-a11y/iframe-has-title": "error",
92
+ "jsx-a11y/img-redundant-alt": "error",
93
+ "jsx-a11y/interactive-supports-focus": [
94
+ "error",
95
+ {
96
+ tabbable: [
97
+ "button",
98
+ "checkbox",
99
+ "link",
100
+ "searchbox",
101
+ "spinbutton",
102
+ "switch",
103
+ "textbox"
104
+ ]
105
+ }
106
+ ],
107
+ "jsx-a11y/label-has-associated-control": "error",
108
+ "jsx-a11y/label-has-for": "off",
109
+ "jsx-a11y/media-has-caption": "error",
110
+ "jsx-a11y/mouse-events-have-key-events": "error",
111
+ "jsx-a11y/no-access-key": "error",
112
+ "jsx-a11y/no-autofocus": "error",
113
+ "jsx-a11y/no-distracting-elements": "error",
114
+ "jsx-a11y/no-interactive-element-to-noninteractive-role": [
115
+ "error",
116
+ {
117
+ canvas: [
118
+ "img"
119
+ ],
120
+ tr: [
121
+ "none",
122
+ "presentation"
123
+ ]
124
+ }
125
+ ],
126
+ "jsx-a11y/no-noninteractive-element-interactions": [
127
+ "error",
128
+ {
129
+ alert: [
130
+ "onKeyUp",
131
+ "onKeyDown",
132
+ "onKeyPress"
133
+ ],
134
+ body: [
135
+ "onError",
136
+ "onLoad"
137
+ ],
138
+ dialog: [
139
+ "onKeyUp",
140
+ "onKeyDown",
141
+ "onKeyPress"
142
+ ],
143
+ handlers: [
144
+ "onClick",
145
+ "onError",
146
+ "onLoad",
147
+ "onMouseDown",
148
+ "onMouseUp",
149
+ "onKeyPress",
150
+ "onKeyDown",
151
+ "onKeyUp"
152
+ ],
153
+ iframe: [
154
+ "onError",
155
+ "onLoad"
156
+ ],
157
+ img: [
158
+ "onError",
159
+ "onLoad"
160
+ ]
161
+ }
162
+ ],
163
+ "jsx-a11y/no-noninteractive-element-to-interactive-role": [
164
+ "error",
165
+ {
166
+ fieldset: [
167
+ "radiogroup",
168
+ "presentation"
169
+ ],
170
+ li: [
171
+ "menuitem",
172
+ "option",
173
+ "row",
174
+ "tab",
175
+ "treeitem"
176
+ ],
177
+ ol: [
178
+ "listbox",
179
+ "menu",
180
+ "menubar",
181
+ "radiogroup",
182
+ "tablist",
183
+ "tree",
184
+ "treegrid"
185
+ ],
186
+ table: [
187
+ "grid"
188
+ ],
189
+ td: [
190
+ "gridcell"
191
+ ],
192
+ ul: [
193
+ "listbox",
194
+ "menu",
195
+ "menubar",
196
+ "radiogroup",
197
+ "tablist",
198
+ "tree",
199
+ "treegrid"
200
+ ]
201
+ }
202
+ ],
203
+ "jsx-a11y/no-noninteractive-tabindex": [
204
+ "error",
205
+ {
206
+ allowExpressionValues: true,
207
+ roles: [
208
+ "tabpanel"
209
+ ],
210
+ tags: []
211
+ }
212
+ ],
213
+ "jsx-a11y/no-redundant-roles": "error",
214
+ "jsx-a11y/no-static-element-interactions": [
215
+ "error",
216
+ {
217
+ allowExpressionValues: true,
218
+ handlers: [
219
+ "onClick",
220
+ "onMouseDown",
221
+ "onMouseUp",
222
+ "onKeyPress",
223
+ "onKeyDown",
224
+ "onKeyUp"
225
+ ]
226
+ }
227
+ ],
228
+ "jsx-a11y/role-has-required-aria-props": "error",
229
+ "jsx-a11y/role-supports-aria-props": "error",
230
+ "jsx-a11y/scope": "error",
231
+ "jsx-a11y/tabindex-no-positive": "error",
232
+ // recommended rules react-hooks
233
+ "react-hooks/exhaustive-deps": "warn",
234
+ "react-hooks/rules-of-hooks": "error",
235
+ // react refresh
236
+ "react-refresh/only-export-components": ["warn", { allowConstantExport: true }],
237
+ // recommended rules react
238
+ "react/display-name": "error",
239
+ "react/jsx-key": "error",
240
+ "react/jsx-no-comment-textnodes": "error",
241
+ "react/jsx-no-duplicate-props": "error",
242
+ "react/jsx-no-target-blank": "error",
243
+ "react/jsx-no-undef": "error",
244
+ "react/jsx-uses-react": "error",
245
+ "react/jsx-uses-vars": "error",
246
+ "react/no-children-prop": "error",
247
+ "react/no-danger-with-children": "error",
248
+ "react/no-deprecated": "error",
249
+ "react/no-direct-mutation-state": "error",
250
+ "react/no-find-dom-node": "error",
251
+ "react/no-is-mounted": "error",
252
+ "react/no-render-return-value": "error",
253
+ "react/no-string-refs": "error",
254
+ "react/no-unescaped-entities": "error",
255
+ "react/no-unknown-property": "error",
256
+ "react/no-unsafe": "off",
257
+ "react/prop-types": "error",
258
+ "react/react-in-jsx-scope": "off",
259
+ "react/require-render-return": "error",
260
+ ...typescript ? {
261
+ "react/prop-type": "off"
262
+ } : {},
263
+ // overrides
264
+ ...overrides
265
+ },
266
+ settings: {
267
+ react: {
268
+ version: "detect"
269
+ }
270
+ }
271
+ }
272
+ ];
273
+ }
274
+
275
+ export {
276
+ react
277
+ };
@@ -1550,15 +1550,16 @@ async function nextjs(options = {}) {
1550
1550
  }
1551
1551
 
1552
1552
  // src/configs/react.ts
1553
- var import_globals2 = __toESM(require("globals"), 1);
1554
1553
  async function react(options) {
1555
1554
  const [
1556
1555
  pluginReact,
1557
1556
  pluginReactHooks,
1557
+ pluginReactRefresh,
1558
1558
  pluginA11y
1559
1559
  ] = await Promise.all([
1560
1560
  interop(import("eslint-plugin-react")),
1561
1561
  interop(import("eslint-plugin-react-hooks")),
1562
+ interop(import("eslint-plugin-react-refresh")),
1562
1563
  ...options.a11y ? [interop(import("eslint-plugin-jsx-a11y"))] : []
1563
1564
  ]);
1564
1565
  const {
@@ -1572,16 +1573,13 @@ async function react(options) {
1572
1573
  plugins: {
1573
1574
  "react": pluginReact,
1574
1575
  "react-hooks": pluginReactHooks,
1576
+ "react-refresh": pluginReactRefresh,
1575
1577
  ...a11y ? { "jsx-a11y": pluginA11y } : {}
1576
1578
  }
1577
1579
  },
1578
1580
  {
1579
1581
  files: [GLOB_JSX],
1580
1582
  languageOptions: {
1581
- ...pluginReact.configs.recommended.languageOptions,
1582
- globals: {
1583
- ...import_globals2.default.browser
1584
- },
1585
1583
  parserOptions: {
1586
1584
  ecmaFeatures: {
1587
1585
  jsx: true
@@ -1590,13 +1588,223 @@ async function react(options) {
1590
1588
  },
1591
1589
  name: "luxass:react:rules",
1592
1590
  rules: {
1593
- ...pluginReact.configs.recommended.rules,
1594
- ...pluginReactHooks.configs.recommended.rules,
1595
- ...a11y ? pluginA11y.configs.recommended.rules : {},
1591
+ // recommended rules for jsx-a11y
1592
+ "jsx-a11y/alt-text": "error",
1593
+ "jsx-a11y/anchor-ambiguous-text": "off",
1594
+ "jsx-a11y/anchor-has-content": "error",
1595
+ "jsx-a11y/anchor-is-valid": "error",
1596
+ "jsx-a11y/aria-activedescendant-has-tabindex": "error",
1597
+ "jsx-a11y/aria-props": "error",
1598
+ "jsx-a11y/aria-proptypes": "error",
1599
+ "jsx-a11y/aria-role": "error",
1600
+ "jsx-a11y/aria-unsupported-elements": "error",
1601
+ "jsx-a11y/autocomplete-valid": "error",
1602
+ "jsx-a11y/click-events-have-key-events": "error",
1603
+ "jsx-a11y/control-has-associated-label": [
1604
+ "off",
1605
+ {
1606
+ ignoreElements: [
1607
+ "audio",
1608
+ "canvas",
1609
+ "embed",
1610
+ "input",
1611
+ "textarea",
1612
+ "tr",
1613
+ "video"
1614
+ ],
1615
+ ignoreRoles: [
1616
+ "grid",
1617
+ "listbox",
1618
+ "menu",
1619
+ "menubar",
1620
+ "radiogroup",
1621
+ "row",
1622
+ "tablist",
1623
+ "toolbar",
1624
+ "tree",
1625
+ "treegrid"
1626
+ ],
1627
+ includeRoles: [
1628
+ "alert",
1629
+ "dialog"
1630
+ ]
1631
+ }
1632
+ ],
1633
+ "jsx-a11y/heading-has-content": "error",
1634
+ "jsx-a11y/html-has-lang": "error",
1635
+ "jsx-a11y/iframe-has-title": "error",
1636
+ "jsx-a11y/img-redundant-alt": "error",
1637
+ "jsx-a11y/interactive-supports-focus": [
1638
+ "error",
1639
+ {
1640
+ tabbable: [
1641
+ "button",
1642
+ "checkbox",
1643
+ "link",
1644
+ "searchbox",
1645
+ "spinbutton",
1646
+ "switch",
1647
+ "textbox"
1648
+ ]
1649
+ }
1650
+ ],
1651
+ "jsx-a11y/label-has-associated-control": "error",
1652
+ "jsx-a11y/label-has-for": "off",
1653
+ "jsx-a11y/media-has-caption": "error",
1654
+ "jsx-a11y/mouse-events-have-key-events": "error",
1655
+ "jsx-a11y/no-access-key": "error",
1656
+ "jsx-a11y/no-autofocus": "error",
1657
+ "jsx-a11y/no-distracting-elements": "error",
1658
+ "jsx-a11y/no-interactive-element-to-noninteractive-role": [
1659
+ "error",
1660
+ {
1661
+ canvas: [
1662
+ "img"
1663
+ ],
1664
+ tr: [
1665
+ "none",
1666
+ "presentation"
1667
+ ]
1668
+ }
1669
+ ],
1670
+ "jsx-a11y/no-noninteractive-element-interactions": [
1671
+ "error",
1672
+ {
1673
+ alert: [
1674
+ "onKeyUp",
1675
+ "onKeyDown",
1676
+ "onKeyPress"
1677
+ ],
1678
+ body: [
1679
+ "onError",
1680
+ "onLoad"
1681
+ ],
1682
+ dialog: [
1683
+ "onKeyUp",
1684
+ "onKeyDown",
1685
+ "onKeyPress"
1686
+ ],
1687
+ handlers: [
1688
+ "onClick",
1689
+ "onError",
1690
+ "onLoad",
1691
+ "onMouseDown",
1692
+ "onMouseUp",
1693
+ "onKeyPress",
1694
+ "onKeyDown",
1695
+ "onKeyUp"
1696
+ ],
1697
+ iframe: [
1698
+ "onError",
1699
+ "onLoad"
1700
+ ],
1701
+ img: [
1702
+ "onError",
1703
+ "onLoad"
1704
+ ]
1705
+ }
1706
+ ],
1707
+ "jsx-a11y/no-noninteractive-element-to-interactive-role": [
1708
+ "error",
1709
+ {
1710
+ fieldset: [
1711
+ "radiogroup",
1712
+ "presentation"
1713
+ ],
1714
+ li: [
1715
+ "menuitem",
1716
+ "option",
1717
+ "row",
1718
+ "tab",
1719
+ "treeitem"
1720
+ ],
1721
+ ol: [
1722
+ "listbox",
1723
+ "menu",
1724
+ "menubar",
1725
+ "radiogroup",
1726
+ "tablist",
1727
+ "tree",
1728
+ "treegrid"
1729
+ ],
1730
+ table: [
1731
+ "grid"
1732
+ ],
1733
+ td: [
1734
+ "gridcell"
1735
+ ],
1736
+ ul: [
1737
+ "listbox",
1738
+ "menu",
1739
+ "menubar",
1740
+ "radiogroup",
1741
+ "tablist",
1742
+ "tree",
1743
+ "treegrid"
1744
+ ]
1745
+ }
1746
+ ],
1747
+ "jsx-a11y/no-noninteractive-tabindex": [
1748
+ "error",
1749
+ {
1750
+ allowExpressionValues: true,
1751
+ roles: [
1752
+ "tabpanel"
1753
+ ],
1754
+ tags: []
1755
+ }
1756
+ ],
1757
+ "jsx-a11y/no-redundant-roles": "error",
1758
+ "jsx-a11y/no-static-element-interactions": [
1759
+ "error",
1760
+ {
1761
+ allowExpressionValues: true,
1762
+ handlers: [
1763
+ "onClick",
1764
+ "onMouseDown",
1765
+ "onMouseUp",
1766
+ "onKeyPress",
1767
+ "onKeyDown",
1768
+ "onKeyUp"
1769
+ ]
1770
+ }
1771
+ ],
1772
+ "jsx-a11y/role-has-required-aria-props": "error",
1773
+ "jsx-a11y/role-supports-aria-props": "error",
1774
+ "jsx-a11y/scope": "error",
1775
+ "jsx-a11y/tabindex-no-positive": "error",
1776
+ // recommended rules react-hooks
1777
+ "react-hooks/exhaustive-deps": "warn",
1778
+ "react-hooks/rules-of-hooks": "error",
1779
+ // react refresh
1780
+ "react-refresh/only-export-components": ["warn", { allowConstantExport: true }],
1781
+ // recommended rules react
1782
+ "react/display-name": "error",
1783
+ "react/jsx-key": "error",
1784
+ "react/jsx-no-comment-textnodes": "error",
1785
+ "react/jsx-no-duplicate-props": "error",
1786
+ "react/jsx-no-target-blank": "error",
1787
+ "react/jsx-no-undef": "error",
1788
+ "react/jsx-uses-react": "error",
1789
+ "react/jsx-uses-vars": "error",
1790
+ "react/no-children-prop": "error",
1791
+ "react/no-danger-with-children": "error",
1792
+ "react/no-deprecated": "error",
1793
+ "react/no-direct-mutation-state": "error",
1794
+ "react/no-find-dom-node": "error",
1795
+ "react/no-is-mounted": "error",
1796
+ "react/no-render-return-value": "error",
1797
+ "react/no-string-refs": "error",
1798
+ "react/no-unescaped-entities": "error",
1799
+ "react/no-unknown-property": "error",
1800
+ "react/no-unsafe": "off",
1801
+ "react/prop-types": "error",
1596
1802
  "react/react-in-jsx-scope": "off",
1803
+ "react/require-render-return": "error",
1597
1804
  ...typescript2 ? {
1598
1805
  "react/prop-type": "off"
1599
1806
  } : {},
1807
+ // overrides
1600
1808
  ...overrides
1601
1809
  },
1602
1810
  settings: {
@@ -37,7 +37,7 @@ import {
37
37
  } from "../chunk-HLDEUDLN.mjs";
38
38
  import {
39
39
  react
40
- } from "../chunk-2TYG7WFX.mjs";
40
+ } from "../chunk-TJ6SQTNG.mjs";
41
41
  import {
42
42
  sortPackageJson,
43
43
  sortTsconfig
@@ -33,7 +33,6 @@ __export(react_exports, {
33
33
  react: () => react
34
34
  });
35
35
  module.exports = __toCommonJS(react_exports);
36
- var import_globals = __toESM(require("globals"), 1);
37
36
 
38
37
  // src/globs.ts
39
38
  var GLOB_SRC_EXT = "?([cm])[jt]s?(x)";
@@ -77,10 +76,12 @@ async function react(options) {
77
76
  const [
78
77
  pluginReact,
79
78
  pluginReactHooks,
79
+ pluginReactRefresh,
80
80
  pluginA11y
81
81
  ] = await Promise.all([
82
82
  interop(import("eslint-plugin-react")),
83
83
  interop(import("eslint-plugin-react-hooks")),
84
+ interop(import("eslint-plugin-react-refresh")),
84
85
  ...options.a11y ? [interop(import("eslint-plugin-jsx-a11y"))] : []
85
86
  ]);
86
87
  const {
@@ -94,16 +95,13 @@ async function react(options) {
94
95
  plugins: {
95
96
  "react": pluginReact,
96
97
  "react-hooks": pluginReactHooks,
98
+ "react-refresh": pluginReactRefresh,
97
99
  ...a11y ? { "jsx-a11y": pluginA11y } : {}
98
100
  }
99
101
  },
100
102
  {
101
103
  files: [GLOB_JSX],
102
104
  languageOptions: {
103
- ...pluginReact.configs.recommended.languageOptions,
104
- globals: {
105
- ...import_globals.default.browser
106
- },
107
105
  parserOptions: {
108
106
  ecmaFeatures: {
109
107
  jsx: true
@@ -112,13 +110,223 @@ async function react(options) {
112
110
  },
113
111
  name: "luxass:react:rules",
114
112
  rules: {
115
- ...pluginReact.configs.recommended.rules,
116
- ...pluginReactHooks.configs.recommended.rules,
117
- ...a11y ? pluginA11y.configs.recommended.rules : {},
113
+ // recommended rules for jsx-a11y
114
+ "jsx-a11y/alt-text": "error",
115
+ "jsx-a11y/anchor-ambiguous-text": "off",
116
+ "jsx-a11y/anchor-has-content": "error",
117
+ "jsx-a11y/anchor-is-valid": "error",
118
+ "jsx-a11y/aria-activedescendant-has-tabindex": "error",
119
+ "jsx-a11y/aria-props": "error",
120
+ "jsx-a11y/aria-proptypes": "error",
121
+ "jsx-a11y/aria-role": "error",
122
+ "jsx-a11y/aria-unsupported-elements": "error",
123
+ "jsx-a11y/autocomplete-valid": "error",
124
+ "jsx-a11y/click-events-have-key-events": "error",
125
+ "jsx-a11y/control-has-associated-label": [
126
+ "off",
127
+ {
128
+ ignoreElements: [
129
+ "audio",
130
+ "canvas",
131
+ "embed",
132
+ "input",
133
+ "textarea",
134
+ "tr",
135
+ "video"
136
+ ],
137
+ ignoreRoles: [
138
+ "grid",
139
+ "listbox",
140
+ "menu",
141
+ "menubar",
142
+ "radiogroup",
143
+ "row",
144
+ "tablist",
145
+ "toolbar",
146
+ "tree",
147
+ "treegrid"
148
+ ],
149
+ includeRoles: [
150
+ "alert",
151
+ "dialog"
152
+ ]
153
+ }
154
+ ],
155
+ "jsx-a11y/heading-has-content": "error",
156
+ "jsx-a11y/html-has-lang": "error",
157
+ "jsx-a11y/iframe-has-title": "error",
158
+ "jsx-a11y/img-redundant-alt": "error",
159
+ "jsx-a11y/interactive-supports-focus": [
160
+ "error",
161
+ {
162
+ tabbable: [
163
+ "button",
164
+ "checkbox",
165
+ "link",
166
+ "searchbox",
167
+ "spinbutton",
168
+ "switch",
169
+ "textbox"
170
+ ]
171
+ }
172
+ ],
173
+ "jsx-a11y/label-has-associated-control": "error",
174
+ "jsx-a11y/label-has-for": "off",
175
+ "jsx-a11y/media-has-caption": "error",
176
+ "jsx-a11y/mouse-events-have-key-events": "error",
177
+ "jsx-a11y/no-access-key": "error",
178
+ "jsx-a11y/no-autofocus": "error",
179
+ "jsx-a11y/no-distracting-elements": "error",
180
+ "jsx-a11y/no-interactive-element-to-noninteractive-role": [
181
+ "error",
182
+ {
183
+ canvas: [
184
+ "img"
185
+ ],
186
+ tr: [
187
+ "none",
188
+ "presentation"
189
+ ]
190
+ }
191
+ ],
192
+ "jsx-a11y/no-noninteractive-element-interactions": [
193
+ "error",
194
+ {
195
+ alert: [
196
+ "onKeyUp",
197
+ "onKeyDown",
198
+ "onKeyPress"
199
+ ],
200
+ body: [
201
+ "onError",
202
+ "onLoad"
203
+ ],
204
+ dialog: [
205
+ "onKeyUp",
206
+ "onKeyDown",
207
+ "onKeyPress"
208
+ ],
209
+ handlers: [
210
+ "onClick",
211
+ "onError",
212
+ "onLoad",
213
+ "onMouseDown",
214
+ "onMouseUp",
215
+ "onKeyPress",
216
+ "onKeyDown",
217
+ "onKeyUp"
218
+ ],
219
+ iframe: [
220
+ "onError",
221
+ "onLoad"
222
+ ],
223
+ img: [
224
+ "onError",
225
+ "onLoad"
226
+ ]
227
+ }
228
+ ],
229
+ "jsx-a11y/no-noninteractive-element-to-interactive-role": [
230
+ "error",
231
+ {
232
+ fieldset: [
233
+ "radiogroup",
234
+ "presentation"
235
+ ],
236
+ li: [
237
+ "menuitem",
238
+ "option",
239
+ "row",
240
+ "tab",
241
+ "treeitem"
242
+ ],
243
+ ol: [
244
+ "listbox",
245
+ "menu",
246
+ "menubar",
247
+ "radiogroup",
248
+ "tablist",
249
+ "tree",
250
+ "treegrid"
251
+ ],
252
+ table: [
253
+ "grid"
254
+ ],
255
+ td: [
256
+ "gridcell"
257
+ ],
258
+ ul: [
259
+ "listbox",
260
+ "menu",
261
+ "menubar",
262
+ "radiogroup",
263
+ "tablist",
264
+ "tree",
265
+ "treegrid"
266
+ ]
267
+ }
268
+ ],
269
+ "jsx-a11y/no-noninteractive-tabindex": [
270
+ "error",
271
+ {
272
+ allowExpressionValues: true,
273
+ roles: [
274
+ "tabpanel"
275
+ ],
276
+ tags: []
277
+ }
278
+ ],
279
+ "jsx-a11y/no-redundant-roles": "error",
280
+ "jsx-a11y/no-static-element-interactions": [
281
+ "error",
282
+ {
283
+ allowExpressionValues: true,
284
+ handlers: [
285
+ "onClick",
286
+ "onMouseDown",
287
+ "onMouseUp",
288
+ "onKeyPress",
289
+ "onKeyDown",
290
+ "onKeyUp"
291
+ ]
292
+ }
293
+ ],
294
+ "jsx-a11y/role-has-required-aria-props": "error",
295
+ "jsx-a11y/role-supports-aria-props": "error",
296
+ "jsx-a11y/scope": "error",
297
+ "jsx-a11y/tabindex-no-positive": "error",
298
+ // recommended rules react-hooks
299
+ "react-hooks/exhaustive-deps": "warn",
300
+ "react-hooks/rules-of-hooks": "error",
301
+ // react refresh
302
+ "react-refresh/only-export-components": ["warn", { allowConstantExport: true }],
303
+ // recommended rules react
304
+ "react/display-name": "error",
305
+ "react/jsx-key": "error",
306
+ "react/jsx-no-comment-textnodes": "error",
307
+ "react/jsx-no-duplicate-props": "error",
308
+ "react/jsx-no-target-blank": "error",
309
+ "react/jsx-no-undef": "error",
310
+ "react/jsx-uses-react": "error",
311
+ "react/jsx-uses-vars": "error",
312
+ "react/no-children-prop": "error",
313
+ "react/no-danger-with-children": "error",
314
+ "react/no-deprecated": "error",
315
+ "react/no-direct-mutation-state": "error",
316
+ "react/no-find-dom-node": "error",
317
+ "react/no-is-mounted": "error",
318
+ "react/no-render-return-value": "error",
319
+ "react/no-string-refs": "error",
320
+ "react/no-unescaped-entities": "error",
321
+ "react/no-unknown-property": "error",
322
+ "react/no-unsafe": "off",
323
+ "react/prop-types": "error",
118
324
  "react/react-in-jsx-scope": "off",
325
+ "react/require-render-return": "error",
119
326
  ...typescript ? {
120
327
  "react/prop-type": "off"
121
328
  } : {},
329
+ // overrides
122
330
  ...overrides
123
331
  },
124
332
  settings: {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  react
3
- } from "../chunk-2TYG7WFX.mjs";
3
+ } from "../chunk-TJ6SQTNG.mjs";
4
4
  import "../chunk-YPPGNIVG.mjs";
5
5
  import "../chunk-4VUK6ART.mjs";
6
6
  export {
package/dist/index.cjs CHANGED
@@ -1584,15 +1584,16 @@ async function nextjs(options = {}) {
1584
1584
  }
1585
1585
 
1586
1586
  // src/configs/react.ts
1587
- var import_globals2 = __toESM(require("globals"), 1);
1588
1587
  async function react(options) {
1589
1588
  const [
1590
1589
  pluginReact,
1591
1590
  pluginReactHooks,
1591
+ pluginReactRefresh,
1592
1592
  pluginA11y
1593
1593
  ] = await Promise.all([
1594
1594
  interop(import("eslint-plugin-react")),
1595
1595
  interop(import("eslint-plugin-react-hooks")),
1596
+ interop(import("eslint-plugin-react-refresh")),
1596
1597
  ...options.a11y ? [interop(import("eslint-plugin-jsx-a11y"))] : []
1597
1598
  ]);
1598
1599
  const {
@@ -1606,16 +1607,13 @@ async function react(options) {
1606
1607
  plugins: {
1607
1608
  "react": pluginReact,
1608
1609
  "react-hooks": pluginReactHooks,
1610
+ "react-refresh": pluginReactRefresh,
1609
1611
  ...a11y ? { "jsx-a11y": pluginA11y } : {}
1610
1612
  }
1611
1613
  },
1612
1614
  {
1613
1615
  files: [GLOB_JSX],
1614
1616
  languageOptions: {
1615
- ...pluginReact.configs.recommended.languageOptions,
1616
- globals: {
1617
- ...import_globals2.default.browser
1618
- },
1619
1617
  parserOptions: {
1620
1618
  ecmaFeatures: {
1621
1619
  jsx: true
@@ -1624,13 +1622,223 @@ async function react(options) {
1624
1622
  },
1625
1623
  name: "luxass:react:rules",
1626
1624
  rules: {
1627
- ...pluginReact.configs.recommended.rules,
1628
- ...pluginReactHooks.configs.recommended.rules,
1629
- ...a11y ? pluginA11y.configs.recommended.rules : {},
1625
+ // recommended rules for jsx-a11y
1626
+ "jsx-a11y/alt-text": "error",
1627
+ "jsx-a11y/anchor-ambiguous-text": "off",
1628
+ "jsx-a11y/anchor-has-content": "error",
1629
+ "jsx-a11y/anchor-is-valid": "error",
1630
+ "jsx-a11y/aria-activedescendant-has-tabindex": "error",
1631
+ "jsx-a11y/aria-props": "error",
1632
+ "jsx-a11y/aria-proptypes": "error",
1633
+ "jsx-a11y/aria-role": "error",
1634
+ "jsx-a11y/aria-unsupported-elements": "error",
1635
+ "jsx-a11y/autocomplete-valid": "error",
1636
+ "jsx-a11y/click-events-have-key-events": "error",
1637
+ "jsx-a11y/control-has-associated-label": [
1638
+ "off",
1639
+ {
1640
+ ignoreElements: [
1641
+ "audio",
1642
+ "canvas",
1643
+ "embed",
1644
+ "input",
1645
+ "textarea",
1646
+ "tr",
1647
+ "video"
1648
+ ],
1649
+ ignoreRoles: [
1650
+ "grid",
1651
+ "listbox",
1652
+ "menu",
1653
+ "menubar",
1654
+ "radiogroup",
1655
+ "row",
1656
+ "tablist",
1657
+ "toolbar",
1658
+ "tree",
1659
+ "treegrid"
1660
+ ],
1661
+ includeRoles: [
1662
+ "alert",
1663
+ "dialog"
1664
+ ]
1665
+ }
1666
+ ],
1667
+ "jsx-a11y/heading-has-content": "error",
1668
+ "jsx-a11y/html-has-lang": "error",
1669
+ "jsx-a11y/iframe-has-title": "error",
1670
+ "jsx-a11y/img-redundant-alt": "error",
1671
+ "jsx-a11y/interactive-supports-focus": [
1672
+ "error",
1673
+ {
1674
+ tabbable: [
1675
+ "button",
1676
+ "checkbox",
1677
+ "link",
1678
+ "searchbox",
1679
+ "spinbutton",
1680
+ "switch",
1681
+ "textbox"
1682
+ ]
1683
+ }
1684
+ ],
1685
+ "jsx-a11y/label-has-associated-control": "error",
1686
+ "jsx-a11y/label-has-for": "off",
1687
+ "jsx-a11y/media-has-caption": "error",
1688
+ "jsx-a11y/mouse-events-have-key-events": "error",
1689
+ "jsx-a11y/no-access-key": "error",
1690
+ "jsx-a11y/no-autofocus": "error",
1691
+ "jsx-a11y/no-distracting-elements": "error",
1692
+ "jsx-a11y/no-interactive-element-to-noninteractive-role": [
1693
+ "error",
1694
+ {
1695
+ canvas: [
1696
+ "img"
1697
+ ],
1698
+ tr: [
1699
+ "none",
1700
+ "presentation"
1701
+ ]
1702
+ }
1703
+ ],
1704
+ "jsx-a11y/no-noninteractive-element-interactions": [
1705
+ "error",
1706
+ {
1707
+ alert: [
1708
+ "onKeyUp",
1709
+ "onKeyDown",
1710
+ "onKeyPress"
1711
+ ],
1712
+ body: [
1713
+ "onError",
1714
+ "onLoad"
1715
+ ],
1716
+ dialog: [
1717
+ "onKeyUp",
1718
+ "onKeyDown",
1719
+ "onKeyPress"
1720
+ ],
1721
+ handlers: [
1722
+ "onClick",
1723
+ "onError",
1724
+ "onLoad",
1725
+ "onMouseDown",
1726
+ "onMouseUp",
1727
+ "onKeyPress",
1728
+ "onKeyDown",
1729
+ "onKeyUp"
1730
+ ],
1731
+ iframe: [
1732
+ "onError",
1733
+ "onLoad"
1734
+ ],
1735
+ img: [
1736
+ "onError",
1737
+ "onLoad"
1738
+ ]
1739
+ }
1740
+ ],
1741
+ "jsx-a11y/no-noninteractive-element-to-interactive-role": [
1742
+ "error",
1743
+ {
1744
+ fieldset: [
1745
+ "radiogroup",
1746
+ "presentation"
1747
+ ],
1748
+ li: [
1749
+ "menuitem",
1750
+ "option",
1751
+ "row",
1752
+ "tab",
1753
+ "treeitem"
1754
+ ],
1755
+ ol: [
1756
+ "listbox",
1757
+ "menu",
1758
+ "menubar",
1759
+ "radiogroup",
1760
+ "tablist",
1761
+ "tree",
1762
+ "treegrid"
1763
+ ],
1764
+ table: [
1765
+ "grid"
1766
+ ],
1767
+ td: [
1768
+ "gridcell"
1769
+ ],
1770
+ ul: [
1771
+ "listbox",
1772
+ "menu",
1773
+ "menubar",
1774
+ "radiogroup",
1775
+ "tablist",
1776
+ "tree",
1777
+ "treegrid"
1778
+ ]
1779
+ }
1780
+ ],
1781
+ "jsx-a11y/no-noninteractive-tabindex": [
1782
+ "error",
1783
+ {
1784
+ allowExpressionValues: true,
1785
+ roles: [
1786
+ "tabpanel"
1787
+ ],
1788
+ tags: []
1789
+ }
1790
+ ],
1791
+ "jsx-a11y/no-redundant-roles": "error",
1792
+ "jsx-a11y/no-static-element-interactions": [
1793
+ "error",
1794
+ {
1795
+ allowExpressionValues: true,
1796
+ handlers: [
1797
+ "onClick",
1798
+ "onMouseDown",
1799
+ "onMouseUp",
1800
+ "onKeyPress",
1801
+ "onKeyDown",
1802
+ "onKeyUp"
1803
+ ]
1804
+ }
1805
+ ],
1806
+ "jsx-a11y/role-has-required-aria-props": "error",
1807
+ "jsx-a11y/role-supports-aria-props": "error",
1808
+ "jsx-a11y/scope": "error",
1809
+ "jsx-a11y/tabindex-no-positive": "error",
1810
+ // recommended rules react-hooks
1811
+ "react-hooks/exhaustive-deps": "warn",
1812
+ "react-hooks/rules-of-hooks": "error",
1813
+ // react refresh
1814
+ "react-refresh/only-export-components": ["warn", { allowConstantExport: true }],
1815
+ // recommended rules react
1816
+ "react/display-name": "error",
1817
+ "react/jsx-key": "error",
1818
+ "react/jsx-no-comment-textnodes": "error",
1819
+ "react/jsx-no-duplicate-props": "error",
1820
+ "react/jsx-no-target-blank": "error",
1821
+ "react/jsx-no-undef": "error",
1822
+ "react/jsx-uses-react": "error",
1823
+ "react/jsx-uses-vars": "error",
1824
+ "react/no-children-prop": "error",
1825
+ "react/no-danger-with-children": "error",
1826
+ "react/no-deprecated": "error",
1827
+ "react/no-direct-mutation-state": "error",
1828
+ "react/no-find-dom-node": "error",
1829
+ "react/no-is-mounted": "error",
1830
+ "react/no-render-return-value": "error",
1831
+ "react/no-string-refs": "error",
1832
+ "react/no-unescaped-entities": "error",
1833
+ "react/no-unknown-property": "error",
1834
+ "react/no-unsafe": "off",
1835
+ "react/prop-types": "error",
1630
1836
  "react/react-in-jsx-scope": "off",
1837
+ "react/require-render-return": "error",
1631
1838
  ...typescript2 ? {
1632
1839
  "react/prop-type": "off"
1633
1840
  } : {},
1841
+ // overrides
1634
1842
  ...overrides
1635
1843
  },
1636
1844
  settings: {
package/dist/index.mjs CHANGED
@@ -37,7 +37,7 @@ import {
37
37
  } from "./chunk-HLDEUDLN.mjs";
38
38
  import {
39
39
  react
40
- } from "./chunk-2TYG7WFX.mjs";
40
+ } from "./chunk-TJ6SQTNG.mjs";
41
41
  import {
42
42
  sortPackageJson,
43
43
  sortTsconfig
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@luxass/eslint-config",
3
3
  "type": "module",
4
- "version": "4.0.0-beta.4",
4
+ "version": "4.0.0-beta.5",
5
5
  "packageManager": "pnpm@8.10.5",
6
6
  "description": "ESLint config for @luxass",
7
7
  "author": {
@@ -70,14 +70,35 @@
70
70
  "typecheck": "tsc --noEmit"
71
71
  },
72
72
  "peerDependencies": {
73
- "eslint": ">=8.0.0"
73
+ "@next/eslint-plugin-next": "^14.0.3",
74
+ "eslint": ">=8.0.0",
75
+ "eslint-plugin-react": "^7.33.2",
76
+ "eslint-plugin-react-hooks": "^4.6.0",
77
+ "eslint-plugin-react-refresh": "^0.4.4",
78
+ "eslint-plugin-tailwindcss": "^3.13.0"
79
+ },
80
+ "peerDependenciesMeta": {
81
+ "eslint-plugin-react": {
82
+ "optional": true
83
+ },
84
+ "eslint-plugin-react-hooks": {
85
+ "optional": true
86
+ },
87
+ "eslint-plugin-react-refresh": {
88
+ "optional": true
89
+ },
90
+ "@next/eslint-plugin-next": {
91
+ "optional": true
92
+ },
93
+ "eslint-plugin-tailwindcss": {
94
+ "optional": true
95
+ }
74
96
  },
75
97
  "dependencies": {
76
98
  "@antfu/eslint-define-config": "^1.23.0-2",
77
99
  "@eslint-types/jsdoc": "46.9.0",
78
100
  "@eslint-types/typescript-eslint": "^6.11.0",
79
101
  "@eslint-types/unicorn": "^49.0.0",
80
- "@next/eslint-plugin-next": "^14.0.3",
81
102
  "@stylistic/eslint-plugin": "^1.3.2",
82
103
  "@typescript-eslint/eslint-plugin": "^6.11.0",
83
104
  "@typescript-eslint/parser": "^6.11.0",
@@ -95,10 +116,7 @@
95
116
  "eslint-plugin-n": "^16.3.1",
96
117
  "eslint-plugin-no-only-tests": "^3.1.0",
97
118
  "eslint-plugin-perfectionist": "^2.4.0",
98
- "eslint-plugin-react": "^7.33.2",
99
- "eslint-plugin-react-hooks": "^4.6.0",
100
119
  "eslint-plugin-sort-keys": "^2.3.5",
101
- "eslint-plugin-tailwindcss": "^3.13.0",
102
120
  "eslint-plugin-unicorn": "^49.0.0",
103
121
  "eslint-plugin-unused-imports": "^3.0.0",
104
122
  "eslint-plugin-vitest": "^0.3.9",
@@ -1,69 +0,0 @@
1
- import {
2
- GLOB_JSX
3
- } from "./chunk-YPPGNIVG.mjs";
4
- import {
5
- interop
6
- } from "./chunk-4VUK6ART.mjs";
7
-
8
- // src/configs/react.ts
9
- import globals from "globals";
10
- async function react(options) {
11
- const [
12
- pluginReact,
13
- pluginReactHooks,
14
- pluginA11y
15
- ] = await Promise.all([
16
- interop(import("eslint-plugin-react")),
17
- interop(import("eslint-plugin-react-hooks")),
18
- ...options.a11y ? [interop(import("eslint-plugin-jsx-a11y"))] : []
19
- ]);
20
- const {
21
- a11y = false,
22
- overrides = {},
23
- typescript = true
24
- } = options;
25
- return [
26
- {
27
- name: "luxass:react:setup",
28
- plugins: {
29
- "react": pluginReact,
30
- "react-hooks": pluginReactHooks,
31
- ...a11y ? { "jsx-a11y": pluginA11y } : {}
32
- }
33
- },
34
- {
35
- files: [GLOB_JSX],
36
- languageOptions: {
37
- ...pluginReact.configs.recommended.languageOptions,
38
- globals: {
39
- ...globals.browser
40
- },
41
- parserOptions: {
42
- ecmaFeatures: {
43
- jsx: true
44
- }
45
- }
46
- },
47
- name: "luxass:react:rules",
48
- rules: {
49
- ...pluginReact.configs.recommended.rules,
50
- ...pluginReactHooks.configs.recommended.rules,
51
- ...a11y ? pluginA11y.configs.recommended.rules : {},
52
- "react/react-in-jsx-scope": "off",
53
- ...typescript ? {
54
- "react/prop-type": "off"
55
- } : {},
56
- ...overrides
57
- },
58
- settings: {
59
- react: {
60
- version: "detect"
61
- }
62
- }
63
- }
64
- ];
65
- }
66
-
67
- export {
68
- react
69
- };