Skip to content

Commit e8cef50

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 e8cef50

File tree

3 files changed

+80
-1
lines changed

3 files changed

+80
-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

+66
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,22 @@ 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+
},
170+
{
171+
code: '<App>{<Bar />}</App>',
172+
options: [{ allow: 'non-jsx' }],
173+
},
158174
{
159175
code: '<App>{foo && <Bar />}</App>',
160176
options: [{ allow: 'single-child' }],
@@ -184,6 +200,17 @@ ruleTester.run('jsx-one-expression-per-line', rule, {
184200
`,
185201
features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix
186202
},
203+
{
204+
code: '<App>Hello {name}</App>',
205+
options: [{ allow: 'non-jsx' }],
206+
},
207+
{
208+
code: `
209+
<App>
210+
Hello {name} there!
211+
</App>`,
212+
options: [{ allow: 'non-jsx' }],
213+
},
187214
]),
188215

189216
invalid: parsers.all([
@@ -493,6 +520,28 @@ foo
493520
],
494521
parserOptions,
495522
},
523+
{
524+
code: `
525+
<Text style={styles.foo}>
526+
<Bar /> <Baz />
527+
</Text>
528+
`,
529+
output: `
530+
<Text style={styles.foo}>
531+
<Bar />${' '/* intentional trailing space */}
532+
{' '}
533+
<Baz />
534+
</Text>
535+
`,
536+
errors: [
537+
{
538+
messageId: 'moveToNewLine',
539+
data: { descriptor: 'Baz' },
540+
},
541+
],
542+
options: [{ allow: 'non-jsx' }],
543+
parserOptions,
544+
},
496545
{
497546
code: `
498547
<Text style={styles.foo}>
@@ -1257,6 +1306,23 @@ foo
12571306
},
12581307
],
12591308
},
1309+
{
1310+
code: `
1311+
<App><Foo /></App>
1312+
`,
1313+
output: `
1314+
<App>
1315+
<Foo />
1316+
</App>
1317+
`,
1318+
options: [{ allow: 'non-jsx' }],
1319+
errors: [
1320+
{
1321+
messageId: 'moveToNewLine',
1322+
data: { descriptor: 'Foo' },
1323+
},
1324+
],
1325+
},
12601326
{
12611327
code: `
12621328
<App

0 commit comments

Comments
 (0)