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 closing when clicking on content inside it #229

Closed
cdellacqua opened this issue Aug 12, 2020 · 6 comments
Closed

Modal closing when clicking on content inside it #229

cdellacqua opened this issue Aug 12, 2020 · 6 comments
Assignees
Labels
bug Something isn't working

Comments

@cdellacqua
Copy link

I'm using a modal containing a form with a PasswordInput field. When clicking the show/hide password, the modal closes unexpectedly. I found out after some debugging that the problem is here:
(file Modal.svelte)

on:click={({ target }) => {
    if (!innerModal.contains(target)) {
      open = false;
    }
  }}

By clicking the "hide/show" icon inside the PasswordInput, that icon gets unmounted from the DOM so it can be replaced with another one indicating the opposite action. That causes the .contains method to return false, even though the source of the event was inside the modal when it was originally triggered. This should also apply to similar cases.

@cdellacqua
Copy link
Author

cdellacqua commented Aug 12, 2020

A possible solution could be to attach an on:click to the innerModal div that sets a flag to inhibit the close action. Code snippet:

<div
  <!-- outer modal props -->
  on:click={() => {
    if (!inhibitClose) {
      open = false;
    }
    inhibitClose = false;
  }}>
  <div
    <!-- inner modal props -->
    on:click={() => inhibitClose = true}

By doing this, events that propagated from a child of innerModal will set the flag to true (even if unmounted, because the bubbling flow is preserved). Moreover this should be faster than calling .contains, because there is no need to recursively scan the hierarchy of descendants

@cdellacqua
Copy link
Author

cdellacqua commented Aug 12, 2020

I saw your PR that fixes this behavior for the PasswordInput component, but I should have probably hightlighted the

This should also apply to similar cases.

part.
In fact, this behavior happens any time an object clicked inside the modal gets unmounted (just like the icon in the PasswordInput). So it's not really the PasswordInput fault (which now doesn't propagate the click, which could be helpful for other parent components), it's the logic inside the on:click handler of the div wrapping the innerModal that's faulty because it doesn't take into account this possibility (and it's pretty common when using {#if} directives). The code snippet I posted in the comment before should really fix the issue at its root.

Sorry if I didn't express myself clearly enough in the original post. Thanks

@metonym
Copy link
Collaborator

metonym commented Aug 12, 2020

@cdellacqua interesting solution – will give it a try.

@metonym
Copy link
Collaborator

metonym commented Aug 12, 2020

@cdellacqua your solution is brilliant.

  • it's more performant because it doesn't use .contains()
  • it still allows e.target for the click event forwarded by Modal

@metonym
Copy link
Collaborator

metonym commented Aug 12, 2020

@cdellacqua Fixed in v0.9.5

@cdellacqua
Copy link
Author

Perfect! Thanks a lot for your time, I'm really appreciating this library.

Closing the issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants