From 886eac9a74e2fae5cfba31de595c7c9e283da155 Mon Sep 17 00:00:00 2001 From: Bartosz Date: Thu, 11 Jan 2024 18:04:05 +0100 Subject: [PATCH] [New] `jsx-one-expression-per-line`: add `non-jsx` option to allow non-JSX children in one line --- docs/rules/jsx-one-expression-per-line.md | 8 +++ lib/rules/jsx-one-expression-per-line.js | 7 ++- .../lib/rules/jsx-one-expression-per-line.js | 62 +++++++++++++++++++ 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/docs/rules/jsx-one-expression-per-line.md b/docs/rules/jsx-one-expression-per-line.md index 9c5fe0eac6..d2f170278b 100644 --- a/docs/rules/jsx-one-expression-per-line.md +++ b/docs/rules/jsx-one-expression-per-line.md @@ -133,3 +133,11 @@ Examples of **correct** code for this rule, when configured as `"single-child"`: ``` + +Examples of **correct** code for this rule, when configured as `"non-jsx"`: + +```jsx +Hello {someVariable} + +Hello {} there! +``` diff --git a/lib/rules/jsx-one-expression-per-line.js b/lib/rules/jsx-one-expression-per-line.js index 6d0d1575d9..d5db1d96b4 100644 --- a/lib/rules/jsx-one-expression-per-line.js +++ b/lib/rules/jsx-one-expression-per-line.js @@ -38,7 +38,7 @@ module.exports = { type: 'object', properties: { allow: { - enum: ['none', 'literal', 'single-child'], + enum: ['none', 'literal', 'single-child', 'non-jsx'], }, }, default: optionDefaults, @@ -65,6 +65,11 @@ module.exports = { return; } + if (options.allow === 'non-jsx' + && !children.find((child) => (child.type === 'JSXFragment' || child.type === 'JSXElement'))) { + return; + } + const openingElement = node.openingElement || node.openingFragment; const closingElement = node.closingElement || node.closingFragment; const openingElementStartLine = openingElement.loc.start.line; diff --git a/tests/lib/rules/jsx-one-expression-per-line.js b/tests/lib/rules/jsx-one-expression-per-line.js index 0c684c7da5..4e2e266ed2 100644 --- a/tests/lib/rules/jsx-one-expression-per-line.js +++ b/tests/lib/rules/jsx-one-expression-per-line.js @@ -155,6 +155,18 @@ ruleTester.run('jsx-one-expression-per-line', rule, { code: '{"foo"}', options: [{ allow: 'single-child' }], }, + { + code: '123', + options: [{ allow: 'non-jsx' }], + }, + { + code: 'foo', + options: [{ allow: 'non-jsx' }], + }, + { + code: '{"foo"}', + options: [{ allow: 'non-jsx' }], + }, { code: '{foo && }', options: [{ allow: 'single-child' }], @@ -184,6 +196,17 @@ ruleTester.run('jsx-one-expression-per-line', rule, { `, features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix }, + { + code: 'Hello {name}', + options: [{ allow: 'non-jsx' }], + }, + { + code: ` + + Hello {name} there! + `, + options: [{ allow: 'non-jsx' }], + }, ]), invalid: parsers.all([ @@ -493,6 +516,28 @@ foo ], parserOptions, }, + { + code: ` + + + + `, + output: ` + + ${' '/* intentional trailing space */} +{' '} + + + `, + errors: [ + { + messageId: 'moveToNewLine', + data: { descriptor: 'Baz' }, + }, + ], + options: [{ allow: 'non-jsx' }], + parserOptions, + }, { code: ` @@ -1257,6 +1302,23 @@ foo }, ], }, + { + code: ` + + `, + output: ` + + + + `, + options: [{ allow: 'non-jsx' }], + errors: [ + { + messageId: 'moveToNewLine', + data: { descriptor: 'Foo' }, + }, + ], + }, { code: `