eslint-plugin-react-dom 3.0.0-rc.5 → 4.0.0-beta.0

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.
Files changed (3) hide show
  1. package/README.md +2 -2
  2. package/dist/index.js +49 -107
  3. package/package.json +13 -12
package/README.md CHANGED
@@ -13,7 +13,7 @@ npm install --save-dev eslint-plugin-react-dom
13
13
 
14
14
  ```ts
15
15
  import js from "@eslint/js";
16
- import dom from "eslint-plugin-react-dom";
16
+ import reactDom from "eslint-plugin-react-dom";
17
17
  import { defineConfig } from "eslint/config";
18
18
  import tseslint from "typescript-eslint";
19
19
 
@@ -24,7 +24,7 @@ export default defineConfig(
24
24
  js.configs.recommended,
25
25
  tseslint.configs.recommended,
26
26
  // Add configs from eslint-plugin-react-dom
27
- dom.configs.recommended,
27
+ reactDom.configs.recommended,
28
28
  ],
29
29
  rules: {
30
30
  // Put rules you want to override here
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { DEFAULT_ESLINT_REACT_SETTINGS, RE_JAVASCRIPT_PROTOCOL, WEBSITE_URL, defineRuleListener, getSettingsFromContext } from "@eslint-react/shared";
2
- import { JsxInspector } from "@eslint-react/core";
2
+ import { findAttribute, getAttributeStaticValue, getElementFullType, hasAnyAttribute, hasAttribute, isHostElement, isWhitespace, resolveAttributeValue } from "@eslint-react/jsx";
3
3
  import { ESLintUtils } from "@typescript-eslint/utils";
4
4
  import { AST_NODE_TYPES } from "@typescript-eslint/types";
5
5
  import { compare } from "compare-versions";
@@ -24,7 +24,7 @@ var __exportAll = (all, no_symbols) => {
24
24
  //#endregion
25
25
  //#region package.json
26
26
  var name$2 = "eslint-plugin-react-dom";
27
- var version = "3.0.0-rc.5";
27
+ var version = "4.0.0-beta.0";
28
28
 
29
29
  //#endregion
30
30
  //#region src/utils/create-jsx-element-resolver.ts
@@ -41,15 +41,14 @@ var version = "3.0.0-rc.5";
41
41
  */
42
42
  function createJsxElementResolver(context) {
43
43
  const { polymorphicPropName } = getSettingsFromContext(context);
44
- const jsx = JsxInspector.from(context);
45
44
  return { resolve(node) {
46
- const elementName = jsx.getElementType(node);
45
+ const elementName = getElementFullType(node);
47
46
  const result = {
48
47
  domElementType: elementName,
49
48
  jsxElementType: elementName
50
49
  };
51
50
  if (elementName === elementName.toLowerCase() || polymorphicPropName == null) return result;
52
- const polyPropValue = jsx.getAttributeValue(node, polymorphicPropName)?.toStatic();
51
+ const polyPropValue = getAttributeStaticValue(context, node, polymorphicPropName);
53
52
  if (typeof polyPropValue === "string") return {
54
53
  ...result,
55
54
  domElementType: polyPropValue
@@ -67,7 +66,7 @@ const createRule = ESLintUtils.RuleCreator(getDocsUrl);
67
66
 
68
67
  //#endregion
69
68
  //#region src/rules/no-dangerously-set-innerhtml-with-children/no-dangerously-set-innerhtml-with-children.ts
70
- const RULE_NAME$17 = "no-dangerously-set-innerhtml-with-children";
69
+ const RULE_NAME$16 = "no-dangerously-set-innerhtml-with-children";
71
70
  var no_dangerously_set_innerhtml_with_children_default = createRule({
72
71
  meta: {
73
72
  type: "problem",
@@ -75,26 +74,16 @@ var no_dangerously_set_innerhtml_with_children_default = createRule({
75
74
  messages: { default: "A DOM component cannot use both children and 'dangerouslySetInnerHTML'." },
76
75
  schema: []
77
76
  },
78
- name: RULE_NAME$17,
79
- create: create$17,
77
+ name: RULE_NAME$16,
78
+ create: create$16,
80
79
  defaultOptions: []
81
80
  });
82
81
  const DSIH$1 = "dangerouslySetInnerHTML";
83
- /**
84
- * Check if a JSX child node is considered significant (i.e., not just whitespace for formatting)
85
- * @param node The JSX child node to check
86
- * @returns `true` if the node is significant, `false` otherwise
87
- */
88
- function isSignificantChildren(node) {
89
- if (!JsxInspector.isJsxText(node)) return true;
90
- return !(node.raw.trim() === "" && node.raw.includes("\n"));
91
- }
92
- function create$17(context) {
82
+ function create$16(context) {
93
83
  if (!context.sourceCode.text.includes(DSIH$1)) return {};
94
- const jsx = JsxInspector.from(context);
95
84
  return defineRuleListener({ JSXElement(node) {
96
- if (!jsx.hasAttribute(node, DSIH$1)) return;
97
- const childrenPropOrNode = jsx.findAttribute(node, "children") ?? node.children.find(isSignificantChildren);
85
+ if (!hasAttribute(context, node, DSIH$1)) return;
86
+ const childrenPropOrNode = findAttribute(context, node, "children") ?? node.children.find((child) => !isWhitespace(child));
98
87
  if (childrenPropOrNode == null) return;
99
88
  context.report({
100
89
  messageId: "default",
@@ -105,7 +94,7 @@ function create$17(context) {
105
94
 
106
95
  //#endregion
107
96
  //#region src/rules/no-dangerously-set-innerhtml/no-dangerously-set-innerhtml.ts
108
- const RULE_NAME$16 = "no-dangerously-set-innerhtml";
97
+ const RULE_NAME$15 = "no-dangerously-set-innerhtml";
109
98
  const DSIH = "dangerouslySetInnerHTML";
110
99
  var no_dangerously_set_innerhtml_default = createRule({
111
100
  meta: {
@@ -114,15 +103,14 @@ var no_dangerously_set_innerhtml_default = createRule({
114
103
  messages: { default: "Using 'dangerouslySetInnerHTML' may have security implications." },
115
104
  schema: []
116
105
  },
117
- name: RULE_NAME$16,
118
- create: create$16,
106
+ name: RULE_NAME$15,
107
+ create: create$15,
119
108
  defaultOptions: []
120
109
  });
121
- function create$16(context) {
110
+ function create$15(context) {
122
111
  if (!context.sourceCode.text.includes(DSIH)) return {};
123
- const jsx = JsxInspector.from(context);
124
112
  return defineRuleListener({ JSXElement(node) {
125
- const dsihProp = jsx.findAttribute(node, DSIH);
113
+ const dsihProp = findAttribute(context, node, DSIH);
126
114
  if (dsihProp == null) return;
127
115
  context.report({
128
116
  messageId: "default",
@@ -133,7 +121,7 @@ function create$16(context) {
133
121
 
134
122
  //#endregion
135
123
  //#region src/rules/no-find-dom-node/no-find-dom-node.ts
136
- const RULE_NAME$15 = "no-find-dom-node";
124
+ const RULE_NAME$14 = "no-find-dom-node";
137
125
  var no_find_dom_node_default = createRule({
138
126
  meta: {
139
127
  type: "problem",
@@ -141,12 +129,12 @@ var no_find_dom_node_default = createRule({
141
129
  messages: { default: "[Deprecated] Use alternatives instead." },
142
130
  schema: []
143
131
  },
144
- name: RULE_NAME$15,
145
- create: create$15,
132
+ name: RULE_NAME$14,
133
+ create: create$14,
146
134
  defaultOptions: []
147
135
  });
148
136
  const findDOMNode = "findDOMNode";
149
- function create$15(context) {
137
+ function create$14(context) {
150
138
  if (!context.sourceCode.text.includes(findDOMNode)) return {};
151
139
  return defineRuleListener({ CallExpression(node) {
152
140
  const { callee } = node;
@@ -169,7 +157,7 @@ function create$15(context) {
169
157
 
170
158
  //#endregion
171
159
  //#region src/rules/no-flush-sync/no-flush-sync.ts
172
- const RULE_NAME$14 = "no-flush-sync";
160
+ const RULE_NAME$13 = "no-flush-sync";
173
161
  var no_flush_sync_default = createRule({
174
162
  meta: {
175
163
  type: "problem",
@@ -177,12 +165,12 @@ var no_flush_sync_default = createRule({
177
165
  messages: { default: "Using 'flushSync' is uncommon and can hurt the performance of your app." },
178
166
  schema: []
179
167
  },
180
- name: RULE_NAME$14,
181
- create: create$14,
168
+ name: RULE_NAME$13,
169
+ create: create$13,
182
170
  defaultOptions: []
183
171
  });
184
172
  const flushSync = "flushSync";
185
- function create$14(context) {
173
+ function create$13(context) {
186
174
  if (!context.sourceCode.text.includes(flushSync)) return {};
187
175
  return defineRuleListener({ CallExpression(node) {
188
176
  const { callee } = node;
@@ -205,7 +193,7 @@ function create$14(context) {
205
193
 
206
194
  //#endregion
207
195
  //#region src/rules/no-hydrate/no-hydrate.ts
208
- const RULE_NAME$13 = "no-hydrate";
196
+ const RULE_NAME$12 = "no-hydrate";
209
197
  var no_hydrate_default = createRule({
210
198
  meta: {
211
199
  type: "problem",
@@ -214,12 +202,12 @@ var no_hydrate_default = createRule({
214
202
  messages: { default: "[Deprecated] Use 'hydrateRoot()' instead." },
215
203
  schema: []
216
204
  },
217
- name: RULE_NAME$13,
218
- create: create$13,
205
+ name: RULE_NAME$12,
206
+ create: create$12,
219
207
  defaultOptions: []
220
208
  });
221
209
  const hydrate = "hydrate";
222
- function create$13(context) {
210
+ function create$12(context) {
223
211
  if (!context.sourceCode.text.includes(hydrate)) return {};
224
212
  if (compare(getSettingsFromContext(context).version, "18.0.0", "<")) return {};
225
213
  const reactDomNames = /* @__PURE__ */ new Set();
@@ -270,7 +258,7 @@ function getFix$2(context, node) {
270
258
 
271
259
  //#endregion
272
260
  //#region src/rules/no-missing-button-type/no-missing-button-type.ts
273
- const RULE_NAME$12 = "no-missing-button-type";
261
+ const RULE_NAME$11 = "no-missing-button-type";
274
262
  const BUTTON_TYPES = [
275
263
  "button",
276
264
  "submit",
@@ -287,16 +275,15 @@ var no_missing_button_type_default = createRule({
287
275
  },
288
276
  schema: []
289
277
  },
290
- name: RULE_NAME$12,
291
- create: create$12,
278
+ name: RULE_NAME$11,
279
+ create: create$11,
292
280
  defaultOptions: []
293
281
  });
294
- function create$12(context) {
282
+ function create$11(context) {
295
283
  const resolver = createJsxElementResolver(context);
296
- const jsx = JsxInspector.from(context);
297
284
  return defineRuleListener({ JSXElement(node) {
298
285
  if (resolver.resolve(node).domElementType !== "button") return;
299
- if (jsx.hasAttribute(node, "type")) return;
286
+ if (hasAttribute(context, node, "type")) return;
300
287
  context.report({
301
288
  messageId: "missingTypeAttribute",
302
289
  node: node.openingElement,
@@ -311,7 +298,7 @@ function create$12(context) {
311
298
 
312
299
  //#endregion
313
300
  //#region src/rules/no-missing-iframe-sandbox/no-missing-iframe-sandbox.ts
314
- const RULE_NAME$11 = "no-missing-iframe-sandbox";
301
+ const RULE_NAME$10 = "no-missing-iframe-sandbox";
315
302
  var no_missing_iframe_sandbox_default = createRule({
316
303
  meta: {
317
304
  type: "problem",
@@ -324,17 +311,16 @@ var no_missing_iframe_sandbox_default = createRule({
324
311
  },
325
312
  schema: []
326
313
  },
327
- name: RULE_NAME$11,
328
- create: create$11,
314
+ name: RULE_NAME$10,
315
+ create: create$10,
329
316
  defaultOptions: []
330
317
  });
331
- function create$11(context) {
318
+ function create$10(context) {
332
319
  const resolver = createJsxElementResolver(context);
333
- const jsx = JsxInspector.from(context);
334
320
  return defineRuleListener({ JSXElement(node) {
335
321
  const { domElementType } = resolver.resolve(node);
336
322
  if (domElementType !== "iframe") return;
337
- const sandboxProp = jsx.findAttribute(node, "sandbox");
323
+ const sandboxProp = findAttribute(context, node, "sandbox");
338
324
  if (sandboxProp == null) {
339
325
  context.report({
340
326
  messageId: "missingSandboxAttribute",
@@ -349,7 +335,7 @@ function create$11(context) {
349
335
  });
350
336
  return;
351
337
  }
352
- const sandboxValue = jsx.resolveAttributeValue(sandboxProp);
338
+ const sandboxValue = resolveAttributeValue(context, sandboxProp);
353
339
  if (typeof sandboxValue.toStatic() === "string") return;
354
340
  if (sandboxValue.kind === "spreadProps" && typeof sandboxValue.getProperty("sandbox") === "string") return;
355
341
  context.report({
@@ -367,33 +353,6 @@ function create$11(context) {
367
353
  } });
368
354
  }
369
355
 
370
- //#endregion
371
- //#region src/rules/no-namespace/no-namespace.ts
372
- const RULE_NAME$10 = "no-namespace";
373
- var no_namespace_default = createRule({
374
- meta: {
375
- type: "problem",
376
- docs: { description: "Enforces the absence of a 'namespace' in React elements." },
377
- messages: { default: "A React component '{{name}}' must not be in a namespace, as React does not support them." },
378
- schema: []
379
- },
380
- name: RULE_NAME$10,
381
- create: create$10,
382
- defaultOptions: []
383
- });
384
- function create$10(context) {
385
- const jsx = JsxInspector.from(context);
386
- return defineRuleListener({ JSXElement(node) {
387
- const name = jsx.getElementType(node);
388
- if (typeof name !== "string" || !name.includes(":")) return;
389
- context.report({
390
- data: { name },
391
- messageId: "default",
392
- node: node.openingElement.name
393
- });
394
- } });
395
- }
396
-
397
356
  //#endregion
398
357
  //#region src/rules/no-render-return-value/no-render-return-value.ts
399
358
  const RULE_NAME$9 = "no-render-return-value";
@@ -537,10 +496,9 @@ var no_script_url_default = createRule({
537
496
  defaultOptions: []
538
497
  });
539
498
  function create$7(context) {
540
- const jsx = JsxInspector.from(context);
541
499
  return defineRuleListener({ JSXAttribute(node) {
542
500
  if (node.name.type !== AST_NODE_TYPES.JSXIdentifier || node.value == null) return;
543
- const value = jsx.resolveAttributeValue(node).toStatic();
501
+ const value = resolveAttributeValue(context, node).toStatic();
544
502
  if (typeof value === "string" && RE_JAVASCRIPT_PROTOCOL.test(value)) context.report({
545
503
  messageId: "default",
546
504
  node: node.value
@@ -563,12 +521,11 @@ var no_string_style_prop_default = createRule({
563
521
  defaultOptions: []
564
522
  });
565
523
  function create$6(context) {
566
- const jsx = JsxInspector.from(context);
567
524
  return defineRuleListener({ JSXElement(node) {
568
- if (!jsx.isHostElement(node)) return;
569
- const styleProp = jsx.findAttribute(node, "style");
525
+ if (!isHostElement(node)) return;
526
+ const styleProp = findAttribute(context, node, "style");
570
527
  if (styleProp == null) return;
571
- const styleValue = jsx.resolveAttributeValue(styleProp);
528
+ const styleValue = resolveAttributeValue(context, styleProp);
572
529
  if (typeof styleValue.toStatic() === "string") context.report({
573
530
  messageId: "default",
574
531
  node: styleValue.node ?? styleProp
@@ -1739,12 +1696,11 @@ var no_unsafe_iframe_sandbox_default = createRule({
1739
1696
  });
1740
1697
  function create$4(context) {
1741
1698
  const resolver = createJsxElementResolver(context);
1742
- const jsx = JsxInspector.from(context);
1743
1699
  return defineRuleListener({ JSXElement(node) {
1744
1700
  if (resolver.resolve(node).domElementType !== "iframe") return;
1745
- const sandboxProp = jsx.findAttribute(node, "sandbox");
1701
+ const sandboxProp = findAttribute(context, node, "sandbox");
1746
1702
  if (sandboxProp == null) return;
1747
- const sandboxValue = jsx.resolveAttributeValue(sandboxProp);
1703
+ const sandboxValue = resolveAttributeValue(context, sandboxProp);
1748
1704
  if (isUnsafeSandboxCombination(sandboxValue.kind === "spreadProps" ? sandboxValue.getProperty("sandbox") : sandboxValue.toStatic())) context.report({
1749
1705
  messageId: "default",
1750
1706
  node: sandboxValue.node ?? sandboxProp
@@ -1793,20 +1749,12 @@ var no_unsafe_target_blank_default = createRule({
1793
1749
  });
1794
1750
  function create$3(context) {
1795
1751
  const resolver = createJsxElementResolver(context);
1796
- const jsx = JsxInspector.from(context);
1797
1752
  return defineRuleListener({ JSXElement(node) {
1798
1753
  const { domElementType } = resolver.resolve(node);
1799
1754
  if (domElementType !== "a") return;
1800
- const findAttribute = (name) => jsx.findAttribute(node, name);
1801
- const targetProp = findAttribute("target");
1802
- if (targetProp == null) return;
1803
- const targetValue = jsx.resolveAttributeValue(targetProp);
1804
- if ((targetValue.kind === "spreadProps" ? targetValue.getProperty("target") : targetValue.toStatic()) !== "_blank") return;
1805
- const hrefProp = findAttribute("href");
1806
- if (hrefProp == null) return;
1807
- const hrefValue = jsx.resolveAttributeValue(hrefProp);
1808
- if (!isExternalLinkLike(hrefValue.kind === "spreadProps" ? hrefValue.getProperty("href") : hrefValue.toStatic())) return;
1809
- const relProp = findAttribute("rel");
1755
+ if (getAttributeStaticValue(context, node, "target") !== "_blank") return;
1756
+ if (!isExternalLinkLike(getAttributeStaticValue(context, node, "href"))) return;
1757
+ const relProp = findAttribute(context, node, "rel");
1810
1758
  if (relProp == null) {
1811
1759
  context.report({
1812
1760
  messageId: "default",
@@ -1820,8 +1768,7 @@ function create$3(context) {
1820
1768
  });
1821
1769
  return;
1822
1770
  }
1823
- const relValue = jsx.resolveAttributeValue(relProp);
1824
- if (isSafeRel(relValue.kind === "spreadProps" ? relValue.getProperty("rel") : relValue.toStatic())) return;
1771
+ if (isSafeRel(getAttributeStaticValue(context, node, "rel"))) return;
1825
1772
  context.report({
1826
1773
  messageId: "default",
1827
1774
  node: relProp,
@@ -1931,13 +1878,10 @@ var no_void_elements_with_children_default = createRule({
1931
1878
  });
1932
1879
  function create$1(context) {
1933
1880
  const resolver = createJsxElementResolver(context);
1934
- const jsx = JsxInspector.from(context);
1935
1881
  return defineRuleListener({ JSXElement(node) {
1936
1882
  const { domElementType } = resolver.resolve(node);
1937
1883
  if (!voidElements.has(domElementType)) return;
1938
- const hasChildrenProp = jsx.hasAttribute(node, "children");
1939
- const hasDangerouslySetInnerHTML = jsx.hasAttribute(node, "dangerouslySetInnerHTML");
1940
- if (node.children.length > 0 || hasChildrenProp || hasDangerouslySetInnerHTML) context.report({
1884
+ if (node.children.length > 0 || hasAnyAttribute(context, node, ["children", "dangerouslySetInnerHTML"])) context.report({
1941
1885
  data: { elementType: domElementType },
1942
1886
  messageId: "default",
1943
1887
  node
@@ -2003,7 +1947,6 @@ const plugin = {
2003
1947
  "no-hydrate": no_hydrate_default,
2004
1948
  "no-missing-button-type": no_missing_button_type_default,
2005
1949
  "no-missing-iframe-sandbox": no_missing_iframe_sandbox_default,
2006
- "no-namespace": no_namespace_default,
2007
1950
  "no-render": no_render_default,
2008
1951
  "no-render-return-value": no_render_return_value_default,
2009
1952
  "no-script-url": no_script_url_default,
@@ -2032,7 +1975,6 @@ const rules$1 = {
2032
1975
  "react-dom/no-find-dom-node": "error",
2033
1976
  "react-dom/no-flush-sync": "error",
2034
1977
  "react-dom/no-hydrate": "error",
2035
- "react-dom/no-namespace": "error",
2036
1978
  "react-dom/no-render": "error",
2037
1979
  "react-dom/no-render-return-value": "error",
2038
1980
  "react-dom/no-script-url": "warn",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-react-dom",
3
- "version": "3.0.0-rc.5",
3
+ "version": "4.0.0-beta.0",
4
4
  "description": "ESLint React's ESLint plugin for DOM related rules.",
5
5
  "keywords": [
6
6
  "react",
@@ -38,23 +38,24 @@
38
38
  "./package.json"
39
39
  ],
40
40
  "dependencies": {
41
- "@typescript-eslint/scope-manager": "^8.57.0",
42
- "@typescript-eslint/types": "^8.57.0",
43
- "@typescript-eslint/utils": "^8.57.0",
41
+ "@typescript-eslint/scope-manager": "^8.57.2",
42
+ "@typescript-eslint/types": "^8.57.2",
43
+ "@typescript-eslint/utils": "^8.57.2",
44
44
  "compare-versions": "^6.1.1",
45
45
  "ts-pattern": "^5.9.0",
46
- "@eslint-react/ast": "3.0.0-rc.5",
47
- "@eslint-react/core": "3.0.0-rc.5",
48
- "@eslint-react/shared": "3.0.0-rc.5",
49
- "@eslint-react/var": "3.0.0-rc.5"
46
+ "@eslint-react/ast": "4.0.0-beta.0",
47
+ "@eslint-react/jsx": "4.0.0-beta.0",
48
+ "@eslint-react/core": "4.0.0-beta.0",
49
+ "@eslint-react/var": "4.0.0-beta.0",
50
+ "@eslint-react/shared": "4.0.0-beta.0"
50
51
  },
51
52
  "devDependencies": {
52
53
  "@types/react": "^19.2.14",
53
54
  "@types/react-dom": "^19.2.3",
54
- "eslint": "^10.0.3",
55
- "tsdown": "^0.21.2",
56
- "@local/configs": "0.0.0",
57
- "@local/eff": "3.0.0-beta.72"
55
+ "eslint": "^10.1.0",
56
+ "tsdown": "^0.21.4",
57
+ "@local/eff": "3.0.0-beta.72",
58
+ "@local/configs": "0.0.0"
58
59
  },
59
60
  "peerDependencies": {
60
61
  "eslint": "^10.0.0",