React-beautiful-dnd: Strange offset while dragging

Created on 29 Jun 2020  路  7Comments  路  Source: atlassian/react-beautiful-dnd

Hey guys I need some help figuring out what's causing this strange behavior while dragging elements in this portal modal component. I'll leave a demo video below. This problem occurs if I grab the elements from the bottom. In the console, there aren't any warnings or errors.

Expected behavior

Actual behavior

Steps to reproduce

Suggested solution?

What version of React are you using?

^16.13.1

What version of react-beautiful-dnd are you running?

Latest

What browser are you using?

Electron 8.2.5

Demo

https://imgur.com/a/Uxyiwgl

unconfirmed-bug untriaged

Most helpful comment

I solved this by mutating the provided.draggableProps.style.left and provided.draggableProps.style.right values when provided.isDragging is true

<Draggable >
      {(provided, snapshot) => {
          if (snapshot.isDragging) {
              const offset = { x: 100, y: 100 }          // your fixed container left/top position
              const x = provided.draggableProps.style.left - offset.x;
              const y = provided.draggableProps.style.top - offset.y;
              provided.draggableProps.style.left = x;
              provided.draggableProps.style.top = y;
           }
           return (
                <div 
                     ref={provided.innerRef}
                     {...provided.draggableProps}
                     {...provided.dragHandleProps}>
                     YOUR ITEM
                </div>
           );
       }}
</Draggable>

All 7 comments

I have the same problem, in a portal modal as well

I have the same issue with an extra unexpected behavior

To Produce the issue: https://codesandbox.io/s/olk8m320lq

dnd

Same issue here.
Maybe it's happening because the distant parent of the preview element has its position CSS property set to fixed or absolute and the preview element's style top and left aren't calculated as if they were starting from this parent's position, but rather from the window or body coordinates in the package. And CSS transforms the preview element starting from the parent's position.

I have the same problem in a fixed div.

I solved this by mutating the provided.draggableProps.style.left and provided.draggableProps.style.right values when provided.isDragging is true

<Draggable >
      {(provided, snapshot) => {
          if (snapshot.isDragging) {
              const offset = { x: 100, y: 100 }          // your fixed container left/top position
              const x = provided.draggableProps.style.left - offset.x;
              const y = provided.draggableProps.style.top - offset.y;
              provided.draggableProps.style.left = x;
              provided.draggableProps.style.top = y;
           }
           return (
                <div 
                     ref={provided.innerRef}
                     {...provided.draggableProps}
                     {...provided.dragHandleProps}>
                     YOUR ITEM
                </div>
           );
       }}
</Draggable>

I solved this by mutating the provided.draggableProps.style.left and provided.draggableProps.style.right values when provided.isDragging is true

<Draggable >
      {(provided, snapshot) => {
          if (snapshot.isDragging) {
              const offset = { x: 100, y: 100 }          // your fixed container left/top position
              const x = provided.draggableProps.style.left - offset.x;
              const y = provided.draggableProps.style.top - offset.y;
              provided.draggableProps.style.left = x;
              provided.draggableProps.style.top = y;
           }
           return (
                <div 
                     ref={provided.innerRef}
                     {...provided.draggableProps}
                     {...provided.dragHandleProps}>
                     YOUR ITEM
                </div>
           );
       }}
</Draggable>

Based on this, I changed the offset based in fixed position to offsetLeft,offsetTop and it works fine. Also, I don't know the position of my container (is a modal window the user can drag around the screen) so, at least in my case, I prefer to use this as follows:

<Draggable >
      {(provided, snapshot) => {
          if (snapshot.isDragging) {
              provided.draggableProps.style.left = provided.draggableProps.style.offsetLeft;
              provided.draggableProps.style.top = provided.draggableProps.style.offsetTop;
           }
           return (
                <div 
                     ref={provided.innerRef}
                     {...provided.draggableProps}
                     {...provided.dragHandleProps}>
                     YOUR ITEM
                </div>
           );
       }}
</Draggable>

EDIT:

It seems that provided.draggableProps.style.offsetLeft is not working since its value is undefined. I thought it was working okay because it really works with no warnings, but the value is undefined. Any ideas?

I'm having this same issue, and it only affects non-chromium browsers (Safari, Firefox).
The solution that @camdagr8 proposed works great. However if your modal is scrollable, it will completely break. It will work fine if you are at the top of the window, but when you scroll down it will again reposition the draggables incorrectly

Was this page helpful?
0 / 5 - 0 ratings