eslint-plugin-react-x 1.24.2-next.1 → 1.24.2-next.2

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/dist/index.js CHANGED
@@ -42,7 +42,7 @@ var ts__default = /*#__PURE__*/_interopDefault(ts);
42
42
 
43
43
  // package.json
44
44
  var name = "eslint-plugin-react-x";
45
- var version = "1.24.2-next.1";
45
+ var version = "1.24.2-next.2";
46
46
  var createRule = shared.createRuleForPlugin("x");
47
47
 
48
48
  // src/rules/avoid-shorthand-boolean.ts
@@ -2815,16 +2815,42 @@ var RULE_NAME44 = "no-useless-fragment";
2815
2815
  var defaultOptions = [{
2816
2816
  allowExpressions: true
2817
2817
  }];
2818
+ function trimLikeReact(text) {
2819
+ const leadingSpaces = /^\s*/.exec(text)?.[0] ?? "";
2820
+ const trailingSpaces = /\s*$/.exec(text)?.[0] ?? "";
2821
+ const start = leadingSpaces.includes("\n") ? leadingSpaces.length : 0;
2822
+ const end = trailingSpaces.includes("\n") ? text.length - trailingSpaces.length : text.length;
2823
+ return text.slice(start, end);
2824
+ }
2818
2825
  function checkAndReport(node, context, allowExpressions) {
2826
+ function fix(fixer) {
2827
+ if (!(node.parent.type === types.AST_NODE_TYPES.JSXElement || node.parent.type === types.AST_NODE_TYPES.JSXFragment)) {
2828
+ if (node.children.length === 0) {
2829
+ return null;
2830
+ }
2831
+ if (node.children.some(
2832
+ (child) => JSX7__namespace.isLiteral(child) && !JSX7__namespace.isWhiteSpace(child) || AST11__namespace.is(types.AST_NODE_TYPES.JSXExpressionContainer)(child)
2833
+ )) {
2834
+ return null;
2835
+ }
2836
+ }
2837
+ if (JSX7__namespace.isUserDefinedElement(node.parent)) {
2838
+ return null;
2839
+ }
2840
+ const opener = node.type === types.AST_NODE_TYPES.JSXFragment ? node.openingFragment : node.openingElement;
2841
+ const closer = node.type === types.AST_NODE_TYPES.JSXFragment ? node.closingFragment : node.closingElement;
2842
+ const childrenText = opener.type === types.AST_NODE_TYPES.JSXOpeningElement && opener.selfClosing ? "" : context.sourceCode.getText().slice(opener.range[1], closer?.range[0]);
2843
+ return fixer.replaceText(node, trimLikeReact(childrenText));
2844
+ }
2819
2845
  const initialScope = context.sourceCode.getScope(node);
2820
2846
  if (JSX7__namespace.isKeyedElement(node, initialScope)) {
2821
2847
  return;
2822
2848
  }
2823
2849
  if (JSX7__namespace.isBuiltInElement(node.parent)) {
2824
- context.report({ messageId: "noUselessFragmentInBuiltIn", node });
2850
+ context.report({ messageId: "noUselessFragmentInBuiltIn", node, fix });
2825
2851
  }
2826
2852
  if (node.children.length === 0) {
2827
- context.report({ messageId: "noUselessFragment", node });
2853
+ context.report({ messageId: "noUselessFragment", node, fix });
2828
2854
  return;
2829
2855
  }
2830
2856
  const isChildElement = AST11__namespace.isOneOf([types.AST_NODE_TYPES.JSXElement, types.AST_NODE_TYPES.JSXFragment])(node.parent);
@@ -2835,11 +2861,11 @@ function checkAndReport(node, context, allowExpressions) {
2835
2861
  }
2836
2862
  // <Foo><>hello, world</></Foo>
2837
2863
  case (!allowExpressions && isChildElement): {
2838
- context.report({ messageId: "noUselessFragment", node });
2864
+ context.report({ messageId: "noUselessFragment", node, fix });
2839
2865
  return;
2840
2866
  }
2841
2867
  case (!allowExpressions && !isChildElement && node.children.length === 1): {
2842
- context.report({ messageId: "noUselessFragment", node });
2868
+ context.report({ messageId: "noUselessFragment", node, fix });
2843
2869
  return;
2844
2870
  }
2845
2871
  }
@@ -2848,7 +2874,7 @@ function checkAndReport(node, context, allowExpressions) {
2848
2874
  switch (true) {
2849
2875
  case nonPaddingChildren.length === 0:
2850
2876
  case (nonPaddingChildren.length === 1 && firstNonPaddingChild?.type !== types.AST_NODE_TYPES.JSXExpressionContainer): {
2851
- context.report({ messageId: "noUselessFragment", node });
2877
+ context.report({ messageId: "noUselessFragment", node, fix });
2852
2878
  return;
2853
2879
  }
2854
2880
  }
@@ -2861,6 +2887,7 @@ var no_useless_fragment_default = createRule({
2861
2887
  docs: {
2862
2888
  description: "disallow unnecessary fragments"
2863
2889
  },
2890
+ fixable: "code",
2864
2891
  messages: {
2865
2892
  noUselessFragment: "A fragment contains less than two children is unnecessary.",
2866
2893
  noUselessFragmentInBuiltIn: "A fragment placed inside a built-in component is unnecessary."
package/dist/index.mjs CHANGED
@@ -15,7 +15,7 @@ import { getTypeImmutability, isUnknown, isImmutable, isReadonlyShallow, isReado
15
15
 
16
16
  // package.json
17
17
  var name = "eslint-plugin-react-x";
18
- var version = "1.24.2-next.1";
18
+ var version = "1.24.2-next.2";
19
19
  var createRule = createRuleForPlugin("x");
20
20
 
21
21
  // src/rules/avoid-shorthand-boolean.ts
@@ -2788,16 +2788,42 @@ var RULE_NAME44 = "no-useless-fragment";
2788
2788
  var defaultOptions = [{
2789
2789
  allowExpressions: true
2790
2790
  }];
2791
+ function trimLikeReact(text) {
2792
+ const leadingSpaces = /^\s*/.exec(text)?.[0] ?? "";
2793
+ const trailingSpaces = /\s*$/.exec(text)?.[0] ?? "";
2794
+ const start = leadingSpaces.includes("\n") ? leadingSpaces.length : 0;
2795
+ const end = trailingSpaces.includes("\n") ? text.length - trailingSpaces.length : text.length;
2796
+ return text.slice(start, end);
2797
+ }
2791
2798
  function checkAndReport(node, context, allowExpressions) {
2799
+ function fix(fixer) {
2800
+ if (!(node.parent.type === AST_NODE_TYPES.JSXElement || node.parent.type === AST_NODE_TYPES.JSXFragment)) {
2801
+ if (node.children.length === 0) {
2802
+ return null;
2803
+ }
2804
+ if (node.children.some(
2805
+ (child) => JSX7.isLiteral(child) && !JSX7.isWhiteSpace(child) || AST11.is(AST_NODE_TYPES.JSXExpressionContainer)(child)
2806
+ )) {
2807
+ return null;
2808
+ }
2809
+ }
2810
+ if (JSX7.isUserDefinedElement(node.parent)) {
2811
+ return null;
2812
+ }
2813
+ const opener = node.type === AST_NODE_TYPES.JSXFragment ? node.openingFragment : node.openingElement;
2814
+ const closer = node.type === AST_NODE_TYPES.JSXFragment ? node.closingFragment : node.closingElement;
2815
+ const childrenText = opener.type === AST_NODE_TYPES.JSXOpeningElement && opener.selfClosing ? "" : context.sourceCode.getText().slice(opener.range[1], closer?.range[0]);
2816
+ return fixer.replaceText(node, trimLikeReact(childrenText));
2817
+ }
2792
2818
  const initialScope = context.sourceCode.getScope(node);
2793
2819
  if (JSX7.isKeyedElement(node, initialScope)) {
2794
2820
  return;
2795
2821
  }
2796
2822
  if (JSX7.isBuiltInElement(node.parent)) {
2797
- context.report({ messageId: "noUselessFragmentInBuiltIn", node });
2823
+ context.report({ messageId: "noUselessFragmentInBuiltIn", node, fix });
2798
2824
  }
2799
2825
  if (node.children.length === 0) {
2800
- context.report({ messageId: "noUselessFragment", node });
2826
+ context.report({ messageId: "noUselessFragment", node, fix });
2801
2827
  return;
2802
2828
  }
2803
2829
  const isChildElement = AST11.isOneOf([AST_NODE_TYPES.JSXElement, AST_NODE_TYPES.JSXFragment])(node.parent);
@@ -2808,11 +2834,11 @@ function checkAndReport(node, context, allowExpressions) {
2808
2834
  }
2809
2835
  // <Foo><>hello, world</></Foo>
2810
2836
  case (!allowExpressions && isChildElement): {
2811
- context.report({ messageId: "noUselessFragment", node });
2837
+ context.report({ messageId: "noUselessFragment", node, fix });
2812
2838
  return;
2813
2839
  }
2814
2840
  case (!allowExpressions && !isChildElement && node.children.length === 1): {
2815
- context.report({ messageId: "noUselessFragment", node });
2841
+ context.report({ messageId: "noUselessFragment", node, fix });
2816
2842
  return;
2817
2843
  }
2818
2844
  }
@@ -2821,7 +2847,7 @@ function checkAndReport(node, context, allowExpressions) {
2821
2847
  switch (true) {
2822
2848
  case nonPaddingChildren.length === 0:
2823
2849
  case (nonPaddingChildren.length === 1 && firstNonPaddingChild?.type !== AST_NODE_TYPES.JSXExpressionContainer): {
2824
- context.report({ messageId: "noUselessFragment", node });
2850
+ context.report({ messageId: "noUselessFragment", node, fix });
2825
2851
  return;
2826
2852
  }
2827
2853
  }
@@ -2834,6 +2860,7 @@ var no_useless_fragment_default = createRule({
2834
2860
  docs: {
2835
2861
  description: "disallow unnecessary fragments"
2836
2862
  },
2863
+ fixable: "code",
2837
2864
  messages: {
2838
2865
  noUselessFragment: "A fragment contains less than two children is unnecessary.",
2839
2866
  noUselessFragmentInBuiltIn: "A fragment placed inside a built-in component is unnecessary."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-react-x",
3
- "version": "1.24.2-next.1",
3
+ "version": "1.24.2-next.2",
4
4
  "description": "A set of composable ESLint rules for libraries and frameworks that use React as a UI runtime.",
5
5
  "keywords": [
6
6
  "react",
@@ -48,12 +48,12 @@
48
48
  "is-immutable-type": "^5.0.1",
49
49
  "string-ts": "^2.2.0",
50
50
  "ts-pattern": "^5.6.2",
51
- "@eslint-react/ast": "1.24.2-next.1",
52
- "@eslint-react/core": "1.24.2-next.1",
53
- "@eslint-react/shared": "1.24.2-next.1",
54
- "@eslint-react/jsx": "1.24.2-next.1",
55
- "@eslint-react/var": "1.24.2-next.1",
56
- "@eslint-react/eff": "1.24.2-next.1"
51
+ "@eslint-react/ast": "1.24.2-next.2",
52
+ "@eslint-react/core": "1.24.2-next.2",
53
+ "@eslint-react/eff": "1.24.2-next.2",
54
+ "@eslint-react/jsx": "1.24.2-next.2",
55
+ "@eslint-react/var": "1.24.2-next.2",
56
+ "@eslint-react/shared": "1.24.2-next.2"
57
57
  },
58
58
  "devDependencies": {
59
59
  "@types/react": "^19.0.8",