块选择功能允许用户选择和操作整个文本块,而不是单个单词或字符。
特性
- 通过单一操作选择整个块
- 使用鼠标拖动或键盘快捷键进行多块选择
- 对选中块执行复制、剪切和删除操作
- 快速选择的键盘快捷键:
Cmd+A
:选择所有块- 方向键:选择上方或下方的块
- 可自定义选中块的样式
套件使用
安装
添加块选择功能最快的方法是使用 BlockSelectionKit
,它包含预配置的 BlockSelectionPlugin
和 BlockSelection
UI 组件。
BlockSelection
:在选中的块周围渲染选择矩形
添加套件
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;
},
},
});
自定义滚动行为
如果您的编辑器位于可滚动容器内,您可能需要配置选择区域的边界和滚动速度。
- 为滚动容器添加
id
,例如id={editor.meta.uid}
- 在容器上设置
position: relative
- 使用
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
块选择功能的插件。
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
将一个或多个块添加到选择中。
api.blockSelection.clear
将选中的 ID 集合重置为空集。
api.blockSelection.delete
从选择中移除一个或多个块。
api.blockSelection.deselect
取消选择所有块并将 isSelecting
标志设置为 false。
api.blockSelection.focus
聚焦块选择阴影输入。此输入处理选中块的复制、删除和粘贴事件。
api.blockSelection.getNodes
获取编辑器中的选中块。
api.blockSelection.has
检查一个或多个块是否被选中。
api.blockSelection.isSelectable
根据插件选项 isSelectable
检查给定路径的块是否可选择。
api.blockSelection.moveSelection
将选择向上或向下移动到下一个可选择的块。
向上移动时:
- 从最顶部选中的块获取上一个可选择块
- 将其设置为新锚点
- 清除先前选择并仅选择此块 向下移动时:
- 从最底部选中的块获取下一个可选择块
- 将其设置为新锚点
- 清除先前选择并仅选择此块
api.blockSelection.selectAll
选择编辑器中的所有可选择块。
api.blockSelection.set
将选择设置为一个或多个块,清除任何现有选择。
api.blockSelection.shiftSelection
基于锚块扩展或收缩选择。
对于 Shift+ArrowDown
:
- 如果锚点是最顶部:通过添加最底部下方的块向下扩展
- 否则:从最顶部收缩(除非最顶部是锚点)
对于
Shift+ArrowUp
: - 如果锚点是最底部:通过添加最顶部上方的块向上扩展
- 否则:从最底部收缩(除非最底部是锚点) 锚块始终保持选中状态。如果未设置锚点,则默认为:
Shift+ArrowUp
的最底部块Shift+ArrowDown
的最顶部块
转换
tf.blockSelection.duplicate
复制选中的块。
tf.blockSelection.removeNodes
从编辑器中移除选中的节点。
tf.blockSelection.select
选择 getNodes()
返回的编辑器中的节点并重置选中的 ID。
tf.blockSelection.setNodes
在选中的节点上设置属性。
tf.blockSelection.setTexts
在选中的节点上设置文本属性。
钩子
useBlockSelectable
提供使块元素可选择的属性的钩子,包括上下文菜单行为。
useBlockSelected
useBlockSelectionNodes
useBlockSelectionFragment
useBlockSelectionFragmentProp
useSelectionArea
初始化和管理选择区域功能。
On This Page
特性套件使用安装添加套件手动使用安装添加插件从选择中排除块自定义滚动行为全页选择样式选择区域选中元素插件BlockSelectionPlugin
APIapi.blockSelection.add
api.blockSelection.clear
api.blockSelection.delete
api.blockSelection.deselect
api.blockSelection.focus
api.blockSelection.getNodes
api.blockSelection.has
api.blockSelection.isSelectable
api.blockSelection.moveSelection
api.blockSelection.selectAll
api.blockSelection.set
api.blockSelection.shiftSelection
转换tf.blockSelection.duplicate
tf.blockSelection.removeNodes
tf.blockSelection.select
tf.blockSelection.setNodes
tf.blockSelection.setTexts
钩子useBlockSelectable
useBlockSelected
useBlockSelectionNodes
useBlockSelectionFragment
useBlockSelectionFragmentProp
useSelectionArea