dnd-kit 在拖动列表中的项目时显示预览线

问题描述 投票:0回答:1

尚不清楚在可排序列表中拖动项目时如何在列表中显示浅蓝色预览线。文档或示例中不清楚。

https://master--5fc05e08a4a65d0021ae0bf2.chromatic.com/?path=/docs/examples-pages-layout--grid

在示例部分,底部的页面和树示例都有预览线,但完全不清楚如何创建它。

我想在拖动项目时显示类似于概念的水平预览线。有人成功做到过吗?

drag-and-drop react-dnd react-beautiful-dnd dnd-kit
1个回答
0
投票

您可以通过实现以下逻辑来实现这一点。

我们可以在 onDragOver 事件处理程序中访问 active

over
组件,并检查组件状态中活动组件索引是否小于或大于 over 组件索引。

使用此信息,我们可以有条件地渲染预览线。

  1. 初始化状态:
 const [overId, setOverId] = useState(null); // Used to conditionally render the dropLine
 const [dropLinePosition, setDropLinePosition] = useState(""); // To set the preview line where the dragged item will be dropped (top/bottom)
  1. onDragOver
    事件逻辑:
// While the component is being dragged
  const handleDragOver = event => {
    const { active, over } = event;

    if (over) {
      setOverId(over.id);

      // Finding the active index (dragged component) and over index (component below the dragged one)
      // Updating the preview line based on which index is less than the other
      const { activeIndex, overIndex } = getActiveAndOverIndex(active.id, over.id);
      if (activeIndex > overIndex) setDropLinePosition("top");
      else setDropLinePosition("bottom");
    }
  };
  1. getActiveAndOverIndex
    逻辑:(此处使用Zustand商店)
getActiveAndOverIndex: (activeId, overId) => {
    const components = get().components;
    const activeIndex = components.findIndex(component => component.id === activeId);
    const overIndex = components.findIndex(component => component.id === overId);

    return { activeIndex, overIndex };
}
  1. 最后,在 HTML 中使用
    dropLinePosition
    状态来显示组件上方或下方的线条。
<DndContext
      onDragStart={handleDragStart}
      onDragOver={handleDragOver}
      onDragEnd={handleDragEnd}
      sensors={sensors}
      collisionDetection={pointerWithin}
      id={id}
    >
  <SortableContext items={components}>
    {components.map(entity => (
      <div key={entity.id}>
         
         // Top preview line
         <div className={clsx("h-1 w-full bg-primary-blue bg-opacity-80 transition-opacity duration-300 opacity-0",
                  {
                    "opacity-100": overId === entity.id && dropLinePosition === "top",
                  }
                )}
              ></div>

    <SortableItem entity={entity.data} />

    // Bottom preview line
    <div className={clsx("h-1 w-full bg-primary-blue bg-opacity-80 transition-opacity duration-300 opacity-0",
                  {
                    "opacity-100": overId === entity.id && dropLinePosition === "bottom",
                  }
                )}
              ></div>
           </div>
    </SortableContext>
</DndContext>

希望这有帮助:D

© www.soinside.com 2019 - 2024. All rights reserved.