Toggleable Custom Blocks
This example shows how to create custom blocks with a toggle button to show/hide their children, like with the default toggle heading and list item blocks. This is done using the use the ToggleWrapper component from @blocknote/react.
Relevant Docs:
import { BlockNoteSchema, defaultBlockSpecs } from "@blocknote/core";import "@blocknote/core/fonts/inter.css";import { BlockNoteView } from "@blocknote/mantine";import "@blocknote/mantine/style.css";import { useCreateBlockNote } from "@blocknote/react";import { ToggleBlock } from "./Toggle";// Our schema with block specs, which contain the configs and implementations for// blocks that we want our editor to use.const schema = BlockNoteSchema.create({ blockSpecs: { // Adds all default blocks. ...defaultBlockSpecs, // Adds the Toggle block. toggle: ToggleBlock(), },});export default function App() { // Creates a new editor instance. const editor = useCreateBlockNote({ schema, initialContent: [ { type: "paragraph", content: "Welcome to this demo!", }, { // We set a persistent ID so that the toggled state is preserved // on reload. id: "toggle", type: "toggle", content: "This is an example toggle", children: [ { type: "paragraph", content: "This is the first child of the toggle block.", }, { type: "paragraph", content: "This is the second child of the toggle block.", }, ], }, { type: "paragraph", content: "Click the '>' icon to show/hide its children", }, { type: "paragraph", }, ], }); // Renders the editor instance. return <BlockNoteView editor={editor} />;}import { defaultProps } from "@blocknote/core";import { createReactBlockSpec, ToggleWrapper } from "@blocknote/react";// The Toggle block that we want to add to our editor.export const ToggleBlock = createReactBlockSpec( { type: "toggle", propSchema: { ...defaultProps, }, content: "inline", }, { render: (props) => ( // The `ToggleWrapper` component renders a button on the left which // toggles the visibility of the block's children. It also adds a button // to add child blocks if there are none. By default, it uses local // storage to remember the toggled state based on the block ID, but you can pass a custom // `toggledState` prop to use a different storage mechanism. <ToggleWrapper block={props.block} editor={props.editor}> <p ref={props.contentRef} /> </ToggleWrapper> ), },);