🚀 BlockNote AI is here! Access the early preview.
Examples/UI Components/Adding Drag Handle Menu Items

Adding Drag Handle Menu Items

In this example, we add an item to the Drag Handle Menu, which resets the hovered block to a paragraph.

Try it out: Hover a block to open the Block Side Menu, and click "Reset Type" in the Drag Handle Menu to reset the selected block!

Relevant Docs:

import "@blocknote/core/fonts/inter.css";
import { BlockNoteView } from "@blocknote/mantine";
import "@blocknote/mantine/style.css";
import {
  BlockColorsItem,
  DragHandleMenu,
  RemoveBlockItem,
  SideMenu,
  SideMenuController,
  useCreateBlockNote,
} from "@blocknote/react";

import { ResetBlockTypeItem } from "./ResetBlockTypeItem";

// To avoid rendering issues, it's good practice to define your custom drag
// handle menu in a separate component, instead of inline within the `sideMenu`
// prop of `SideMenuController`.
const CustomDragHandleMenu = () => (
  <DragHandleMenu>
    <RemoveBlockItem>Delete</RemoveBlockItem>
    <BlockColorsItem>Colors</BlockColorsItem>
    {/* Item which resets the hovered block's type. */}
    <ResetBlockTypeItem>Reset Type</ResetBlockTypeItem>
  </DragHandleMenu>
);

export default function App() {
  // Creates a new editor instance.
  const editor = useCreateBlockNote({
    initialContent: [
      {
        type: "paragraph",
        content: "Welcome to this demo!",
      },
      {
        type: "paragraph",
        content: "<- Click the Drag Handle to see the new item",
      },
      {
        type: "bulletListItem",
        content:
          "Try resetting this block's type using the new Drag Handle Menu item",
      },
      {
        type: "paragraph",
      },
    ],
  });

  // Renders the editor instance.
  return (
    <BlockNoteView editor={editor} sideMenu={false}>
      <SideMenuController
        sideMenu={(props) => (
          <SideMenu {...props} dragHandleMenu={CustomDragHandleMenu} />
        )}
      />
    </BlockNoteView>
  );
}
import {} from "@blocknote/core";
import { SideMenuExtension } from "@blocknote/core/extensions";
import {
  useBlockNoteEditor,
  useComponentsContext,
  useExtensionState,
} from "@blocknote/react";
import { ReactNode } from "react";

export function ResetBlockTypeItem(props: { children: ReactNode }) {
  const editor = useBlockNoteEditor();

  const Components = useComponentsContext()!;

  const block = useExtensionState(SideMenuExtension, {
    selector: (state) => state?.block,
  });

  if (!block) {
    return null;
  }

  return (
    <Components.Generic.Menu.Item
      onClick={() => {
        editor.updateBlock(block, { type: "paragraph" });
      }}
    >
      {props.children}
    </Components.Generic.Menu.Item>
  );
}