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