Back to Plate

拖拽功能

docs/(plugins)/(functionality)/dnd.cn.mdx

1.0.08.6 KB
Original Source
<ComponentPreview name="dnd-demo" /> <PackageInfo>

功能特性

  • 通过拖拽区块实现内容移动和插入
  • 拖拽至视窗边缘时自动滚动
  • 支持文件拖放插入媒体区块
  • 可视化拖放指示器和拖拽手柄
</PackageInfo>

套件使用

<Steps>

安装

最快捷的方式是使用 DndKit 套件,它包含预配置的 DndPlugin、React DnD 设置以及 BlockDraggable UI组件。

<ComponentSource name="dnd-kit" />

添加套件

tsx
import { createPlateEditor } from 'platejs/react';
import { DndKit } from '@/components/editor/plugins/dnd-kit';

const editor = createPlateEditor({
  plugins: [
    // ...其他插件
    ...DndKit,
  ],
});
</Steps>

手动配置

<Steps>

安装依赖

bash
npm install @platejs/dnd react-dnd react-dnd-html5-backend

添加插件

tsx
import { DndPlugin } from '@platejs/dnd';
import { createPlateEditor } from 'platejs/react';

const editor = createPlateEditor({
  plugins: [
    // ...其他插件
    DndPlugin,
  ],
});

配置插件

通过可拖拽组件和DnD provider配置拖放功能:

tsx
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import { DndPlugin } from '@platejs/dnd';

DndPlugin.configure({
  render: {
    aboveSlate: ({ children }) => (
      <DndProvider backend={HTML5Backend}>{children}</DndProvider>
    ),
  },
});
  • render.aboveNodes: 分配 BlockDraggable 组件在区块上方渲染拖拽手柄
  • render.aboveSlate: 用 DndProvider 包裹编辑器。如果React树中已有 DndProvider 可移除此配置

高级配置

添加自动滚动和文件拖放处理:

tsx
import { DndPlugin } from '@platejs/dnd';
import { PlaceholderPlugin } from '@platejs/media/react';

DndPlugin.configure({
  options: {
    enableScroller: true,
    onDropFiles: ({ dragItem, editor, target }) => {
      editor
        .getTransforms(PlaceholderPlugin)
        .insert.media(dragItem.files, { at: target, nextBlock: false });
    },
  },
  render: {
    aboveNodes: BlockDraggable,
    aboveSlate: ({ children }) => (
      <DndProvider backend={HTML5Backend}>{children}</DndProvider>
    ),
  },
});
  • enableScroller: 启用拖拽至视窗边缘时的自动滚动
  • onDropFiles: 处理文件拖放,在目标位置插入媒体区块
</Steps>

插件

DndPlugin

实现编辑器内拖拽功能的插件。

<API name="DndPlugin"> <APIOptions> <APIItem name="enableScroller" type="boolean" optional> 是否启用拖拽至视窗边缘自动滚动 - **默认值:** `false` </APIItem> <APIItem name="scrollerProps" type="Partial<ScrollerProps>" optional> 当启用滚动时的 `Scroller` 组件属性 </APIItem> <APIItem name="onDropFiles" type="function" optional> 文件拖放事件处理器 <APISubList> <APISubListItem parent="onDropFiles" name="id" type="string"> 目标元素ID </APISubListItem> <APISubListItem parent="onDropFiles" name="dragItem" type="FileDragItemNode"> 包含拖放文件的对象 </APISubListItem> <APISubListItem parent="onDropFiles" name="editor" type="PlateEditor"> 编辑器实例 </APISubListItem> <APISubListItem parent="onDropFiles" name="target" type="Path"> 文件应插入的路径 </APISubListItem> </APISubList> </APIItem> <APIItem name="dropTarget" type="{ id: string | null; line: DropLineDirection }" optional> 当前拖放目标状态,包含目标元素ID和放置线方向 </APIItem> </APIOptions> </API>

API

focusBlockStartById

通过ID选中区块起始位置并聚焦编辑器。

<API name="focusBlockStartById"> <APIParameters> <APIItem name="id" type="string"> 要聚焦的区块ID </APIItem> </APIParameters> </API>

getBlocksWithId

返回带有ID的区块数组。

<API name="getBlocksWithId"> <APIOptions type="EditorNodesOptions"> 获取节点条目的选项 </APIOptions> <APIReturns type="NodeEntry[]"> 带有ID的区块数组 </APIReturns> </API>

selectBlockById

通过ID选中区块。

<API name="selectBlockById"> <APIParameters> <APIItem name="id" type="string"> 要选中的区块ID </APIItem> </APIParameters> </API>

钩子

useDndNode

组合了 useDragNodeuseDropNode 的自定义钩子,用于启用编辑器节点的拖拽功能。提供默认的拖拽预览效果,可自定义或禁用。

<API name="useDndNode"> <APIOptions type="UseDndNodeOptions"> <APIItem name="element" type="TElement"> 要拖拽的节点 </APIItem> <APIItem name="type" type="string" optional> 拖拽项类型 - **默认值:** `'block'` </APIItem> <APIItem name="nodeRef" type="any"> 节点拖拽引用 </APIItem> <APIItem name="orientation" type="'horizontal' | 'vertical'" optional> 拖拽方向 - **默认值:** `'vertical'` </APIItem> <APIItem name="canDropNode" type="(args: { dragEntry: NodeEntry; dragItem: DragItemNode; dropEntry: NodeEntry; editor: PlateEditor }) => boolean" optional> 判断节点能否放置到当前位置的回调 </APIItem> <APIItem name="preview" type="previewOptions" optional> 拖拽节点的预览选项 </APIItem> <APIItem name="drag" type="dragOptions" optional> 拖拽节点的拖拽选项 </APIItem> <APIItem name="drop" type="dropOptions" optional> 拖拽节点的放置选项 </APIItem> <APIItem name="onDropHandler" type="string" optional> 节点放置时的处理函数 </APIItem> </APIOptions> <APIReturns type="object"> <APIItem name="isDragging" type="boolean"> 节点是否正在被拖拽 </APIItem> <APIItem name="isOver" type="boolean"> 拖拽节点是否在放置目标上方 </APIItem> <APIItem name="dragRef" type="ConnectDragSource"> 可拖拽元素的拖拽引用 </APIItem> </APIReturns> </API>

useDragNode

使用 react-dnduseDrag 钩子实现节点拖拽功能的自定义钩子。

<API name="useDragNode"> <APIOptions type="UseDragNodeOptions"> <APIItem name="element" type="TElement"> 要拖拽的节点 </APIItem> <APIItem name="item" type="DragObject | DragObjectFactory<DragObject>" optional> 拖拽对象或其工厂函数 </APIItem> </APIOptions> </API>

useDraggable

使元素具备可拖拽行为的自定义钩子,提供可自定义或禁用的拖拽预览效果。

<API name="useDraggable"> <APIOptions type="object"> <APIItem name="element" type="TElement"> 要设为可拖拽的元素 </APIItem> <APIItem name="orientation" type="'horizontal' | 'vertical'" optional> 拖拽方向 - **默认值:** `'vertical'` </APIItem> <APIItem name="type" type="string" optional> 拖拽项类型 - **默认值:** `'block'` </APIItem> <APIItem name="onDropHandler" type="function" optional> 元素放置时的处理函数 </APIItem> </APIOptions> <APIReturns type="object"> <APIItem name="handleRef" type="(element: Element | React.ReactElement | React.RefObject<any> | null) => void"> 拖拽源连接函数 </APIItem> <APIItem name="isDragging" type="boolean"> 元素是否正在被拖拽 </APIItem> <APIItem name="previewRef" type="React.RefObject<HTMLDivElement>"> 可拖拽元素的引用 </APIItem> </APIReturns> </API>

useDropNode

使用 react-dnduseDrop 钩子实现节点放置功能的自定义钩子。

<API name="useDropNode"> <APIOptions type="UseDropNodeOptions"> <APIItem name="nodeRef" type="any"> 被拖拽节点的引用 </APIItem> <APIItem name="element" type="TElement"> 放置线依附的节点 </APIItem> <APIItem name="dropLine" type="string"> 当前放置线的值 </APIItem> <APIItem name="onChangeDropLine" type="function"> 放置线变化时的回调 </APIItem> <APIItem name="onDropHandler" type="object"> 拦截放置处理的回调 - 返回 `true` 阻止默认行为 - 返回 `false` 执行默认行为 </APIItem> </APIOptions> </API>

useDropLine

返回元素的当前放置线状态。

<API name="useDropLine"> <APIOptions type="object"> <APIItem name="id" type="string" optional> 显示放置线的元素ID - **默认值:** 当前元素ID </APIItem> <APIItem name="orientation" type="'horizontal' | 'vertical'" optional> 按方向过滤放置线 - **默认值:** `'vertical'` </APIItem> </APIOptions> <APIReturns type="object"> <APIItem name="dropLine" type="'top' | 'bottom' | 'left' | 'right' | ''"> 当前放置线方向 </APIItem> </APIReturns> </API>