-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Components: Remove unexpected has-text
class when empty children are passed to Button
#44198
Conversation
children?.[ 0 ] && | ||
children[ 0 ] !== null && | ||
// Tooltip should not considered as a child | ||
children?.[ 0 ]?.props?.className !== 'components-tooltip'; |
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.
If Tooltip
is not excluded as a child, it will be considered to have children when moused over and has-text
class will be given.
I couldn't find a good approach to not regard Tooltip
as a child.
Is there a better way?
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.
Oof, I can't think of a better way either. I think it's good enough for a temporary measure though.
Long term, I'm hoping it could be resolved by the Tooltip
rewrite. Maybe that will remove the need to inject direct children?
Otherwise, we could perhaps add an official API to Button
that allows consumers to set some kind of "ignore me as a visible child" flag in CSS. So like if you add a designated CSS class, e.g. <Button><div className="ignore-as-components-button-child" /></Button>
, Button could exclude it from its hasChildren
check.
Another way might be to only apply .has-text
when the child is actually a ReactText
. I'm not sure, but I'm guessing that there are not a lot of use cases that involve a icon
prop and an element child with 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.
Otherwise, we could perhaps add an official API to Button that allows consumers to set some kind of "ignore me as a visible child" flag in CSS. So like if you add a designated CSS class, e.g.
, Button could exclude it from its hasChildren check.
Perhaps I think this new API should be considered in the overall Button component in #44042 for consideration.
Another way might be to only apply .has-text when the child is actually a ReactText. I'm not sure, but I'm guessing that there are not a lot of use cases that involve a icon prop and an element child with text.
Is it correct that a use case with a icon prop and an element child with text is something like the following?
<Button icon={ help } variant="primary">
Push Me
</Button>
I've seen such usage many times in my experience, so I think that the has-text
class should be added.
Long term, I'm hoping it could be resolved by the Tooltip rewrite. Maybe that will remove the need to inject direct children?
Yes, that's the challenge I must address in #42753 😅
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.
Another way might be to only apply .has-text when the child is actually a ReactText. I'm not sure, but I'm guessing that there are not a lot of use cases that involve a icon prop and an element child with text.
Is it correct that a use case with a icon prop and an element child with text is something like the following?
Sorry, this was unclear. By "icon prop and an element child with text" I meant something like:
// *Element* child with text
<Button icon={ help }>
<span>Push Me</span>
</Button>
in contrast to a text child:
// *Text* child
<Button icon={ help }>
Push Me
</Button>
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.
Thank you, I understand.
From what I have found on GitHub Code Search, it appears that "an element child with text" is almost never used.
For now, however, I think it would have less impact to consider both "element child with text" and "text child" as "having text".
This specification may need to be reconsidered in relation to #44042, but I think it is reasonable in this PR.
If it is not a problem, I would like to merge it 🚀
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.
Yep, sounds good! 🚢
Size Change: +616 B (0%) Total Size: 1.26 MB
ℹ️ View Unchanged
|
Thank you for the PR and test! 🙏 |
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 for fixing this so quickly!
We also need a changelog for this before merging 🙏
children?.[ 0 ] && | ||
children[ 0 ] !== null && | ||
// Tooltip should not considered as a child | ||
children?.[ 0 ]?.props?.className !== 'components-tooltip'; |
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.
Oof, I can't think of a better way either. I think it's good enough for a temporary measure though.
Long term, I'm hoping it could be resolved by the Tooltip
rewrite. Maybe that will remove the need to inject direct children?
Otherwise, we could perhaps add an official API to Button
that allows consumers to set some kind of "ignore me as a visible child" flag in CSS. So like if you add a designated CSS class, e.g. <Button><div className="ignore-as-components-button-child" /></Button>
, Button could exclude it from its hasChildren
check.
Another way might be to only apply .has-text
when the child is actually a ReactText
. I'm not sure, but I'm guessing that there are not a lot of use cases that involve a icon
prop and an element child with text.
</Button> | ||
); | ||
expect( screen.getByRole( 'button' ) ).not.toHaveClass( | ||
'has-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.
Eventually I'm hoping we can move these kinds of tests to visual regression testing because they are more robust than checking for class names ✨
@@ -4,7 +4,7 @@ exports[`PostSavedState returns a disabled button if the post is not saveable 1` | |||
<button | |||
aria-disabled="true" | |||
aria-label="Save draft" | |||
class="components-button has-text has-icon" | |||
class="components-button has-icon" |
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 to the failure of this unit test I have found another problem.
When the screen width is narrow, only an icon is shown on the Button
that indicates the save status. The has-text
class should not be given, but in the trunk, The has-text
class is shown for a certain status, which causes strange behaviour.
PostSavedState_trunk.mp4
This PR will solve this problem as well. Therefore, this snapshot update is intended.
PostSavedState_pr.mp4
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.
Looks good, I think we can merge once the .focus()
issue is fixed up in the test 👍
…n children are passed' test
Fix the problem found in #43802's comment.
What?
This PR fixes unexpected
has-text
class being given to aButton
component when an empty child is passed to it.Why?
As I have investigated in this comment, when a
Button
component is placed directly under aTooltip
component, the Button component has an array with null as a child and is given thehas-text
class, which is not expected.Similarly, I found that not specifying a child, such as
<Button></Button>
, or passing an empty fragment caused the same problem.I think that this problem is caused by the laxity of the conditions for checking whether the
Button
has children or not.How?
The conditions for granting the has-text class have been made stricter.
Testing Instructions
edit.js
in any of the blocks:Code
Screenshot and Screencast