docs/(plugins)/(functionality)/block-selection.cn.mdx
块选择功能允许用户选择和操作整个文本块,而不是单个单词或字符。
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: [
// ...otherPlugins,
...BlockSelectionKit,
],
});
npm install @platejs/selection
import { BlockSelectionPlugin } from '@platejs/selection/react';
import { createPlateEditor } from 'platejs/react';
const editor = createPlateEditor({
plugins: [
// ...otherPlugins,
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 hook 来确定块是否被选中。您可以渲染一个视觉指示器,例如专为此目的设计的 BlockSelection 组件。
Plate UI 使用 render.belowRootNodes 为所有可选择的块渲染此组件:
render: {
belowRootNodes: (props) => {
if (!props.className?.includes('slate-selectable')) return null;
return <BlockSelection />;
},
},
BlockSelectionPlugin块选择功能的插件。
<API name="BlockSelectionPlugin"> <APIOptions> <APIItem name="areaOptions" type="PartialSelectionOptions" optional> 选择区域的选项。查看 [SelectionJS 文档](https://github.com/Simonwep/selection-js) 了解所有可用选项。{
boundaries: [`#${editor.meta.uid}`],
container: [`#${editor.meta.uid}`],
selectables: [`#${editor.meta.uid} .slate-selectable`],
selectionAreaClass: 'slate-selection-area',
}
api.blockSelection.add将一个或多个块添加到选择中。
<API name="add"> <APIParameters> <APIItem name="id" type="string | string[]"> 要选择的块的 ID。 </APIItem> </APIParameters> </API>api.blockSelection.clear将选中的 ID 集合重置为空集合。
api.blockSelection.delete从选择中移除一个或多个块。
<API name="delete"> <APIParameters> <APIItem name="id" type="string | string[]"> 要从选择中移除的块的 ID。 </APIItem> </APIParameters> </API>api.blockSelection.deselect取消选择所有块并将 isSelecting 标志设置为 false。
api.blockSelection.focus聚焦块选择的影子输入框。此输入框处理选中块的复制、删除和粘贴事件。
api.blockSelection.getNodes获取编辑器中选中的块。
<API name="getNodes"> <APIParameters> <APIItem name="options" type="{ selectionFallback?: boolean }" optional> 获取节点的选项。 </APIItem> </APIParameters> <APIOptions type="object"> <APIItem name="selectionFallback" type="boolean" optional> 如果为 true,且块选择未选中任何块,该方法将使用编辑器的原始选择来获取块。- **默认值:** `false` </APIItem> </APIOptions> <APIReturns type="NodeEntry[]"> 选中块条目的数组。 </APIReturns> </API>api.blockSelection.has检查一个或多个块是否被选中。
<API name="has"> <APIParameters> <APIItem name="id" type="string | string[]"> 要检查的块的 ID。 </APIItem> </APIParameters> <APIReturns> <APIItem type="boolean">块是否被选中。</APIItem> </APIReturns> </API>api.blockSelection.isSelectable根据 isSelectable 插件选项检查给定路径的块是否可选择。
api.blockSelection.moveSelection将选择向上或向下移动到下一个可选择的块。
向上移动时:
api.blockSelection.selectAll选择编辑器中所有可选择的块。
api.blockSelection.set将选择设置为一个或多个块,清除任何现有选择。
<API name="set"> <APIParameters> <APIItem name="id" type="string | string[]"> 要选择的块的 ID。 </APIItem> </APIParameters> </API>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设置选中节点的属性。
<API name="setNodes"> <APIParameters> <APIItem name="props" type="Partial<NodeProps<TElement>>"> 要设置到选中节点的属性。 </APIItem> <APIItem name="options" type="SetNodesOptions" optional> 设置节点的选项。 </APIItem> </APIParameters> </API>tf.blockSelection.setTexts设置选中节点的文本属性。
<API name="setTexts"> <APIParameters> <APIItem name="props" type="Partial<NodeProps<TText>>"> 要设置到选中节点的文本属性。 </APIItem> <APIItem name="options" type="Omit<SetNodesOptions, 'at'>" optional> 设置文本节点的选项,不包括 'at' 属性。 </APIItem> </APIParameters> </API>useBlockSelectable提供使块元素可选择的 props 的 hook,包括上下文菜单行为。
<API name="useBlockSelectable"> <APIReturns type="object"> <APIItem name="props" type="object"> 要展开到块元素上的 props。 <APISubList> <APISubListItem parent="props" name="className" type="string"> 选择功能所需的类。- **默认值:** `'slate-selectable'` </APISubListItem> <APISubListItem parent="props" name="onContextMenu" type="(event: React.MouseEvent) => void" > 处理右键上下文菜单行为:- 为选中的块打开上下文菜单 - 为 void 元素打开 - 为带有 `data-plate-open-context-menu="true"` 的元素打开 - 使用 Shift 键添加块到选择以进行多选 </APISubListItem> </APISubList> </APIItem> </APIReturns> </API>useBlockSelecteduseBlockSelectionNodesuseBlockSelectionFragmentuseBlockSelectionFragmentPropuseSelectionArea初始化和管理选择区域功能。