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> ), }, );