diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2dee06358b..944a9f1472 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
* [`prefer-exact-props`] improve performance for `Identifier` visitor ([#3190][] @meowtec)
* `propTypes`: Handle TSTypeReference in no-unused-prop-type ([#3195][] @niik)
* [`sort-prop-types`]: avoid repeated warnings of the same node/reason ([#519][] @ljharb)
+* [`jsx-indent`]: Fix indent handling for closing parentheses ([#620][] @stefanbuck])
### Changed
* [readme] change [`jsx-runtime`] link from branch to sha ([#3160][] @tatsushitoji)
@@ -40,6 +41,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
[#3133]: https://github.com/yannickcr/eslint-plugin-react/pull/3133
[#2921]: https://github.com/yannickcr/eslint-plugin-react/pull/2921
[#2753]: https://github.com/yannickcr/eslint-plugin-react/pull/2753
+[#620]: https://github.com/yannickcr/eslint-plugin-react/pull/620
[#519]: https://github.com/yannickcr/eslint-plugin-react/issues/519
## [7.28.0] - 2021.12.22
diff --git a/lib/rules/jsx-indent.js b/lib/rules/jsx-indent.js
index dca534229d..9f8692119e 100644
--- a/lib/rules/jsx-indent.js
+++ b/lib/rules/jsx-indent.js
@@ -104,13 +104,32 @@ module.exports = {
* @private
*/
function getFixerFunction(node, needed) {
- return function fix(fixer) {
- const indent = Array(needed + 1).join(indentChar);
- if (node.type === 'JSXText' || node.type === 'Literal') {
+ const indent = Array(needed + 1).join(indentChar);
+
+ if (node.type === 'JSXText' || node.type === 'Literal') {
+ return function fix(fixer) {
const regExp = /\n[\t ]*(\S)/g;
const fixedText = node.raw.replace(regExp, (match, p1) => `\n${indent}${p1}`);
return fixer.replaceText(node, fixedText);
+ };
+ }
+
+ if (node.type === 'ReturnStatement') {
+ const raw = context.getSourceCode().getText(node);
+ const lines = raw.split('\n');
+ if (lines.length > 1) {
+ return function fix(fixer) {
+ const lastLineStart = raw.lastIndexOf('\n');
+ const lastLine = raw.slice(lastLineStart).replace(/^\n[\t ]*(\S)/, (match, p1) => `\n${indent}${p1}`);
+ return fixer.replaceTextRange(
+ [node.range[0] + lastLineStart, node.range[1]],
+ lastLine
+ );
+ };
}
+ }
+
+ return function fix(fixer) {
return fixer.replaceTextRange(
[node.range[0] - node.loc.start.column, node.range[0]],
indent
@@ -392,6 +411,19 @@ module.exports = {
},
Literal: handleLiteral,
JSXText: handleLiteral,
+
+ ReturnStatement(node) {
+ if (!node.parent) {
+ return;
+ }
+
+ const openingIndent = getNodeIndent(node);
+ const closingIndent = getNodeIndent(node, true);
+
+ if (openingIndent !== closingIndent) {
+ report(node, openingIndent, closingIndent);
+ }
+ },
};
},
};
diff --git a/tests/lib/rules/jsx-indent.js b/tests/lib/rules/jsx-indent.js
index 677fc459bd..a955ab2417 100644
--- a/tests/lib/rules/jsx-indent.js
+++ b/tests/lib/rules/jsx-indent.js
@@ -1094,6 +1094,28 @@ const Component = () => (
}
`,
},
+ {
+ code: `
+ function App() {
+ return (
+
+ );
+ }
+ `,
+ options: [2],
+ parserOptions,
+ },
+ {
+ code: `
+ function App() {
+ return
+
+ ;
+ }
+ `,
+ options: [2],
+ parserOptions,
+ },
]),
invalid: parsers.all([
@@ -1291,6 +1313,17 @@ const Component = () => (
errors: [
{
messageId: 'wrongIndent',
+ line: 3,
+ data: {
+ needed: 10,
+ type: 'space',
+ characters: 'characters',
+ gotten: 17,
+ },
+ },
+ {
+ messageId: 'wrongIndent',
+ line: 5,
data: {
needed: 10,
type: 'space',
@@ -1319,6 +1352,17 @@ const Component = () => (
errors: [
{
messageId: 'wrongIndent',
+ line: 3,
+ data: {
+ needed: 10,
+ type: 'space',
+ characters: 'characters',
+ gotten: 12,
+ },
+ },
+ {
+ messageId: 'wrongIndent',
+ line: 5,
data: {
needed: 10,
type: 'space',
@@ -2771,5 +2815,43 @@ const Component = () => (
},
],
},
+ {
+ code: `
+ function App() {
+ return (
+
+ );
+ }
+ `,
+ output: `
+ function App() {
+ return (
+
+ );
+ }
+ `,
+ options: [2],
+ parserOptions,
+ errors: [{ message: 'Expected indentation of 10 space characters but found 12.' }],
+ },
+ {
+ code: `
+ function App() {
+ return (
+
+ );
+ }
+ `,
+ output: `
+ function App() {
+ return (
+
+ );
+ }
+ `,
+ options: [2],
+ parserOptions,
+ errors: [{ message: 'Expected indentation of 10 space characters but found 8.' }],
+ },
]),
});