🖊️

Notion-styleのテキストエディタ、BlockNoteを使う

2024/02/08に公開

概要

BlockNoteは、ブロックベースのリッチテキストエディタを提供するReactのライブラリです。

文章中の要素(ヘッダー、段落、画像など)をブロックという単位で構造化していることが特徴です。もしNotionを使ったことがあれば、ほぼ同じ編集体験なのでイメージしやすいかと思います。

公式サイトのトップに誰でも共同編集できるエディタがあるので試すのもおすすめです。


治安を乱してはならない

特徴

BlockNoteはProseMirrorというリッチテキストエディタを構築するためのライブラリをベースに開発されています。
ProseMirrorは高いカスタマイズ性を持ち幅広い使用実績がある一方で、その利用にはいくつかのハードルがあります。

  • 多数のモジュール群から機能を選択する必要性
  • テキストの構造を表現するスキーマの管理
  • UIの構築

これらを解決し、十分なプリセットとモダンなUI、そして簡潔なAPIの形にしたのがBlockNoteです。

利用

BlockNoteは非常に簡単に導入できます。

npm install @blocknote/core @blocknote/react
import { BlockNoteView, useBlockNote } from "@blocknote/react";
import "@blocknote/react/style.css";

function App() {
  const editor = useBlockNote();
  return <BlockNoteView editor={editor} />;
}

以上の記述でエディタが使用できるようになります。

「/」キーでメニューを表示できる

editorには、以下のようなのブロックの配列としてデータが保管されています。MarkDownでも似たようなドキュメントは作成できますが、ブロックとしてデータを持つことによって並べ替えなどの操作が容易に行えるメリットがあります。

  {
    "id": "...",
    "type": "paragraph",
    "content": [
      {
        "type": "text",
        "text": "Header",
        "styles": {}
      }
    ],
    ...
  },

拡張性

ProseMirrorをベースにしている背景もあり、BlockNoteは高い拡張性を持っています。例えば、「Hello World」という文章のブロックを挿入するコマンドをスラッシュメニューに追加する方法を見てみましょう。

まず、メニューに追加するアイテムを定義します。

const insertHelloWorldItem = {
  name: "Insert Hello World",
  execute: insertHelloWorld,
  aliases: ["helloworld", "hw"],
  group: "Other",
  icon: <>👋</>,
  hint: "Used to insert a block with 'Hello World' below.",
};

insertHelloWorldItemが選択されたときに実行する関数も書いてみましょう。

  const insertHelloWorld = (editor) => {
    // 現在のカーソルの位置にあるブロックを取得する
    const currentBlock = editor.getTextCursorPosition().block;
    // 挿入するブロック
    const helloWorldBlock = {
      type: "paragraph",
      content: [{ type: "text", text: "Hello World", styles: { bold: true } }],
    };
    // ブロックを直後に挿入する
    editor.insertBlocks([helloWorldBlock], currentBlock, "after");
  };

最後にuseBlackNoteのオプションに渡します。

  const slashMenuItems = [
    ...getDefaultReactSlashMenuItems(),
    insertHelloWorldItem,
  ];

  const editor = useBlockNote({
    slashMenuItems,
  });

これでスラッシュメニューからInsert Hello Worldが利用できるようになりました。

ほかにも、エディタ全体のスタイルであったり、スラッシュメニュー以外の各種メニューに対しての要素追加・編集についても行う手段が用意されています。

まとめ

BlockNoteはデフォルトで洗練された機能とUIと編集体験を備えつつ、拡張性も高く保ったライブラリです。また、HTMLやMarkdownへのインポート・エクスポートにも対応しており、既存のリッチテキストエディタを置き換えることを検討することも可能です。

また、現状はβ版のため不足する機能や不具合があった場合でも、今後改善される可能性は低くありません。ロードマップを見る限り、AIを利用した編集体験の向上についても展望があるようです。

ありがとうございました。

X (Twitter): @koyo_k0

Discussion