建议菜单
当用户输入触发字符时,会出现建议菜单,触发字符后的文本用于过滤菜单项。
斜杠菜单
斜杠菜单是一种建议菜单,使用 / 字符打开(或者点击区块侧边菜单中的 + 按钮时打开)。
更改斜杠菜单项
你可以更改斜杠菜单中的项。下面的演示添加了一个插入新块的项,其中包含加粗的“Hello World”。
斜杠菜单项是具有以下字段的对象:
type DefaultSuggestionItem = {
title: string;
onItemClick: () => void;
subtext?: string;
badge?: string;
aliases?: string[];
group?: string;
};title: 项的标题。
onItemClick: 选择该项时调用的回调函数。
subtext: 项的副标题。
badge: 在项内徽章中显示的文本。用于显示该项的键盘快捷键。
aliases: 除 title 外的该项其他名称,用于基于用户查询过滤项。
group: 项所属的组。属于同一组的项在菜单中用分隔线分隔。为确保项被正确分组,请确保它们在传递给斜杠菜单的项数组中是连续的。
创建你的项后,你还需要对 BlockNoteView 进行一些更改,以将该项添加到斜杠菜单。
向 BlockNoteView 传递 slashMenu={false} 告诉 BlockNote 不显示默认斜杠菜单。添加带有 triggerCharacter={"/"} 和自定义 getItems 函数的 SuggestionMenuController 则告诉 BlockNote 显示一个自定义项的菜单。
getItems 应基于用户输入的 query(用户在触发字符后输入的内容)返回需要显示在斜杠菜单中的项。在此示例中,我们只是将“Hello World”项添加到默认斜杠菜单项列表,并使用 filterSuggestionItems 根据用户查询过滤完整项列表。
项分组与排序
斜杠菜单项会按照 getItems 返回的顺序进行渲染。相邻且共享相同 group 属性的项会被渲染在同一组中,并显示在一个标签下。
排序
菜单中的项会严格按照数组顺序显示。重新排列数组即可重新排列菜单:
getItems={async (query) =>
filterSuggestionItems(
[
insertHelloWorldItem(editor), // 最先显示
...getDefaultReactSlashMenuItems(editor), // 之后显示
],
query,
)
}分组
具有相同 group 属性的项必须在数组中相邻,才能作为一组渲染。如果相同 group 的项被不同 group 的项隔开,它们会被渲染成两个独立的组,并且各自拥有自己的标签:
// 渲染为一个名为 "Basic" 的组:
[
{ title: "Item A", group: "Basic", /* ... */ },
{ title: "Item B", group: "Basic", /* ... */ },
{ title: "Item C", group: "Other", /* ... */ },
]
// 渲染为两个独立的 "Basic" 组,中间夹着 "Other":
[
{ title: "Item A", group: "Basic", /* ... */ },
{ title: "Item C", group: "Other", /* ... */ },
{ title: "Item B", group: "Basic", /* ... */ },
]查找、插入、移除与重新排序项
使用常规数组操作来处理这些项。例如,要在默认 Heading 1 项后直接插入一个自定义项:
const items = getDefaultReactSlashMenuItems(editor);
const headingIndex = items.findIndex((item) => item.title === "Heading 1");
items.splice(headingIndex + 1, 0, insertHelloWorldItem(editor));要移除一个项:
const items = getDefaultReactSlashMenuItems(editor).filter(
(item) => item.title !== "Heading 1",
);要重新排序项,只需在从 getItems 返回之前对数组进行排序或重新排列即可。
下面的演示结合了这些技巧,只渲染“基础块”和“标题”两个组,并交换它们的顺序:
替换斜杠菜单组件
你可以用自己的 React 组件替换斜杠菜单中使用的组件,下面的演示展示了这一点。
同样,我们添加了带有 triggerCharacter={"/"} 的 SuggestionMenuController 组件,并设置 slashMenu={false} 来替换默认斜杠菜单。
现在,我们还将一个组件传递给它的 suggestionMenuComponent 属性。传递的 suggestionMenuComponent 负责渲染过滤后的项。SuggestionMenuController 控制它的位置和可见性(触发字符下方),并且还决定显示哪些项(使用之前见过的可选 getItems 属性)。
创建额外的建议菜单
你可以在编辑器中添加额外的建议菜单,触发字符可以为任意字符。下面的演示添加了一个示例建议菜单,用于提及,使用 @ 字符打开。
更改新建议菜单中的项,或用于渲染它的组件,与更改斜杠菜单的方法相同。有关提及元素如何工作的更多信息,请参见自定义内联内容。
其他功能
BlockNote 提供了一些用于建议菜单的其他功能,可能适合你的使用场景。
编程式打开建议菜单
虽然建议菜单通常在用户按下触发字符时打开,但你也可以通过代码打开它们。为此,你可以使用编辑器的以下方法:
openSuggestionMenu(triggerCharacter: string): void;
// 用法示例
editor.openSuggestionMenu("/");等待查询
你可能希望延迟显示建议菜单,除非确定用户确实想打开菜单,而不仅仅是输入了触发字符。在这种情况下,应使用 SuggestionMenuController 的 minQueryLength 属性,该属性接受一个数字。
该数字表示用户查询需要达到的最小字符数,菜单才会显示。当该值大于 0 时,还能防止用户在触发字符后立即输入空格时显示菜单。