Kit 使用方式
安装
添加块选择最快的方式是使用 BlockSelectionKit,它包含预配置的 BlockSelectionPlugin 和 BlockSelection UI 组件。
'use client';
import { AIChatPlugin } from '@platejs/ai/react';
import { BlockSelectionPlugin } from '@platejs/selection/react';
import { getPluginTypes, isHotkey, KEYS } from 'platejs';
import { BlockSelection } from '@/components/ui/block-selection';
export const hasSelectableClass = ({
attributes,
className,
}: {
attributes: { className?: string };
className?: string;
}) =>
[className, attributes.className]
.filter(Boolean)
.join(' ')
.includes('slate-selectable');
export const BlockSelectionKit = [
BlockSelectionPlugin.configure(({ editor }) => ({
options: {
enableContextMenu: true,
isSelectable: (element) =>
!getPluginTypes(editor, [KEYS.column, KEYS.codeLine, KEYS.td]).includes(
element.type
),
onKeyDownSelecting: (editor, e) => {
if (isHotkey('mod+j')(e)) {
editor.getApi(AIChatPlugin).aiChat.show();
}
},
},
render: {
belowRootNodes: (props) => {
if (!hasSelectableClass(props)) return null;
return <BlockSelection {...(props as any)} />;
},
},
})),
];'use client';
import { AIChatPlugin } from '@platejs/ai/react';
import { BlockSelectionPlugin } from '@platejs/selection/react';
import { getPluginTypes, isHotkey, KEYS } from 'platejs';
import { BlockSelection } from '@/components/ui/block-selection';
export const hasSelectableClass = ({
attributes,
className,
}: {
attributes: { className?: string };
className?: string;
}) =>
[className, attributes.className]
.filter(Boolean)
.join(' ')
.includes('slate-selectable');
export const BlockSelectionKit = [
BlockSelectionPlugin.configure(({ editor }) => ({
options: {
enableContextMenu: true,
isSelectable: (element) =>
!getPluginTypes(editor, [KEYS.column, KEYS.codeLine, KEYS.td]).includes(
element.type
),
onKeyDownSelecting: (editor, e) => {
if (isHotkey('mod+j')(e)) {
editor.getApi(AIChatPlugin).aiChat.show();
}
},
},
render: {
belowRootNodes: (props) => {
if (!hasSelectableClass(props)) return null;
return <BlockSelection {...(props as any)} />;
},
},
})),
];BlockSelection:在选中的块周围渲染选择矩形。
添加 Kit
BlockSelectionKit 默认启用上下文菜单,并提供默认的 isSelectable 逻辑来排除常见的不可选择块,如代码行和表格单元格。
import { createPlateEditor } from 'platejs/react';
import { BlockSelectionKit } from '@/components/editor/plugins/block-selection-kit';
const editor = createPlateEditor({
plugins: [
// ...otherPlugins,
...BlockSelectionKit,
],
});import { createPlateEditor } from 'platejs/react';
import { BlockSelectionKit } from '@/components/editor/plugins/block-selection-kit';
const editor = createPlateEditor({
plugins: [
// ...otherPlugins,
...BlockSelectionKit,
],
});手动使用方式
安装
pnpm add @platejs/selectionpnpm add @platejs/selection添加插件
import { BlockSelectionPlugin } from '@platejs/selection/react';
import { createPlateEditor } from 'platejs/react';
const editor = createPlateEditor({
plugins: [
// ...otherPlugins,
BlockSelectionPlugin,
],
});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;
},
},
});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,
},
},
},
});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 /><Cover data-plate-selectable />
<Sidebar data-plate-selectable />要防止点击某些元素(例如工具栏按钮)时取消选择块,请添加 data-plate-prevent-unselect 属性。
<YourToolbarButton 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();
}
};// 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'/* 使用 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 />;
},
},render: {
belowRootNodes: (props) => {
if (!props.className?.includes('slate-selectable')) return null;
return <BlockSelection />;
},
},插件
BlockSelectionPlugin
块选择功能的插件。
- 默认值:
false - 默认值:
false - 默认值:
{ maxLevel: 1 } - 默认值:
new Set() - 默认值:
null - 默认值:
() => true
选择区域的选项。查看 SelectionJS 文档 了解所有可用选项。
{
boundaries: [`#${editor.meta.uid}`],
container: [`#${editor.meta.uid}`],
selectables: [`#${editor.meta.uid} .slate-selectable`],
selectionAreaClass: 'slate-selection-area',
}{
boundaries: [`#${editor.meta.uid}`],
container: [`#${editor.meta.uid}`],
selectables: [`#${editor.meta.uid} .slate-selectable`],
selectionAreaClass: 'slate-selection-area',
}启用或禁用块选择的上下文菜单。
指示块选择当前是否处于活动状态。
处理选择时键盘按下事件的函数。
块选择期间查询节点的选项。
当前选中块的 ID 集合。
(内部)当前选择中锚点块的 ID。用于基于 Shift 的选择。
确定块元素是否可选择的函数。
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时为最顶部的块
Transforms
tf.blockSelection.duplicate
复制选中的块。
tf.blockSelection.removeNodes
从编辑器中移除选中的节点。
tf.blockSelection.select
在编辑器中选择由 getNodes() 返回的节点并重置选中的 ID。
tf.blockSelection.setNodes
设置选中节点的属性。
tf.blockSelection.setTexts
设置选中节点的文本属性。
Hooks
useBlockSelectable
提供使块元素可选择的 props 的 hook,包括上下文菜单行为。
useBlockSelected
useBlockSelectionNodes
useBlockSelectionFragment
useBlockSelectionFragmentProp
useSelectionArea
初始化和管理选择区域功能。
On This Page
功能特性Kit 使用方式安装添加 Kit手动使用方式安装添加插件从选择中排除块自定义滚动行为全页面选择样式选择区域选中元素插件BlockSelectionPluginAPIapi.blockSelection.addapi.blockSelection.clearapi.blockSelection.deleteapi.blockSelection.deselectapi.blockSelection.focusapi.blockSelection.getNodesapi.blockSelection.hasapi.blockSelection.isSelectableapi.blockSelection.moveSelectionapi.blockSelection.selectAllapi.blockSelection.setapi.blockSelection.shiftSelectionTransformstf.blockSelection.duplicatetf.blockSelection.removeNodestf.blockSelection.selecttf.blockSelection.setNodestf.blockSelection.setTextsHooksuseBlockSelectableuseBlockSelecteduseBlockSelectionNodesuseBlockSelectionFragmentuseBlockSelectionFragmentPropuseSelectionArea