0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Quill.js】アイコンの追加方法

Posted at

最近、個人的にQuill.jsを使用したアプリを開発しています。
ヘッダーにアイコンを追加する処理で少し詰まったのでその備忘録です。

全体像

今回は react を用いて開発しました。
全体像はこんな感じです。

import { useEffect, useRef, useState } from "react";
import Quill from "quill";
import "quill/dist/quill.snow.css";
import { MemoContent } from "@/app/constants/interfaces";

// ツールバーに表示するアイコンのオプション
const toolbarOptions = [
  ["bold", "italic", "underline", "strike"],
  ["blockquote", "code-block"],
  ["link", "image"],
  [{ list: "ordered" }, { list: "bullet" }],
  [{ indent: "-1" }, { indent: "+1" }], 
  [{ header: [1, 2, 3, 4, 5, 6, false] }],
  [{ align: [] }],
  ["clean"], 
  ["markdown"], // 追加
];

export default function Editor({ onValueChange, content }: MemoContent) {
  const editorRef = useRef<HTMLDivElement>(null);
  const [quill, setQuill] = useState<Quill | null>(null);

  const isMounted = useRef(false);

  const icons = Quill.import("ui/icons") as Record<string, string>;
  
  // 追加するアイコンのSVG
  icons["markdown"] = `
    <svg  xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 20" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round">
      <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
      <path d="M3 5m0 2a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v10a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z" />
      <path d="M7 15v-6l2 2l2 -2v6" />
      <path d="M14 13l2 2l2 -2m-2 2v-6" />
    </svg>
  `;

  useEffect(() => {
    if (!editorRef.current || quill) return;

    if (!isMounted.current) {
      const quillInstance = new Quill(editorRef.current, {
        theme: "snow",
        modules: {
          toolbar: {
            container: toolbarOptions,
            handlers: {
	            // 追加したアイコンをクリックしたときの処理 
              markdown: function () {
                console.log("markdown");
              },
            },
          },
        },
      });

      setQuill(quillInstance);

      isMounted.current = true;

      quillInstance.on("text-change", () => {
        const editorContent = quillInstance.getContents();
        if (editorContent) onValueChange(editorContent);
      });
    }
  }, []);

  useEffect(() => {
    if (quill) {
      if (content && content.ops.length > 0) {
        const currentContent = quill.getContents();
        if (JSON.stringify(currentContent) !== JSON.stringify(content)) {
          quill.setContents(content);
        }
      } else {
        quill.setText("");
      }
    }
  }, [content, quill]);

  return (
    <>
      <div ref={editorRef} />
    </>
  );
}

解説

toolbarOptions への追加

まずはここに追加したいアイコン名を追加します。
今回はmarkdown形式に変換する機能を実装したかったので markdown という名前で追加しました。

const toolbarOptions = [
  ["bold", "italic", "underline", "strike"],
  ["blockquote", "code-block"],
  ["link", "image"],
  [{ list: "ordered" }, { list: "bullet" }],
  [{ indent: "-1" }, { indent: "+1" }], 
  [{ header: [1, 2, 3, 4, 5, 6, false] }],
  [{ align: [] }],
  ["clean"], 
  ["markdown"], // 追加
];

アイコンの追加

ここで追加したいアイコンのSVG要素を追加します。
今回はべた書きでSVG要素を記述していますが、
font-awesome のアイコンとかでも問題ないみたいです。

const icons = Quill.import("ui/icons") as Record<string, string>;
  
  // 追加するアイコンのSVG
  icons["markdown"] = `
    <svg  xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 20" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round">
      <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
      <path d="M3 5m0 2a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v10a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z" />
      <path d="M7 15v-6l2 2l2 -2v6" />
      <path d="M14 13l2 2l2 -2m-2 2v-6" />
    </svg>
  `;

handlers にクリック時の処理を追加

ql-'クラス名' の 'クラス名' にあたる部分と同じfunction名を追加します。

const quillInstance = new Quill(editorRef.current, {
        theme: "snow",
        modules: {
          toolbar: {
            container: toolbarOptions,
            handlers: {
	            // 追加したアイコンをクリックしたときの処理 
              markdown: function () {
                console.log("markdown");
              },
            },
          },
        },
      });

おわりに

少し複雑ですが、任意のアイコンを追加できるのは面白いなと思いました。

既存のアイコンも変更できるようなので、
またタイミングで変更してみたいと思います。

参考文献

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?