eslint-plugin-react-dom 1.34.2-beta.0 → 1.34.2-beta.3

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
@@ -15,14 +15,17 @@ declare const _default: {
15
15
  readonly "no-dangerously-set-innerhtml-with-children": _typescript_eslint_utils_ts_eslint.RuleModule<"noDangerouslySetInnerhtmlWithChildren", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
16
16
  readonly "no-find-dom-node": _typescript_eslint_utils_ts_eslint.RuleModule<"noFindDomNode", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
17
17
  readonly "no-flush-sync": _typescript_eslint_utils_ts_eslint.RuleModule<"noFlushSync", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
18
+ readonly "no-hydrate": _typescript_eslint_utils_ts_eslint.RuleModule<"noHydrate", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
18
19
  readonly "no-missing-button-type": _typescript_eslint_utils_ts_eslint.RuleModule<"noMissingButtonType", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
19
20
  readonly "no-missing-iframe-sandbox": _typescript_eslint_utils_ts_eslint.RuleModule<"noMissingIframeSandbox", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
20
21
  readonly "no-namespace": _typescript_eslint_utils_ts_eslint.RuleModule<"noNamespace", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
22
+ readonly "no-render": _typescript_eslint_utils_ts_eslint.RuleModule<"noRender", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
21
23
  readonly "no-render-return-value": _typescript_eslint_utils_ts_eslint.RuleModule<"noRenderReturnValue", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
22
24
  readonly "no-script-url": _typescript_eslint_utils_ts_eslint.RuleModule<"noScriptUrl", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
23
25
  readonly "no-unknown-property": _typescript_eslint_utils_ts_eslint.RuleModule<"dataLowercaseRequired" | "invalidPropOnTag" | "unknownProp" | "unknownPropWithStandardName", unknown[], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
24
26
  readonly "no-unsafe-iframe-sandbox": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnsafeIframeSandbox", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
25
27
  readonly "no-unsafe-target-blank": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnsafeTargetBlank", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
28
+ readonly "no-use-form-state": _typescript_eslint_utils_ts_eslint.RuleModule<"noUseFormState", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
26
29
  readonly "no-void-elements-with-children": _typescript_eslint_utils_ts_eslint.RuleModule<"noVoidElementsWithChildren", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
27
30
  readonly "no-children-in-void-dom-elements": _typescript_eslint_utils_ts_eslint.RuleModule<"noVoidElementsWithChildren", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
28
31
  };
@@ -45,14 +48,17 @@ declare const _default: {
45
48
  readonly "no-dangerously-set-innerhtml-with-children": _typescript_eslint_utils_ts_eslint.RuleModule<"noDangerouslySetInnerhtmlWithChildren", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
46
49
  readonly "no-find-dom-node": _typescript_eslint_utils_ts_eslint.RuleModule<"noFindDomNode", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
47
50
  readonly "no-flush-sync": _typescript_eslint_utils_ts_eslint.RuleModule<"noFlushSync", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
51
+ readonly "no-hydrate": _typescript_eslint_utils_ts_eslint.RuleModule<"noHydrate", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
48
52
  readonly "no-missing-button-type": _typescript_eslint_utils_ts_eslint.RuleModule<"noMissingButtonType", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
49
53
  readonly "no-missing-iframe-sandbox": _typescript_eslint_utils_ts_eslint.RuleModule<"noMissingIframeSandbox", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
50
54
  readonly "no-namespace": _typescript_eslint_utils_ts_eslint.RuleModule<"noNamespace", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
55
+ readonly "no-render": _typescript_eslint_utils_ts_eslint.RuleModule<"noRender", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
51
56
  readonly "no-render-return-value": _typescript_eslint_utils_ts_eslint.RuleModule<"noRenderReturnValue", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
52
57
  readonly "no-script-url": _typescript_eslint_utils_ts_eslint.RuleModule<"noScriptUrl", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
53
58
  readonly "no-unknown-property": _typescript_eslint_utils_ts_eslint.RuleModule<"dataLowercaseRequired" | "invalidPropOnTag" | "unknownProp" | "unknownPropWithStandardName", unknown[], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
54
59
  readonly "no-unsafe-iframe-sandbox": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnsafeIframeSandbox", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
55
60
  readonly "no-unsafe-target-blank": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnsafeTargetBlank", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
61
+ readonly "no-use-form-state": _typescript_eslint_utils_ts_eslint.RuleModule<"noUseFormState", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
56
62
  readonly "no-void-elements-with-children": _typescript_eslint_utils_ts_eslint.RuleModule<"noVoidElementsWithChildren", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
57
63
  readonly "no-children-in-void-dom-elements": _typescript_eslint_utils_ts_eslint.RuleModule<"noVoidElementsWithChildren", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
58
64
  };
package/dist/index.d.ts CHANGED
@@ -15,14 +15,17 @@ declare const _default: {
15
15
  readonly "no-dangerously-set-innerhtml-with-children": _typescript_eslint_utils_ts_eslint.RuleModule<"noDangerouslySetInnerhtmlWithChildren", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
16
16
  readonly "no-find-dom-node": _typescript_eslint_utils_ts_eslint.RuleModule<"noFindDomNode", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
17
17
  readonly "no-flush-sync": _typescript_eslint_utils_ts_eslint.RuleModule<"noFlushSync", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
18
+ readonly "no-hydrate": _typescript_eslint_utils_ts_eslint.RuleModule<"noHydrate", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
18
19
  readonly "no-missing-button-type": _typescript_eslint_utils_ts_eslint.RuleModule<"noMissingButtonType", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
19
20
  readonly "no-missing-iframe-sandbox": _typescript_eslint_utils_ts_eslint.RuleModule<"noMissingIframeSandbox", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
20
21
  readonly "no-namespace": _typescript_eslint_utils_ts_eslint.RuleModule<"noNamespace", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
22
+ readonly "no-render": _typescript_eslint_utils_ts_eslint.RuleModule<"noRender", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
21
23
  readonly "no-render-return-value": _typescript_eslint_utils_ts_eslint.RuleModule<"noRenderReturnValue", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
22
24
  readonly "no-script-url": _typescript_eslint_utils_ts_eslint.RuleModule<"noScriptUrl", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
23
25
  readonly "no-unknown-property": _typescript_eslint_utils_ts_eslint.RuleModule<"dataLowercaseRequired" | "invalidPropOnTag" | "unknownProp" | "unknownPropWithStandardName", unknown[], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
24
26
  readonly "no-unsafe-iframe-sandbox": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnsafeIframeSandbox", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
25
27
  readonly "no-unsafe-target-blank": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnsafeTargetBlank", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
28
+ readonly "no-use-form-state": _typescript_eslint_utils_ts_eslint.RuleModule<"noUseFormState", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
26
29
  readonly "no-void-elements-with-children": _typescript_eslint_utils_ts_eslint.RuleModule<"noVoidElementsWithChildren", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
27
30
  readonly "no-children-in-void-dom-elements": _typescript_eslint_utils_ts_eslint.RuleModule<"noVoidElementsWithChildren", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
28
31
  };
@@ -45,14 +48,17 @@ declare const _default: {
45
48
  readonly "no-dangerously-set-innerhtml-with-children": _typescript_eslint_utils_ts_eslint.RuleModule<"noDangerouslySetInnerhtmlWithChildren", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
46
49
  readonly "no-find-dom-node": _typescript_eslint_utils_ts_eslint.RuleModule<"noFindDomNode", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
47
50
  readonly "no-flush-sync": _typescript_eslint_utils_ts_eslint.RuleModule<"noFlushSync", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
51
+ readonly "no-hydrate": _typescript_eslint_utils_ts_eslint.RuleModule<"noHydrate", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
48
52
  readonly "no-missing-button-type": _typescript_eslint_utils_ts_eslint.RuleModule<"noMissingButtonType", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
49
53
  readonly "no-missing-iframe-sandbox": _typescript_eslint_utils_ts_eslint.RuleModule<"noMissingIframeSandbox", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
50
54
  readonly "no-namespace": _typescript_eslint_utils_ts_eslint.RuleModule<"noNamespace", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
55
+ readonly "no-render": _typescript_eslint_utils_ts_eslint.RuleModule<"noRender", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
51
56
  readonly "no-render-return-value": _typescript_eslint_utils_ts_eslint.RuleModule<"noRenderReturnValue", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
52
57
  readonly "no-script-url": _typescript_eslint_utils_ts_eslint.RuleModule<"noScriptUrl", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
53
58
  readonly "no-unknown-property": _typescript_eslint_utils_ts_eslint.RuleModule<"dataLowercaseRequired" | "invalidPropOnTag" | "unknownProp" | "unknownPropWithStandardName", unknown[], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
54
59
  readonly "no-unsafe-iframe-sandbox": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnsafeIframeSandbox", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
55
60
  readonly "no-unsafe-target-blank": _typescript_eslint_utils_ts_eslint.RuleModule<"noUnsafeTargetBlank", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
61
+ readonly "no-use-form-state": _typescript_eslint_utils_ts_eslint.RuleModule<"noUseFormState", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
56
62
  readonly "no-void-elements-with-children": _typescript_eslint_utils_ts_eslint.RuleModule<"noVoidElementsWithChildren", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
57
63
  readonly "no-children-in-void-dom-elements": _typescript_eslint_utils_ts_eslint.RuleModule<"noVoidElementsWithChildren", [], unknown, _typescript_eslint_utils_ts_eslint.RuleListener>;
58
64
  };
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) {
@@ -47,14 +47,17 @@ var rules = {
47
47
  "react-dom/no-dangerously-set-innerhtml-with-children": "error",
48
48
  "react-dom/no-find-dom-node": "error",
49
49
  "react-dom/no-flush-sync": "error",
50
+ "react-dom/no-hydrate": "error",
50
51
  "react-dom/no-missing-button-type": "warn",
51
52
  "react-dom/no-missing-iframe-sandbox": "warn",
52
53
  "react-dom/no-namespace": "error",
54
+ "react-dom/no-render": "error",
53
55
  "react-dom/no-render-return-value": "error",
54
56
  "react-dom/no-script-url": "warn",
55
57
  "react-dom/no-unknown-property": "warn",
56
58
  "react-dom/no-unsafe-iframe-sandbox": "warn",
57
59
  "react-dom/no-unsafe-target-blank": "warn",
60
+ "react-dom/no-use-form-state": "error",
58
61
  "react-dom/no-void-elements-with-children": "error"
59
62
  };
60
63
  var settings = {
@@ -63,7 +66,7 @@ var settings = {
63
66
 
64
67
  // package.json
65
68
  var name2 = "eslint-plugin-react-dom";
66
- var version = "1.34.2-beta.0";
69
+ var version = "1.34.2-beta.3";
67
70
  var createRule = shared.createRuleForPlugin("dom");
68
71
 
69
72
  // src/utils/find-custom-component.ts
@@ -251,8 +254,85 @@ function create4(context) {
251
254
  }
252
255
  };
253
256
  }
254
- var RULE_NAME5 = "no-missing-button-type";
257
+ var RULE_NAME5 = "no-hydrate";
255
258
  var RULE_FEATURES5 = [
259
+ "CHK",
260
+ "MOD"
261
+ ];
262
+ var no_hydrate_default = createRule({
263
+ meta: {
264
+ type: "problem",
265
+ docs: {
266
+ description: "replaces usages of 'ReactDom.hydrate()' with 'hydrateRoot()'",
267
+ [Symbol.for("rule_features")]: RULE_FEATURES5
268
+ },
269
+ fixable: "code",
270
+ messages: {
271
+ noHydrate: "[Deprecated] Use 'hydrateRoot()' instead."
272
+ },
273
+ schema: []
274
+ },
275
+ name: RULE_NAME5,
276
+ create(context) {
277
+ if (!context.sourceCode.text.includes("hydrate")) return {};
278
+ const settings2 = shared.getSettingsFromContext(context);
279
+ if (compareVersions.compare(settings2.version, "18.0.0", "<")) return {};
280
+ const reactDomNames = /* @__PURE__ */ new Set();
281
+ const hydrateNames = /* @__PURE__ */ new Set();
282
+ return {
283
+ CallExpression(node) {
284
+ switch (true) {
285
+ case (node.callee.type === types.AST_NODE_TYPES.Identifier && hydrateNames.has(node.callee.name)):
286
+ context.report({
287
+ messageId: "noHydrate",
288
+ node,
289
+ fix: getFix(context, node)
290
+ });
291
+ return;
292
+ 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 === "hydrate" && reactDomNames.has(node.callee.object.name)):
293
+ context.report({
294
+ messageId: "noHydrate",
295
+ node,
296
+ fix: getFix(context, node)
297
+ });
298
+ return;
299
+ }
300
+ },
301
+ ImportDeclaration(node) {
302
+ const [baseSource] = node.source.value.split("/");
303
+ if (baseSource !== "react-dom") return;
304
+ for (const specifier of node.specifiers) {
305
+ switch (specifier.type) {
306
+ case types.AST_NODE_TYPES.ImportSpecifier:
307
+ if (specifier.imported.type !== types.AST_NODE_TYPES.Identifier) continue;
308
+ if (specifier.imported.name === "hydrate") {
309
+ hydrateNames.add(specifier.local.name);
310
+ }
311
+ continue;
312
+ case types.AST_NODE_TYPES.ImportDefaultSpecifier:
313
+ case types.AST_NODE_TYPES.ImportNamespaceSpecifier:
314
+ reactDomNames.add(specifier.local.name);
315
+ continue;
316
+ }
317
+ }
318
+ }
319
+ };
320
+ },
321
+ defaultOptions: []
322
+ });
323
+ function getFix(context, node) {
324
+ const getText2 = (n) => context.sourceCode.getText(n);
325
+ return (fixer) => {
326
+ const [arg0, arg1] = node.arguments;
327
+ if (arg0 == null || arg1 == null) return null;
328
+ return [
329
+ fixer.insertTextBefore(context.sourceCode.ast, 'import { hydrateRoot } from "react-dom/client";\n'),
330
+ fixer.replaceText(node, `hydrateRoot(${getText2(arg1)}, ${getText2(arg0)})`)
331
+ ];
332
+ };
333
+ }
334
+ var RULE_NAME6 = "no-missing-button-type";
335
+ var RULE_FEATURES6 = [
256
336
  "CHK"
257
337
  ];
258
338
  var no_missing_button_type_default = createRule({
@@ -260,14 +340,14 @@ var no_missing_button_type_default = createRule({
260
340
  type: "problem",
261
341
  docs: {
262
342
  description: "enforce that button component have an explicit 'type' attribute",
263
- [Symbol.for("rule_features")]: RULE_FEATURES5
343
+ [Symbol.for("rule_features")]: RULE_FEATURES6
264
344
  },
265
345
  messages: {
266
346
  noMissingButtonType: "Add missing 'type' attribute on 'button' component."
267
347
  },
268
348
  schema: []
269
349
  },
270
- name: RULE_NAME5,
350
+ name: RULE_NAME6,
271
351
  create: create5,
272
352
  defaultOptions: []
273
353
  });
@@ -313,8 +393,8 @@ function create5(context) {
313
393
  }
314
394
  };
315
395
  }
316
- var RULE_NAME6 = "no-missing-iframe-sandbox";
317
- var RULE_FEATURES6 = [
396
+ var RULE_NAME7 = "no-missing-iframe-sandbox";
397
+ var RULE_FEATURES7 = [
318
398
  "CHK"
319
399
  ];
320
400
  var validTypes = [
@@ -343,14 +423,14 @@ var no_missing_iframe_sandbox_default = createRule({
343
423
  type: "problem",
344
424
  docs: {
345
425
  description: "enforce that 'iframe' component have an explicit 'sandbox' attribute",
346
- [Symbol.for("rule_features")]: RULE_FEATURES6
426
+ [Symbol.for("rule_features")]: RULE_FEATURES7
347
427
  },
348
428
  messages: {
349
429
  noMissingIframeSandbox: "Add missing 'sandbox' attribute on 'iframe' component."
350
430
  },
351
431
  schema: []
352
432
  },
353
- name: RULE_NAME6,
433
+ name: RULE_NAME7,
354
434
  create: create6,
355
435
  defaultOptions: []
356
436
  });
@@ -395,8 +475,8 @@ function create6(context) {
395
475
  }
396
476
  };
397
477
  }
398
- var RULE_NAME7 = "no-namespace";
399
- var RULE_FEATURES7 = [
478
+ var RULE_NAME8 = "no-namespace";
479
+ var RULE_FEATURES8 = [
400
480
  "CHK"
401
481
  ];
402
482
  var no_namespace_default = createRule({
@@ -404,14 +484,14 @@ var no_namespace_default = createRule({
404
484
  type: "problem",
405
485
  docs: {
406
486
  description: "enforce that namespaces are not used in React elements",
407
- [Symbol.for("rule_features")]: RULE_FEATURES7
487
+ [Symbol.for("rule_features")]: RULE_FEATURES8
408
488
  },
409
489
  messages: {
410
490
  noNamespace: "A React component '{{name}}' must not be in a namespace, as React does not support them."
411
491
  },
412
492
  schema: []
413
493
  },
414
- name: RULE_NAME7,
494
+ name: RULE_NAME8,
415
495
  create: create7,
416
496
  defaultOptions: []
417
497
  });
@@ -432,8 +512,85 @@ function create7(context) {
432
512
  }
433
513
  };
434
514
  }
435
- var RULE_NAME8 = "no-render-return-value";
436
- var RULE_FEATURES8 = [
515
+ var RULE_NAME9 = "no-render";
516
+ var RULE_FEATURES9 = [
517
+ "CHK",
518
+ "MOD"
519
+ ];
520
+ var no_render_default = createRule({
521
+ meta: {
522
+ type: "problem",
523
+ docs: {
524
+ description: "replace usages of 'ReactDom.render()' with 'createRoot(node).render()'",
525
+ [Symbol.for("rule_features")]: RULE_FEATURES9
526
+ },
527
+ fixable: "code",
528
+ messages: {
529
+ noRender: "[Deprecated] Use 'createRoot(node).render()' instead."
530
+ },
531
+ schema: []
532
+ },
533
+ name: RULE_NAME9,
534
+ create(context) {
535
+ if (!context.sourceCode.text.includes("render")) return {};
536
+ const settings2 = shared.getSettingsFromContext(context);
537
+ if (compareVersions.compare(settings2.version, "18.0.0", "<")) return {};
538
+ const reactDomNames = /* @__PURE__ */ new Set();
539
+ const renderNames = /* @__PURE__ */ new Set();
540
+ return {
541
+ CallExpression(node) {
542
+ switch (true) {
543
+ case (node.callee.type === types.AST_NODE_TYPES.Identifier && renderNames.has(node.callee.name)):
544
+ context.report({
545
+ messageId: "noRender",
546
+ node,
547
+ fix: getFix2(context, node)
548
+ });
549
+ return;
550
+ 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)):
551
+ context.report({
552
+ messageId: "noRender",
553
+ node,
554
+ fix: getFix2(context, node)
555
+ });
556
+ return;
557
+ }
558
+ },
559
+ ImportDeclaration(node) {
560
+ const [baseSource] = node.source.value.split("/");
561
+ if (baseSource !== "react-dom") return;
562
+ for (const specifier of node.specifiers) {
563
+ switch (specifier.type) {
564
+ case types.AST_NODE_TYPES.ImportSpecifier:
565
+ if (specifier.imported.type !== types.AST_NODE_TYPES.Identifier) continue;
566
+ if (specifier.imported.name === "render") {
567
+ renderNames.add(specifier.local.name);
568
+ }
569
+ continue;
570
+ case types.AST_NODE_TYPES.ImportDefaultSpecifier:
571
+ case types.AST_NODE_TYPES.ImportNamespaceSpecifier:
572
+ reactDomNames.add(specifier.local.name);
573
+ continue;
574
+ }
575
+ }
576
+ }
577
+ };
578
+ },
579
+ defaultOptions: []
580
+ });
581
+ function getFix2(context, node) {
582
+ const getText2 = (n) => context.sourceCode.getText(n);
583
+ return (fixer) => {
584
+ const [arg0, arg1] = node.arguments;
585
+ if (arg0 == null || arg1 == null) return null;
586
+ return [
587
+ fixer.insertTextBefore(context.sourceCode.ast, 'import { createRoot } from "react-dom/client";\n'),
588
+ fixer.replaceText(node, `createRoot(${getText2(arg1)}).render(${getText2(arg0)})`)
589
+ ];
590
+ };
591
+ }
592
+ var RULE_NAME10 = "no-render-return-value";
593
+ var RULE_FEATURES10 = [
437
594
  "CHK"
438
595
  ];
439
596
  var banParentTypes = [
@@ -448,14 +605,14 @@ var no_render_return_value_default = createRule({
448
605
  type: "problem",
449
606
  docs: {
450
607
  description: "disallow usage of the return value of 'ReactDOM.render'",
451
- [Symbol.for("rule_features")]: RULE_FEATURES8
608
+ [Symbol.for("rule_features")]: RULE_FEATURES10
452
609
  },
453
610
  messages: {
454
611
  noRenderReturnValue: "Do not depend on the return value from '{{objectName}}.render'."
455
612
  },
456
613
  schema: []
457
614
  },
458
- name: RULE_NAME8,
615
+ name: RULE_NAME10,
459
616
  create: create8,
460
617
  defaultOptions: []
461
618
  });
@@ -486,8 +643,8 @@ function create8(context) {
486
643
  }
487
644
  };
488
645
  }
489
- var RULE_NAME9 = "no-script-url";
490
- var RULE_FEATURES9 = [
646
+ var RULE_NAME11 = "no-script-url";
647
+ var RULE_FEATURES11 = [
491
648
  "CHK"
492
649
  ];
493
650
  var no_script_url_default = createRule({
@@ -495,14 +652,14 @@ var no_script_url_default = createRule({
495
652
  type: "problem",
496
653
  docs: {
497
654
  description: "disallow 'javascript:' URLs as JSX event handler prop's value",
498
- [Symbol.for("rule_features")]: RULE_FEATURES9
655
+ [Symbol.for("rule_features")]: RULE_FEATURES11
499
656
  },
500
657
  messages: {
501
658
  noScriptUrl: "Using a `javascript:` URL is a security risk and should be avoided."
502
659
  },
503
660
  schema: []
504
661
  },
505
- name: RULE_NAME9,
662
+ name: RULE_NAME11,
506
663
  create: create9,
507
664
  defaultOptions: []
508
665
  });
@@ -525,7 +682,7 @@ function create9(context) {
525
682
  }
526
683
  };
527
684
  }
528
- var RULE_NAME10 = "no-unknown-property";
685
+ var RULE_NAME12 = "no-unknown-property";
529
686
  var DEFAULTS = {
530
687
  ignore: [],
531
688
  requireDataLowercase: false
@@ -1488,7 +1645,7 @@ var no_unknown_property_default = createRule({
1488
1645
  }
1489
1646
  }]
1490
1647
  },
1491
- name: RULE_NAME10,
1648
+ name: RULE_NAME12,
1492
1649
  create: create10,
1493
1650
  defaultOptions: []
1494
1651
  });
@@ -1584,8 +1741,8 @@ function testReactVersion(context, comparator, version2) {
1584
1741
  const { version: localVersion } = shared.getSettingsFromContext(context);
1585
1742
  return compareVersions.compare(localVersion, version2, comparator);
1586
1743
  }
1587
- var RULE_NAME11 = "no-unsafe-iframe-sandbox";
1588
- var RULE_FEATURES10 = [
1744
+ var RULE_NAME13 = "no-unsafe-iframe-sandbox";
1745
+ var RULE_FEATURES12 = [
1589
1746
  "CHK"
1590
1747
  ];
1591
1748
  var unsafeSandboxValues = [
@@ -1602,14 +1759,14 @@ var no_unsafe_iframe_sandbox_default = createRule({
1602
1759
  type: "problem",
1603
1760
  docs: {
1604
1761
  description: "disallow unsafe iframe 'sandbox' attribute combinations",
1605
- [Symbol.for("rule_features")]: RULE_FEATURES10
1762
+ [Symbol.for("rule_features")]: RULE_FEATURES12
1606
1763
  },
1607
1764
  messages: {
1608
1765
  noUnsafeIframeSandbox: "Unsafe 'sandbox' attribute value on 'iframe' component."
1609
1766
  },
1610
1767
  schema: []
1611
1768
  },
1612
- name: RULE_NAME11,
1769
+ name: RULE_NAME13,
1613
1770
  create: create11,
1614
1771
  defaultOptions: []
1615
1772
  });
@@ -1656,8 +1813,8 @@ function create11(context) {
1656
1813
  }
1657
1814
  };
1658
1815
  }
1659
- var RULE_NAME12 = "no-unsafe-target-blank";
1660
- var RULE_FEATURES11 = [
1816
+ var RULE_NAME14 = "no-unsafe-target-blank";
1817
+ var RULE_FEATURES13 = [
1661
1818
  "CHK"
1662
1819
  ];
1663
1820
  function isExternalLinkLike(value) {
@@ -1673,14 +1830,14 @@ var no_unsafe_target_blank_default = createRule({
1673
1830
  type: "problem",
1674
1831
  docs: {
1675
1832
  description: `disallow 'target="_blank"' on an external link without 'rel="noreferrer noopener"'`,
1676
- [Symbol.for("rule_features")]: RULE_FEATURES11
1833
+ [Symbol.for("rule_features")]: RULE_FEATURES13
1677
1834
  },
1678
1835
  messages: {
1679
1836
  noUnsafeTargetBlank: `Using 'target="_blank"' on an external link without 'rel="noreferrer noopener"' is a security risk.`
1680
1837
  },
1681
1838
  schema: []
1682
1839
  },
1683
- name: RULE_NAME12,
1840
+ name: RULE_NAME14,
1684
1841
  create: create12,
1685
1842
  defaultOptions: []
1686
1843
  });
@@ -1731,8 +1888,84 @@ function create12(context) {
1731
1888
  }
1732
1889
  };
1733
1890
  }
1734
- var RULE_NAME13 = "no-void-elements-with-children";
1735
- var RULE_FEATURES12 = [
1891
+ var RULE_NAME15 = "no-use-form-state";
1892
+ var RULE_FEATURES14 = [
1893
+ "CHK",
1894
+ "MOD"
1895
+ ];
1896
+ var no_use_form_state_default = createRule({
1897
+ meta: {
1898
+ type: "problem",
1899
+ docs: {
1900
+ description: "replace usages of 'ReactDom.render()' with 'createRoot(node).render()'",
1901
+ [Symbol.for("rule_features")]: RULE_FEATURES14
1902
+ },
1903
+ fixable: "code",
1904
+ messages: {
1905
+ noUseFormState: "[Deprecated] Use 'useActionState' from 'react' package instead."
1906
+ },
1907
+ schema: []
1908
+ },
1909
+ name: RULE_NAME15,
1910
+ create(context) {
1911
+ if (!context.sourceCode.text.includes("useFormState")) return {};
1912
+ const settings2 = shared.getSettingsFromContext(context);
1913
+ if (compareVersions.compare(settings2.version, "19.0.0", "<")) return {};
1914
+ const reactDomNames = /* @__PURE__ */ new Set();
1915
+ const useFormStateNames = /* @__PURE__ */ new Set();
1916
+ return {
1917
+ CallExpression(node) {
1918
+ switch (true) {
1919
+ case (node.callee.type === types.AST_NODE_TYPES.Identifier && useFormStateNames.has(node.callee.name)):
1920
+ context.report({
1921
+ messageId: "noUseFormState",
1922
+ node,
1923
+ fix: getFix3(context, node)
1924
+ });
1925
+ return;
1926
+ 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)):
1927
+ context.report({
1928
+ messageId: "noUseFormState",
1929
+ node,
1930
+ fix: getFix3(context, node)
1931
+ });
1932
+ return;
1933
+ }
1934
+ },
1935
+ ImportDeclaration(node) {
1936
+ const [baseSource] = node.source.value.split("/");
1937
+ if (baseSource !== "react-dom") return;
1938
+ for (const specifier of node.specifiers) {
1939
+ switch (specifier.type) {
1940
+ case types.AST_NODE_TYPES.ImportSpecifier:
1941
+ if (specifier.imported.type !== types.AST_NODE_TYPES.Identifier) continue;
1942
+ if (specifier.imported.name === "useFormState") {
1943
+ useFormStateNames.add(specifier.local.name);
1944
+ }
1945
+ continue;
1946
+ case types.AST_NODE_TYPES.ImportDefaultSpecifier:
1947
+ case types.AST_NODE_TYPES.ImportNamespaceSpecifier:
1948
+ reactDomNames.add(specifier.local.name);
1949
+ continue;
1950
+ }
1951
+ }
1952
+ }
1953
+ };
1954
+ },
1955
+ defaultOptions: []
1956
+ });
1957
+ function getFix3(context, node) {
1958
+ const { importSource } = shared.getSettingsFromContext(context);
1959
+ return (fixer) => {
1960
+ return [
1961
+ fixer.insertTextBefore(context.sourceCode.ast, `import { useActionState } from "${importSource}";
1962
+ `),
1963
+ fixer.replaceText(node.callee, "useActionState")
1964
+ ];
1965
+ };
1966
+ }
1967
+ var RULE_NAME16 = "no-void-elements-with-children";
1968
+ var RULE_FEATURES15 = [
1736
1969
  "CHK"
1737
1970
  ];
1738
1971
  var voidElements = /* @__PURE__ */ new Set([
@@ -1758,14 +1991,14 @@ var no_void_elements_with_children_default = createRule({
1758
1991
  type: "problem",
1759
1992
  docs: {
1760
1993
  description: "disallow void elements (AKA self-closing elements) from having children",
1761
- [Symbol.for("rule_features")]: RULE_FEATURES12
1994
+ [Symbol.for("rule_features")]: RULE_FEATURES15
1762
1995
  },
1763
1996
  messages: {
1764
1997
  noVoidElementsWithChildren: "'{{element}}' is a void element tag and must not have children."
1765
1998
  },
1766
1999
  schema: []
1767
2000
  },
1768
- name: RULE_NAME13,
2001
+ name: RULE_NAME16,
1769
2002
  create: create13,
1770
2003
  defaultOptions: []
1771
2004
  });
@@ -1812,14 +2045,17 @@ var plugin = {
1812
2045
  "no-dangerously-set-innerhtml-with-children": no_dangerously_set_innerhtml_with_children_default,
1813
2046
  "no-find-dom-node": no_find_dom_node_default,
1814
2047
  "no-flush-sync": no_flush_sync_default,
2048
+ "no-hydrate": no_hydrate_default,
1815
2049
  "no-missing-button-type": no_missing_button_type_default,
1816
2050
  "no-missing-iframe-sandbox": no_missing_iframe_sandbox_default,
1817
2051
  "no-namespace": no_namespace_default,
2052
+ "no-render": no_render_default,
1818
2053
  "no-render-return-value": no_render_return_value_default,
1819
2054
  "no-script-url": no_script_url_default,
1820
2055
  "no-unknown-property": no_unknown_property_default,
1821
2056
  "no-unsafe-iframe-sandbox": no_unsafe_iframe_sandbox_default,
1822
2057
  "no-unsafe-target-blank": no_unsafe_target_blank_default,
2058
+ "no-use-form-state": no_use_form_state_default,
1823
2059
  "no-void-elements-with-children": no_void_elements_with_children_default,
1824
2060
  // Part: deprecated rules
1825
2061
  /** @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;
@@ -24,14 +24,17 @@ var rules = {
24
24
  "react-dom/no-dangerously-set-innerhtml-with-children": "error",
25
25
  "react-dom/no-find-dom-node": "error",
26
26
  "react-dom/no-flush-sync": "error",
27
+ "react-dom/no-hydrate": "error",
27
28
  "react-dom/no-missing-button-type": "warn",
28
29
  "react-dom/no-missing-iframe-sandbox": "warn",
29
30
  "react-dom/no-namespace": "error",
31
+ "react-dom/no-render": "error",
30
32
  "react-dom/no-render-return-value": "error",
31
33
  "react-dom/no-script-url": "warn",
32
34
  "react-dom/no-unknown-property": "warn",
33
35
  "react-dom/no-unsafe-iframe-sandbox": "warn",
34
36
  "react-dom/no-unsafe-target-blank": "warn",
37
+ "react-dom/no-use-form-state": "error",
35
38
  "react-dom/no-void-elements-with-children": "error"
36
39
  };
37
40
  var settings = {
@@ -40,7 +43,7 @@ var settings = {
40
43
 
41
44
  // package.json
42
45
  var name2 = "eslint-plugin-react-dom";
43
- var version = "1.34.2-beta.0";
46
+ var version = "1.34.2-beta.3";
44
47
  var createRule = createRuleForPlugin("dom");
45
48
 
46
49
  // src/utils/find-custom-component.ts
@@ -228,8 +231,85 @@ function create4(context) {
228
231
  }
229
232
  };
230
233
  }
231
- var RULE_NAME5 = "no-missing-button-type";
234
+ var RULE_NAME5 = "no-hydrate";
232
235
  var RULE_FEATURES5 = [
236
+ "CHK",
237
+ "MOD"
238
+ ];
239
+ var no_hydrate_default = createRule({
240
+ meta: {
241
+ type: "problem",
242
+ docs: {
243
+ description: "replaces usages of 'ReactDom.hydrate()' with 'hydrateRoot()'",
244
+ [Symbol.for("rule_features")]: RULE_FEATURES5
245
+ },
246
+ fixable: "code",
247
+ messages: {
248
+ noHydrate: "[Deprecated] Use 'hydrateRoot()' instead."
249
+ },
250
+ schema: []
251
+ },
252
+ name: RULE_NAME5,
253
+ create(context) {
254
+ if (!context.sourceCode.text.includes("hydrate")) return {};
255
+ const settings2 = getSettingsFromContext(context);
256
+ if (compare(settings2.version, "18.0.0", "<")) return {};
257
+ const reactDomNames = /* @__PURE__ */ new Set();
258
+ const hydrateNames = /* @__PURE__ */ new Set();
259
+ return {
260
+ CallExpression(node) {
261
+ switch (true) {
262
+ case (node.callee.type === AST_NODE_TYPES.Identifier && hydrateNames.has(node.callee.name)):
263
+ context.report({
264
+ messageId: "noHydrate",
265
+ node,
266
+ fix: getFix(context, node)
267
+ });
268
+ return;
269
+ 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 === "hydrate" && reactDomNames.has(node.callee.object.name)):
270
+ context.report({
271
+ messageId: "noHydrate",
272
+ node,
273
+ fix: getFix(context, node)
274
+ });
275
+ return;
276
+ }
277
+ },
278
+ ImportDeclaration(node) {
279
+ const [baseSource] = node.source.value.split("/");
280
+ if (baseSource !== "react-dom") return;
281
+ for (const specifier of node.specifiers) {
282
+ switch (specifier.type) {
283
+ case AST_NODE_TYPES.ImportSpecifier:
284
+ if (specifier.imported.type !== AST_NODE_TYPES.Identifier) continue;
285
+ if (specifier.imported.name === "hydrate") {
286
+ hydrateNames.add(specifier.local.name);
287
+ }
288
+ continue;
289
+ case AST_NODE_TYPES.ImportDefaultSpecifier:
290
+ case AST_NODE_TYPES.ImportNamespaceSpecifier:
291
+ reactDomNames.add(specifier.local.name);
292
+ continue;
293
+ }
294
+ }
295
+ }
296
+ };
297
+ },
298
+ defaultOptions: []
299
+ });
300
+ function getFix(context, node) {
301
+ const getText2 = (n) => context.sourceCode.getText(n);
302
+ return (fixer) => {
303
+ const [arg0, arg1] = node.arguments;
304
+ if (arg0 == null || arg1 == null) return null;
305
+ return [
306
+ fixer.insertTextBefore(context.sourceCode.ast, 'import { hydrateRoot } from "react-dom/client";\n'),
307
+ fixer.replaceText(node, `hydrateRoot(${getText2(arg1)}, ${getText2(arg0)})`)
308
+ ];
309
+ };
310
+ }
311
+ var RULE_NAME6 = "no-missing-button-type";
312
+ var RULE_FEATURES6 = [
233
313
  "CHK"
234
314
  ];
235
315
  var no_missing_button_type_default = createRule({
@@ -237,14 +317,14 @@ var no_missing_button_type_default = createRule({
237
317
  type: "problem",
238
318
  docs: {
239
319
  description: "enforce that button component have an explicit 'type' attribute",
240
- [Symbol.for("rule_features")]: RULE_FEATURES5
320
+ [Symbol.for("rule_features")]: RULE_FEATURES6
241
321
  },
242
322
  messages: {
243
323
  noMissingButtonType: "Add missing 'type' attribute on 'button' component."
244
324
  },
245
325
  schema: []
246
326
  },
247
- name: RULE_NAME5,
327
+ name: RULE_NAME6,
248
328
  create: create5,
249
329
  defaultOptions: []
250
330
  });
@@ -290,8 +370,8 @@ function create5(context) {
290
370
  }
291
371
  };
292
372
  }
293
- var RULE_NAME6 = "no-missing-iframe-sandbox";
294
- var RULE_FEATURES6 = [
373
+ var RULE_NAME7 = "no-missing-iframe-sandbox";
374
+ var RULE_FEATURES7 = [
295
375
  "CHK"
296
376
  ];
297
377
  var validTypes = [
@@ -320,14 +400,14 @@ var no_missing_iframe_sandbox_default = createRule({
320
400
  type: "problem",
321
401
  docs: {
322
402
  description: "enforce that 'iframe' component have an explicit 'sandbox' attribute",
323
- [Symbol.for("rule_features")]: RULE_FEATURES6
403
+ [Symbol.for("rule_features")]: RULE_FEATURES7
324
404
  },
325
405
  messages: {
326
406
  noMissingIframeSandbox: "Add missing 'sandbox' attribute on 'iframe' component."
327
407
  },
328
408
  schema: []
329
409
  },
330
- name: RULE_NAME6,
410
+ name: RULE_NAME7,
331
411
  create: create6,
332
412
  defaultOptions: []
333
413
  });
@@ -372,8 +452,8 @@ function create6(context) {
372
452
  }
373
453
  };
374
454
  }
375
- var RULE_NAME7 = "no-namespace";
376
- var RULE_FEATURES7 = [
455
+ var RULE_NAME8 = "no-namespace";
456
+ var RULE_FEATURES8 = [
377
457
  "CHK"
378
458
  ];
379
459
  var no_namespace_default = createRule({
@@ -381,14 +461,14 @@ var no_namespace_default = createRule({
381
461
  type: "problem",
382
462
  docs: {
383
463
  description: "enforce that namespaces are not used in React elements",
384
- [Symbol.for("rule_features")]: RULE_FEATURES7
464
+ [Symbol.for("rule_features")]: RULE_FEATURES8
385
465
  },
386
466
  messages: {
387
467
  noNamespace: "A React component '{{name}}' must not be in a namespace, as React does not support them."
388
468
  },
389
469
  schema: []
390
470
  },
391
- name: RULE_NAME7,
471
+ name: RULE_NAME8,
392
472
  create: create7,
393
473
  defaultOptions: []
394
474
  });
@@ -409,8 +489,85 @@ function create7(context) {
409
489
  }
410
490
  };
411
491
  }
412
- var RULE_NAME8 = "no-render-return-value";
413
- var RULE_FEATURES8 = [
492
+ var RULE_NAME9 = "no-render";
493
+ var RULE_FEATURES9 = [
494
+ "CHK",
495
+ "MOD"
496
+ ];
497
+ var no_render_default = createRule({
498
+ meta: {
499
+ type: "problem",
500
+ docs: {
501
+ description: "replace usages of 'ReactDom.render()' with 'createRoot(node).render()'",
502
+ [Symbol.for("rule_features")]: RULE_FEATURES9
503
+ },
504
+ fixable: "code",
505
+ messages: {
506
+ noRender: "[Deprecated] Use 'createRoot(node).render()' instead."
507
+ },
508
+ schema: []
509
+ },
510
+ name: RULE_NAME9,
511
+ create(context) {
512
+ if (!context.sourceCode.text.includes("render")) return {};
513
+ const settings2 = getSettingsFromContext(context);
514
+ if (compare(settings2.version, "18.0.0", "<")) return {};
515
+ const reactDomNames = /* @__PURE__ */ new Set();
516
+ const renderNames = /* @__PURE__ */ new Set();
517
+ return {
518
+ CallExpression(node) {
519
+ switch (true) {
520
+ case (node.callee.type === AST_NODE_TYPES.Identifier && renderNames.has(node.callee.name)):
521
+ context.report({
522
+ messageId: "noRender",
523
+ node,
524
+ fix: getFix2(context, node)
525
+ });
526
+ return;
527
+ 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)):
528
+ context.report({
529
+ messageId: "noRender",
530
+ node,
531
+ fix: getFix2(context, node)
532
+ });
533
+ return;
534
+ }
535
+ },
536
+ ImportDeclaration(node) {
537
+ const [baseSource] = node.source.value.split("/");
538
+ if (baseSource !== "react-dom") return;
539
+ for (const specifier of node.specifiers) {
540
+ switch (specifier.type) {
541
+ case AST_NODE_TYPES.ImportSpecifier:
542
+ if (specifier.imported.type !== AST_NODE_TYPES.Identifier) continue;
543
+ if (specifier.imported.name === "render") {
544
+ renderNames.add(specifier.local.name);
545
+ }
546
+ continue;
547
+ case AST_NODE_TYPES.ImportDefaultSpecifier:
548
+ case AST_NODE_TYPES.ImportNamespaceSpecifier:
549
+ reactDomNames.add(specifier.local.name);
550
+ continue;
551
+ }
552
+ }
553
+ }
554
+ };
555
+ },
556
+ defaultOptions: []
557
+ });
558
+ function getFix2(context, node) {
559
+ const getText2 = (n) => context.sourceCode.getText(n);
560
+ return (fixer) => {
561
+ const [arg0, arg1] = node.arguments;
562
+ if (arg0 == null || arg1 == null) return null;
563
+ return [
564
+ fixer.insertTextBefore(context.sourceCode.ast, 'import { createRoot } from "react-dom/client";\n'),
565
+ fixer.replaceText(node, `createRoot(${getText2(arg1)}).render(${getText2(arg0)})`)
566
+ ];
567
+ };
568
+ }
569
+ var RULE_NAME10 = "no-render-return-value";
570
+ var RULE_FEATURES10 = [
414
571
  "CHK"
415
572
  ];
416
573
  var banParentTypes = [
@@ -425,14 +582,14 @@ var no_render_return_value_default = createRule({
425
582
  type: "problem",
426
583
  docs: {
427
584
  description: "disallow usage of the return value of 'ReactDOM.render'",
428
- [Symbol.for("rule_features")]: RULE_FEATURES8
585
+ [Symbol.for("rule_features")]: RULE_FEATURES10
429
586
  },
430
587
  messages: {
431
588
  noRenderReturnValue: "Do not depend on the return value from '{{objectName}}.render'."
432
589
  },
433
590
  schema: []
434
591
  },
435
- name: RULE_NAME8,
592
+ name: RULE_NAME10,
436
593
  create: create8,
437
594
  defaultOptions: []
438
595
  });
@@ -463,8 +620,8 @@ function create8(context) {
463
620
  }
464
621
  };
465
622
  }
466
- var RULE_NAME9 = "no-script-url";
467
- var RULE_FEATURES9 = [
623
+ var RULE_NAME11 = "no-script-url";
624
+ var RULE_FEATURES11 = [
468
625
  "CHK"
469
626
  ];
470
627
  var no_script_url_default = createRule({
@@ -472,14 +629,14 @@ var no_script_url_default = createRule({
472
629
  type: "problem",
473
630
  docs: {
474
631
  description: "disallow 'javascript:' URLs as JSX event handler prop's value",
475
- [Symbol.for("rule_features")]: RULE_FEATURES9
632
+ [Symbol.for("rule_features")]: RULE_FEATURES11
476
633
  },
477
634
  messages: {
478
635
  noScriptUrl: "Using a `javascript:` URL is a security risk and should be avoided."
479
636
  },
480
637
  schema: []
481
638
  },
482
- name: RULE_NAME9,
639
+ name: RULE_NAME11,
483
640
  create: create9,
484
641
  defaultOptions: []
485
642
  });
@@ -502,7 +659,7 @@ function create9(context) {
502
659
  }
503
660
  };
504
661
  }
505
- var RULE_NAME10 = "no-unknown-property";
662
+ var RULE_NAME12 = "no-unknown-property";
506
663
  var DEFAULTS = {
507
664
  ignore: [],
508
665
  requireDataLowercase: false
@@ -1465,7 +1622,7 @@ var no_unknown_property_default = createRule({
1465
1622
  }
1466
1623
  }]
1467
1624
  },
1468
- name: RULE_NAME10,
1625
+ name: RULE_NAME12,
1469
1626
  create: create10,
1470
1627
  defaultOptions: []
1471
1628
  });
@@ -1561,8 +1718,8 @@ function testReactVersion(context, comparator, version2) {
1561
1718
  const { version: localVersion } = getSettingsFromContext(context);
1562
1719
  return compare(localVersion, version2, comparator);
1563
1720
  }
1564
- var RULE_NAME11 = "no-unsafe-iframe-sandbox";
1565
- var RULE_FEATURES10 = [
1721
+ var RULE_NAME13 = "no-unsafe-iframe-sandbox";
1722
+ var RULE_FEATURES12 = [
1566
1723
  "CHK"
1567
1724
  ];
1568
1725
  var unsafeSandboxValues = [
@@ -1579,14 +1736,14 @@ var no_unsafe_iframe_sandbox_default = createRule({
1579
1736
  type: "problem",
1580
1737
  docs: {
1581
1738
  description: "disallow unsafe iframe 'sandbox' attribute combinations",
1582
- [Symbol.for("rule_features")]: RULE_FEATURES10
1739
+ [Symbol.for("rule_features")]: RULE_FEATURES12
1583
1740
  },
1584
1741
  messages: {
1585
1742
  noUnsafeIframeSandbox: "Unsafe 'sandbox' attribute value on 'iframe' component."
1586
1743
  },
1587
1744
  schema: []
1588
1745
  },
1589
- name: RULE_NAME11,
1746
+ name: RULE_NAME13,
1590
1747
  create: create11,
1591
1748
  defaultOptions: []
1592
1749
  });
@@ -1633,8 +1790,8 @@ function create11(context) {
1633
1790
  }
1634
1791
  };
1635
1792
  }
1636
- var RULE_NAME12 = "no-unsafe-target-blank";
1637
- var RULE_FEATURES11 = [
1793
+ var RULE_NAME14 = "no-unsafe-target-blank";
1794
+ var RULE_FEATURES13 = [
1638
1795
  "CHK"
1639
1796
  ];
1640
1797
  function isExternalLinkLike(value) {
@@ -1650,14 +1807,14 @@ var no_unsafe_target_blank_default = createRule({
1650
1807
  type: "problem",
1651
1808
  docs: {
1652
1809
  description: `disallow 'target="_blank"' on an external link without 'rel="noreferrer noopener"'`,
1653
- [Symbol.for("rule_features")]: RULE_FEATURES11
1810
+ [Symbol.for("rule_features")]: RULE_FEATURES13
1654
1811
  },
1655
1812
  messages: {
1656
1813
  noUnsafeTargetBlank: `Using 'target="_blank"' on an external link without 'rel="noreferrer noopener"' is a security risk.`
1657
1814
  },
1658
1815
  schema: []
1659
1816
  },
1660
- name: RULE_NAME12,
1817
+ name: RULE_NAME14,
1661
1818
  create: create12,
1662
1819
  defaultOptions: []
1663
1820
  });
@@ -1708,8 +1865,84 @@ function create12(context) {
1708
1865
  }
1709
1866
  };
1710
1867
  }
1711
- var RULE_NAME13 = "no-void-elements-with-children";
1712
- var RULE_FEATURES12 = [
1868
+ var RULE_NAME15 = "no-use-form-state";
1869
+ var RULE_FEATURES14 = [
1870
+ "CHK",
1871
+ "MOD"
1872
+ ];
1873
+ var no_use_form_state_default = createRule({
1874
+ meta: {
1875
+ type: "problem",
1876
+ docs: {
1877
+ description: "replace usages of 'ReactDom.render()' with 'createRoot(node).render()'",
1878
+ [Symbol.for("rule_features")]: RULE_FEATURES14
1879
+ },
1880
+ fixable: "code",
1881
+ messages: {
1882
+ noUseFormState: "[Deprecated] Use 'useActionState' from 'react' package instead."
1883
+ },
1884
+ schema: []
1885
+ },
1886
+ name: RULE_NAME15,
1887
+ create(context) {
1888
+ if (!context.sourceCode.text.includes("useFormState")) return {};
1889
+ const settings2 = getSettingsFromContext(context);
1890
+ if (compare(settings2.version, "19.0.0", "<")) return {};
1891
+ const reactDomNames = /* @__PURE__ */ new Set();
1892
+ const useFormStateNames = /* @__PURE__ */ new Set();
1893
+ return {
1894
+ CallExpression(node) {
1895
+ switch (true) {
1896
+ case (node.callee.type === AST_NODE_TYPES.Identifier && useFormStateNames.has(node.callee.name)):
1897
+ context.report({
1898
+ messageId: "noUseFormState",
1899
+ node,
1900
+ fix: getFix3(context, node)
1901
+ });
1902
+ return;
1903
+ 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)):
1904
+ context.report({
1905
+ messageId: "noUseFormState",
1906
+ node,
1907
+ fix: getFix3(context, node)
1908
+ });
1909
+ return;
1910
+ }
1911
+ },
1912
+ ImportDeclaration(node) {
1913
+ const [baseSource] = node.source.value.split("/");
1914
+ if (baseSource !== "react-dom") return;
1915
+ for (const specifier of node.specifiers) {
1916
+ switch (specifier.type) {
1917
+ case AST_NODE_TYPES.ImportSpecifier:
1918
+ if (specifier.imported.type !== AST_NODE_TYPES.Identifier) continue;
1919
+ if (specifier.imported.name === "useFormState") {
1920
+ useFormStateNames.add(specifier.local.name);
1921
+ }
1922
+ continue;
1923
+ case AST_NODE_TYPES.ImportDefaultSpecifier:
1924
+ case AST_NODE_TYPES.ImportNamespaceSpecifier:
1925
+ reactDomNames.add(specifier.local.name);
1926
+ continue;
1927
+ }
1928
+ }
1929
+ }
1930
+ };
1931
+ },
1932
+ defaultOptions: []
1933
+ });
1934
+ function getFix3(context, node) {
1935
+ const { importSource } = getSettingsFromContext(context);
1936
+ return (fixer) => {
1937
+ return [
1938
+ fixer.insertTextBefore(context.sourceCode.ast, `import { useActionState } from "${importSource}";
1939
+ `),
1940
+ fixer.replaceText(node.callee, "useActionState")
1941
+ ];
1942
+ };
1943
+ }
1944
+ var RULE_NAME16 = "no-void-elements-with-children";
1945
+ var RULE_FEATURES15 = [
1713
1946
  "CHK"
1714
1947
  ];
1715
1948
  var voidElements = /* @__PURE__ */ new Set([
@@ -1735,14 +1968,14 @@ var no_void_elements_with_children_default = createRule({
1735
1968
  type: "problem",
1736
1969
  docs: {
1737
1970
  description: "disallow void elements (AKA self-closing elements) from having children",
1738
- [Symbol.for("rule_features")]: RULE_FEATURES12
1971
+ [Symbol.for("rule_features")]: RULE_FEATURES15
1739
1972
  },
1740
1973
  messages: {
1741
1974
  noVoidElementsWithChildren: "'{{element}}' is a void element tag and must not have children."
1742
1975
  },
1743
1976
  schema: []
1744
1977
  },
1745
- name: RULE_NAME13,
1978
+ name: RULE_NAME16,
1746
1979
  create: create13,
1747
1980
  defaultOptions: []
1748
1981
  });
@@ -1789,14 +2022,17 @@ var plugin = {
1789
2022
  "no-dangerously-set-innerhtml-with-children": no_dangerously_set_innerhtml_with_children_default,
1790
2023
  "no-find-dom-node": no_find_dom_node_default,
1791
2024
  "no-flush-sync": no_flush_sync_default,
2025
+ "no-hydrate": no_hydrate_default,
1792
2026
  "no-missing-button-type": no_missing_button_type_default,
1793
2027
  "no-missing-iframe-sandbox": no_missing_iframe_sandbox_default,
1794
2028
  "no-namespace": no_namespace_default,
2029
+ "no-render": no_render_default,
1795
2030
  "no-render-return-value": no_render_return_value_default,
1796
2031
  "no-script-url": no_script_url_default,
1797
2032
  "no-unknown-property": no_unknown_property_default,
1798
2033
  "no-unsafe-iframe-sandbox": no_unsafe_iframe_sandbox_default,
1799
2034
  "no-unsafe-target-blank": no_unsafe_target_blank_default,
2035
+ "no-use-form-state": no_use_form_state_default,
1800
2036
  "no-void-elements-with-children": no_void_elements_with_children_default,
1801
2037
  // Part: deprecated rules
1802
2038
  /** @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.3",
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.3",
53
+ "@eslint-react/core": "1.34.2-beta.3",
54
+ "@eslint-react/shared": "1.34.2-beta.3",
55
+ "@eslint-react/jsx": "1.34.2-beta.3",
56
+ "@eslint-react/eff": "1.34.2-beta.3",
57
+ "@eslint-react/var": "1.34.2-beta.3"
58
58
  },
59
59
  "devDependencies": {
60
60
  "@types/react": "^19.0.10",