eslint-plugin-react icon indicating copy to clipboard operation
eslint-plugin-react copied to clipboard

How to prevent jsx-newline for elements and expressions on one line?

Open gregorybolkenstijn opened this issue 3 years ago • 3 comments

I have jsx-newline enabled, but how can I allow these cases where I want everything to stay on the same line? Without adding {/* eslint-disable[-line] react/jsx-newline */} around it?

<p>
  {t('text')} <span>{email}</span>
</p>

or

<div>
  {activeStep}/{steps}
</div>

It would be nice if there would be a setting that allowed for cases where everything is on the same line. So:

// BAD
<p>
  {t('text')} 
  <span>{email}</span>
</p>

// BOTH GOOD
<p>
  {t('text')} <span>{email}</span>
</p>

<p>
  {t('text')} 

  <span>{email}</span>
</p>

gregorybolkenstijn avatar May 23 '22 14:05 gregorybolkenstijn

Might be related to #3033.

ljharb avatar May 23 '22 17:05 ljharb

@ljharb I would like to work on this issue.

caroline223 avatar Jul 06 '22 04:07 caroline223

@caroline223 go for it!

ljharb avatar Jul 06 '22 04:07 ljharb

Any chance of movement on this?

P.S. I was surprised jsx-newline even considered what is essentially a template string; I expected it to concern itself only with components (eg <Foo …>). I can't imagine anyone would want

foo
{bar}
qux
{zed}

instead of

foo {bar} qux {zed}

jacob-orbiit avatar Nov 17 '22 16:11 jacob-orbiit

@jacob-orbiit since it's definitely not a template literal - contents aren't stringified, they're rendered - i don't think that logic holds.

Separately, there's no linked PR and I've just added the "help wanted" label, so anyone is free to make a PR for it :-)

ljharb avatar Nov 17 '22 17:11 ljharb

Maybe "essentially" was the wrong word—perhaps "effectively":

const copy = `Hello ${name}! ${sentiment} to meet you`;

return (
  <p>{copy}</p>
);
return (
  <p>Hello {name}! {sentiment} to meet you</p>
);

potato, potato 😜

Could it be classified as some kind of "inline element" since it could also be a <span> or something like, and name the option something like ignoreInlineElements? (I don't know what the official JSX name for this is—if it even has one).

I think there's no need for fancy detection of what {name} actually is; it's surrounded by a bunch of text, so the intention is fairly clear that it's inline.

jacob-orbiit avatar Nov 18 '22 10:11 jacob-orbiit

It's only inline if name is text, or a component renders inline elements or text. If it renders a block-level element, it's not inline.

ljharb avatar Nov 21 '22 03:11 ljharb

If the goal is to ensure it's inline, you'd have done <p>{`Hello ${name}! ${sentiment} to meet you'}</p> or something similar.

ljharb avatar Nov 21 '22 03:11 ljharb

I think people won't care if it's truly inline. <p>Hello {name}! {sentiment} to meet you</p> is close enough. If someone shoves a block into name or sentiment, well, then dunce-cap for them, but it doesn't affect readability, which (I believe) is the purpose of this rule.

jacob-orbiit avatar Nov 28 '22 19:11 jacob-orbiit