昨天我們知道如何設定編輯器的 CSS 樣式,並且修改既有的功能按鈕。今天接著研究要如何自訂工具列的內容以及加入自訂功能的按鈕。

自訂工具列:Toolbar Options

Quill Editor 的工具列有兩種設置方式,一種是定義 toolbarOption 物件,由於 Quill 內建相當豐富實用的功能,因此我們可以直接以陣列的方式設定想要加入的控制按鈕,陣列底下的每個元素也是陣列,用來表示一個群組,除了可以調整工具列的功能按鈕順序之外,我們也能以分組的方式將同類型的功能擺在一起。

const toolbarOptions = {
    container: [
        ['bold', 'italic', 'underline', 'strike'], // 預設的工具按鈕
        [{ header: 1 }, { header: 2 }], // 預設的工具按鈕
        [{ list: 'ordered' }, { list: 'bullet' }], // 預設的工具按鈕
        [{ script: 'sub' }, { script: 'super' }], // 預設的工具按鈕
        [{ indent: '-1' }, { indent: '+1' }], // 預設的工具按鈕
        [{ direction: 'rtl' }], // 預設的工具按鈕
        [{ size: ['small', false, 'large', 'huge'] }], // false 是 normal
        [{ header: [1, 2, 3, 4, 5, 6, false] }], // 預設的工具按鈕
        [{ color: [] }, { background: [] }], // 預設的工具按鈕
        [{ font: [] }], // 預設的工具按鈕
        ['image', 'customButton'], // 自定義與內建工具按鈕
        ['clean'], // 預設的工具按鈕
    ],
}

另外需要留意的部分像是 size 以及 header,分別是文字的大小以及標題層級,兩者都與字體大小有關,陣列中有設定值是 false ,在畫面渲染之後,可以看到下拉清單會表示 Normal,意思是移除該樣式,僅顯示原本的大小。

toolbar options

例如原本選擇了一段文字並設定 header1,意思就是把選取的範圍文字套上 <h1> 標籤,這時的字體是呈現大標題的樣式,接著我們再把一樣的選取範圍切換到 Normal,原本的 H1 標題樣式就會被移除,回到原始的文字狀態。

加入自定義按鈕

接著我們嘗試新增一個 customButton 的自訂按鈕,並透過 toolbar 物件下的 handlers 屬性註冊按鈕的自訂函式,這個函式主要處理按下按鈕後的操作。我們可以在 handlers 中實作我們需要的功能,例如插入特定的內容、修改編輯器文本內容…等等。另外 toolbar 也提供了群組按鈕的設定,例如要將相同類型的按鈕放一起,直接放在同一個陣列即可。

使用自訂按鈕功能

quillConfigtoolbar 中加入自訂功能按鈕的名稱及對應的 handler,並且設定按鈕的 icon:

const quillConfig = {
  modules: {
    toolbar: {
      container: [
        // ...其他按鈕
        ['image', 'customButton'], // 自定義的工具按鈕群組
      ],
      handlers: {
        "customButton": () => console.log('handle custom button')
      }
    },
    theme: 'snow',
  }
};

// 使用 font awesome 自訂按鈕 icon
const icons = Quill.import('ui/icons');
icons['customButton'] = '<i class="fa-regular fa-star"></i>';

自訂工具列:HTML

我們也可以自訂工具列的 HTML,在初始化的時候,Quill 會根據 toolbar 屬性給的工具列容器選擇器進行內建功能的事件綁定,我們也可以自訂額外的按鈕或元件在上面。例如:

<div #toolbar>
  <span class="ql-formats">
    <button class="ql-bold">Bold</button>
    <button class="ql-italic">Italic</button>
    <button class="ql-link">Link</button>
    <button class="ql-list" value="bullet">Ul</button>
  </span>

  <!-- customButton -->
  <span class="ql-formats">
    <button class="ql-customButton" [title]="'Custom Button'">
      Custom Button
    </button>
  </span>
</div>

在 Component 初始化的時候帶入指定的容器,這邊我們一樣透過 @ViewChild 來獲取 HTML,同時也將對應的 handlers 加上來模擬觸發按鈕的時候進行的操作:

@ViewChild('editor') editor!: ElementRef;
@ViewChild('toolbar') toolbar!: ElementRef;
// ...
const quill = new Quill(this.editor.nativeElement, { 
  modules: { 
    // toolbar: toolbarOptions,
    toolbar: {
      container: this.toolbar.nativeElement,
      handlers: {
        customButton: () => console.log('handle custom button'),
      },
    },
  } 
});

重新整理之後可以看到工具列變成自訂的 HTML 內容:
自訂的 HTML 內容

小結

今天我們了解到工具列的設定,Quill 提供了這兩種設定方式,在大部分的情況下,我們可以選擇定義 toolbarOption 物件的方式,將想要使用的內建功能分門別類組成不同的群組後編排順序,當遇到較特殊的情況,只設定顯示以及順序無法滿足需求的時候,我們可以直接以 HTML 的方式完全自訂一個工具列,並按照需求加入額外的介面或其他功能。

雜記

昨天下班的時候路過南港展覽館,發現今天突然好多人,而且感覺就不是剛下班的樣子,也看到許多代客寄物的小攤,看到告示牌才知道,原來今天展覽館有舉辦演唱會,外頭都是排隊的人潮。可以看到很多元的打扮風格,不過人真的是多到差點進不去捷運站。到了隔天上班的時候發現展覽館外圍地上一堆垃圾,有沒喝完的飲料,更多的是抽完菸的菸蒂,對於厭惡抽菸的我來說,很久沒看到這麼精彩的景象了,還是希望民眾參加演唱會之後,也別忘了把垃圾帶走,抽完菸的菸蒂熄滅之後也順手丟到垃圾桶吧。真心覺得素質還有待提升QQ

文章同步發表於2023 iThome 鐵人賽