Skip to content
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

[Modal] Should not call stopPropagation if onEscapeKeyDown=true #20611

Closed
1 task done
mainfraame opened this issue Apr 17, 2020 · 4 comments · Fixed by #20786
Closed
1 task done

[Modal] Should not call stopPropagation if onEscapeKeyDown=true #20611

mainfraame opened this issue Apr 17, 2020 · 4 comments · Fixed by #20786
Labels
bug 🐛 Something doesn't work component: modal This is the name of the generic UI component, not the React module! good first issue Great for first contributions. Enable to learn the contribution process.

Comments

@mainfraame
Copy link

I'm running into an issue where I need to handle the event propagation for the escape key on my own. It's impossible to get around because it's hard-coded in the handleKeyDown callback.

To be specific, I have a Popper rendered (via portal) over the modal, and when a user hits the Escape key, I want to close the Popper, but not the modal.

  • [-] The issue is present in the latest release. (not sure; cannot upgrade)
  • I have searched the issues of this repository and believe that this is not a duplicate.

Current Behavior 😯

When passing onEscapeKeyDown and disableEscapeKeyDown props to Modal, I do not want the event.stopPropagation to be called.

Instead of allowing the onEscapeKeyDown to handle the event propagation; the escape keydown event's propagation is stopped.

Expected Behavior 🤔

When modal is provided onEscapeKeyDown, a develop should expect to handle all aspects of the event. What also might be nice is if the modal manager is passed as a second parameter to the callback.

Tech Version
Material-UI v4.4.3
@oliviertassinari oliviertassinari added component: modal This is the name of the generic UI component, not the React module! out of scope The problem looks valid but we won't fix it (maybe we will revisit it in the future) and removed out of scope The problem looks valid but we won't fix it (maybe we will revisit it in the future) labels Apr 17, 2020
@oliviertassinari
Copy link
Member

@mentierd It seems that you are right, the current logic doesn't match the props' descriptions. What do you think of this diff? Do you want to submit a pull request? :)

diff --git a/packages/material-ui/src/Modal/Modal.js b/packages/material-ui/src/Modal/Modal.js
index badf67093..dc8eb6cee 100644
--- a/packages/material-ui/src/Modal/Modal.js
+++ b/packages/material-ui/src/Modal/Modal.js
@@ -189,7 +189,7 @@ const Modal = React.forwardRef(function Modal(inProps, ref) {
     // clicking a checkbox to check it, hitting a button to submit a form,
     // and hitting left arrow to move the cursor in a text input etc.
     // Only special HTML elements have these default behaviors.
-    if (event.key !== 'Escape' || !isTopModal()) {
+    if (event.key !== 'Escape' || !isTopModal() || disableEscapeKeyDown) {
       return;
     }

@@ -200,7 +200,7 @@ const Modal = React.forwardRef(function Modal(inProps, ref) {
       onEscapeKeyDown(event);
     }

-    if (!disableEscapeKeyDown && onClose) {
+    if (onClose) {
       onClose(event, 'escapeKeyDown');
     }
   };

For curiosity, I have looked at how the problem is handled in a couple of alternatives:

@oliviertassinari oliviertassinari added bug 🐛 Something doesn't work good first issue Great for first contributions. Enable to learn the contribution process. labels Apr 17, 2020
@oliviertassinari oliviertassinari changed the title Modal - handleKeyDown should not call event.stopPropagation when onEscapeKeyDown is provided [Modal] Should not call stopPropagation if onEscapeKeyDown=true Apr 17, 2020
@matthewbal
Copy link

I'd do it if @mentierd is too busy this weekend 😀

@weslenng
Copy link

@oliviertassinari I tried to implement your solution but one test fail:

it('when disableEscapeKeyDown should call only onEscapeKeyDownSpy', () => {

What do you think about this diff?

diff --git a/packages/material-ui/src/Modal/Modal.js b/packages/material-ui/src/Modal/Modal.js
index 1c38d39c4..748a70ec1 100644
--- a/packages/material-ui/src/Modal/Modal.js
+++ b/packages/material-ui/src/Modal/Modal.js
@@ -193,11 +193,11 @@ const Modal = React.forwardRef(function Modal(inProps, ref) {
       return;
     }
 
-    // Swallow the event, in case someone is listening for the escape key on the body.
-    event.stopPropagation();
-
     if (onEscapeKeyDown) {
       onEscapeKeyDown(event);
+    } else {
+      // Swallow the event, in case someone is listening for the escape key on the body.
+      event.stopPropagation();
     }
 
     if (!disableEscapeKeyDown && onClose) {

@oliviertassinari
Copy link
Member

oliviertassinari commented Apr 26, 2020

@weslenng The test goes against the documentation: If `true`, hitting escape will not fire any callback but it's the same issue with disableBackdropClick. Ok, I think that your alternative proposal is great.

For v5, I think that we can drop disableBackdropClick, onBackdropClick, onEscapeKeyDown, disableEscapeKeyDown. onChange + reason + filtering should be enough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 Something doesn't work component: modal This is the name of the generic UI component, not the React module! good first issue Great for first contributions. Enable to learn the contribution process.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants