docs/(plugins)/(functionality)/dnd.cn.mdx
最快捷的方式是使用 DndKit 套件,它包含预配置的 DndPlugin、React DnD 设置以及 BlockDraggable UI组件。
BlockDraggable: 为区块渲染拖拽手柄和放置指示器import { createPlateEditor } from 'platejs/react';
import { DndKit } from '@/components/editor/plugins/dnd-kit';
const editor = createPlateEditor({
plugins: [
// ...其他插件
...DndKit,
],
});
npm install @platejs/dnd react-dnd react-dnd-html5-backend
import { DndPlugin } from '@platejs/dnd';
import { createPlateEditor } from 'platejs/react';
const editor = createPlateEditor({
plugins: [
// ...其他插件
DndPlugin,
],
});
通过可拖拽组件和DnD provider配置拖放功能:
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 可移除此配置添加自动滚动和文件拖放处理:
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: 处理文件拖放,在目标位置插入媒体区块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>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组合了 useDragNode 和 useDropNode 的自定义钩子,用于启用编辑器节点的拖拽功能。提供默认的拖拽预览效果,可自定义或禁用。
useDragNode使用 react-dnd 的 useDrag 钩子实现节点拖拽功能的自定义钩子。
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-dnd 的 useDrop 钩子实现节点放置功能的自定义钩子。
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>