拖拽功能

通过拖拽区块来重新组织编辑器中的内容。

Loading...

功能特性

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

套件使用

安装

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

添加套件

import { createPlateEditor } from 'platejs/react';
import { DndKit } from '@/components/editor/plugins/dnd-kit';
 
const editor = createPlateEditor({
  plugins: [
    // ...其他插件
    ...DndKit,
  ],
});

手动配置

安装依赖

pnpm add @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

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

Options

  • enableScroller optional boolean

    是否启用拖拽至视窗边缘自动滚动

    • 默认值: false
  • scrollerProps optional Partial<ScrollerProps>

    当启用滚动时的 Scroller 组件属性

  • onDropFiles optional function

    文件拖放事件处理器

  • dropTarget optional { id: string | null; line: DropLineDirection }

    当前拖放目标状态,包含目标元素ID和放置线方向

API

focusBlockStartById

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

Parameters

Collapse all
  • id string

    要聚焦的区块ID

getBlocksWithId

返回带有ID的区块数组。

OptionsEditorNodesOptions

    获取节点条目的选项

ReturnsNodeEntry[]

    带有ID的区块数组

selectBlockById

通过ID选中区块。

Parameters

Collapse all
  • id string

    要选中的区块ID

钩子

useDndNode

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

OptionsUseDndNodeOptions

Collapse all
  • element TElement

    要拖拽的节点

  • type optional string

    拖拽项类型

    • 默认值: 'block'
  • nodeRef any

    节点拖拽引用

  • orientation optional 'horizontal' | 'vertical'

    拖拽方向

    • 默认值: 'vertical'
  • canDropNode optional (args: { dragEntry: NodeEntry; dragItem: DragItemNode; dropEntry: NodeEntry; editor: PlateEditor }) => boolean

    判断节点能否放置到当前位置的回调

  • preview optional previewOptions

    拖拽节点的预览选项

  • drag optional dragOptions

    拖拽节点的拖拽选项

  • drop optional dropOptions

    拖拽节点的放置选项

  • onDropHandler optional string

    节点放置时的处理函数

Returnsobject

Collapse all
  • isDragging boolean

    节点是否正在被拖拽

  • isOver boolean

    拖拽节点是否在放置目标上方

  • dragRef ConnectDragSource

    可拖拽元素的拖拽引用

useDragNode

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

OptionsUseDragNodeOptions

Collapse all
  • element TElement

    要拖拽的节点

  • item optional DragObject | DragObjectFactory<DragObject>

    拖拽对象或其工厂函数

useDraggable

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

Optionsobject

Collapse all
  • element TElement

    要设为可拖拽的元素

  • orientation optional 'horizontal' | 'vertical'

    拖拽方向

    • 默认值: 'vertical'
  • type optional string

    拖拽项类型

    • 默认值: 'block'
  • onDropHandler optional function

    元素放置时的处理函数

Returnsobject

Collapse all
  • handleRef (element: Element | React.ReactElement | React.RefObject<any> | null) => void

    拖拽源连接函数

  • isDragging boolean

    元素是否正在被拖拽

  • previewRef React.RefObject<HTMLDivElement>

    可拖拽元素的引用

useDropNode

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

OptionsUseDropNodeOptions

Collapse all
  • nodeRef any

    被拖拽节点的引用

  • element TElement

    放置线依附的节点

  • dropLine string

    当前放置线的值

  • onChangeDropLine function

    放置线变化时的回调

  • onDropHandler object

    拦截放置处理的回调

    • 返回 true 阻止默认行为
    • 返回 false 执行默认行为

useDropLine

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

Optionsobject

Collapse all
  • id optional string

    显示放置线的元素ID

    • 默认值: 当前元素ID
  • orientation optional 'horizontal' | 'vertical'

    按方向过滤放置线

    • 默认值: 'vertical'

Returnsobject

Collapse all
  • dropLine 'top' | 'bottom' | 'left' | 'right' | ''

    当前放置线方向