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 8e3317c3d4..9f8692119e 100644 --- a/lib/rules/jsx-indent.js +++ b/lib/rules/jsx-indent.js @@ -114,6 +114,21 @@ module.exports = { }; } + 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]], @@ -396,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.' }], + }, ]), });