rbd(react-beautiful-dnd)-拖动时copy一个新的元素占据原来的位置

江阳冰
2023-12-01
import React, { useState } from "react";
import styled from "styled-components";
import {
  DragDropContext,
  Draggable,
  DraggableProvided,
  DraggableRubric,
  DraggableStateSnapshot,
  DragStart,
  DragUpdate,
  Droppable,
  DropResult,
  ResponderProvided,
} from "react-beautiful-dnd";
import "./styles.css";

interface IItem {
  id: string;
  label: string;
}

export const DndForm: React.FC = () => {
  const COLLECTION: IItem[] = [
    { id: "1", label: "Apple" },
    { id: "2", label: "Banana" },
    { id: "3", label: "orange" },
  ];
  const [items, setItems] = useState<IItem[]>(COLLECTION);
  const [enabled, setEnabled] = React.useState(false);
  React.useEffect(() => {
    const animation = requestAnimationFrame(() => setEnabled(true));

    return () => {
      cancelAnimationFrame(animation);
      setEnabled(false);
    };
  }, []);
  const onDragStart = (start: DragStart, provided: ResponderProvided) => {
    console.log("onDragStart", start, provided);
  };
  const onDragUpdate = (update: DragUpdate, provided: ResponderProvided) => {
    console.log("onDragUpdate", update, provided);
  };
  const onDragEnd = (result: DropResult, provided: ResponderProvided) => {
    console.log("onDragEnd", result, provided);
  };

  const getRenderItem =
    (items: IItem[]) =>
    (
      provided: DraggableProvided,
      snapshot: DraggableStateSnapshot,
      rubric: DraggableRubric
    ) => {
      const item = items[rubric.source.index];
      return (
        <React.Fragment>
          <li
            {...provided.draggableProps}
            {...provided.dragHandleProps}
            ref={provided.innerRef}
            style={provided.draggableProps.style}
            className={snapshot.isDragging ? "dragging" : ""}
          >
            {item.label}
          </li>
        </React.Fragment>
      );
    };
  return (
    <DragDropContext
      onDragStart={onDragStart}
      onDragUpdate={onDragUpdate}
      onDragEnd={onDragEnd}
    >
      {enabled && (
        <Wrapper>
          <Droppable
            droppableId="tools"
            renderClone={getRenderItem(COLLECTION)}
            isDropDisabled
          >
            {(provided, snapshot) => {
              return (
                <LeftWapper
                  ref={provided.innerRef}
                  {...provided.droppableProps}
                >
                  <ul ref={provided.innerRef} className="shop">
                    {items.map((item: IItem, index: number) => {
                      const shouldRenderClone =
                        item.id === snapshot.draggingFromThisWith;
                      return (
                        <React.Fragment key={item.id}>
                          {shouldRenderClone ? (
                            <li className="react-beatiful-dnd-copy">
                              {item.label}
                            </li>
                          ) : (
                            <Draggable draggableId={item.id} index={index}>
                              {(provided, snapshot) => (
                                <React.Fragment>
                                  <li
                                    ref={provided.innerRef}
                                    {...provided.draggableProps}
                                    {...provided.dragHandleProps}
                                    className={
                                      snapshot.isDragging ? "dragging" : ""
                                    }
                                  >
                                    {item.label}
                                  </li>
                                </React.Fragment>
                              )}
                            </Draggable>
                          )}
                        </React.Fragment>
                      );
                    })}
                  </ul>
                </LeftWapper>
              );
            }}
          </Droppable>

          <Droppable droppableId="form">
            {(provided, snapshot) => {
              return (
                <MiddleWrapper
                  ref={provided.innerRef}
                  {...provided.droppableProps}
                ></MiddleWrapper>
              );
            }}
          </Droppable>
          <RightWrapper></RightWrapper>
        </Wrapper>
      )}
    </DragDropContext>
  );
};

const Wrapper = styled.div`
  position: absolute;
  width: 100%;
  height: 100%;
  background-color: #6dc1e6;
  display: flex;
  justify-content: space-between;
`;

const LeftWapper = styled.div`
  width: 350px;
  height: 100%;
  background-color: aquamarine;
  flex-shrink: 0;
`;

const MiddleWrapper = styled.div`
  min-width: 500px;
  flex-grow: 10;
`;

const RightWrapper = styled.div`
  width: 300px;
  height: 100%;
  background-color: #e8d4ba;
`;

/* 不重要 */
ul,
li {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* 重要 copy后的拖动元素样式 */
.react-beatiful-dnd-copy ~ li {
  transform: none !important;
}

/* 拖动时的样式 */
.dragging {
  background: yellow;
  text-align: center;
  font-family: sans-serif;
}

/* 拖动时复制停留在原来空间的样式 */
.react-beatiful-dnd-copy {
  background: lightblue;
}

.react-beatiful-dnd-copy ~ [data-rbd-placeholder-context-id] {
  display: none !important;
}

/* 不重要 */
.shop {
  padding: 10px;
  border: 1px solid #aaa;
}


 类似资料: