Skip to content

Commit 886eac9

Browse files
committed
[New] jsx-one-expression-per-line: add non-jsx option to allow non-JSX children in one line
1 parent 3730edb commit 886eac9

File tree

3 files changed

+76
-1
lines changed

3 files changed

+76
-1
lines changed

docs/rules/jsx-one-expression-per-line.md

+8
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,11 @@ Examples of **correct** code for this rule, when configured as `"single-child"`:
133133

134134
<App><Hello /></App>
135135
```
136+
137+
Examples of **correct** code for this rule, when configured as `"non-jsx"`:
138+
139+
```jsx
140+
<App>Hello {someVariable}</App>
141+
142+
<App>Hello {<Hello />} there!</App>
143+
```

lib/rules/jsx-one-expression-per-line.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ module.exports = {
3838
type: 'object',
3939
properties: {
4040
allow: {
41-
enum: ['none', 'literal', 'single-child'],
41+
enum: ['none', 'literal', 'single-child', 'non-jsx'],
4242
},
4343
},
4444
default: optionDefaults,
@@ -65,6 +65,11 @@ module.exports = {
6565
return;
6666
}
6767

68+
if (options.allow === 'non-jsx'
69+
&& !children.find((child) => (child.type === 'JSXFragment' || child.type === 'JSXElement'))) {
70+
return;
71+
}
72+
6873
const openingElement = node.openingElement || node.openingFragment;
6974
const closingElement = node.closingElement || node.closingFragment;
7075
const openingElementStartLine = openingElement.loc.start.line;

tests/lib/rules/jsx-one-expression-per-line.js

+62
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,18 @@ ruleTester.run('jsx-one-expression-per-line', rule, {
155155
code: '<App>{"foo"}</App>',
156156
options: [{ allow: 'single-child' }],
157157
},
158+
{
159+
code: '<App>123</App>',
160+
options: [{ allow: 'non-jsx' }],
161+
},
162+
{
163+
code: '<App>foo</App>',
164+
options: [{ allow: 'non-jsx' }],
165+
},
166+
{
167+
code: '<App>{"foo"}</App>',
168+
options: [{ allow: 'non-jsx' }],
169+
},
158170
{
159171
code: '<App>{foo && <Bar />}</App>',
160172
options: [{ allow: 'single-child' }],
@@ -184,6 +196,17 @@ ruleTester.run('jsx-one-expression-per-line', rule, {
184196
`,
185197
features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix
186198
},
199+
{
200+
code: '<App>Hello {name}</App>',
201+
options: [{ allow: 'non-jsx' }],
202+
},
203+
{
204+
code: `
205+
<App>
206+
Hello {name} there!
207+
</App>`,
208+
options: [{ allow: 'non-jsx' }],
209+
},
187210
]),
188211

189212
invalid: parsers.all([
@@ -493,6 +516,28 @@ foo
493516
],
494517
parserOptions,
495518
},
519+
{
520+
code: `
521+
<Text style={styles.foo}>
522+
<Bar /> <Baz />
523+
</Text>
524+
`,
525+
output: `
526+
<Text style={styles.foo}>
527+
<Bar />${' '/* intentional trailing space */}
528+
{' '}
529+
<Baz />
530+
</Text>
531+
`,
532+
errors: [
533+
{
534+
messageId: 'moveToNewLine',
535+
data: { descriptor: 'Baz' },
536+
},
537+
],
538+
options: [{ allow: 'non-jsx' }],
539+
parserOptions,
540+
},
496541
{
497542
code: `
498543
<Text style={styles.foo}>
@@ -1257,6 +1302,23 @@ foo
12571302
},
12581303
],
12591304
},
1305+
{
1306+
code: `
1307+
<App><Foo /></App>
1308+
`,
1309+
output: `
1310+
<App>
1311+
<Foo />
1312+
</App>
1313+
`,
1314+
options: [{ allow: 'non-jsx' }],
1315+
errors: [
1316+
{
1317+
messageId: 'moveToNewLine',
1318+
data: { descriptor: 'Foo' },
1319+
},
1320+
],
1321+
},
12601322
{
12611323
code: `
12621324
<App

0 commit comments

Comments
 (0)