Open Jarred-Sumner opened 6 years ago
Are you just adding the class ignore-react-onclickoutside
to the root div of the shadow dom? I'm doing the following but the click is still closing the calendar.
const template = `
<style>
@import "${ this.getAttribute('pathToStyles') }";
#root {
font-size: 1rem;
display: block;
}
</style>
<div id="root" class='ignore-react-onclickoutside'></div>`;
this.shadow.innerHTML = template;
Adding the ability to specify a custom root so that the HOC stops once it hits that makes a lot of sense. Would you be up for writing a PR for that, @Jarred-Sumner?
I've run into this same issue, when using react-datepicker within a shadowdom, click events within the date picker are hiding the date picker :(
Is there a simple solution for this ?
Could a solution be to walk up out of a shadow root into the containing document, so change findHighest to
function findHighest(current, componentNode, ignoreClass) {
if (current === componentNode) {
return true;
} // If source=local then this event came from 'somewhere'
// inside and should be ignored. We could handle this with
// a layered approach, too, but that requires going back to
// thinking in terms of Dom node nesting, running counter
// to React's 'you shouldn't care about the DOM' philosophy.
while (current.parentNode) {
if (isNodeFound(current, componentNode, ignoreClass)) {
return true;
}
// if we are at a shadow root, continue up via the host document
if (!current.parentNode && current.host) {
current = current.host
}
else {
current = current.parentNode;
}
}
from local testing this seems to work
actually, I think it can be simplified to
current = current.parentNode || current.host;
Actaully, I was wrong, I had broken something.
What appears to be happening is that the mousedown listener is registered on the host document, and therefore the event target is the element that hosts the shadow root, not the element that is contained within the react component
When using
react-onclickoutside
from inside a Shadow DOM, the events propagate through to the DOM node containing the shadow DOM and do not descend into the shadow DOM.This means
react-onclickoutside
is still useful! It essentially becomesreact-onclickoutsideshadowdom
(once you add.ignore-react-onclickoutside
to the root of the shadow DOM). However, it'd be even better if it knew to listen for events within the Shadow DOM, so that it knows to ignore clicks inside the "real" target.Concrete example: I have a dropdown inside a shadow DOM. I want that dropdown to only disappear when clicking outside of the dropdown (versus anywhere on the page), and the default behavior right now is
handleClickOutside
gets called on any click. So, I addedignore-react-onclickoutside
to the shadow DOM root, and now it gets called only when I click outside of the shadow DOM.Maybe one potential approach here would be adding a config option for
rootNodes
which defaults to[document]
, and then in the following places, it loops throughrootNodes
instead ofdocument
directly? Then, when using from inside a shadow DOM, we would add the root node of the shadow DOM to the list ofrootNodes
?