編輯器
Editor Superscript / Subscript
toolbar 上標/下標按鈕;sup/sub 行內樣式。
安裝
Terminal
pnpm add @tiptap/extension-superscript @tiptap/extension-subscript上標/下標來自 tiptap Superscript/Subscript。與 highlight/text-align 不同,它們是單純 toggle mark,不需額外元件:注入官方 extension、用 :handlers 註冊 toggle handler,再於 toolbar 加上 { kind: 'superscript' }/{ kind: 'subscript' } item 即可;本頁無對應 registry 包。
用法
<script setup lang="ts">import type { Editor, JSONContent } from '@tiptap/core'import type { EditorToolbarItem } from '@/components/admin/editor-toolbar'import { IconSubscript, IconSuperscript } from '@tabler/icons-vue'import Subscript from '@tiptap/extension-subscript'import Superscript from '@tiptap/extension-superscript'import { ref } from 'vue'import { cn } from '@/lib/utils'import { baseProseClass } from '@/components/admin/editor'import { AdminEditorToolbar, defaultEditorItems } from '@/components/admin/editor-toolbar'import { AdminRichEditor, starterKitProseClass } from '@/components/admin/rich-editor'const value = ref<JSONContent | string>( '<p>E = mc<sup>2</sup>,H<sub>2</sub>O。選取文字後點 toolbar 的上標 / 下標。</p>')const extensions = [Superscript, Subscript]const scriptHandlers = { superscript: { canExecute: (e: Editor) => e.can().toggleSuperscript(), execute: (e: Editor) => e.chain().focus().toggleSuperscript(), isActive: (e: Editor) => e.isActive('superscript') }, subscript: { canExecute: (e: Editor) => e.can().toggleSubscript(), execute: (e: Editor) => e.chain().focus().toggleSubscript(), isActive: (e: Editor) => e.isActive('subscript') }}const items: EditorToolbarItem[][] = [ ...defaultEditorItems, [ { kind: 'superscript', icon: IconSuperscript, tooltip: '上標' }, { kind: 'subscript', icon: IconSubscript, tooltip: '下標' } ]]</script><template> <admin-rich-editor v-slot="{ editor, handlers }" v-model="value" :extensions="extensions" :handlers="scriptHandlers" :ui="{ base: cn(baseProseClass, starterKitProseClass) }" > <admin-editor-toolbar :editor :handlers="handlers" :items="items" /> </admin-rich-editor></template>handler 直接以 inline 物件註冊,無任何內部依賴,可原樣複製:
import type { Editor } from '@tiptap/core'import Subscript from '@tiptap/extension-subscript'import Superscript from '@tiptap/extension-superscript'const extensions = [Superscript, Subscript]const scriptHandlers = { superscript: { canExecute: (e: Editor) => e.can().toggleSuperscript(), execute: (e: Editor) => e.chain().focus().toggleSuperscript(), isActive: (e: Editor) => e.isActive('superscript') }, subscript: { canExecute: (e: Editor) => e.can().toggleSubscript(), execute: (e: Editor) => e.chain().focus().toggleSubscript(), isActive: (e: Editor) => e.isActive('subscript') }}<admin-rich-editor v-slot="{ editor }" v-model="value" :extensions="extensions" :handlers="scriptHandlers"> <admin-editor-toolbar :editor :items="items" /></admin-rich-editor>toolbar item 以 kind 對應 handler,經 rich-editor context 派發:
const items = [ ...defaultEditorItems, [ { kind: 'superscript', icon: IconSuperscript, tooltip: '上標' }, { kind: 'subscript', icon: IconSubscript, tooltip: '下標' } ]]注入後 toggleSuperscript() / toggleSubscript() command 可用(官方 extension 另附 Mod-. / Mod-, 快捷鍵);toolbar 按鈕依當前 mark 高亮。
API 參考
@tiptap/extension-superscript / @tiptap/extension-subscript 套件 API 詳見 tiptap superscript 官方文件與 subscript 官方文件。
注意事項
- 不互斥:上標與下標可同時套用於同一段文字。若需互斥,自行以
Superscript.extend({ excludes: 'subscript' })(及對稱設定)於 schema 層處理。 - 不支援 markdown 模式:官方 extension 不含 markdown tokenizer / serializer,
content-type="markdown"下 sup / sub 不會被序列化,來回轉換會遺失。此情境需自寫帶markdownTokenizer的 custom mark。