Web/React

[React] react-beautiful-dnd에서 draggable 요소끼리 겹칠 때 움직이지 않게 하기

메바동 2023. 6. 2. 17:44
728x90

 

지금 하고 있는 프로젝트에서 Drag and Drop 기능을 구현하기 위해 react-beautiful-dnd 라이브러리를 사용하고 있다.

react-beautiful-dnd를 사용하면 요소 간의 순서를 변경하기 용이하지만, 요소 간의 순서 변경이 필요 없고 단순히 이동만 구현하려고 하는데 draggable 요소가 움직이는 것이 거슬렸다.

 

 

단순 이동만 구현하려는데 위와 같이 정렬 애니메이션이 들어가는 것은 사용자에게 혼란을 줄 수도 있기에 요소가 움직이는 것을 막기로 하였다.

 

import { Card } from 'antd';
import { Draggable } from 'react-beautiful-dnd';

function ItemCard({ id, index, title, content }) {
  return (
    <Draggable draggableId={id} index={index}>
      {(provided) => (
        <Card
          size="small"
          title={title}
          ref={provided.innerRef}
          {...provided.dragHandleProps}
          {...provided.draggableProps}
          style={{
            ...provided.draggableProps.style,
            marginBottom: 12,
          }}
        >
          <p>{content}</p>
        </Card>
      )}
    </Draggable>
  );
}

export default ItemCard;

 

드래그되는 컴포넌트는 다음과 같이 되어있는데, 우선 rdb에서 Droppable과 Draggable의 속성 중에 해당 기능을 지원하는지 찾아보았다.

 

Droppable 컴포넌트에서 지원하는 속성

 

Draggable 컴포넌트에서 지원하는 속성

 

 

따로 정렬 기능을 막는 속성은 지원하지 않았다.

 

무슨 방법이 없을까 싶어 요소가 이동될 때 개발자 콘솔을 보니

 

 

위와 같이 겹치는 요소도 translate 스타일이 적용되고 있었다.

 

Draggable 요소에서 현재 드래그 중인지 판단을 하고 드래그 중일 때만 provided.draggableProps.style.transform의 스타일을 적용시켜 주면 될 것 같았다.

 

import { Card } from 'antd';
import { Draggable } from 'react-beautiful-dnd';

function ItemCard({ id, index, title, content }) {
  return (
    <Draggable draggableId={id} index={index}>
      {(provided, snapshot) => {
        return (
          <Card
            size="small"
            title={title}
            ref={provided.innerRef}
            {...provided.dragHandleProps}
            {...provided.draggableProps}
            style={{
              ...provided.draggableProps.style,
              marginBottom: 12,
              transform: snapshot.isDragging
                ? provided.draggableProps.style.transform
                : null,
            }}
          >
            <p>{content}</p>
          </Card>
        );
      }}
    </Draggable>
  );
}

export default ItemCard;

 

요소 간 겹쳤을 경우 애니메이션이 발생하는 현상은 사라졌지만, 마지막처럼 요소 위에 드롭을 했을 경우 드롭 애니메이션이 요소 위에 발생하는 문제가 남게 되었다.

 

snapshot에서 isDropAnimating이 true일 때 dropAnimation의 moveTo를 지정해 요소가 겹칠 경우 가장 하단의 위치로 지정해주면 될 것 같은데 단순하게 해결될 것 같지 않아 나중에 해결하기로 한다.

728x90