PuruVJ/neodrag

Can't drag elements inside shadow DOM

Closed this issue · 2 comments

So far, the only code I found preventing using this library in shadow DOM is this condition:

if (
dragEls.some((el) => el.contains(<HTMLElement>e.target)) &&
!cancelElementContains(cancelEls, [<HTMLElement>e.target])
) {

The problem is with e.target which has some parent custom element instead of the one I'm actually trying to drag.

I'm now testing if this simple patch is sufficient:

// use composedPath instead of e.target
const eventTarget = e.composedPath()[0];
if (dragEls.some((el) => el.contains(eventTarget)) && !cancelElementContains(cancelEls, [eventTarget])) {
  currentlyDraggedEl = dragEls.length === 1 ? node : dragEls.find((el) => el.contains(eventTarget));
  active = true;
}

I can send a PR if you want me to, but I'm unsure if using composedPath is a good solution for you or if you have maybe a better idea. Fixing this makes it possible to use this library with Lit before there is a specific Lit implementation (which is my use case).

@PuruVJ thanks for fixing this and sorry for bothering you with this issue again. Unfortunately, I was too slow and just now I found another limitation. My previous solution fixed dragging only for custom element roots (meaning no dragging of elements inside of shadow roots).

This is the updated patch I'm testing now:

const eventTarget = e.composedPath()[0];
    if (dragEls.some((el) => el.contains(eventTarget) || (el.shadowRoot !== null && el.shadowRoot.contains(eventTarget))) && !cancelElementContains(cancelEls, [eventTarget])) {
      currentlyDraggedEl = dragEls.length === 1 ? node : dragEls.find((el) => el.contains(eventTarget));
      active = true;
    }

The only difference is that I'm calling contains() on the shadowRoot if it exists.

Released in 2.0.3