Web/React

[React] react-beautiful-dnd에서 드래그 시 기존 요소가 유지시키기

메바동 2023. 6. 3. 00:02
728x90

 

react-beautiful-dnd 라이브러리를 이용하여 Droppable 요소 내의 정렬을 지원하지 않고, 위치시킨 순서대로 정렬하도록 구현을 하니 아래와 같은 문제가 굉장히 신경 쓰였다.

 

 

Draggable 요소를 드래그했을 때, transform: translate(x, y) 스타일을 이용하여 해당 요소를 움직이도록 하고 있기 때문에 요소가 있던 부분이 사라지는 것이 신경 쓰였다.

다른 공간에 드롭을 했을 때는 문제없었지만, 위와 같이 동일한 공간에 드롭을 시켰을 경우 기능상으로는 문제가 없지만 보기 좋지 않았다.

 

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

function ItemCard({ id, index, title, content }) {
  const cloneCard = () => (
    <Card size="small" title={title} style={{ marginBottom: 12 }}>
      <p>{content}</p>
    </Card>
  );

  return (
    <Draggable draggableId={id} index={index}>
      {(provided, snapshot) => (
        <>
          <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>
          {snapshot.isDragging ? cloneCard() : null}
        </>
      )}
    </Draggable>
  );
}

export default ItemCard;

 

그래서 위와 같이 snapshot.isDragging을 이용하여 드래그 상태일 경우 기존 요소의 내용을 복제하여 화면에 나타내도록 해주었다.

 

 

물론 이전에 완벽히 해결하지 못했던 Draggable 요소 위에 겹쳐 놓았을 경우 애니메이션 위치가 이상한 것은 해결하지 못하였지만, 드래그 이벤트 발생 시 기존 요소가 사라지지 않고 화면에 나타나있게 되었다.

 

그다음 드래그 중인 요소가 뭔가 어색해 보여 isDragging을 이용하여 투명도를 지정하도록 다음과 같이 수정하였다.

 

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

function ItemCard({ id, index, title, content }) {
  const cloneCard = () => (
    <Card size="small" title={title} style={{ marginBottom: 12 }}>
      <p>{content}</p>
    </Card>
  );

  return (
    <Draggable draggableId={id} index={index}>
      {(provided, snapshot) => (
        <>
          <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,
              opacity:
                snapshot.isDragging && !snapshot.isDropAnimating ? 0.5 : 1,
            }}
          >
            <p>{content}</p>
          </Card>
          {snapshot.isDragging && !snapshot.isDropAnimating
            ? cloneCard()
            : null}
        </>
      )}
    </Draggable>
  );
}

export default ItemCard;

 

 

드래그 중인 요소가 투명하게 보이니 어색함이 살짝 줄어든 느낌이다.

 

snapshot의 isDragging와 isDropAnimating을 같이 사용하여 투명도와 복제 요소 조건을 판단하고 있는데 이렇게 한 이유는 다음과 같다.

 

 

좌측이 isDragging과 isDropAnimating을 같이 확인한 경우고, 우측이 isDragging만 확인하는 경우다.

물론 사람마다 다르겠지만 나는 isDragging만 확인할 경우 기존 요소가 사라지는 게 한 박자 느린 느낌이라 isDropAnimating을 같이 확인하는 경우가 더 자연스러워 보였다.

 

 

 

이제 Drappable 요소에 겹쳤을 경우 애니메이션 위치가 이상한 경우만 손보면 될 것 같은데 좋은 방법이 떠오르지 않는다.

 

728x90