-
Notifications
You must be signed in to change notification settings - Fork 933
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
Fix incorrect input reset #354
Fix incorrect input reset #354
Conversation
Codecov Report
@@ Coverage Diff @@
## master #354 +/- ##
=====================================
Coverage 100% 100%
=====================================
Files 4 4
Lines 329 330 +1
Branches 84 84
=====================================
+ Hits 329 330 +1
Continue to review full report at Codecov.
|
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 like this solution better as well! 👍
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.
Looking good! Let's try something simpler first.
src/downshift.js
Outdated
@@ -827,7 +840,8 @@ class Downshift extends Component { | |||
if ( | |||
(event.target === this._rootNode || | |||
!this._rootNode.contains(event.target)) && | |||
this.getState().isOpen | |||
this.getState().isOpen && | |||
!this.isInputFocused |
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 if instead we just change this to:
// above:
const {document} = this.props.environment
// this line
(!this.inputId || document.getElementById(this.inputId) !== document.activeElement)
Then I think we could remove all the focus logic.
Want to give that a try? The tests shouldn't need to change if it works.
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 like it, and looks like it's working.
It is breaking the test though as it seems like enzyme doesn't really support the document.activeElement
enzymejs/enzyme#1128
I believe I can just go ahead and set the document.activeElement
in my test.
And what if instead of looking for the getElementById
we would do as simple text check :
(!this.inputId || this.inputId !== document.activeElement.id)
?
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.
Well seems like the testing might get a bit hairier with the document.activeElement
solution.
To use document.activeElement
from what I read we might need to use JSDOM
to simulate this.
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.
And what if instead of looking for the getElementById we would do as simple text check:
(!this.inputId || this.inputId !== document.activeElement.id)
That's fantastic.
Yeah, go ahead and set document.activeElement
manually in your tests. Kinda weird, but should be ok. If you want you could try to add a browser test via cypress:
Learn more about cypress here.
I think we should have both, one for the quick feedback loop and the other to ensure it works without jsdom
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 you can't get it to work with the jest tests then that's fine. Add an /* istanbul ignore next */
comment on the line above this condition and it should prevent coverage being recorded for that line and we'll cover it using cypress 👍
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.
Awesome 👍
Let me know if you need a hand :)
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.
Oh, and to start up cypress, run npm run test:cypress:dev
. I should probably add that to the contributing docs... Would you like to?
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.
Hmmm not so sure I have the time atm, but I might do it later if you want.
I believe the cypress
test is up, it's pretty cool and quite straightforward.
I tested with npm run test:cypress
though, hope it's equivalent.
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.
hi guys! how did u set up the document.activeelement in enzyme? im using activeElement in my component code. However, in my enzyme testing, it won't recognize the activeelement. i kept getting undefined.
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 you read the thread you commented on you'll see that we didn't do it either....
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.
Sweet, I've verified with the netlify preview that the bug has been fixed, the cypress tests look good and they're passing! Well done! Thank you for your work on this :D
You are welcome. |
Actually, now I'm starting to wonder if we should change this to be more generic... How about this: this._rootNode.contains(document.activeElement) This way if the active element is the button or really anything else within the component it wont reset. I'm not 100% certain this is what we're looking for, but it's something to think about and maybe try... Would you like to give it a try? |
Thanks so much for your help! I've added you as a collaborator on the project. Please make sure that you review the |
@kentcdodds what would be the advantage to make this more generic. Let me know if you want to go for the |
Using this as an example... Let's say the user types out 'Luke Skywalker' and does a Do we want that to reset? I would say no which would suggest that the Separately though, what if the user clicks on the label? I would think the ideal behavior would be the same as |
The thing is that downshift has absolutely 0 opinions about what you render within it. So some implementation could add a second input that serves to further filter the list of items. We wouldn't want to have this same bug on that second input. That's just one example. The use cases are wide and varied. Also, I think that this change would make the solution more robust :) |
That's a fair point.... Hmmm.... I'm not certain what to do here. @austintackaberry, would you mind opening a new issue that outlines the problem and arguments for and against for us to discuss this further? That way we can get more people to weigh in. |
Not at all! |
…ownshift-js#354) * Fixes downshift-js#350 : Selecting input text can lead to state reset * Updated contributors * Makes sense to switch the isInputFocused bool first thing in handle_inputBlur * Added test * Better way to handle knowing if the input is focused * Updated test * chore: update .all-contributorsrc
What:
Bug with selecting the input text which might lead to reseting the state
How:
I added a
onFocus
on the input, which is responsible with theonBlur
to keep aisInputFocused
boolean updated.If the input is focused, we do not want to reset the state and fire the
onOuterClick
prop.It seemed to me that was a clearer way to go than what was discussed in the issue.
Though if you consider it not the right way, feel free to ask for edit.
Checklist: