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

DragOverlay does not work if element is in absolute position with a scaled container #50

Open
rams23 opened this issue Jan 11, 2021 · 5 comments
Labels
bug Something isn't working

Comments

@rams23
Copy link

rams23 commented Jan 11, 2021

When I use the DragOverlay inside a container (scaled), and the item has an absolute position inside it, the item replicated inside the drag overlay has the fixed position but with the left and top are taken from the original item (inside the scaled container).

Here is a repro example https://codesandbox.io/s/dnd-kit-scale-o69qm

This image shows the element that appears on click (bigger and shifted).
image

I tried to use adjustScale (but the provided scale inside the transform is 6 or 7 instead of 0.5) and other things. The only way to solve the problem was to add a modifier, force the scale, and add a transformation compensation, but I think it's a workaround.

Using getBoundingClientRect() I'm able to retrieve the correct coordinates with respect to the window, which I think should be used in this case to solve the problem.

@amankkg
Copy link

amankkg commented Mar 7, 2022

In our case, this bug reproduced if the parent container had a position: fixed + inset + transform, with no scaling adjustments.

And, we found out two workarounds:

  • as suggested by @rams23, compensate X/Y-axises transform via DragOverlay#modifiers
  • reset ancestor's inset, transform CSS properties in a parent node

Deps:

"@dnd-kit/core": "4.0.3",
"@dnd-kit/modifiers": "4.0.0",
"@dnd-kit/sortable": "5.1.0",
"@dnd-kit/utilities": "3.0.1",

@NateLevin1
Copy link

If you are having this issue, you might be able to solve it with an easier/hackier fix.

On your DndContext, add a measuring prop like so:

measuring={{
    draggable: {
        measure: (node) => {
            console.log("the measured node: ", node);
            console.log("children: ", node.children);
            return node.getBoundingClientRect();
        },
    },
}}

First, find the element in the children with the correct rect. Then, use selectors to find that element and return that element's getBoundingClientRect() in the function.
E.g. something like return node.children[0].children[0].getBoundingClientRect();

This is definitely a hack that is against React principles, so use with great caution. But, it might be the best option as a workaround, until this gets fixed.

@ArthurClemens
Copy link

ArthurClemens commented Nov 13, 2023

I'm having the same issue with draggable elements inside an absolute container. The workaround mentioned above works for the draggable item, but a problem with drop animation remains: the animation moves across the screen from right to left.

Edit: found the solution for the drop animation. The trick is to only do the subtraction while dragging (while we have an active element), because for the drop animation we do need the default client rect.

const rect = node.getBoundingClientRect();
const container = node.closest('[data-name=form-container');
if (active && container) {
  const containerRect = container.getBoundingClientRect();
  rect.x -= containerRect.x;
  rect.y -= containerRect.y;
}
return rect;

@ReubenJCarter
Copy link

ReubenJCarter commented Jan 12, 2024

I had a similar problem, which seemed to be caused by the DragOverlay being fixed positioned and dnd-kit internally sets CSS left / top to the getBoundingClientRect() which is relative to the viewport. Usually fine, but my case the fixed positioning was not actually relative to the viewport but to a parent element. An element can sometimes become the containing block if it has a filter or transform for example. https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
I fixed it by using createPortal, as per the docs https://docs.dndkit.com/api-documentation/draggable/drag-overlay#portals

@lucidprojects
Copy link

createPortal for the win for my issue too. thanks @ReubenJCarter 🙏💪

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

7 participants