eslint-plugin-react-x 2.7.4-next.5 โ†’ 2.7.4-next.7

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
@@ -36,6 +36,85 @@ export default defineConfig(
36
36
  );
37
37
  ```
38
38
 
39
+ ## JSX Rules
40
+
41
+ > [!NOTE]
42
+ > The `jsx-*` rules check for issues exclusive to JSX syntax, which are absent from standard JavaScript (like handwritten `createElement()` calls).
43
+
44
+ **Key Rules:**
45
+
46
+ - `jsx-dollar` - Prevents unnecessary `$` symbols before `JSX` expressions
47
+ - `jsx-key-before-spread` - Enforces `key` prop placement before spread operators
48
+ - `jsx-no-comment-textnodes` - Prevents comments from rendering as text
49
+ - `jsx-no-duplicate-props` - Disallows duplicate `props` in elements
50
+ - `jsx-no-iife` - Disallows immediately-invoked function expressions in `JSX`
51
+ - `jsx-no-undef` - Disallows undefined variables in `JSX` elements
52
+ - `jsx-shorthand-boolean` - Enforces shorthand for boolean attributes (๐Ÿ”ง Fixable, โš™๏ธ Configurable)
53
+ - `jsx-shorthand-fragment` - Enforces `<>` over `<React.Fragment>` (๐Ÿ”ง Fixable, โš™๏ธ Configurable)
54
+ - `jsx-uses-react` - Marks `React` as used when `JSX` is present
55
+ - `jsx-uses-vars` - Marks `JSX` element variables as used
56
+
57
+ ## Component Rules
58
+
59
+ > [!NOTE]
60
+ > Component rules enforce best practices and prevent common mistakes in `React` component definitions, covering both class and function components.
61
+
62
+ **Key Rule Groups:**
63
+
64
+ **Lifecycle & Deprecated APIs:**
65
+
66
+ - `no-component-will-mount` - Replaces `componentWillMount` with `UNSAFE_componentWillMount` (๐Ÿ”„ Codemod, `React` >=16.3.0)
67
+ - `no-component-will-receive-props` - Replaces `componentWillReceiveProps` with `UNSAFE_componentWillReceiveProps` (๐Ÿ”„ Codemod)
68
+ - `no-component-will-update` - Replaces `componentWillUpdate` with `UNSAFE_componentWillUpdate` (๐Ÿ”„ Codemod)
69
+ - `no-unsafe-component-will-mount` - Warns about `UNSAFE_componentWillMount` usage
70
+ - `no-unsafe-component-will-receive-props` - Warns about `UNSAFE_componentWillReceiveProps` usage
71
+ - `no-unsafe-component-will-update` - Warns about `UNSAFE_componentWillUpdate` usage
72
+
73
+ **React 19 Migrations:**
74
+
75
+ - `no-context-provider` - Replaces `<Context.Provider>` with `<Context>` (๐Ÿ”„ Codemod, `React` >=19.0.0)
76
+ - `no-forward-ref` - Replaces `forwardRef` with `ref` as prop (๐Ÿ”„ Codemod, `React` >=19.0.0)
77
+ - `no-use-context` - Replaces `useContext` with `use` (๐Ÿ”„ Codemod, `React` >=19.0.0)
78
+
79
+ **Component Structure:**
80
+
81
+ - `no-nested-component-definitions` - Prevents defining components inside other components
82
+ - `no-nested-lazy-component-declarations` - Prevents lazy component declarations inside components
83
+ - `no-class-component` - Disallows class components except error boundaries
84
+
85
+ **State Management:**
86
+
87
+ - `no-access-state-in-setstate` - Prevents `this.state` access inside `setState` calls
88
+ - `no-direct-mutation-state` - Prevents direct `this.state` mutation
89
+ - `no-set-state-in-component-did-mount` - Restricts `setState` in `componentDidMount`
90
+ - `no-set-state-in-component-did-update` - Restricts `setState` in `componentDidUpdate`
91
+ - `no-set-state-in-component-will-update` - Restricts `setState` in `componentWillUpdate`
92
+
93
+ **Props & Keys:**
94
+
95
+ - `no-missing-key` - Requires `key` prop in list renderings
96
+ - `no-duplicate-key` - Prevents duplicate `key` values
97
+ - `no-implicit-key` - Prevents implicit `key` spreading (๐Ÿงช Experimental)
98
+ - `no-unnecessary-key` - Prevents `key` on non-list elements (๐Ÿงช Experimental)
99
+ - `no-array-index-key` - Warns against using array indices as `keys`
100
+
101
+ **Children API:**
102
+
103
+ - `no-children-count` - Disallows `Children.count`
104
+ - `no-children-for-each` - Disallows `Children.forEach`
105
+ - `no-children-map` - Disallows `Children.map`
106
+ - `no-children-only` - Disallows `Children.only`
107
+ - `no-children-to-array` - Disallows `Children.toArray`
108
+ - `no-children-prop` - Disallows passing `children` as prop
109
+
110
+ **Performance & Optimization:**
111
+
112
+ - `no-unstable-context-value` - Prevents unstable values in `Context.Provider`
113
+ - `no-unstable-default-props` - Prevents referential values as default `props`
114
+ - `no-unnecessary-use-callback` - Warns about unnecessary `useCallback` usage (๐Ÿงช Experimental)
115
+ - `no-unnecessary-use-memo` - Warns about unnecessary `useMemo` usage (๐Ÿงช Experimental)
116
+ - `prefer-use-state-lazy-initialization` - Enforces lazy initialization in `useState`
117
+
39
118
  ## Rules
40
119
 
41
- <https://eslint-react.xyz/docs/rules/overview#x-rules>
120
+ <https://eslint-react.xyz/docs/rules/overview#core-rules>
package/dist/index.d.ts CHANGED
@@ -4,8 +4,8 @@ import * as _eslint_react_shared0 from "@eslint-react/shared";
4
4
  declare const _default: {
5
5
  configs: {
6
6
  /**
7
- * Disable experimental rules that might be subject to change in the future
8
- */
7
+ * Disable experimental rules that might be subject to change in the future
8
+ */
9
9
  "disable-experimental": {
10
10
  plugins: {};
11
11
  name?: string;
@@ -13,8 +13,8 @@ declare const _default: {
13
13
  settings?: _eslint_react_shared0.SettingsConfig;
14
14
  };
15
15
  /**
16
- * Disable rules that can be enforced by TypeScript
17
- */
16
+ * Disable rules that can be enforced by TypeScript
17
+ */
18
18
  "disable-type-checked": {
19
19
  plugins: {};
20
20
  name?: string;
@@ -22,8 +22,8 @@ declare const _default: {
22
22
  settings?: _eslint_react_shared0.SettingsConfig;
23
23
  };
24
24
  /**
25
- * Enforce rules that are recommended by ESLint React for general purpose React + React DOM projects
26
- */
25
+ * Enforce rules that are recommended by ESLint React for general purpose React + React DOM projects
26
+ */
27
27
  recommended: {
28
28
  plugins: {};
29
29
  name?: string;
@@ -31,8 +31,8 @@ declare const _default: {
31
31
  settings?: _eslint_react_shared0.SettingsConfig;
32
32
  };
33
33
  /**
34
- * Same as the `recommended-typescript` preset but enables additional rules that require type information
35
- */
34
+ * Same as the `recommended-typescript` preset but enables additional rules that require type information
35
+ */
36
36
  "recommended-type-checked": {
37
37
  plugins: {};
38
38
  name?: string;
@@ -40,8 +40,8 @@ declare const _default: {
40
40
  settings?: _eslint_react_shared0.SettingsConfig;
41
41
  };
42
42
  /**
43
- * Same as the `recommended` preset but disables rules that can be enforced by TypeScript
44
- */
43
+ * Same as the `recommended` preset but disables rules that can be enforced by TypeScript
44
+ */
45
45
  "recommended-typescript": {
46
46
  plugins: {};
47
47
  name?: string;
@@ -49,8 +49,8 @@ declare const _default: {
49
49
  settings?: _eslint_react_shared0.SettingsConfig;
50
50
  };
51
51
  /**
52
- * More strict version of the `recommended` preset
53
- */
52
+ * More strict version of the `recommended` preset
53
+ */
54
54
  strict: {
55
55
  plugins: {};
56
56
  name?: string;
@@ -58,8 +58,8 @@ declare const _default: {
58
58
  settings?: _eslint_react_shared0.SettingsConfig;
59
59
  };
60
60
  /**
61
- * Same as the `strict-typescript` preset but enables additional rules that require type information
62
- */
61
+ * Same as the `strict-typescript` preset but enables additional rules that require type information
62
+ */
63
63
  "strict-type-checked": {
64
64
  plugins: {};
65
65
  name?: string;
@@ -67,8 +67,8 @@ declare const _default: {
67
67
  settings?: _eslint_react_shared0.SettingsConfig;
68
68
  };
69
69
  /**
70
- * Same as the `strict` preset but disables rules that can be enforced by TypeScript
71
- */
70
+ * Same as the `strict` preset but disables rules that can be enforced by TypeScript
71
+ */
72
72
  "strict-typescript": {
73
73
  plugins: {};
74
74
  name?: string;
package/dist/index.js CHANGED
@@ -19,9 +19,9 @@ import { camelCase } from "string-ts";
19
19
  var __defProp = Object.defineProperty;
20
20
  var __exportAll = (all, symbols) => {
21
21
  let target = {};
22
- for (var name$9 in all) {
23
- __defProp(target, name$9, {
24
- get: all[name$9],
22
+ for (var name in all) {
23
+ __defProp(target, name, {
24
+ get: all[name],
25
25
  enumerable: true
26
26
  });
27
27
  }
@@ -68,7 +68,7 @@ const rules$7 = {
68
68
  //#endregion
69
69
  //#region package.json
70
70
  var name$6 = "eslint-plugin-react-x";
71
- var version = "2.7.4-next.5";
71
+ var version = "2.7.4-next.7";
72
72
 
73
73
  //#endregion
74
74
  //#region src/utils/create-rule.ts
@@ -150,17 +150,17 @@ function getTypeVariants(types) {
150
150
  } else if (booleans.length === 2) variants.add("boolean");
151
151
  const strings = types.filter(isStringType);
152
152
  if (strings.length > 0) {
153
- const evaluated = match(strings).when((types$1) => types$1.every(isTruthyStringType), () => "truthy string").when((types$1) => types$1.every(isFalsyStringType), () => "falsy string").otherwise(() => "string");
153
+ const evaluated = match(strings).when((types) => types.every(isTruthyStringType), () => "truthy string").when((types) => types.every(isFalsyStringType), () => "falsy string").otherwise(() => "string");
154
154
  variants.add(evaluated);
155
155
  }
156
156
  const bigints = types.filter(isBigIntType);
157
157
  if (bigints.length > 0) {
158
- const evaluated = match(bigints).when((types$1) => types$1.every(isTruthyBigIntType), () => "truthy bigint").when((types$1) => types$1.every(isFalsyBigIntType), () => "falsy bigint").otherwise(() => "bigint");
158
+ const evaluated = match(bigints).when((types) => types.every(isTruthyBigIntType), () => "truthy bigint").when((types) => types.every(isFalsyBigIntType), () => "falsy bigint").otherwise(() => "bigint");
159
159
  variants.add(evaluated);
160
160
  }
161
161
  const numbers = types.filter(isNumberType);
162
162
  if (numbers.length > 0) {
163
- const evaluated = match(numbers).when((types$1) => types$1.every(isTruthyNumberType), () => "truthy number").when((types$1) => types$1.every(isFalsyNumberType), () => "falsy number").otherwise(() => "number");
163
+ const evaluated = match(numbers).when((types) => types.every(isTruthyNumberType), () => "truthy number").when((types) => types.every(isFalsyNumberType), () => "falsy number").otherwise(() => "number");
164
164
  variants.add(evaluated);
165
165
  }
166
166
  if (types.some(isEnumType)) variants.add("enum");
@@ -316,10 +316,10 @@ function create$60(context) {
316
316
  const props = [];
317
317
  for (const attr of node.attributes) {
318
318
  if (attr.type === AST_NODE_TYPES.JSXSpreadAttribute) continue;
319
- const name$9 = attr.name.name;
320
- if (typeof name$9 !== "string") continue;
321
- if (!props.includes(name$9)) {
322
- props.push(name$9);
319
+ const name = attr.name.name;
320
+ if (typeof name !== "string") continue;
321
+ if (!props.includes(name)) {
322
+ props.push(name);
323
323
  continue;
324
324
  }
325
325
  context.report({
@@ -377,17 +377,17 @@ var jsx_no_undef_default = createRule({
377
377
  });
378
378
  function create$58(context) {
379
379
  return { JSXOpeningElement(node) {
380
- const name$9 = match(node.name).with({ type: AST_NODE_TYPES.JSXIdentifier }, (n) => n.name).with({
380
+ const name = match(node.name).with({ type: AST_NODE_TYPES.JSXIdentifier }, (n) => n.name).with({
381
381
  type: AST_NODE_TYPES.JSXMemberExpression,
382
382
  object: { type: AST_NODE_TYPES.JSXIdentifier }
383
383
  }, (n) => n.object.name).otherwise(() => null);
384
- if (name$9 == null) return;
385
- if (name$9 === "this") return;
386
- if (/^[a-z]/u.test(name$9)) return;
387
- if (findVariable(name$9, context.sourceCode.getScope(node)) == null) context.report({
384
+ if (name == null) return;
385
+ if (name === "this") return;
386
+ if (/^[a-z]/u.test(name)) return;
387
+ if (findVariable(name, context.sourceCode.getScope(node)) == null) context.report({
388
388
  messageId: "jsxNoUndef",
389
389
  node,
390
- data: { name: name$9 }
390
+ data: { name }
391
391
  });
392
392
  } };
393
393
  }
@@ -525,12 +525,12 @@ function create$55(context) {
525
525
  JSXOpeningFragment: handleJsxElement
526
526
  };
527
527
  }
528
- function debugReport(context, node, name$9) {
528
+ function debugReport(context, node, name) {
529
529
  if (process.env["ESLINT_REACT_DEBUG"] !== "1") return;
530
530
  context.report({
531
531
  messageId: "jsxUsesReact",
532
532
  node,
533
- data: { name: name$9 }
533
+ data: { name }
534
534
  });
535
535
  }
536
536
 
@@ -674,8 +674,8 @@ function getIndexParamPosition(methodName) {
674
674
  default: return -1;
675
675
  }
676
676
  }
677
- function isReactChildrenMethod(name$9) {
678
- return REACT_CHILDREN_METHOD.includes(name$9);
677
+ function isReactChildrenMethod(name) {
678
+ return REACT_CHILDREN_METHOD.includes(name);
679
679
  }
680
680
  function isUsingReactChildren(context, node) {
681
681
  const { importSource = "react" } = coerceSettings(context.settings);
@@ -691,8 +691,8 @@ function getMapIndexParamName(context, node) {
691
691
  const { callee } = node;
692
692
  if (callee.type !== AST_NODE_TYPES.MemberExpression) return unit;
693
693
  if (callee.property.type !== AST_NODE_TYPES.Identifier) return unit;
694
- const { name: name$9 } = callee.property;
695
- const indexPosition = getIndexParamPosition(name$9);
694
+ const { name } = callee.property;
695
+ const indexPosition = getIndexParamPosition(name);
696
696
  if (indexPosition === -1) return unit;
697
697
  const callbackArg = node.arguments[isUsingReactChildren(context, node) ? 1 : 0];
698
698
  if (callbackArg == null) return unit;
@@ -721,7 +721,7 @@ var no_array_index_key_default = createRule({
721
721
  function create$52(context) {
722
722
  const indexParamNames = [];
723
723
  function isArrayIndex(node) {
724
- return node.type === AST_NODE_TYPES.Identifier && indexParamNames.some((name$9) => name$9 != null && name$9 === node.name);
724
+ return node.type === AST_NODE_TYPES.Identifier && indexParamNames.some((name) => name != null && name === node.name);
725
725
  }
726
726
  function isCreateOrCloneElementCall(node) {
727
727
  return isCreateElementCall(context, node) || isCloneElementCall(context, node);
@@ -729,7 +729,7 @@ function create$52(context) {
729
729
  function getReportDescriptors(node) {
730
730
  switch (node.type) {
731
731
  case AST_NODE_TYPES.Identifier:
732
- if (indexParamNames.some((name$9) => name$9 != null && name$9 === node.name)) return [{
732
+ if (indexParamNames.some((name) => name != null && name === node.name)) return [{
733
733
  messageId: "noArrayIndexKey",
734
734
  node
735
735
  }];
@@ -939,12 +939,12 @@ function create$45(context) {
939
939
  if (!context.sourceCode.text.includes("Component")) return {};
940
940
  const { ctx, visitor } = useComponentCollectorLegacy(context);
941
941
  return defineRuleListener(visitor, { "Program:exit"(program) {
942
- for (const { name: name$9 = "anonymous", node: component } of ctx.getAllComponents(program)) {
942
+ for (const { name = "anonymous", node: component } of ctx.getAllComponents(program)) {
943
943
  if (component.body.body.some((m) => isComponentDidCatch(m) || isGetDerivedStateFromError(m))) continue;
944
944
  context.report({
945
945
  messageId: "noClassComponent",
946
946
  node: component,
947
- data: { name: name$9 }
947
+ data: { name }
948
948
  });
949
949
  }
950
950
  } });
@@ -1089,8 +1089,8 @@ var no_context_provider_default = createRule({
1089
1089
  });
1090
1090
  function create$40(context) {
1091
1091
  if (!context.sourceCode.text.includes("Provider")) return {};
1092
- const { version: version$1 } = getSettingsFromContext(context);
1093
- if (compare(version$1, "19.0.0", "<")) return {};
1092
+ const { version } = getSettingsFromContext(context);
1093
+ if (compare(version, "19.0.0", "<")) return {};
1094
1094
  return { JSXElement(node) {
1095
1095
  const parts = getJsxElementType(context, node).split(".");
1096
1096
  const selfName = parts.pop();
@@ -1280,8 +1280,8 @@ var no_forward_ref_default = createRule({
1280
1280
  });
1281
1281
  function create$35(context) {
1282
1282
  if (!context.sourceCode.text.includes("forwardRef")) return {};
1283
- const { version: version$1 } = getSettingsFromContext(context);
1284
- if (compare(version$1, "19.0.0", "<")) return {};
1283
+ const { version } = getSettingsFromContext(context);
1284
+ if (compare(version, "19.0.0", "<")) return {};
1285
1285
  return { CallExpression(node) {
1286
1286
  if (!isForwardRefCall(context, node)) return;
1287
1287
  const id = AST.getFunctionId(node);
@@ -1336,7 +1336,7 @@ function getFix(context, node) {
1336
1336
  * @returns An array of fixes for the component's signature
1337
1337
  */
1338
1338
  function getComponentPropsFixes(context, fixer, node, typeArguments) {
1339
- const getText = (node$1) => context.sourceCode.getText(node$1);
1339
+ const getText = (node) => context.sourceCode.getText(node);
1340
1340
  const [arg0, arg1] = node.params;
1341
1341
  const [typeArg0, typeArg1] = typeArguments;
1342
1342
  if (arg0 == null) return [];
@@ -1412,7 +1412,7 @@ var no_leaked_conditional_rendering_default = createRule({
1412
1412
  });
1413
1413
  function create$33(context) {
1414
1414
  if (!context.sourceCode.text.includes("&&")) return {};
1415
- const { version: version$1 } = getSettingsFromContext(context);
1415
+ const { version } = getSettingsFromContext(context);
1416
1416
  const allowedVariants = [
1417
1417
  "any",
1418
1418
  "boolean",
@@ -1424,7 +1424,7 @@ function create$33(context) {
1424
1424
  "truthy boolean",
1425
1425
  "truthy number",
1426
1426
  "truthy string",
1427
- ...compare(version$1, "18.0.0", "<") ? [] : ["string", "falsy string"]
1427
+ ...compare(version, "18.0.0", "<") ? [] : ["string", "falsy string"]
1428
1428
  ];
1429
1429
  const services = ESLintUtils.getParserServices(context, false);
1430
1430
  /**
@@ -1623,8 +1623,8 @@ function create$30(ctx) {
1623
1623
  if (inChildrenToArray) return;
1624
1624
  if (node.callee.type !== AST_NODE_TYPES.MemberExpression) return;
1625
1625
  if (node.callee.property.type !== AST_NODE_TYPES.Identifier) return;
1626
- const name$9 = node.callee.property.name;
1627
- const idx = name$9 === "from" ? 1 : name$9 === "map" ? 0 : -1;
1626
+ const name = node.callee.property.name;
1627
+ const idx = name === "from" ? 1 : name === "map" ? 0 : -1;
1628
1628
  if (idx < 0) return;
1629
1629
  const cb = node.arguments[idx];
1630
1630
  if (!AST.isFunction(cb)) return;
@@ -1713,18 +1713,18 @@ function create$28(context) {
1713
1713
  const isFunctionComponent = (node) => {
1714
1714
  return AST.isFunction(node) && fComponents.some((component) => component.node === node);
1715
1715
  };
1716
- const isClassComponent$1 = (node) => {
1716
+ const isClassComponent = (node) => {
1717
1717
  return AST.isClass(node) && cComponents.some((component) => component.node === node);
1718
1718
  };
1719
- for (const { name: name$9, node: component } of fComponents) {
1720
- if (name$9 == null) continue;
1719
+ for (const { name, node: component } of fComponents) {
1720
+ if (name == null) continue;
1721
1721
  if (isDirectValueOfRenderPropertyLoose(component)) continue;
1722
1722
  if (isInsideJSXAttributeValue(component)) {
1723
1723
  if (!isDeclaredInRenderPropLoose(component)) context.report({
1724
1724
  messageId: "noNestedComponentDefinitions",
1725
1725
  node: component,
1726
1726
  data: {
1727
- name: name$9,
1727
+ name,
1728
1728
  suggestion: "Move it to the top level or pass it as a prop."
1729
1729
  }
1730
1730
  });
@@ -1735,7 +1735,7 @@ function create$28(context) {
1735
1735
  messageId: "noNestedComponentDefinitions",
1736
1736
  node: component,
1737
1737
  data: {
1738
- name: name$9,
1738
+ name,
1739
1739
  suggestion: "Move it to the top level or pass it as a prop."
1740
1740
  }
1741
1741
  });
@@ -1747,7 +1747,7 @@ function create$28(context) {
1747
1747
  messageId: "noNestedComponentDefinitions",
1748
1748
  node: component,
1749
1749
  data: {
1750
- name: name$9,
1750
+ name,
1751
1751
  suggestion: component.parent.type === AST_NODE_TYPES.Property ? "Move it to the top level or pass it as a prop." : "Move it to the top level."
1752
1752
  }
1753
1753
  });
@@ -1757,18 +1757,18 @@ function create$28(context) {
1757
1757
  messageId: "noNestedComponentDefinitions",
1758
1758
  node: component,
1759
1759
  data: {
1760
- name: name$9,
1760
+ name,
1761
1761
  suggestion: "Move it to the top level."
1762
1762
  }
1763
1763
  });
1764
1764
  }
1765
- for (const { name: name$9 = "unknown", node: component } of cComponents) {
1766
- if (AST.findParentNode(component, (n) => isClassComponent$1(n) || isFunctionComponent(n)) == null) continue;
1765
+ for (const { name = "unknown", node: component } of cComponents) {
1766
+ if (AST.findParentNode(component, (n) => isClassComponent(n) || isFunctionComponent(n)) == null) continue;
1767
1767
  context.report({
1768
1768
  messageId: "noNestedComponentDefinitions",
1769
1769
  node: component,
1770
1770
  data: {
1771
- name: name$9,
1771
+ name,
1772
1772
  suggestion: component.parent.type === AST_NODE_TYPES.Property ? "Move it to the top level or pass it as a prop." : "Move it to the top level."
1773
1773
  }
1774
1774
  });
@@ -1908,13 +1908,13 @@ function create$25(context) {
1908
1908
  if (!context.sourceCode.text.includes("shouldComponentUpdate")) return {};
1909
1909
  const { ctx, visitor } = useComponentCollectorLegacy(context);
1910
1910
  return defineRuleListener(visitor, { "Program:exit"(program) {
1911
- for (const { name: name$9 = "PureComponent", node: component, flag } of ctx.getAllComponents(program)) {
1911
+ for (const { name = "PureComponent", node: component, flag } of ctx.getAllComponents(program)) {
1912
1912
  if ((flag & ComponentFlag.PureComponent) === 0n) continue;
1913
1913
  const { body } = component.body;
1914
1914
  for (const member of body) if (isShouldComponentUpdate(member)) context.report({
1915
1915
  messageId: "noRedundantShouldComponentUpdate",
1916
1916
  node: member,
1917
- data: { componentName: name$9 }
1917
+ data: { componentName: name }
1918
1918
  });
1919
1919
  }
1920
1920
  } });
@@ -2326,16 +2326,16 @@ var no_unnecessary_use_prefix_default = createRule({
2326
2326
  function create$17(context) {
2327
2327
  const { ctx, visitor } = useHookCollector(context);
2328
2328
  return defineRuleListener(visitor, { "Program:exit"(program) {
2329
- for (const { id, name: name$9, node, hookCalls } of ctx.getAllHooks(program)) {
2329
+ for (const { id, name, node, hookCalls } of ctx.getAllHooks(program)) {
2330
2330
  if (hookCalls.length > 0) continue;
2331
2331
  if (AST.isFunctionEmpty(node)) continue;
2332
- if (WELL_KNOWN_HOOKS.includes(name$9)) continue;
2332
+ if (WELL_KNOWN_HOOKS.includes(name)) continue;
2333
2333
  if (containsUseComments(context, node)) continue;
2334
2334
  if (AST.findParentNode(node, AST.isViMockCallback) != null) continue;
2335
2335
  context.report({
2336
2336
  messageId: "noUnnecessaryUsePrefix",
2337
2337
  node: id ?? node,
2338
- data: { name: name$9 }
2338
+ data: { name }
2339
2339
  });
2340
2340
  }
2341
2341
  } });
@@ -2365,8 +2365,8 @@ function create$16(context) {
2365
2365
  if (ref.name.toLowerCase().startsWith("prev")) return;
2366
2366
  const effects = /* @__PURE__ */ new Set();
2367
2367
  let globalUsages = 0;
2368
- for (const { identifier, init: init$1 } of ref.references) {
2369
- if (init$1 != null) continue;
2368
+ for (const { identifier, init } of ref.references) {
2369
+ if (init != null) continue;
2370
2370
  const effect = AST.findParentNode(identifier, isUseEffectLikeCall);
2371
2371
  if (effect == null) globalUsages++;
2372
2372
  else effects.add(effect);
@@ -2478,8 +2478,8 @@ var no_unstable_context_value_default = createRule({
2478
2478
  defaultOptions: []
2479
2479
  });
2480
2480
  function create$12(context) {
2481
- const { version: version$1 } = getSettingsFromContext(context);
2482
- const isReact18OrBelow = compare(version$1, "19.0.0", "<");
2481
+ const { version } = getSettingsFromContext(context);
2482
+ const isReact18OrBelow = compare(version, "19.0.0", "<");
2483
2483
  const { ctx, visitor } = useComponentCollector(context);
2484
2484
  const constructions = /* @__PURE__ */ new WeakMap();
2485
2485
  return defineRuleListener(visitor, {
@@ -2489,7 +2489,7 @@ function create$12(context) {
2489
2489
  if (!isContextName(selfName, isReact18OrBelow)) return;
2490
2490
  const functionEntry = ctx.getCurrentEntry();
2491
2491
  if (functionEntry == null) return;
2492
- const attribute = node.attributes.find((attribute$1) => attribute$1.type === AST_NODE_TYPES.JSXAttribute && attribute$1.name.name === "value");
2492
+ const attribute = node.attributes.find((attribute) => attribute.type === AST_NODE_TYPES.JSXAttribute && attribute.name.name === "value");
2493
2493
  if (attribute == null || !("value" in attribute)) return;
2494
2494
  const value = attribute.value;
2495
2495
  if (value?.type !== AST_NODE_TYPES.JSXExpressionContainer) return;
@@ -2515,9 +2515,9 @@ function create$12(context) {
2515
2515
  }
2516
2516
  });
2517
2517
  }
2518
- function isContextName(name$9, isReact18OrBelow) {
2519
- if (name$9 === "Provider") return true;
2520
- if (!isReact18OrBelow) return name$9.endsWith("Context") || name$9.endsWith("CONTEXT");
2518
+ function isContextName(name, isReact18OrBelow) {
2519
+ if (name === "Provider") return true;
2520
+ if (!isReact18OrBelow) return name.endsWith("Context") || name.endsWith("CONTEXT");
2521
2521
  return false;
2522
2522
  }
2523
2523
 
@@ -2568,8 +2568,8 @@ function create$11(context, [options]) {
2568
2568
  const { params } = component;
2569
2569
  const [props] = params;
2570
2570
  if (props == null) continue;
2571
- const properties = match(props).with({ type: AST_NODE_TYPES.ObjectPattern }, ({ properties: properties$1 }) => properties$1).with({ type: AST_NODE_TYPES.Identifier }, ({ name: name$9 }) => {
2572
- return declarators.get(component)?.filter((d) => d.init.name === name$9).flatMap((d) => d.id.properties) ?? [];
2571
+ const properties = match(props).with({ type: AST_NODE_TYPES.ObjectPattern }, ({ properties }) => properties).with({ type: AST_NODE_TYPES.Identifier }, ({ name }) => {
2572
+ return declarators.get(component)?.filter((d) => d.init.name === name).flatMap((d) => d.id.properties) ?? [];
2573
2573
  }).otherwise(() => []);
2574
2574
  for (const prop of properties) {
2575
2575
  if (prop.type !== AST_NODE_TYPES.Property || prop.value.type !== AST_NODE_TYPES.AssignmentPattern) continue;
@@ -2964,8 +2964,8 @@ var no_use_context_default = createRule({
2964
2964
  });
2965
2965
  function create$7(context) {
2966
2966
  if (!context.sourceCode.text.includes("useContext")) return {};
2967
- const settings$6 = getSettingsFromContext(context);
2968
- if (compare(settings$6.version, "19.0.0", "<")) return {};
2967
+ const settings = getSettingsFromContext(context);
2968
+ if (compare(settings.version, "19.0.0", "<")) return {};
2969
2969
  const hookCalls = /* @__PURE__ */ new Set();
2970
2970
  return {
2971
2971
  CallExpression(node) {
@@ -2973,7 +2973,7 @@ function create$7(context) {
2973
2973
  hookCalls.add(node);
2974
2974
  },
2975
2975
  ImportDeclaration(node) {
2976
- if (node.source.value !== settings$6.importSource) return;
2976
+ if (node.source.value !== settings.importSource) return;
2977
2977
  const isUseImported = node.specifiers.some(isMatching({ local: {
2978
2978
  type: AST_NODE_TYPES.Identifier,
2979
2979
  name: "use"
@@ -3095,21 +3095,21 @@ function create$5(context, [option]) {
3095
3095
  /**
3096
3096
  * Check if a fragment node is useless and should be reported
3097
3097
  */
3098
- function checkNode(context$1, node) {
3099
- if (node.type === AST_NODE_TYPES.JSXElement && getJsxAttribute(context$1, node)("key") != null) return;
3100
- if (isJsxHostElement(context$1, node.parent)) context$1.report({
3098
+ function checkNode(context, node) {
3099
+ if (node.type === AST_NODE_TYPES.JSXElement && getJsxAttribute(context, node)("key") != null) return;
3100
+ if (isJsxHostElement(context, node.parent)) context.report({
3101
3101
  messageId: "noUselessFragment",
3102
3102
  node,
3103
3103
  data: { reason: "placed inside a host component" },
3104
- fix: getFix$1(context$1, node)
3104
+ fix: getFix(context, node)
3105
3105
  });
3106
3106
  if (node.children.length === 0) {
3107
3107
  if (allowEmptyFragment) return;
3108
- context$1.report({
3108
+ context.report({
3109
3109
  messageId: "noUselessFragment",
3110
3110
  node,
3111
3111
  data: { reason: "contains less than two children" },
3112
- fix: getFix$1(context$1, node)
3112
+ fix: getFix(context, node)
3113
3113
  });
3114
3114
  return;
3115
3115
  }
@@ -3117,45 +3117,45 @@ function create$5(context, [option]) {
3117
3117
  switch (true) {
3118
3118
  case allowExpressions && !isChildElement && node.children.length === 1 && isJsxText(node.children.at(0)): return;
3119
3119
  case !allowExpressions && isChildElement:
3120
- context$1.report({
3120
+ context.report({
3121
3121
  messageId: "noUselessFragment",
3122
3122
  node,
3123
3123
  data: { reason: "contains less than two children" },
3124
- fix: getFix$1(context$1, node)
3124
+ fix: getFix(context, node)
3125
3125
  });
3126
3126
  return;
3127
3127
  case !allowExpressions && !isChildElement && node.children.length === 1:
3128
- context$1.report({
3128
+ context.report({
3129
3129
  messageId: "noUselessFragment",
3130
3130
  node,
3131
3131
  data: { reason: "contains less than two children" },
3132
- fix: getFix$1(context$1, node)
3132
+ fix: getFix(context, node)
3133
3133
  });
3134
3134
  return;
3135
3135
  }
3136
3136
  const nonPaddingChildren = node.children.filter((child) => !isPaddingSpaces(child));
3137
3137
  const firstNonPaddingChild = nonPaddingChildren.at(0);
3138
- if (nonPaddingChildren.length === 0 || nonPaddingChildren.length === 1 && firstNonPaddingChild?.type !== AST_NODE_TYPES.JSXExpressionContainer) context$1.report({
3138
+ if (nonPaddingChildren.length === 0 || nonPaddingChildren.length === 1 && firstNonPaddingChild?.type !== AST_NODE_TYPES.JSXExpressionContainer) context.report({
3139
3139
  messageId: "noUselessFragment",
3140
3140
  node,
3141
3141
  data: { reason: "contains less than two children" },
3142
- fix: getFix$1(context$1, node)
3142
+ fix: getFix(context, node)
3143
3143
  });
3144
3144
  }
3145
- function getFix$1(context$1, node) {
3146
- if (!canFix$1(context$1, node)) return null;
3145
+ function getFix(context, node) {
3146
+ if (!canFix(context, node)) return null;
3147
3147
  return (fixer) => {
3148
3148
  const opener = node.type === AST_NODE_TYPES.JSXFragment ? node.openingFragment : node.openingElement;
3149
3149
  const closer = node.type === AST_NODE_TYPES.JSXFragment ? node.closingFragment : node.closingElement;
3150
- const childrenText = opener.type === AST_NODE_TYPES.JSXOpeningElement && opener.selfClosing ? "" : context$1.sourceCode.getText().slice(opener.range[1], closer?.range[0]);
3150
+ const childrenText = opener.type === AST_NODE_TYPES.JSXOpeningElement && opener.selfClosing ? "" : context.sourceCode.getText().slice(opener.range[1], closer?.range[0]);
3151
3151
  return fixer.replaceText(node, trimLikeReact(childrenText));
3152
3152
  };
3153
3153
  }
3154
3154
  /**
3155
3155
  * Check if it's safe to automatically fix the fragment
3156
3156
  */
3157
- function canFix$1(context$1, node) {
3158
- if (node.parent.type === AST_NODE_TYPES.JSXElement || node.parent.type === AST_NODE_TYPES.JSXFragment) return isJsxHostElement(context$1, node.parent);
3157
+ function canFix(context, node) {
3158
+ if (node.parent.type === AST_NODE_TYPES.JSXElement || node.parent.type === AST_NODE_TYPES.JSXFragment) return isJsxHostElement(context, node.parent);
3159
3159
  if (node.children.length === 0) return false;
3160
3160
  return !node.children.some((child) => isJsxText(child) && !isWhiteSpace(child) || AST.is(AST_NODE_TYPES.JSXExpressionContainer)(child));
3161
3161
  }
@@ -3217,7 +3217,7 @@ function create$4(context) {
3217
3217
  const propName = props.name;
3218
3218
  const propReferences = context.sourceCode.getScope(component.node).variables.find((v) => v.name === propName)?.references ?? [];
3219
3219
  for (const ref of propReferences) {
3220
- const { name: name$9, parent } = ref.identifier;
3220
+ const { name, parent } = ref.identifier;
3221
3221
  if (parent.type !== AST_NODE_TYPES.MemberExpression) continue;
3222
3222
  context.report({
3223
3223
  messageId: "preferDestructuringAssignment",
@@ -3432,17 +3432,17 @@ function create(context, [option]) {
3432
3432
  else if (node.name.type === AST_NODE_TYPES.JSXNamespacedName) nodeName = node.name.name.name;
3433
3433
  for (const attr of node.attributes) {
3434
3434
  if (attr.type === AST_NODE_TYPES.JSXSpreadAttribute) continue;
3435
- const name$9 = attr.name.name;
3436
- if (typeof name$9 !== "string") continue;
3435
+ const name = attr.name.name;
3436
+ if (typeof name !== "string") continue;
3437
3437
  for (const forbiddenPropItem of forbid) {
3438
3438
  if (typeof forbiddenPropItem !== "string" && nodeName != null) {
3439
3439
  if ("excludedNodes" in forbiddenPropItem && forbiddenPropItem.excludedNodes.includes(nodeName)) continue;
3440
3440
  if ("includedNodes" in forbiddenPropItem && !forbiddenPropItem.includedNodes.includes(nodeName)) continue;
3441
3441
  }
3442
- if (toRegExp(typeof forbiddenPropItem === "string" ? forbiddenPropItem : forbiddenPropItem.prop).test(name$9)) context.report({
3442
+ if (toRegExp(typeof forbiddenPropItem === "string" ? forbiddenPropItem : forbiddenPropItem.prop).test(name)) context.report({
3443
3443
  messageId,
3444
3444
  node: attr,
3445
- data: { name: name$9 }
3445
+ data: { name }
3446
3446
  });
3447
3447
  }
3448
3448
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-react-x",
3
- "version": "2.7.4-next.5",
3
+ "version": "2.7.4-next.7",
4
4
  "description": "A set of composable ESLint rules for for libraries and frameworks that use React as a UI runtime.",
5
5
  "keywords": [
6
6
  "react",
@@ -46,16 +46,16 @@
46
46
  "string-ts": "^2.3.1",
47
47
  "ts-api-utils": "^2.4.0",
48
48
  "ts-pattern": "^5.9.0",
49
- "@eslint-react/core": "2.7.4-next.5",
50
- "@eslint-react/shared": "2.7.4-next.5",
51
- "@eslint-react/var": "2.7.4-next.5",
52
- "@eslint-react/ast": "2.7.4-next.5",
53
- "@eslint-react/eff": "2.7.4-next.5"
49
+ "@eslint-react/ast": "2.7.4-next.7",
50
+ "@eslint-react/eff": "2.7.4-next.7",
51
+ "@eslint-react/core": "2.7.4-next.7",
52
+ "@eslint-react/shared": "2.7.4-next.7",
53
+ "@eslint-react/var": "2.7.4-next.7"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@types/react": "^19.2.9",
57
57
  "@types/react-dom": "^19.2.3",
58
- "tsdown": "^0.20.0-beta.4",
58
+ "tsdown": "^0.20.1",
59
59
  "@local/configs": "0.0.0"
60
60
  },
61
61
  "peerDependencies": {