atlassian / react-beautiful-dnd

Beautiful and accessible drag and drop for lists with React
https://react-beautiful-dnd.netlify.app
Other
33.37k stars 2.56k forks source link

Margin top glitch on drop #1855

Closed ibraheemdev closed 3 years ago

ibraheemdev commented 4 years ago

Expected behavior

dndbug2 Usually the dropped card smoothly moves into place

Actual behavior

dndbug When moving to the top, the dropped card first directly above the card below, and then the top margin is applied

Steps to reproduce

Create list with each card having a margin top of 2, and :first margin-top of 0

React version: ^16.13.1

react-beautiful-dnd version: ^13.0.0

Browser: Chrome

ibraheemdev commented 4 years ago

I fixed this my changing the margin to a negative margin bottom on the list title, but is that the only way to solve this issue?

ZacharyKearns commented 4 years ago

I had the same issue and fixed it by making sure the margin was applied to the component receiving the draggable and draghandle props and not any of it's children

function CardContainer(props: Props) {
  return (
    <div
      {...props.draggableProps}
      {...props.dragHandleProps}
      ref={props.innerRef}
      className="mb-2"
    >
      {props.children}
    </div>
  );
}
alifarooq0 commented 4 years ago

Seeing the same issue. Had to resolve it by using padding instead of margins.

ibraheemdev commented 3 years ago

I think this is expected behavior, as adjusting the margin fixes it. I'm not sure any other action can be taken.

rnowm commented 3 years ago

We were able to find a fix for that issue, just replace:

{provided => (
  <div
    ref={provided.innerRef}
    {...provided.draggableProps}
    {...provided.dragHandleProps}
  >
    {render(item, index)}
  </div>
)}

with:

{(provided) =>
    React.cloneElement(render(item, index), {
      ref: provided.innerRef,
      ...provided.draggableProps,
      ...provided.dragHandleProps,
    })
}
CubedEye commented 1 year ago

You can solve this by creating the margin space using :after on the container element. If you're still having trouble with this, you can wrap your draggable card with another component and add the after to that instead.

 <div
    ref={provided.innerRef}
    {...provided.draggableProps}
    {...provided.dragHandleProps}
    class="card-root"
  >
    {render(item, index)}
  </div>

and

  .card-root:after {
        display: block;
        content: " ";
        height: 5px; // Margin height
    }
Anishali2 commented 1 year ago

use div with height outside of the draggable

 <>
  <Draggable
        key={item.id}
        draggableId={item.id}
        index={index}
        >
    {(provid: any) => (
              <li
                   {...provid.draggableProps}
                   {...provid.dragHandleProps}
                   ref={provid.innerRef}
               >
             <item.component />
        </li>
      )}
   </Draggable>
  <div className="h-2" /> // here
</>