diff --git a/CHANGELOG.md b/CHANGELOG.md
index ddbbfef5c8..9696eca775 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,9 +6,13 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
## Unreleased
+### Added
+* [`jsx-props-no-multi-spaces`]: improve autofix for multi-line ([#3930][] @justisb)
+
### Fixed
* [`no-unknown-property`]: allow `onLoad` on `body` ([#3923][] @DerekStapleton)
+[#3930]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3930
[#3923]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3923
## [7.37.5] - 2025.04.03
diff --git a/lib/rules/jsx-props-no-multi-spaces.js b/lib/rules/jsx-props-no-multi-spaces.js
index 8402c6d4ff..5786506d11 100644
--- a/lib/rules/jsx-props-no-multi-spaces.js
+++ b/lib/rules/jsx-props-no-multi-spaces.js
@@ -80,6 +80,22 @@ module.exports = {
prop1: getPropName(prev),
prop2: getPropName(node),
},
+ fix(fixer) {
+ const comments = sourceCode.getCommentsBefore ? sourceCode.getCommentsBefore(node) : [];
+ const nodes = [].concat(prev, comments, node);
+ const fixes = [];
+
+ for (let i = 1; i < nodes.length; i += 1) {
+ const prevNode = nodes[i - 1];
+ const currNode = nodes[i];
+ if (currNode.loc.start.line - prevNode.loc.end.line >= 2) {
+ const indent = ' '.repeat(currNode.loc.start.column);
+ fixes.push(fixer.replaceTextRange([prevNode.range[1], currNode.range[0]], `\n${indent}`));
+ }
+ }
+
+ return fixes;
+ },
});
}
diff --git a/tests/lib/rules/jsx-props-no-multi-spaces.js b/tests/lib/rules/jsx-props-no-multi-spaces.js
index d85573702f..8b8d15a9b4 100644
--- a/tests/lib/rules/jsx-props-no-multi-spaces.js
+++ b/tests/lib/rules/jsx-props-no-multi-spaces.js
@@ -84,7 +84,7 @@ ruleTester.run('jsx-props-no-multi-spaces', rule, {
{
code: `
`,
@@ -92,7 +92,7 @@ ruleTester.run('jsx-props-no-multi-spaces', rule, {
{
code: `