eslint-plugin-react-dom 1.34.2-beta.0 → 1.34.2-beta.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.d.mts CHANGED
@@ -18,11 +18,13 @@ declare const _default: {
18
18
  readonly "no-missing-button-type": _typescript_eslint_utils_ts_eslint.RuleModule<"noMissingButtonType", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
19
19
  readonly "no-missing-iframe-sandbox": _typescript_eslint_utils_ts_eslint.RuleModule<"noMissingIframeSandbox", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
20
20
  readonly "no-namespace": _typescript_eslint_utils_ts_eslint.RuleModule<"noNamespace", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
21
+ readonly "no-render": _typescript_eslint_utils_ts_eslint.RuleModule<"noRender", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
21
22
  readonly "no-render-return-value": _typescript_eslint_utils_ts_eslint.RuleModule<"noRenderReturnValue", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
22
23
  readonly "no-script-url": _typescript_eslint_utils_ts_eslint.RuleModule<"noScriptUrl", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
23
24
  readonly "no-unknown-property": _typescript_eslint_utils_ts_eslint.RuleModule<"dataLowercaseRequired" | "invalidPropOnTag" | "unknownProp" | "unknownPropWithStandardName", unknown[], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
24
25
  readonly "no-unsafe-iframe-sandbox": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnsafeIframeSandbox", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
25
26
  readonly "no-unsafe-target-blank": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnsafeTargetBlank", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
27
+ readonly "no-use-form-state": _typescript_eslint_utils_ts_eslint.RuleModule<"noUseFormState", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
26
28
  readonly "no-void-elements-with-children": _typescript_eslint_utils_ts_eslint.RuleModule<"noVoidElementsWithChildren", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
27
29
  readonly "no-children-in-void-dom-elements": _typescript_eslint_utils_ts_eslint.RuleModule<"noVoidElementsWithChildren", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
28
30
  };
@@ -48,11 +50,13 @@ declare const _default: {
48
50
  readonly "no-missing-button-type": _typescript_eslint_utils_ts_eslint.RuleModule<"noMissingButtonType", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
49
51
  readonly "no-missing-iframe-sandbox": _typescript_eslint_utils_ts_eslint.RuleModule<"noMissingIframeSandbox", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
50
52
  readonly "no-namespace": _typescript_eslint_utils_ts_eslint.RuleModule<"noNamespace", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
53
+ readonly "no-render": _typescript_eslint_utils_ts_eslint.RuleModule<"noRender", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
51
54
  readonly "no-render-return-value": _typescript_eslint_utils_ts_eslint.RuleModule<"noRenderReturnValue", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
52
55
  readonly "no-script-url": _typescript_eslint_utils_ts_eslint.RuleModule<"noScriptUrl", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
53
56
  readonly "no-unknown-property": _typescript_eslint_utils_ts_eslint.RuleModule<"dataLowercaseRequired" | "invalidPropOnTag" | "unknownProp" | "unknownPropWithStandardName", unknown[], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
54
57
  readonly "no-unsafe-iframe-sandbox": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnsafeIframeSandbox", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
55
58
  readonly "no-unsafe-target-blank": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnsafeTargetBlank", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
59
+ readonly "no-use-form-state": _typescript_eslint_utils_ts_eslint.RuleModule<"noUseFormState", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
56
60
  readonly "no-void-elements-with-children": _typescript_eslint_utils_ts_eslint.RuleModule<"noVoidElementsWithChildren", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
57
61
  readonly "no-children-in-void-dom-elements": _typescript_eslint_utils_ts_eslint.RuleModule<"noVoidElementsWithChildren", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
58
62
  };
package/dist/index.d.ts CHANGED
@@ -18,11 +18,13 @@ declare const _default: {
18
18
  readonly "no-missing-button-type": _typescript_eslint_utils_ts_eslint.RuleModule<"noMissingButtonType", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
19
19
  readonly "no-missing-iframe-sandbox": _typescript_eslint_utils_ts_eslint.RuleModule<"noMissingIframeSandbox", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
20
20
  readonly "no-namespace": _typescript_eslint_utils_ts_eslint.RuleModule<"noNamespace", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
21
+ readonly "no-render": _typescript_eslint_utils_ts_eslint.RuleModule<"noRender", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
21
22
  readonly "no-render-return-value": _typescript_eslint_utils_ts_eslint.RuleModule<"noRenderReturnValue", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
22
23
  readonly "no-script-url": _typescript_eslint_utils_ts_eslint.RuleModule<"noScriptUrl", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
23
24
  readonly "no-unknown-property": _typescript_eslint_utils_ts_eslint.RuleModule<"dataLowercaseRequired" | "invalidPropOnTag" | "unknownProp" | "unknownPropWithStandardName", unknown[], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
24
25
  readonly "no-unsafe-iframe-sandbox": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnsafeIframeSandbox", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
25
26
  readonly "no-unsafe-target-blank": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnsafeTargetBlank", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
27
+ readonly "no-use-form-state": _typescript_eslint_utils_ts_eslint.RuleModule<"noUseFormState", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
26
28
  readonly "no-void-elements-with-children": _typescript_eslint_utils_ts_eslint.RuleModule<"noVoidElementsWithChildren", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
27
29
  readonly "no-children-in-void-dom-elements": _typescript_eslint_utils_ts_eslint.RuleModule<"noVoidElementsWithChildren", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
28
30
  };
@@ -48,11 +50,13 @@ declare const _default: {
48
50
  readonly "no-missing-button-type": _typescript_eslint_utils_ts_eslint.RuleModule<"noMissingButtonType", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
49
51
  readonly "no-missing-iframe-sandbox": _typescript_eslint_utils_ts_eslint.RuleModule<"noMissingIframeSandbox", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
50
52
  readonly "no-namespace": _typescript_eslint_utils_ts_eslint.RuleModule<"noNamespace", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
53
+ readonly "no-render": _typescript_eslint_utils_ts_eslint.RuleModule<"noRender", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
51
54
  readonly "no-render-return-value": _typescript_eslint_utils_ts_eslint.RuleModule<"noRenderReturnValue", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
52
55
  readonly "no-script-url": _typescript_eslint_utils_ts_eslint.RuleModule<"noScriptUrl", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
53
56
  readonly "no-unknown-property": _typescript_eslint_utils_ts_eslint.RuleModule<"dataLowercaseRequired" | "invalidPropOnTag" | "unknownProp" | "unknownPropWithStandardName", unknown[], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
54
57
  readonly "no-unsafe-iframe-sandbox": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnsafeIframeSandbox", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
55
58
  readonly "no-unsafe-target-blank": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnsafeTargetBlank", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
59
+ readonly "no-use-form-state": _typescript_eslint_utils_ts_eslint.RuleModule<"noUseFormState", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
56
60
  readonly "no-void-elements-with-children": _typescript_eslint_utils_ts_eslint.RuleModule<"noVoidElementsWithChildren", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
57
61
  readonly "no-children-in-void-dom-elements": _typescript_eslint_utils_ts_eslint.RuleModule<"noVoidElementsWithChildren", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
58
62
  };
package/dist/index.js CHANGED
@@ -3,8 +3,8 @@
3
3
  var shared = require('@eslint-react/shared');
4
4
  var JSX = require('@eslint-react/jsx');
5
5
  var types = require('@typescript-eslint/types');
6
- var AST = require('@eslint-react/ast');
7
6
  var compareVersions = require('compare-versions');
7
+ var AST = require('@eslint-react/ast');
8
8
  var eff = require('@eslint-react/eff');
9
9
 
10
10
  function _interopNamespace(e) {
@@ -50,11 +50,13 @@ var rules = {
50
50
  "react-dom/no-missing-button-type": "warn",
51
51
  "react-dom/no-missing-iframe-sandbox": "warn",
52
52
  "react-dom/no-namespace": "error",
53
+ "react-dom/no-render": "error",
53
54
  "react-dom/no-render-return-value": "error",
54
55
  "react-dom/no-script-url": "warn",
55
56
  "react-dom/no-unknown-property": "warn",
56
57
  "react-dom/no-unsafe-iframe-sandbox": "warn",
57
58
  "react-dom/no-unsafe-target-blank": "warn",
59
+ "react-dom/no-use-form-state": "error",
58
60
  "react-dom/no-void-elements-with-children": "error"
59
61
  };
60
62
  var settings = {
@@ -63,7 +65,7 @@ var settings = {
63
65
 
64
66
  // package.json
65
67
  var name2 = "eslint-plugin-react-dom";
66
- var version = "1.34.2-beta.0";
68
+ var version = "1.34.2-beta.2";
67
69
  var createRule = shared.createRuleForPlugin("dom");
68
70
 
69
71
  // src/utils/find-custom-component.ts
@@ -432,8 +434,85 @@ function create7(context) {
432
434
  }
433
435
  };
434
436
  }
435
- var RULE_NAME8 = "no-render-return-value";
437
+ var RULE_NAME8 = "no-render";
436
438
  var RULE_FEATURES8 = [
439
+ "CHK",
440
+ "MOD"
441
+ ];
442
+ var no_render_default = createRule({
443
+ meta: {
444
+ type: "problem",
445
+ docs: {
446
+ description: "replace usages of 'ReactDom.render()' with 'createRoot(node).render()'",
447
+ [Symbol.for("rule_features")]: RULE_FEATURES8
448
+ },
449
+ fixable: "code",
450
+ messages: {
451
+ noRender: "[Deprecated] Use 'createRoot(node).render()' instead."
452
+ },
453
+ schema: []
454
+ },
455
+ name: RULE_NAME8,
456
+ create(context) {
457
+ if (!context.sourceCode.text.includes("render")) return {};
458
+ const settings2 = shared.getSettingsFromContext(context);
459
+ if (compareVersions.compare(settings2.version, "18.0.0", "<")) return {};
460
+ const reactDomNames = /* @__PURE__ */ new Set();
461
+ const renderNames = /* @__PURE__ */ new Set();
462
+ return {
463
+ CallExpression(node) {
464
+ switch (true) {
465
+ case (node.callee.type === types.AST_NODE_TYPES.Identifier && renderNames.has(node.callee.name)):
466
+ context.report({
467
+ messageId: "noRender",
468
+ node,
469
+ fix: getFix(context, node)
470
+ });
471
+ return;
472
+ case (node.callee.type === types.AST_NODE_TYPES.MemberExpression && node.callee.object.type === types.AST_NODE_TYPES.Identifier && node.callee.property.type === types.AST_NODE_TYPES.Identifier && node.callee.property.name === "render" && reactDomNames.has(node.callee.object.name)):
473
+ context.report({
474
+ messageId: "noRender",
475
+ node,
476
+ fix: getFix(context, node)
477
+ });
478
+ return;
479
+ }
480
+ },
481
+ ImportDeclaration(node) {
482
+ const [baseSource] = node.source.value.split("/");
483
+ if (baseSource !== "react-dom") return;
484
+ for (const specifier of node.specifiers) {
485
+ switch (specifier.type) {
486
+ case types.AST_NODE_TYPES.ImportSpecifier:
487
+ if (specifier.imported.type !== types.AST_NODE_TYPES.Identifier) continue;
488
+ if (specifier.imported.name === "render") {
489
+ renderNames.add(specifier.local.name);
490
+ }
491
+ continue;
492
+ case types.AST_NODE_TYPES.ImportDefaultSpecifier:
493
+ case types.AST_NODE_TYPES.ImportNamespaceSpecifier:
494
+ reactDomNames.add(specifier.local.name);
495
+ continue;
496
+ }
497
+ }
498
+ }
499
+ };
500
+ },
501
+ defaultOptions: []
502
+ });
503
+ function getFix(context, node) {
504
+ const getText2 = (n) => context.sourceCode.getText(n);
505
+ return (fixer) => {
506
+ const [arg0, arg1] = node.arguments;
507
+ if (arg0 == null || arg1 == null) return null;
508
+ return [
509
+ fixer.insertTextBefore(context.sourceCode.ast, 'import { createRoot } from "react-dom/client";\n'),
510
+ fixer.replaceText(node, `createRoot(${getText2(arg1)}).render(${getText2(arg0)})`)
511
+ ];
512
+ };
513
+ }
514
+ var RULE_NAME9 = "no-render-return-value";
515
+ var RULE_FEATURES9 = [
437
516
  "CHK"
438
517
  ];
439
518
  var banParentTypes = [
@@ -448,14 +527,14 @@ var no_render_return_value_default = createRule({
448
527
  type: "problem",
449
528
  docs: {
450
529
  description: "disallow usage of the return value of 'ReactDOM.render'",
451
- [Symbol.for("rule_features")]: RULE_FEATURES8
530
+ [Symbol.for("rule_features")]: RULE_FEATURES9
452
531
  },
453
532
  messages: {
454
533
  noRenderReturnValue: "Do not depend on the return value from '{{objectName}}.render'."
455
534
  },
456
535
  schema: []
457
536
  },
458
- name: RULE_NAME8,
537
+ name: RULE_NAME9,
459
538
  create: create8,
460
539
  defaultOptions: []
461
540
  });
@@ -486,8 +565,8 @@ function create8(context) {
486
565
  }
487
566
  };
488
567
  }
489
- var RULE_NAME9 = "no-script-url";
490
- var RULE_FEATURES9 = [
568
+ var RULE_NAME10 = "no-script-url";
569
+ var RULE_FEATURES10 = [
491
570
  "CHK"
492
571
  ];
493
572
  var no_script_url_default = createRule({
@@ -495,14 +574,14 @@ var no_script_url_default = createRule({
495
574
  type: "problem",
496
575
  docs: {
497
576
  description: "disallow 'javascript:' URLs as JSX event handler prop's value",
498
- [Symbol.for("rule_features")]: RULE_FEATURES9
577
+ [Symbol.for("rule_features")]: RULE_FEATURES10
499
578
  },
500
579
  messages: {
501
580
  noScriptUrl: "Using a `javascript:` URL is a security risk and should be avoided."
502
581
  },
503
582
  schema: []
504
583
  },
505
- name: RULE_NAME9,
584
+ name: RULE_NAME10,
506
585
  create: create9,
507
586
  defaultOptions: []
508
587
  });
@@ -525,7 +604,7 @@ function create9(context) {
525
604
  }
526
605
  };
527
606
  }
528
- var RULE_NAME10 = "no-unknown-property";
607
+ var RULE_NAME11 = "no-unknown-property";
529
608
  var DEFAULTS = {
530
609
  ignore: [],
531
610
  requireDataLowercase: false
@@ -1488,7 +1567,7 @@ var no_unknown_property_default = createRule({
1488
1567
  }
1489
1568
  }]
1490
1569
  },
1491
- name: RULE_NAME10,
1570
+ name: RULE_NAME11,
1492
1571
  create: create10,
1493
1572
  defaultOptions: []
1494
1573
  });
@@ -1584,8 +1663,8 @@ function testReactVersion(context, comparator, version2) {
1584
1663
  const { version: localVersion } = shared.getSettingsFromContext(context);
1585
1664
  return compareVersions.compare(localVersion, version2, comparator);
1586
1665
  }
1587
- var RULE_NAME11 = "no-unsafe-iframe-sandbox";
1588
- var RULE_FEATURES10 = [
1666
+ var RULE_NAME12 = "no-unsafe-iframe-sandbox";
1667
+ var RULE_FEATURES11 = [
1589
1668
  "CHK"
1590
1669
  ];
1591
1670
  var unsafeSandboxValues = [
@@ -1602,14 +1681,14 @@ var no_unsafe_iframe_sandbox_default = createRule({
1602
1681
  type: "problem",
1603
1682
  docs: {
1604
1683
  description: "disallow unsafe iframe 'sandbox' attribute combinations",
1605
- [Symbol.for("rule_features")]: RULE_FEATURES10
1684
+ [Symbol.for("rule_features")]: RULE_FEATURES11
1606
1685
  },
1607
1686
  messages: {
1608
1687
  noUnsafeIframeSandbox: "Unsafe 'sandbox' attribute value on 'iframe' component."
1609
1688
  },
1610
1689
  schema: []
1611
1690
  },
1612
- name: RULE_NAME11,
1691
+ name: RULE_NAME12,
1613
1692
  create: create11,
1614
1693
  defaultOptions: []
1615
1694
  });
@@ -1656,8 +1735,8 @@ function create11(context) {
1656
1735
  }
1657
1736
  };
1658
1737
  }
1659
- var RULE_NAME12 = "no-unsafe-target-blank";
1660
- var RULE_FEATURES11 = [
1738
+ var RULE_NAME13 = "no-unsafe-target-blank";
1739
+ var RULE_FEATURES12 = [
1661
1740
  "CHK"
1662
1741
  ];
1663
1742
  function isExternalLinkLike(value) {
@@ -1673,14 +1752,14 @@ var no_unsafe_target_blank_default = createRule({
1673
1752
  type: "problem",
1674
1753
  docs: {
1675
1754
  description: `disallow 'target="_blank"' on an external link without 'rel="noreferrer noopener"'`,
1676
- [Symbol.for("rule_features")]: RULE_FEATURES11
1755
+ [Symbol.for("rule_features")]: RULE_FEATURES12
1677
1756
  },
1678
1757
  messages: {
1679
1758
  noUnsafeTargetBlank: `Using 'target="_blank"' on an external link without 'rel="noreferrer noopener"' is a security risk.`
1680
1759
  },
1681
1760
  schema: []
1682
1761
  },
1683
- name: RULE_NAME12,
1762
+ name: RULE_NAME13,
1684
1763
  create: create12,
1685
1764
  defaultOptions: []
1686
1765
  });
@@ -1731,8 +1810,84 @@ function create12(context) {
1731
1810
  }
1732
1811
  };
1733
1812
  }
1734
- var RULE_NAME13 = "no-void-elements-with-children";
1735
- var RULE_FEATURES12 = [
1813
+ var RULE_NAME14 = "no-use-form-state";
1814
+ var RULE_FEATURES13 = [
1815
+ "CHK",
1816
+ "MOD"
1817
+ ];
1818
+ var no_use_form_state_default = createRule({
1819
+ meta: {
1820
+ type: "problem",
1821
+ docs: {
1822
+ description: "replace usages of 'ReactDom.render()' with 'createRoot(node).render()'",
1823
+ [Symbol.for("rule_features")]: RULE_FEATURES13
1824
+ },
1825
+ fixable: "code",
1826
+ messages: {
1827
+ noUseFormState: "[Deprecated] Use 'useActionState' from 'react' package instead."
1828
+ },
1829
+ schema: []
1830
+ },
1831
+ name: RULE_NAME14,
1832
+ create(context) {
1833
+ if (!context.sourceCode.text.includes("useFormState")) return {};
1834
+ const settings2 = shared.getSettingsFromContext(context);
1835
+ if (compareVersions.compare(settings2.version, "19.0.0", "<")) return {};
1836
+ const reactDomNames = /* @__PURE__ */ new Set();
1837
+ const useFormStateNames = /* @__PURE__ */ new Set();
1838
+ return {
1839
+ CallExpression(node) {
1840
+ switch (true) {
1841
+ case (node.callee.type === types.AST_NODE_TYPES.Identifier && useFormStateNames.has(node.callee.name)):
1842
+ context.report({
1843
+ messageId: "noUseFormState",
1844
+ node,
1845
+ fix: getFix2(context, node)
1846
+ });
1847
+ return;
1848
+ case (node.callee.type === types.AST_NODE_TYPES.MemberExpression && node.callee.object.type === types.AST_NODE_TYPES.Identifier && node.callee.property.type === types.AST_NODE_TYPES.Identifier && node.callee.property.name === "useFormState" && reactDomNames.has(node.callee.object.name)):
1849
+ context.report({
1850
+ messageId: "noUseFormState",
1851
+ node,
1852
+ fix: getFix2(context, node)
1853
+ });
1854
+ return;
1855
+ }
1856
+ },
1857
+ ImportDeclaration(node) {
1858
+ const [baseSource] = node.source.value.split("/");
1859
+ if (baseSource !== "react-dom") return;
1860
+ for (const specifier of node.specifiers) {
1861
+ switch (specifier.type) {
1862
+ case types.AST_NODE_TYPES.ImportSpecifier:
1863
+ if (specifier.imported.type !== types.AST_NODE_TYPES.Identifier) continue;
1864
+ if (specifier.imported.name === "useFormState") {
1865
+ useFormStateNames.add(specifier.local.name);
1866
+ }
1867
+ continue;
1868
+ case types.AST_NODE_TYPES.ImportDefaultSpecifier:
1869
+ case types.AST_NODE_TYPES.ImportNamespaceSpecifier:
1870
+ reactDomNames.add(specifier.local.name);
1871
+ continue;
1872
+ }
1873
+ }
1874
+ }
1875
+ };
1876
+ },
1877
+ defaultOptions: []
1878
+ });
1879
+ function getFix2(context, node) {
1880
+ const { importSource } = shared.getSettingsFromContext(context);
1881
+ return (fixer) => {
1882
+ return [
1883
+ fixer.insertTextBefore(context.sourceCode.ast, `import { useActionState } from "${importSource}";
1884
+ `),
1885
+ fixer.replaceText(node.callee, "useActionState")
1886
+ ];
1887
+ };
1888
+ }
1889
+ var RULE_NAME15 = "no-void-elements-with-children";
1890
+ var RULE_FEATURES14 = [
1736
1891
  "CHK"
1737
1892
  ];
1738
1893
  var voidElements = /* @__PURE__ */ new Set([
@@ -1758,14 +1913,14 @@ var no_void_elements_with_children_default = createRule({
1758
1913
  type: "problem",
1759
1914
  docs: {
1760
1915
  description: "disallow void elements (AKA self-closing elements) from having children",
1761
- [Symbol.for("rule_features")]: RULE_FEATURES12
1916
+ [Symbol.for("rule_features")]: RULE_FEATURES14
1762
1917
  },
1763
1918
  messages: {
1764
1919
  noVoidElementsWithChildren: "'{{element}}' is a void element tag and must not have children."
1765
1920
  },
1766
1921
  schema: []
1767
1922
  },
1768
- name: RULE_NAME13,
1923
+ name: RULE_NAME15,
1769
1924
  create: create13,
1770
1925
  defaultOptions: []
1771
1926
  });
@@ -1815,11 +1970,13 @@ var plugin = {
1815
1970
  "no-missing-button-type": no_missing_button_type_default,
1816
1971
  "no-missing-iframe-sandbox": no_missing_iframe_sandbox_default,
1817
1972
  "no-namespace": no_namespace_default,
1973
+ "no-render": no_render_default,
1818
1974
  "no-render-return-value": no_render_return_value_default,
1819
1975
  "no-script-url": no_script_url_default,
1820
1976
  "no-unknown-property": no_unknown_property_default,
1821
1977
  "no-unsafe-iframe-sandbox": no_unsafe_iframe_sandbox_default,
1822
1978
  "no-unsafe-target-blank": no_unsafe_target_blank_default,
1979
+ "no-use-form-state": no_use_form_state_default,
1823
1980
  "no-void-elements-with-children": no_void_elements_with_children_default,
1824
1981
  // Part: deprecated rules
1825
1982
  /** @deprecated Use `no-void-elements-with-children` instead */
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  import { createRuleForPlugin, getSettingsFromContext, RE_JAVASCRIPT_PROTOCOL, DEFAULT_ESLINT_REACT_SETTINGS } from '@eslint-react/shared';
2
2
  import * as JSX from '@eslint-react/jsx';
3
3
  import { AST_NODE_TYPES } from '@typescript-eslint/types';
4
- import * as AST from '@eslint-react/ast';
5
4
  import { compare } from 'compare-versions';
5
+ import * as AST from '@eslint-react/ast';
6
6
  import { _ } from '@eslint-react/eff';
7
7
 
8
8
  var __defProp = Object.defineProperty;
@@ -27,11 +27,13 @@ var rules = {
27
27
  "react-dom/no-missing-button-type": "warn",
28
28
  "react-dom/no-missing-iframe-sandbox": "warn",
29
29
  "react-dom/no-namespace": "error",
30
+ "react-dom/no-render": "error",
30
31
  "react-dom/no-render-return-value": "error",
31
32
  "react-dom/no-script-url": "warn",
32
33
  "react-dom/no-unknown-property": "warn",
33
34
  "react-dom/no-unsafe-iframe-sandbox": "warn",
34
35
  "react-dom/no-unsafe-target-blank": "warn",
36
+ "react-dom/no-use-form-state": "error",
35
37
  "react-dom/no-void-elements-with-children": "error"
36
38
  };
37
39
  var settings = {
@@ -40,7 +42,7 @@ var settings = {
40
42
 
41
43
  // package.json
42
44
  var name2 = "eslint-plugin-react-dom";
43
- var version = "1.34.2-beta.0";
45
+ var version = "1.34.2-beta.2";
44
46
  var createRule = createRuleForPlugin("dom");
45
47
 
46
48
  // src/utils/find-custom-component.ts
@@ -409,8 +411,85 @@ function create7(context) {
409
411
  }
410
412
  };
411
413
  }
412
- var RULE_NAME8 = "no-render-return-value";
414
+ var RULE_NAME8 = "no-render";
413
415
  var RULE_FEATURES8 = [
416
+ "CHK",
417
+ "MOD"
418
+ ];
419
+ var no_render_default = createRule({
420
+ meta: {
421
+ type: "problem",
422
+ docs: {
423
+ description: "replace usages of 'ReactDom.render()' with 'createRoot(node).render()'",
424
+ [Symbol.for("rule_features")]: RULE_FEATURES8
425
+ },
426
+ fixable: "code",
427
+ messages: {
428
+ noRender: "[Deprecated] Use 'createRoot(node).render()' instead."
429
+ },
430
+ schema: []
431
+ },
432
+ name: RULE_NAME8,
433
+ create(context) {
434
+ if (!context.sourceCode.text.includes("render")) return {};
435
+ const settings2 = getSettingsFromContext(context);
436
+ if (compare(settings2.version, "18.0.0", "<")) return {};
437
+ const reactDomNames = /* @__PURE__ */ new Set();
438
+ const renderNames = /* @__PURE__ */ new Set();
439
+ return {
440
+ CallExpression(node) {
441
+ switch (true) {
442
+ case (node.callee.type === AST_NODE_TYPES.Identifier && renderNames.has(node.callee.name)):
443
+ context.report({
444
+ messageId: "noRender",
445
+ node,
446
+ fix: getFix(context, node)
447
+ });
448
+ return;
449
+ case (node.callee.type === AST_NODE_TYPES.MemberExpression && node.callee.object.type === AST_NODE_TYPES.Identifier && node.callee.property.type === AST_NODE_TYPES.Identifier && node.callee.property.name === "render" && reactDomNames.has(node.callee.object.name)):
450
+ context.report({
451
+ messageId: "noRender",
452
+ node,
453
+ fix: getFix(context, node)
454
+ });
455
+ return;
456
+ }
457
+ },
458
+ ImportDeclaration(node) {
459
+ const [baseSource] = node.source.value.split("/");
460
+ if (baseSource !== "react-dom") return;
461
+ for (const specifier of node.specifiers) {
462
+ switch (specifier.type) {
463
+ case AST_NODE_TYPES.ImportSpecifier:
464
+ if (specifier.imported.type !== AST_NODE_TYPES.Identifier) continue;
465
+ if (specifier.imported.name === "render") {
466
+ renderNames.add(specifier.local.name);
467
+ }
468
+ continue;
469
+ case AST_NODE_TYPES.ImportDefaultSpecifier:
470
+ case AST_NODE_TYPES.ImportNamespaceSpecifier:
471
+ reactDomNames.add(specifier.local.name);
472
+ continue;
473
+ }
474
+ }
475
+ }
476
+ };
477
+ },
478
+ defaultOptions: []
479
+ });
480
+ function getFix(context, node) {
481
+ const getText2 = (n) => context.sourceCode.getText(n);
482
+ return (fixer) => {
483
+ const [arg0, arg1] = node.arguments;
484
+ if (arg0 == null || arg1 == null) return null;
485
+ return [
486
+ fixer.insertTextBefore(context.sourceCode.ast, 'import { createRoot } from "react-dom/client";\n'),
487
+ fixer.replaceText(node, `createRoot(${getText2(arg1)}).render(${getText2(arg0)})`)
488
+ ];
489
+ };
490
+ }
491
+ var RULE_NAME9 = "no-render-return-value";
492
+ var RULE_FEATURES9 = [
414
493
  "CHK"
415
494
  ];
416
495
  var banParentTypes = [
@@ -425,14 +504,14 @@ var no_render_return_value_default = createRule({
425
504
  type: "problem",
426
505
  docs: {
427
506
  description: "disallow usage of the return value of 'ReactDOM.render'",
428
- [Symbol.for("rule_features")]: RULE_FEATURES8
507
+ [Symbol.for("rule_features")]: RULE_FEATURES9
429
508
  },
430
509
  messages: {
431
510
  noRenderReturnValue: "Do not depend on the return value from '{{objectName}}.render'."
432
511
  },
433
512
  schema: []
434
513
  },
435
- name: RULE_NAME8,
514
+ name: RULE_NAME9,
436
515
  create: create8,
437
516
  defaultOptions: []
438
517
  });
@@ -463,8 +542,8 @@ function create8(context) {
463
542
  }
464
543
  };
465
544
  }
466
- var RULE_NAME9 = "no-script-url";
467
- var RULE_FEATURES9 = [
545
+ var RULE_NAME10 = "no-script-url";
546
+ var RULE_FEATURES10 = [
468
547
  "CHK"
469
548
  ];
470
549
  var no_script_url_default = createRule({
@@ -472,14 +551,14 @@ var no_script_url_default = createRule({
472
551
  type: "problem",
473
552
  docs: {
474
553
  description: "disallow 'javascript:' URLs as JSX event handler prop's value",
475
- [Symbol.for("rule_features")]: RULE_FEATURES9
554
+ [Symbol.for("rule_features")]: RULE_FEATURES10
476
555
  },
477
556
  messages: {
478
557
  noScriptUrl: "Using a `javascript:` URL is a security risk and should be avoided."
479
558
  },
480
559
  schema: []
481
560
  },
482
- name: RULE_NAME9,
561
+ name: RULE_NAME10,
483
562
  create: create9,
484
563
  defaultOptions: []
485
564
  });
@@ -502,7 +581,7 @@ function create9(context) {
502
581
  }
503
582
  };
504
583
  }
505
- var RULE_NAME10 = "no-unknown-property";
584
+ var RULE_NAME11 = "no-unknown-property";
506
585
  var DEFAULTS = {
507
586
  ignore: [],
508
587
  requireDataLowercase: false
@@ -1465,7 +1544,7 @@ var no_unknown_property_default = createRule({
1465
1544
  }
1466
1545
  }]
1467
1546
  },
1468
- name: RULE_NAME10,
1547
+ name: RULE_NAME11,
1469
1548
  create: create10,
1470
1549
  defaultOptions: []
1471
1550
  });
@@ -1561,8 +1640,8 @@ function testReactVersion(context, comparator, version2) {
1561
1640
  const { version: localVersion } = getSettingsFromContext(context);
1562
1641
  return compare(localVersion, version2, comparator);
1563
1642
  }
1564
- var RULE_NAME11 = "no-unsafe-iframe-sandbox";
1565
- var RULE_FEATURES10 = [
1643
+ var RULE_NAME12 = "no-unsafe-iframe-sandbox";
1644
+ var RULE_FEATURES11 = [
1566
1645
  "CHK"
1567
1646
  ];
1568
1647
  var unsafeSandboxValues = [
@@ -1579,14 +1658,14 @@ var no_unsafe_iframe_sandbox_default = createRule({
1579
1658
  type: "problem",
1580
1659
  docs: {
1581
1660
  description: "disallow unsafe iframe 'sandbox' attribute combinations",
1582
- [Symbol.for("rule_features")]: RULE_FEATURES10
1661
+ [Symbol.for("rule_features")]: RULE_FEATURES11
1583
1662
  },
1584
1663
  messages: {
1585
1664
  noUnsafeIframeSandbox: "Unsafe 'sandbox' attribute value on 'iframe' component."
1586
1665
  },
1587
1666
  schema: []
1588
1667
  },
1589
- name: RULE_NAME11,
1668
+ name: RULE_NAME12,
1590
1669
  create: create11,
1591
1670
  defaultOptions: []
1592
1671
  });
@@ -1633,8 +1712,8 @@ function create11(context) {
1633
1712
  }
1634
1713
  };
1635
1714
  }
1636
- var RULE_NAME12 = "no-unsafe-target-blank";
1637
- var RULE_FEATURES11 = [
1715
+ var RULE_NAME13 = "no-unsafe-target-blank";
1716
+ var RULE_FEATURES12 = [
1638
1717
  "CHK"
1639
1718
  ];
1640
1719
  function isExternalLinkLike(value) {
@@ -1650,14 +1729,14 @@ var no_unsafe_target_blank_default = createRule({
1650
1729
  type: "problem",
1651
1730
  docs: {
1652
1731
  description: `disallow 'target="_blank"' on an external link without 'rel="noreferrer noopener"'`,
1653
- [Symbol.for("rule_features")]: RULE_FEATURES11
1732
+ [Symbol.for("rule_features")]: RULE_FEATURES12
1654
1733
  },
1655
1734
  messages: {
1656
1735
  noUnsafeTargetBlank: `Using 'target="_blank"' on an external link without 'rel="noreferrer noopener"' is a security risk.`
1657
1736
  },
1658
1737
  schema: []
1659
1738
  },
1660
- name: RULE_NAME12,
1739
+ name: RULE_NAME13,
1661
1740
  create: create12,
1662
1741
  defaultOptions: []
1663
1742
  });
@@ -1708,8 +1787,84 @@ function create12(context) {
1708
1787
  }
1709
1788
  };
1710
1789
  }
1711
- var RULE_NAME13 = "no-void-elements-with-children";
1712
- var RULE_FEATURES12 = [
1790
+ var RULE_NAME14 = "no-use-form-state";
1791
+ var RULE_FEATURES13 = [
1792
+ "CHK",
1793
+ "MOD"
1794
+ ];
1795
+ var no_use_form_state_default = createRule({
1796
+ meta: {
1797
+ type: "problem",
1798
+ docs: {
1799
+ description: "replace usages of 'ReactDom.render()' with 'createRoot(node).render()'",
1800
+ [Symbol.for("rule_features")]: RULE_FEATURES13
1801
+ },
1802
+ fixable: "code",
1803
+ messages: {
1804
+ noUseFormState: "[Deprecated] Use 'useActionState' from 'react' package instead."
1805
+ },
1806
+ schema: []
1807
+ },
1808
+ name: RULE_NAME14,
1809
+ create(context) {
1810
+ if (!context.sourceCode.text.includes("useFormState")) return {};
1811
+ const settings2 = getSettingsFromContext(context);
1812
+ if (compare(settings2.version, "19.0.0", "<")) return {};
1813
+ const reactDomNames = /* @__PURE__ */ new Set();
1814
+ const useFormStateNames = /* @__PURE__ */ new Set();
1815
+ return {
1816
+ CallExpression(node) {
1817
+ switch (true) {
1818
+ case (node.callee.type === AST_NODE_TYPES.Identifier && useFormStateNames.has(node.callee.name)):
1819
+ context.report({
1820
+ messageId: "noUseFormState",
1821
+ node,
1822
+ fix: getFix2(context, node)
1823
+ });
1824
+ return;
1825
+ case (node.callee.type === AST_NODE_TYPES.MemberExpression && node.callee.object.type === AST_NODE_TYPES.Identifier && node.callee.property.type === AST_NODE_TYPES.Identifier && node.callee.property.name === "useFormState" && reactDomNames.has(node.callee.object.name)):
1826
+ context.report({
1827
+ messageId: "noUseFormState",
1828
+ node,
1829
+ fix: getFix2(context, node)
1830
+ });
1831
+ return;
1832
+ }
1833
+ },
1834
+ ImportDeclaration(node) {
1835
+ const [baseSource] = node.source.value.split("/");
1836
+ if (baseSource !== "react-dom") return;
1837
+ for (const specifier of node.specifiers) {
1838
+ switch (specifier.type) {
1839
+ case AST_NODE_TYPES.ImportSpecifier:
1840
+ if (specifier.imported.type !== AST_NODE_TYPES.Identifier) continue;
1841
+ if (specifier.imported.name === "useFormState") {
1842
+ useFormStateNames.add(specifier.local.name);
1843
+ }
1844
+ continue;
1845
+ case AST_NODE_TYPES.ImportDefaultSpecifier:
1846
+ case AST_NODE_TYPES.ImportNamespaceSpecifier:
1847
+ reactDomNames.add(specifier.local.name);
1848
+ continue;
1849
+ }
1850
+ }
1851
+ }
1852
+ };
1853
+ },
1854
+ defaultOptions: []
1855
+ });
1856
+ function getFix2(context, node) {
1857
+ const { importSource } = getSettingsFromContext(context);
1858
+ return (fixer) => {
1859
+ return [
1860
+ fixer.insertTextBefore(context.sourceCode.ast, `import { useActionState } from "${importSource}";
1861
+ `),
1862
+ fixer.replaceText(node.callee, "useActionState")
1863
+ ];
1864
+ };
1865
+ }
1866
+ var RULE_NAME15 = "no-void-elements-with-children";
1867
+ var RULE_FEATURES14 = [
1713
1868
  "CHK"
1714
1869
  ];
1715
1870
  var voidElements = /* @__PURE__ */ new Set([
@@ -1735,14 +1890,14 @@ var no_void_elements_with_children_default = createRule({
1735
1890
  type: "problem",
1736
1891
  docs: {
1737
1892
  description: "disallow void elements (AKA self-closing elements) from having children",
1738
- [Symbol.for("rule_features")]: RULE_FEATURES12
1893
+ [Symbol.for("rule_features")]: RULE_FEATURES14
1739
1894
  },
1740
1895
  messages: {
1741
1896
  noVoidElementsWithChildren: "'{{element}}' is a void element tag and must not have children."
1742
1897
  },
1743
1898
  schema: []
1744
1899
  },
1745
- name: RULE_NAME13,
1900
+ name: RULE_NAME15,
1746
1901
  create: create13,
1747
1902
  defaultOptions: []
1748
1903
  });
@@ -1792,11 +1947,13 @@ var plugin = {
1792
1947
  "no-missing-button-type": no_missing_button_type_default,
1793
1948
  "no-missing-iframe-sandbox": no_missing_iframe_sandbox_default,
1794
1949
  "no-namespace": no_namespace_default,
1950
+ "no-render": no_render_default,
1795
1951
  "no-render-return-value": no_render_return_value_default,
1796
1952
  "no-script-url": no_script_url_default,
1797
1953
  "no-unknown-property": no_unknown_property_default,
1798
1954
  "no-unsafe-iframe-sandbox": no_unsafe_iframe_sandbox_default,
1799
1955
  "no-unsafe-target-blank": no_unsafe_target_blank_default,
1956
+ "no-use-form-state": no_use_form_state_default,
1800
1957
  "no-void-elements-with-children": no_void_elements_with_children_default,
1801
1958
  // Part: deprecated rules
1802
1959
  /** @deprecated Use `no-void-elements-with-children` instead */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-react-dom",
3
- "version": "1.34.2-beta.0",
3
+ "version": "1.34.2-beta.2",
4
4
  "description": "ESLint React's ESLint plugin for React DOM related rules.",
5
5
  "keywords": [
6
6
  "react",
@@ -49,12 +49,12 @@
49
49
  "compare-versions": "^6.1.1",
50
50
  "string-ts": "^2.2.1",
51
51
  "ts-pattern": "^5.6.2",
52
- "@eslint-react/ast": "1.34.2-beta.0",
53
- "@eslint-react/eff": "1.34.2-beta.0",
54
- "@eslint-react/core": "1.34.2-beta.0",
55
- "@eslint-react/var": "1.34.2-beta.0",
56
- "@eslint-react/shared": "1.34.2-beta.0",
57
- "@eslint-react/jsx": "1.34.2-beta.0"
52
+ "@eslint-react/ast": "1.34.2-beta.2",
53
+ "@eslint-react/core": "1.34.2-beta.2",
54
+ "@eslint-react/eff": "1.34.2-beta.2",
55
+ "@eslint-react/jsx": "1.34.2-beta.2",
56
+ "@eslint-react/var": "1.34.2-beta.2",
57
+ "@eslint-react/shared": "1.34.2-beta.2"
58
58
  },
59
59
  "devDependencies": {
60
60
  "@types/react": "^19.0.10",