-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: jsx-child-element-spacing proposal #1519
Conversation
Open to feedback on
|
code: ` | ||
<App> | ||
foo | ||
<a>bar</a> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what would the output be if you wanted this autofixed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think as you pointed out in the original issue, the intent is ambiguous so autofixing may not be feasible.
If we were to autofix, replacing with the comment form would maintain the semantic without too much disruption (though would perhaps be less aesthetically pleasing)
I would advocate for no automatic action since, in my experience, the developer most often intended to add a space, though I could be convinced otherwise
Could you add a bunch more valid and invalid examples? That would help evaluate the usefulness of the rule. |
Thanks @ljharb - I've added some more test cases that cover some different case. Please let me know if that helps or if I can provide cases of another type |
<App> | ||
<a> | ||
<b>nested1</b> | ||
<b>nested2</b> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this an error? are you going to keep a list of inline-by-default elements? What about when the display is changed via css?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be an error because it would render as nested1nested2 which is unlikely to be the developers intent
We certainly could just use the complete list of inline elements here: https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements
Certainly it would not be feasible to capture changes to display by CSS. I wouldn't be overly concerned about it because...
- If the developer uses CSS to make a block element inline, then the rule will not catch this. However without this rule they are equally likely not to catch this. I would also expect that, since the developer is already modifying the default layout, they are likely to be visually inspecting the results manually to look for inconsistencies
- If the developer uses CSS to make an inline element into a block, then the rule may error unnecessarily. However the error can be silenced by adding either an explicit space or a comment form, as above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless there's already a package that keeps the list of inline elements up to date, i'd be hesitant to hardcode it in this package.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A fair concern - here's one that I found: https://www.npmjs.com/package/block-elements (and it's less popular cousin https://www.npmjs.com/package/inline-elements)
Worth noting that React, when tackling a similar problem, opted to just hardcode a list of relevant tags
Another alternative would be not to do any special-casing on tag type and treat any adjacent tags as problematic, though I suspect that would get annoying pretty fast with adjacent divs.
Another concern - custom React classes for which it would be infeasible to detect the display type statically. This leads me to believe the rule should only report cases where we know the tag is inline - I think this covers a lot of common cases (like tags in text)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The real ideal would be if we could use React's list directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, they are not the same use case
Note: this does not catch all invalid nesting, nor does it try to (as it's
// not clear what practical benefit doing so provides); instead, we warn only
// for cases where the parser will give a parse tree differing from what React
// intended. For example, <b><div></div></b> is invalid but we don't warn
// because it still parses correctly; we do warn for other cases like nested
// <p> tags where the beginning of the second element implicitly closes the
// first, causing a confusing mess.
I've updated this PR to reduce its scope. Originally I was hoping to catch cases like
the original draft of this rule searched for cases like that. Ultimately there were just too many false positives (such as a's, span's, button's that used CSS to distinguish between them). By reducing the scope to just search for
the rule became much more useful and has very few false positives. I ran this on about 60k lines of React code and the results were
The majority of the error cases were a's, code's, strong's appearing inside paragraphs. The majority of the ambiguous cases were checkboxes appearing next to text. The false positives were that were separately styled with CSS This suggests to me this is a useful rule and I submit it for your consideration cc @ljharb |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I think this LGTM.
@@ -0,0 +1,102 @@ | |||
'use strict'; | |||
|
|||
const INLINE_ELEMENTS = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you add a comment here that links to the source of this list?
|
||
const isInlineElement = node => ( | ||
node.type === 'JSXElement' && | ||
INLINE_ELEMENTS.indexOf(elementName(node)) !== -1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this be made into a Set instead?
comments addressed @ljharb |
Failing tests to illustrate use cases for #1515