格式化工具栏
当您在编辑器中高亮文本时,格式化工具栏会出现。

更改格式化工具栏
您可以用自己的 React 组件更改或替换格式化工具栏。以下示例演示了如何在默认格式化工具栏中添加两个按钮——一个用于添加蓝色文本/背景,另一个用于切换代码样式。
import "@blocknote/core/fonts/inter.css";
import { BlockNoteView } from "@blocknote/mantine";
import "@blocknote/mantine/style.css";
import {
BasicTextStyleButton,
BlockTypeSelect,
ColorStyleButton,
CreateLinkButton,
FileCaptionButton,
FileReplaceButton,
FormattingToolbar,
FormattingToolbarController,
NestBlockButton,
TextAlignButton,
UnnestBlockButton,
useCreateBlockNote,
} from "@blocknote/react";
import { BlueButton } from "./BlueButton.js";
export default function App() {
// Creates a new editor instance.
const editor = useCreateBlockNote({
initialContent: [
{
type: "paragraph",
content: "Welcome to this demo!",
},
{
type: "paragraph",
content: [
{
type: "text",
text: "You can now toggle ",
styles: {},
},
{
type: "text",
text: "blue",
styles: { textColor: "blue", backgroundColor: "blue" },
},
{
type: "text",
text: " and ",
styles: {},
},
{
type: "text",
text: "code",
styles: { code: true },
},
{
type: "text",
text: " styles with new buttons in the Formatting Toolbar",
styles: {},
},
],
},
{
type: "paragraph",
content: "Select some text to try them out",
},
{
type: "paragraph",
},
],
});
// Renders the editor instance.
return (
<BlockNoteView editor={editor} formattingToolbar={false}>
<FormattingToolbarController
formattingToolbar={() => (
<FormattingToolbar>
<BlockTypeSelect key={"blockTypeSelect"} />
{/* Extra button to toggle blue text & background */}
<BlueButton key={"customButton"} />
<FileCaptionButton key={"fileCaptionButton"} />
<FileReplaceButton key={"replaceFileButton"} />
<BasicTextStyleButton
basicTextStyle={"bold"}
key={"boldStyleButton"}
/>
<BasicTextStyleButton
basicTextStyle={"italic"}
key={"italicStyleButton"}
/>
<BasicTextStyleButton
basicTextStyle={"underline"}
key={"underlineStyleButton"}
/>
<BasicTextStyleButton
basicTextStyle={"strike"}
key={"strikeStyleButton"}
/>
{/* Extra button to toggle code styles */}
<BasicTextStyleButton
key={"codeStyleButton"}
basicTextStyle={"code"}
/>
<TextAlignButton
textAlignment={"left"}
key={"textAlignLeftButton"}
/>
<TextAlignButton
textAlignment={"center"}
key={"textAlignCenterButton"}
/>
<TextAlignButton
textAlignment={"right"}
key={"textAlignRightButton"}
/>
<ColorStyleButton key={"colorStyleButton"} />
<NestBlockButton key={"nestBlockButton"} />
<UnnestBlockButton key={"unnestBlockButton"} />
<CreateLinkButton key={"createLinkButton"} />
</FormattingToolbar>
)}
/>
</BlockNoteView>
);
}
我们首先定义自定义的 BlueButton
。useComponentsContext
钩子获取 BlockNote 内部使用的所有组件,因此我们想使用 Components.FormattingToolbar.Button
。
我们使用 FormattingToolbar
组件创建自定义格式化工具栏。通过指定其子元素,我们可以用自己的按钮替换工具栏中的默认按钮。
这个自定义格式化工具栏被传递给一个 FormattingToolbarController
,它控制工具栏的位置和可见性(在高亮文本的上方或下方)。
在 BlockNoteView
上设置 formattingToolbar={false}
告诉 BlockNote 不显示默认的格式化工具栏。
更改块类型选择(下拉菜单)项
默认格式化工具栏中的第一个元素是块类型选择,您可以更改其中的项。示例通过向其添加一个项目,使块类型选择支持图像块。
import { defaultProps } from "@blocknote/core";
import { createReactBlockSpec } from "@blocknote/react";
import { Menu } from "@mantine/core";
import { MdCancel, MdCheckCircle, MdError, MdInfo } from "react-icons/md";
import "./styles.css";
// The types of alerts that users can choose from.
export const alertTypes = [
{
title: "Warning",
value: "warning",
icon: MdError,
color: "#e69819",
backgroundColor: {
light: "#fff6e6",
dark: "#805d20",
},
},
{
title: "Error",
value: "error",
icon: MdCancel,
color: "#d80d0d",
backgroundColor: {
light: "#ffe6e6",
dark: "#802020",
},
},
{
title: "Info",
value: "info",
icon: MdInfo,
color: "#507aff",
backgroundColor: {
light: "#e6ebff",
dark: "#203380",
},
},
{
title: "Success",
value: "success",
icon: MdCheckCircle,
color: "#0bc10b",
backgroundColor: {
light: "#e6ffe6",
dark: "#208020",
},
},
] as const;
// The Alert block.
export const Alert = createReactBlockSpec(
{
type: "alert",
propSchema: {
textAlignment: defaultProps.textAlignment,
textColor: defaultProps.textColor,
type: {
default: "warning",
values: ["warning", "error", "info", "success"],
},
},
content: "inline",
},
{
render: (props) => {
const alertType = alertTypes.find(
(a) => a.value === props.block.props.type,
)!;
const Icon = alertType.icon;
return (
<div className={"alert"} data-alert-type={props.block.props.type}>
{/*Icon which opens a menu to choose the Alert type*/}
<Menu withinPortal={false}>
<Menu.Target>
<div className={"alert-icon-wrapper"} contentEditable={false}>
<Icon
className={"alert-icon"}
data-alert-icon-type={props.block.props.type}
size={32}
/>
</div>
</Menu.Target>
{/*Dropdown to change the Alert type*/}
<Menu.Dropdown>
<Menu.Label>Alert Type</Menu.Label>
<Menu.Divider />
{alertTypes.map((type) => {
const ItemIcon = type.icon;
return (
<Menu.Item
key={type.value}
leftSection={
<ItemIcon
className={"alert-icon"}
data-alert-icon-type={type.value}
/>
}
onClick={() =>
props.editor.updateBlock(props.block, {
type: "alert",
props: { type: type.value },
})
}
>
{type.title}
</Menu.Item>
);
})}
</Menu.Dropdown>
</Menu>
{/*Rich text field for user to type in*/}
<div className={"inline-content"} ref={props.contentRef} />
</div>
);
},
},
);
这里,我们使用了 FormattingToolbar
组件,但保留了默认按钮(没有传递任何子元素)。相反,我们通过 blockTypeSelectItems
属性传入了自定义的块类型选择项。