🚀 BlockNote AI is here! Access the early preview.
Examples/Custom Schemas/Toggleable Custom Blocks

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