Loading...

块选择功能允许用户选择和操作整个文本块,而不是单个单词或字符。

特性

  • 通过单一操作选择整个块
  • 使用鼠标拖动或键盘快捷键进行多块选择
  • 对选中块执行复制、剪切和删除操作
  • 快速选择的键盘快捷键:
    • Cmd+A:选择所有块
    • 方向键:选择上方或下方的块
  • 可自定义选中块的样式

套件使用

安装

添加块选择功能最快的方法是使用 BlockSelectionKit,它包含预配置的 BlockSelectionPluginBlockSelection UI 组件。

添加套件

BlockSelectionKit 默认启用上下文菜单,并提供默认的 isSelectable 逻辑来排除常见的不可选择块,如代码行和表格单元格。

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

手动使用

安装

pnpm add @platejs/selection

添加插件

import { BlockSelectionPlugin } from '@platejs/selection/react';
import { createPlateEditor } from 'platejs/react';
 
const editor = createPlateEditor({
  plugins: [
    // ...其他插件
    BlockSelectionPlugin,
  ],
});

将此插件放在任何覆盖 selectAll - Cmd+A(代码块、表格、列等)的其他插件之前,以避免冲突。

从选择中排除块

您可以使用 options.isSelectable 控制哪些块是可选择的。此函数接收一个元素及其路径,如果块可选择则应返回 true

例如,排除代码行、列和表格单元格:

import { BlockSelectionPlugin } from '@platejs/selection/react';
 
BlockSelectionPlugin.configure({
  options: {
    isSelectable: (element, path) => {
      if (['code_line', 'column', 'td'].includes(element.type)) {
        return false;
      }
      // 排除表格行内的块
      if (editor.api.block({ above: true, at: path, match: { type: 'tr' } })) {
        return false;
      }
      return true;
    },
  },
});

自定义滚动行为

如果您的编辑器位于可滚动容器内,您可能需要配置选择区域的边界和滚动速度。

  1. 为滚动容器添加 id,例如 id={editor.meta.uid}
  2. 在容器上设置 position: relative
  3. 使用 areaOptions 配置边界和滚动行为
BlockSelectionPlugin.configure({
  options: {
    areaOptions: {
      boundaries: `#${editor.meta.uid}`,
      container: `#${editor.meta.uid}`,
      behaviour: {
        scrolling: {
          // 推荐速度,接近原生
          speedDivider: 0.8,
        },
        // 开始选择区域的阈值
        startThreshold: 4,
      },
    },
  },
});

全页选择

您可以通过添加 data-plate-selectable 属性为 <Editor /> 组件之外的元素启用块选择。

<Cover data-plate-selectable />
<Sidebar data-plate-selectable />

为了防止在点击某些元素(例如工具栏按钮)时取消选择块,请添加 data-plate-prevent-unselect 属性。

<YourToolbarButton data-plate-prevent-unselect />

要在点击可选择区域之外时重置选择,您可以使用点击处理程序或直接调用 API:

// 1. 直接调用 API
editor.api.blockSelection.deselect();
 
// 2. 点击外部处理程序
const handleClickOutside = (event: MouseEvent) => {
  if (!(event.target as HTMLElement).closest('[data-plate-selectable]')) {
    editor.api.blockSelection.deselect();
  }
};

样式

选择区域

通过定位添加到编辑器容器的 .slate-selection-area 类来设置选择区域的样式。

/* 使用 Tailwind CSS 实用类的示例 */
'[&_.slate-selection-area]:border [&_.slate-selection-area]:border-primary [&_.slate-selection-area]:bg-primary/10'

选中元素

使用 useBlockSelected 钩子确定块是否被选中。您可以渲染一个视觉指示器,如 BlockSelection 组件,该组件专为此目的设计。

Plate UI 使用 render.belowRootNodes 为所有可选择块渲染此组件:

render: {
  belowRootNodes: (props) => {
    if (!props.className?.includes('slate-selectable')) return null;
 
    return <BlockSelection />;
  },
},

插件

BlockSelectionPlugin

块选择功能的插件。

Options

  • areaOptions optional PartialSelectionOptions

    选择区域的选项。查看 SelectionJS 文档 获取所有可用选项。

    {
      boundaries: [`#${editor.meta.uid}`],
      container: [`#${editor.meta.uid}`],
      selectables: [`#${editor.meta.uid} .slate-selectable`],
      selectionAreaClass: 'slate-selection-area',
    }
  • enableContextMenu optional boolean

    启用或禁用块选择的上下文菜单。

    • 默认值: false
  • isSelecting optional boolean

    指示块选择当前是否处于活动状态。

    • 默认值: false
  • onKeyDownSelecting optional (e: KeyboardEvent) => void

    在选择时处理键盘按下事件的函数。

  • query optional QueryNodeOptions

    在块选择期间查询节点的选项。

    • 默认值: { maxLevel: 1 }
  • selectedIds optional Set<string>

    当前选中块的 ID 集合。

    • 默认值: new Set()
  • anchorId optional string | null

    (内部) 当前选择中锚块的 ID。用于基于 Shift 的选择。

    • 默认值: null
  • isSelectable optional (element: TElement, path: Path) => boolean

    确定块元素是否可选择的函数。

    • 默认值: () => true

API

api.blockSelection.add

将一个或多个块添加到选择中。

Parameters

Collapse all
  • id string | string[]

    要选择的块的 ID。

api.blockSelection.clear

将选中的 ID 集合重置为空集。

api.blockSelection.delete

从选择中移除一个或多个块。

Parameters

Collapse all
  • id string | string[]

    要从选择中移除的块的 ID。

api.blockSelection.deselect

取消选择所有块并将 isSelecting 标志设置为 false。

api.blockSelection.focus

聚焦块选择阴影输入。此输入处理选中块的复制、删除和粘贴事件。

api.blockSelection.getNodes

获取编辑器中的选中块。

ReturnsNodeEntry[]

    选中块的条目数组。

api.blockSelection.has

检查一个或多个块是否被选中。

Parameters

Collapse all
  • id string | string[]

    要检查的块的 ID。

Returns

Collapse all
  • boolean

    块是否被选中。

api.blockSelection.isSelectable

根据插件选项 isSelectable 检查给定路径的块是否可选择。

Parameters

Collapse all
  • element TElement

    要检查的块元素。

  • path Path

    块元素的路径。

Returnsboolean

    块是否可选择。

api.blockSelection.moveSelection

将选择向上或向下移动到下一个可选择的块。

向上移动时:

  • 从最顶部选中的块获取上一个可选择块
  • 将其设置为新锚点
  • 清除先前选择并仅选择此块 向下移动时:
  • 从最底部选中的块获取下一个可选择块
  • 将其设置为新锚点
  • 清除先前选择并仅选择此块

Parameters

Collapse all
  • direction 'up' | 'down'

    移动选择的方向。

api.blockSelection.selectAll

选择编辑器中的所有可选择块。

api.blockSelection.set

将选择设置为一个或多个块,清除任何现有选择。

Parameters

Collapse all
  • id string | string[]

    要选择的块的 ID。

api.blockSelection.shiftSelection

基于锚块扩展或收缩选择。

对于 Shift+ArrowDown

  • 如果锚点是最顶部:通过添加最底部下方的块向下扩展
  • 否则:从最顶部收缩(除非最顶部是锚点) 对于 Shift+ArrowUp
  • 如果锚点是最底部:通过添加最顶部上方的块向上扩展
  • 否则:从最底部收缩(除非最底部是锚点) 锚块始终保持选中状态。如果未设置锚点,则默认为:
  • Shift+ArrowUp 的最底部块
  • Shift+ArrowDown 的最顶部块

Parameters

Collapse all
  • direction 'up' | 'down'

    扩展/收缩选择的方向。

转换

tf.blockSelection.duplicate

复制选中的块。

tf.blockSelection.removeNodes

从编辑器中移除选中的节点。

tf.blockSelection.select

选择 getNodes() 返回的编辑器中的节点并重置选中的 ID。

tf.blockSelection.setNodes

在选中的节点上设置属性。

Parameters

Collapse all
  • props Partial<NodeProps<TElement>>

    要在选中节点上设置的属性。

  • options optional SetNodesOptions

    设置节点的选项。

tf.blockSelection.setTexts

在选中的节点上设置文本属性。

Parameters

Collapse all
  • props Partial<NodeProps<TText>>

    要在选中节点上设置的文本属性。

  • options optional Omit<SetNodesOptions, 'at'>

    设置文本节点的选项,不包括 'at' 属性。

钩子

useBlockSelectable

提供使块元素可选择的属性的钩子,包括上下文菜单行为。

Returnsobject

Collapse all
  • props object

    要应用于块元素的属性。

useBlockSelected

Returnsboolean

    上下文块是否被选中。

useBlockSelectionNodes

ReturnsNodeEntry[]

    选中块的条目数组。

useBlockSelectionFragment

ReturnsNode[]

    选中块的节点数组。

useBlockSelectionFragmentProp

ReturnsNode[]

    选中块的片段属性。

useSelectionArea

初始化和管理选择区域功能。