-
Notifications
You must be signed in to change notification settings - Fork 8.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
#10099 adds keyboard handling to close confirm_modal on ESC #10455
#10099 adds keyboard handling to close confirm_modal on ESC #10455
Conversation
Can one of the admins verify this patch? |
I just signed the CLA a minute ago, so maybe it takes a bit for it to register. |
confirmButtonText: 'bye', | ||
onConfirm: confirmCallback, | ||
onCancel: cancelCallback, | ||
onClose: closeCallback, |
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.
You can remove the onClose
lines in your tests, as well as the showClose
setting. They aren't actually used in these tests anyway.
|
||
const e = angular.element.Event('keydown'); // eslint-disable-line new-cap | ||
e.keyCode = 27; | ||
while(e.keyCode === 27) { |
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 think you need to worry about the random value here. Just set the keyCode to a value other than 27. Probably good to avoid 9 (tab) and 13 (enter) too. You could play it safe and just pick a letter, so any value between 48 and 90 is fine.
} | ||
}; | ||
|
||
angular.element(document.body).bind('keydown', onKeyDown); |
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.
Please use .on
here instead of .bind
@@ -1 +1 @@ | |||
<div class="kuiModalOverlay"></div> | |||
<div class="kuiModalOverlay" ng-keydown="onKeyDown($event)"></div> |
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.
Since you're listening for the keypress event on document.body
, you don't need this keydown directive here.
Thanks for the comments, I will make these changes later on tonight or tomorrow. |
@dpenny52 you got it. Sorry it took me a while to review this, my local environment was being really goofy. I also opened dpenny52#1 for you to check out. It's a small change to some of the test code that was already there, but it affects the couple tests you wrote as well. |
Remove resetSpyCounts, use beforeEach
Updated with your PR + comments @w33ble |
|
||
angular.element(document.body).on('keydown', (event) => { | ||
if(event.keyCode === 27) { | ||
scope.onCancel(); |
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 should be onClose
, not onCancel
(I know you have concerns @w33ble about the differences between them, and I am starting to see your side of things, since this is a subtle difference, and it caused confusion here).
onClose
will be onCancel
unless a caller specifically sent a separate function - onClose maps to the X
, while onCancel
maps to one of the buttons.
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 if there is no X, then onCancel
is the interaction we want.
And this is why I've been advocating for a new dialog type for when you want the X/close button. They're different things ;)
But this isn't really a concern for @dpenny52 to worry about. I think this PR should be handled with the intention of working with the "confirm" modal, and we can break out the "close" functionality and make a new modal later. To my knowledge, we don't use the yes/no/close interaction anywhere right now, so it's safe to pretend it doesn't exist yet.
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.
Related: #10104 (comment) - your comment which advocates removing the Close option (and thus onClose
) from the existing confirm modal.
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.
Fair enough. Actually the whole reason for the onClose functionality may be going away, so we could rip that out (though I'd prefer to wait till after #10585 gets checked in just to be sure).
My modified feedback, in that case, is that I still think this logic should either go in confirm_modal, or be passed in as a function. No need for the modal overlay to have scope knowledge, and this could easily break if we change the name of the function inside confirm_modal.
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 both agree on that point I'd be happy to move that code down to the dialog level.
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.
Yeah, I think I'm on board with that part. I think that, while you're right @dpenny52 about the ESC being a universal modal interaction, we probably want to handle it differently in each case (as outlined in the whole onClose/onCancel conversation here). For now, let's move it into the confirm modal, and we can worry about pushing that logic back up when we add other modal types.
@@ -5,16 +5,23 @@ import modalOverlayTemplate from './modal_overlay.html'; | |||
* Appends the modal to the dom on instantiation, and removes it when destroy is called. | |||
*/ | |||
export class ModalOverlay { | |||
constructor(modalElement) { | |||
constructor(modalElement, scope) { |
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 feel like this functionality belongs in confirm_modal.js, and I think we should only bind ESC key functionality if showClose is true in confirm_modal.
My concern is, we don't always show the X
in the modal, and if we don't show the X
then I think we should force the user to be explicit about their choice. Esc
usually means, do nothing
or dont make a choice right now
which is what I see being mapped to the X
icon functionality on a dialog. onCancel
and onConfirm
can be any functions, and the button text can also be anything, so it might not be a "noop" type of function.
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 we should only bind ESC key functionality if showClose is true in confirm_modal
I disagree. Keyboard navigation is key, and ESC means "no" on a confirmation dialog. If we're going to replace native functionality, we need to provide the same interactions in our replacement.
if we don't show the X then I think we should force the user to be explicit about their choice
We are. They can't do anything else until they deal with the confirm dialog. "no" is a valid response, and ESC allows the user to respond that way with from the keyboard, just like they could always do before.
The functionality we're trying to replicate here is that of window.confirm
, and adding ESC handling gets us there.
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 also agree that ESC traditionally maps to "Cancel" in basically any dialog that I can think of. It would be very confusing/annoying to me as a user if I was used to navigating using a keyboard, then opened a dialog with "showClose=false" and suddenly my normal means of navigation doesn't work anymore.
@stacey-gammon The reason I put this in the ModalOverlay rather than the ConfirmDialog itself was so that the functionality could be re-used for other dialog types when they are created. I figured that ESC->Cancel is universal enough that it would be re-used for any other dialog. If that's not desired then it is easy enough to move that code to the dialog itself.
Updated with keyboard handling in confirm_modal.js |
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.
lgtm Thanks @dpenny52!
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 @dpenny52 for the submission!
Closes #10099 by adding keyDown handling to document.body while the ConfirmModal is open, looking for ESC keyDown events (keyCode === 27) and calling the onCancel() method of the ConfirmModal when they are detected.