編輯器

Editor Code Block

參考
程式碼區塊;語言選擇與語法上色。

安裝

Terminal
pnpm dlx shadcn-vue add @admin/editor-code-block
import { createCodeBlockExtension, editorCodeBlockClass } from '@/registry/admin/ui/editor-code-block'

本包以 @tiptap/extension-code-block-lowlight(highlight.js)取代 StarterKit 內建的 codeBlock,註冊 lowlight/common 的常用語言,並在每個區塊右上角掛上可搜尋的語言下拉。lowlight 隨安裝一併帶入,不用另裝。

用法

啟用要兩步:先 :starter-kit="{ codeBlock: false }" 關掉內建 codeBlock,再把 createCodeBlockExtension() 加進 :extensions。上色配色由 editorCodeBlockClass 提供,append 到 :ui 的 base。

<script setup lang="ts">import type { JSONContent } from '@tiptap/core'import { ref } from 'vue'import { cn } from '@/lib/utils'import { baseProseClass } from '@/components/admin/editor'import {  createCodeBlockExtension,  editorCodeBlockClass} from '@/components/admin/editor-code-block'import { AdminEditorToolbar, defaultEditorItems } from '@/components/admin/editor-toolbar'import { AdminRichEditor, starterKitProseClass } from '@/components/admin/rich-editor'​const value = ref<JSONContent | string>(  "<p>點程式碼區塊右上角的下拉可切換語言,選好即時上色:</p><pre><code class=\"language-typescript\">function greet(name: string): string {\n  return 'Hello, ' + name\n}\nconsole.log(greet('TPI'))</code></pre>")​// opt-in:關掉 starter-kit 內建 codeBlock,改用本擴展(含語言下拉 + lowlight 上色)const extensions = [createCodeBlockExtension()]</script>​<template>  <admin-rich-editor    v-slot="{ editor, handlers }"    v-model="value"    :extensions="extensions"    :starter-kit="{ codeBlock: false }"    :ui="{ base: cn(baseProseClass, starterKitProseClass, editorCodeBlockClass) }"  >    <admin-editor-toolbar :editor :handlers="handlers" :items="defaultEditorItems" />  </admin-rich-editor></template>
<script setup lang="ts">import { ref } from 'vue'import { cn } from '@/lib/utils'import { baseProseClass } from '@/registry/admin/ui/editor'import { createCodeBlockExtension, editorCodeBlockClass } from '@/registry/admin/ui/editor-code-block'import { AdminEditorToolbar, defaultEditorItems } from '@/registry/admin/ui/editor-toolbar'import { AdminRichEditor, starterKitProseClass } from '@/registry/admin/ui/rich-editor'​const value = ref('<pre><code class="language-typescript">const x = 1</code></pre>')​const extensions = [createCodeBlockExtension()]</script>​<template>  <admin-rich-editor    v-slot="{ editor, handlers }"    v-model="value"    :extensions="extensions"    :starter-kit="{ codeBlock: false }"    :ui="{ base: cn(baseProseClass, starterKitProseClass, editorCodeBlockClass) }"  >    <admin-editor-toolbar :editor :handlers="handlers" :items="defaultEditorItems" />  </admin-rich-editor></template>

啟用後:

  • toolbar 的程式碼區塊按鈕照舊建立/取消區塊
  • 區塊右上角的下拉切換語言,選好就上色;預設「純文字」不上色
  • 存檔輸出標準的 <pre><code class="language-<lang>">,純文字則是 language-plaintext
  • 唯讀(:editable="false")時下拉收起,程式碼仍照原語言上色

預設語言

新建區塊預設為純文字,要換個預設語言就傳 defaultLanguage:

const extensions = [createCodeBlockExtension({ defaultLanguage: 'typescript' })]

注意事項

  • 一定要先關掉內建 codeBlock:本擴展跟 StarterKit 的 codeBlock 同名,同時存在會讓 TipTap 拋 duplicate node: codeBlock。
  • 顏色不寫進內容:語法色是顯示層的 decoration,存檔只留純碼與 language class,前台各自於 render 時再上色。
  • 前台要一致上色:把 editorCodeBlockClass 一起 append 到前台唯讀 viewer 容器的 :class,顏色才會跟編輯器一致。

API 參考

匯出說明
createCodeBlockExtension(options?)回傳配置好 lowlight 與語言下拉的 code block extension,傳入 <AdminRichEditor :extensions>
editorCodeBlockClass語法上色的 class 字串(hljs-* 對應 admin tokens),append 到 :ui 的 base 或前台 viewer 容器
選項型別預設說明
defaultLanguagestring'plaintext'新建區塊的預設語言