diff --git a/packages/plugins/eslint-plugin-react-dom/package.json b/packages/plugins/eslint-plugin-react-dom/package.json
index 35563e5ea..a6e1f6ca1 100644
--- a/packages/plugins/eslint-plugin-react-dom/package.json
+++ b/packages/plugins/eslint-plugin-react-dom/package.json
@@ -58,6 +58,7 @@
"@typescript-eslint/scope-manager": "^8.15.0",
"@typescript-eslint/types": "^8.15.0",
"@typescript-eslint/utils": "^8.15.0",
+ "compare-versions": "^6.1.1",
"ts-pattern": "^5.5.0"
},
"devDependencies": {
diff --git a/packages/plugins/eslint-plugin-react-dom/src/rules/no-unknown-property.spec.ts b/packages/plugins/eslint-plugin-react-dom/src/rules/no-unknown-property.spec.ts
index e48584e49..6ef9c4be1 100644
--- a/packages/plugins/eslint-plugin-react-dom/src/rules/no-unknown-property.spec.ts
+++ b/packages/plugins/eslint-plugin-react-dom/src/rules/no-unknown-property.spec.ts
@@ -655,6 +655,25 @@ ruleTester.run(RULE_NAME, rule, {
Greetings, one and all!
`,
+ settings: {
+ "react-x": {
+ version: "18.3.1",
+ },
+ },
+ },
+ {
+ code: `
+
+
+
+
Greetings, one and all!
+
+ `,
+ settings: {
+ "react-x": {
+ version: "19.0.0-rc.0",
+ },
+ },
},
],
});
diff --git a/packages/plugins/eslint-plugin-react-dom/src/rules/no-unknown-property.ts b/packages/plugins/eslint-plugin-react-dom/src/rules/no-unknown-property.ts
index 0e347ee63..1ee416125 100644
--- a/packages/plugins/eslint-plugin-react-dom/src/rules/no-unknown-property.ts
+++ b/packages/plugins/eslint-plugin-react-dom/src/rules/no-unknown-property.ts
@@ -4,7 +4,9 @@
// Ported from https://github.com/jsx-eslint/eslint-plugin-react/blob/master/lib/rules/no-unknown-property.js
// TODO: Port to TypeScript
+import { decodeSettings, normalizeSettings } from "@eslint-react/shared";
import { createRule } from "../utils";
+import { compare, compareVersions } from "compare-versions";
// ------------------------------------------------------------------------------
// Constants
@@ -419,10 +421,6 @@ const DOM_PROPERTY_NAMES_ONE_WORD = [
"security",
// Video specific
"controls",
- // popovers
- "popover",
- "popovertarget",
- "popovertargetaction",
];
const DOM_PROPERTY_NAMES_TWO_WORDS = [
@@ -890,16 +888,29 @@ const REACT_ON_PROPS = [
"onPointerUpCapture",
];
+const POPOVER_API_PROPS = [
+ "popover",
+ "popoverTarget",
+ "popoverTargetAction",
+ "onToggle",
+ "onBeforeToggle",
+];
+
function getDOMPropertyNames(context) {
const ALL_DOM_PROPERTY_NAMES = DOM_PROPERTY_NAMES_TWO_WORDS.concat(DOM_PROPERTY_NAMES_ONE_WORD);
// this was removed in React v16.1+, see https://github.com/facebook/react/pull/10823
- if (!testReactVersion(context, ">= 16.1.0")) {
- return ALL_DOM_PROPERTY_NAMES.concat("allowTransparency");
+ if (testReactVersion(context, "<=", "16.1.0")) {
+ ALL_DOM_PROPERTY_NAMES.push("allowTransparency");
+ return ALL_DOM_PROPERTY_NAMES;
}
// these were added in React v16.4.0, see https://reactjs.org/blog/2018/05/23/react-v-16-4.html and https://github.com/facebook/react/pull/12507
- if (testReactVersion(context, ">= 16.4.0")) {
- return ALL_DOM_PROPERTY_NAMES.concat(REACT_ON_PROPS);
+ if (testReactVersion(context, ">=", "16.4.0")) {
+ ALL_DOM_PROPERTY_NAMES.push(...REACT_ON_PROPS);
}
+ // these were added in React v19.0.0-rc.0, see https://github.com/facebook/react/pull/27981
+ testReactVersion(context, ">=", "19.0.0-rc.0")
+ ? ALL_DOM_PROPERTY_NAMES.push(...POPOVER_API_PROPS)
+ : ALL_DOM_PROPERTY_NAMES.push(...POPOVER_API_PROPS.map((prop) => prop.toLowerCase()));
return ALL_DOM_PROPERTY_NAMES;
}
@@ -1185,6 +1196,8 @@ function report(context, message, messageId, data) {
});
}
-function testReactVersion(context, version) {
- return true;
+function testReactVersion(context, comparator, version) {
+ const { version: localVersion } = normalizeSettings(decodeSettings(context.settings));
+ console.log(localVersion, version, comparator);
+ return compare(localVersion, version, comparator);
}
diff --git a/packages/plugins/eslint-plugin-react-x/package.json b/packages/plugins/eslint-plugin-react-x/package.json
index 3593608c7..7a17ecc68 100644
--- a/packages/plugins/eslint-plugin-react-x/package.json
+++ b/packages/plugins/eslint-plugin-react-x/package.json
@@ -60,7 +60,7 @@
"@typescript-eslint/types": "^8.15.0",
"@typescript-eslint/utils": "^8.15.0",
"compare-versions": "^6.1.1",
- "is-immutable-type": "5.0.0",
+ "is-immutable-type": "^5.0.0",
"ts-pattern": "^5.5.0"
},
"devDependencies": {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index c487f4311..47bbbd449 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -8,12 +8,12 @@ overrides:
array-flatten: npm:@nolyfill/array-flatten@^1.0.42
is-core-module: npm:@nolyfill/is-core-module@^1.0.39
isarray: npm:@nolyfill/isarray@^1.0.29
+ nextra: 3.1.0
+ nextra-theme-docs: 3.1.0
safe-buffer: npm:@nolyfill/safe-buffer@^1.0.41
safer-buffer: npm:@nolyfill/safer-buffer@^1.0.41
side-channel: npm:@nolyfill/side-channel@^1.0.29
typedarray: npm:@nolyfill/typedarray@^1.0.29
- nextra: 3.1.0
- nextra-theme-docs: 3.1.0
typescript: ^5.6.3
importers:
@@ -639,6 +639,9 @@ importers:
'@typescript-eslint/utils':
specifier: ^8.15.0
version: 8.15.0(eslint@9.15.0(jiti@2.3.3))(typescript@5.6.3)
+ compare-versions:
+ specifier: ^6.1.1
+ version: 6.1.1
eslint:
specifier: ^8.57.0 || ^9.0.0
version: 9.15.0(jiti@2.3.3)
@@ -875,7 +878,7 @@ importers:
specifier: ^8.57.0 || ^9.0.0
version: 9.15.0(jiti@2.3.3)
is-immutable-type:
- specifier: 5.0.0
+ specifier: ^5.0.0
version: 5.0.0(eslint@9.15.0(jiti@2.3.3))(typescript@5.6.3)
ts-pattern:
specifier: ^5.5.0