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

Parent portal closes when clicking inside of a nested portal #101

Closed
woodenconsulting opened this issue Oct 5, 2016 · 3 comments
Closed

Comments

@woodenconsulting
Copy link

woodenconsulting commented Oct 5, 2016

screen shot 2016-10-05 at 12 11 05 pm

Portal Version: 2.2.1

Consider the above screenshot of what I am currently working on. I have a portal nested inside of another portal. The issue is when I click inside of the child portal (the calendar) the parent portal closes (along with all child portals).

This is due to the handleOutsideMouseClick method; specifically the following line:

if (root.contains(e.target) || (e.button && e.button !== 0)) { return; }

The reason why the above fails is because the child portal isn't actually inside of the parent portal. Portals are appended to the document body in the renderPortal method, so using the node.contains method does not work in this instance.

I've come up with a solution using the DOM id property. Essentially, the parent portal now takes a childPortals prop, e.g.:

<Portal
  childPortals={['child-portal-1', 'child-portal-2']}
  ... other props ...
>

So in the above code example, assume my parent portal contains two child portals, each of which will be passed the id property that corresponds with the childPortals array, e.g.:

<Portal
  id='child-portal-1'
  ... other props ...
>

With the above additions, the handleOutsideMouseClick method can be adjusted to search for these DOM elements and check if they contain the target:

handleOutsideMouseClick(e) {
  if (!this.state.active) { return; }

  const root = findDOMNode(this.portal);
  const isChildPortalEl = this.props.childPortals.some(id => {
    const el = document.getElementById(id);
    if (el) {
      return el.contains(e.target);
    }
    return false;
  });
  if (root.contains(e.target) || (e.button && e.button !== 0) || isChildPortalEl) { return; }

  e.stopPropagation();
  this.closePortal();
}

I've PR'd the changes if you're interested.

woodenconsulting added a commit to woodenconsulting/react-portal that referenced this issue Oct 5, 2016
@woodenconsulting
Copy link
Author

Since I need this functionality, I've published a temporary module for anyone interested (based off 2.2.1). This also contains functionality I wrote related to #97.

@sirpeas
Copy link

sirpeas commented Sep 27, 2017

@tajo what about this enhancment? Are you planning to do something with it?

@tajo
Copy link
Owner

tajo commented Oct 1, 2017

Hey, please check the new major version of react-portal: #157

It's React v16 only since its uses the new official Portal API. There is the first beta released and I would like to get your feedback. I don't have bandwidth to maintain v3 which is very different and full of hacks.

I am happy to discuss this with v4 in mind. If this is still a problem, please re-open/update the issue. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants