diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d957976ac..a2eed5f339 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange ### Added * [`display-name`]: add `checkContextObjects` option ([#3529][] @JulesBlm) +* [`jsx-first-prop-new-line`]: add `multiprop` option ([#3533][] @haydncomley) ### Fixed * [`no-array-index-key`]: consider flatMap ([#3530][] @k-yle) @@ -14,6 +15,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange * [`no-unknown-property`]: allow `onLoad` on `source` (@ljharb) [#3538]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3538 +[#3533]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3533 [#3530]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3530 [#3529]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3529 diff --git a/docs/rules/jsx-first-prop-new-line.md b/docs/rules/jsx-first-prop-new-line.md index 0ec839dbdc..36215794cf 100644 --- a/docs/rules/jsx-first-prop-new-line.md +++ b/docs/rules/jsx-first-prop-new-line.md @@ -15,6 +15,7 @@ This rule checks whether the first property of all JSX elements is correctly pla - `always`: The first property should always be placed on a new line. - `never` : The first property should never be placed on a new line, e.g. should always be on the same line as the Component opening tag. - `multiline`: The first property should always be placed on a new line when the JSX tag takes up multiple lines. +- `multiprop`: The first property should never be placed on a new line unless there are multiple properties. - `multiline-multiprop`: The first property should always be placed on a new line if the JSX tag takes up multiple lines and there are multiple properties. This is the `default` value. Examples of **incorrect** code for this rule, when configured with `"always"`: diff --git a/lib/rules/jsx-first-prop-new-line.js b/lib/rules/jsx-first-prop-new-line.js index d301a5f3aa..143368c137 100644 --- a/lib/rules/jsx-first-prop-new-line.js +++ b/lib/rules/jsx-first-prop-new-line.js @@ -30,7 +30,7 @@ module.exports = { messages, schema: [{ - enum: ['always', 'never', 'multiline', 'multiline-multiprop'], + enum: ['always', 'never', 'multiline', 'multiline-multiprop', 'multiprop'], }], }, @@ -46,6 +46,7 @@ module.exports = { if ( (configuration === 'multiline' && isMultilineJSX(node)) || (configuration === 'multiline-multiprop' && isMultilineJSX(node) && node.attributes.length > 1) + || (configuration === 'multiprop' && node.attributes.length > 1) || (configuration === 'always') ) { node.attributes.some((decl) => { @@ -59,7 +60,10 @@ module.exports = { } return true; }); - } else if (configuration === 'never' && node.attributes.length > 0) { + } else if ( + (configuration === 'never' && node.attributes.length > 0) + || (configuration === 'multiprop' && isMultilineJSX(node) && node.attributes.length <= 1) + ) { const firstNode = node.attributes[0]; if (node.loc.start.line < firstNode.loc.start.line) { report(context, messages.propOnSameLine, 'propOnSameLine', { diff --git a/tests/lib/rules/jsx-first-prop-new-line.js b/tests/lib/rules/jsx-first-prop-new-line.js index 8fea1441fc..7e5d485689 100644 --- a/tests/lib/rules/jsx-first-prop-new-line.js +++ b/tests/lib/rules/jsx-first-prop-new-line.js @@ -139,6 +139,24 @@ ruleTester.run('jsx-first-prop-new-line', rule, { `, options: ['always'], }, + { + code: ` + + `, + options: ['multiprop'], + }, + { + code: ` + + `, + options: ['multiprop'], + }, + { + code: ` + + `, + options: ['multiprop'], + }, ]), invalid: parsers.all([ @@ -209,5 +227,38 @@ bar={{ options: ['multiline-multiprop'], errors: [{ messageId: 'propOnNewLine' }], }, + { + code: ` + + `, + output: ` + + `, + options: ['multiprop'], + errors: [{ messageId: 'propOnNewLine' }], + }, + { + code: ` + + `, + output: ` + + `, + options: ['multiprop'], + errors: [{ messageId: 'propOnSameLine' }], + }, + { + code: ` + + `, + output: ` + + `, + options: ['multiprop'], + errors: [{ messageId: 'propOnSameLine' }], + }, ]), });