-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
[datetime] fix(DateInput): Improve blur handling to avoid unexpected popover closures #4316
Conversation
aa30e86
to
a23310b
Compare
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.
see my comment #3603 (comment)
@adidahiya I think by the point we reach However what happens if theoretically a month change leads the popover to a state without any tabbable element? Besides from that let me know what you think about this idea. |
a23310b
to
90db227
Compare
@adidahiya I've refactored this PR, now it should cover all use cases and even improve existing function-ability which had another unreported bug. To reproduce the other bug, on a DateInput will nul value, place the active element on the first day of the month, and then press left arrow key, notice how the popover closes. This is because we're making I also removed the step where it makes |
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.
this does appear to fix the issue, so the UX changes are ok
...this.props.dayPickerProps, | ||
// If the user tabs on a DayPicker Day element and the lastElementInPopover is also a DayPicker Day | ||
// element, the popover should be closed |
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 don't quite follow this comment, why is this the case?
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.
From your #3603 (comment)
but I would still like to retain the functionality added in #2093 which closes the DateInput popover after a user TABs out of the last tabbable element in the popover.
Which is basically a remark with that comment, if you feel it's redundant I can remove 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.
but what about "...and the lastElementInPopover is also a DayPicker Day element"? why is this guard necessary? the comment leaves me wondering what the other possibilities are (I assume it refers to cases where a time picker is rendered, making that the last tabbable element?)
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.
Yes, I tried all combinations and that extra guards need to be in place for when there's any tabbable element below the calendar (like time picker, but it would cover any new element added in the future)
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.
ok, then that begs the question... which code is responsible for closing the popover when there is a tabbable element (like TimePicker) below the calendar? your implementation seems to work fine, but I want to make sure the code comments are clear and comprehensible for the next person who reads this code. I'm pulling your branch now to figure this out for myself
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.
registerPopoverBlurHandler
along handlePopoverBlur
is handling that (like originally implemented), just excluding the 2 cases mentioned in the comment. It's actually "agnostic" regarding if the last tabbable element is below the calendar or not, that state variable holds the last tabbable element inside the popover and listens for blur events.
Actually, now that you mention it, I found that this code
blueprint/packages/datetime/src/dateInput.tsx
Lines 446 to 447 in 408a8a7
this.lastElementInPopover = relatedTarget; | |
this.lastElementInPopover.addEventListener("blur", this.handlePopoverBlur); |
registerPopoverBlurHandler
(also maybe a documentation to lastElementInPopover
meaning "last element in popover that is tabbable, and the one that triggers closure if the user press tabs on it"
...this.props.dayPickerProps, | ||
// If the user tabs on a DayPicker Day element and the lastElementInPopover is also a DayPicker Day | ||
// element, the popover should be closed |
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.
but what about "...and the lastElementInPopover is also a DayPicker Day element"? why is this guard necessary? the comment leaves me wondering what the other possibilities are (I assume it refers to cases where a time picker is rendered, making that the last tabbable element?)
Co-authored-by: Adi Dahiya <adi.dahiya14@gmail.com>
confirmed in Chrome, FF, IE11 👍 thanks @ejose19 |
Fixes #3603
Changes proposed in this pull request:
The poposed solution is to avoid the case where minDate/maxDate is set, and using the change month arrows makes the popover to close on chrome browser, upon debugging, the issue is that document.activeElement is returning "body" instead of the change month button, which makes
handlePopoverBlur
set up execute incorrectly and subsequently callinghandleClosePopover
which causes the described issue.Reviewers should focus on:
While this solution works correctly for that case, it makes "Popover closes when first day of the month is blurred" test fail, and after evaluating both use cases, it seems the min/max date has more weight, and so losing that "feature" is worth it.
Here's the sandbox (open in chrome) and without selecting any date, move 2 months before/after and notice how the popover closes incorrectly.