kutlugsahin / smooth-dnd

drag and drop library for javascript
MIT License
599 stars 147 forks source link

ghost div is misplaced in a nested container #19

Closed adjioev closed 5 years ago

adjioev commented 5 years ago

Hello,

I have a following structure with nested containers:

    <div id="main" class="container">
        <div class="drag-item">Draggable main-1</div>
        <div class="drag-item">Draggable main-2</div>
        <div class="drag-item">Draggable main-3</div>

        <div id="c1" class="container">
            <div class="drag-item">Draggable c1-1</div>
            <div class="drag-item">Draggable c1-2</div>
            <div class="drag-item">Draggable c1-3</div>
        </div>

        <div  id="c2" class="container"> 
            <div class="drag-item">Draggable c3-1</div>
            <div class="drag-item">Draggable c3-2</div>
            <div class="drag-item">Draggable c3-3</div>
            <div class="drag-item">Draggable c3-1</div>
            <div class="drag-item">Draggable c3-2</div>                     
        </div>

        <div class="drag-item">Draggable main-4</div>
        <div class="drag-item">Draggable main-5</div>
        <div class="drag-item">Draggable main-6</div>
    </div>

If I start to drag div from c2 down to the "main" container evertyhing works fine, but when it's dragged up where "Draggable main-3" div is 'ghost' div all of a sudden shifts itself into down/right position. After debugging turns out that 'ghost' div has lost its 'fixed' property and position becomes relative to the "main" container. From

The element is removed from the normal document flow, and no space is created for the element in the page layout. It is positioned relative to the initial containing block established by the viewport, except when one of its ancestors has a transform, perspective, or filter property set to something other than none

To fix this problem in mediator.js file there is a function:

function getGhostParent() {
  if (grabbedElement) {
    return grabbedElement.parentElement || global.document.body;
  } else {
    return global.document.body;
  }
}

Changing it to

function getGhostParent() {
    return global.document.body;
}

Solves the problem.

Let me know if you need a demo to replicate the bug, I will commit it into git repo.

Best regards, Alex

kutlugsahin commented 5 years ago

Hey @adjioev thanks for submitting the issue. I tried to reproduce the problem but no luck, a demo would be great. But what I understand with the quote you add is that some of the containers or any parent has a transformation which breaks the ghost positioning (which is assumed to be always positioned relative to the window, but this is not the case if the fixed element is inside a transformed element). There is already a bug for this and will be fixed in the next releases. If the problem is something else please let me know and a demo would be nice. Cheers! Kutlu

adjioev commented 5 years ago

Hi @kutlugsahin,

sorry for the late response, was on holidays :)

That's an exact problem, looks like I duplicated it. Do you still want me to add bug demo into github?

Thanks, Alex

kutlugsahin commented 5 years ago

Hey @adjioev I addressed this issue in v0.6.3. I added getGhostParent function property to return the element that the ghost will be added. You can simple return document.body in it. This should fix the misplacement issue of ghost element when container has a transformed parent somewhere in the tree.