編輯器
Editor Font Size
toolbar 字級控制:−/下拉/+。
安裝
Terminal
pnpm dlx shadcn-vue add @admin/editor-font-sizepnpm add @tiptap/extension-text-styleimport { FontSize, TextStyle } from '@tiptap/extension-text-style'import { AdminEditorFontSize } from '@/registry/admin/ui/editor-font-size'含 toolbar 字級控制(− stepper、數值下拉、+ stepper,共用同一狀態);字級能力來自 tiptap TextStyle/FontSize(@tiptap/extension-text-style),需自行注入(見下方用法)。
用法
加入字級需三個步驟:在 :extensions 注入 [TextStyle, FontSize]、在 toolbar items 加入一個指定 slot: 'fontSize' 的項目、在 toolbar 的 #fontSize slot 放入 <AdminEditorFontSize>。
<script setup lang="ts">import type { JSONContent } from '@tiptap/core'import type { EditorToolbarItem } from '@/components/admin/editor-toolbar'import { IconTextResize } from '@tabler/icons-vue'import { FontSize, TextStyle } from '@tiptap/extension-text-style'import { ref } from 'vue'import { cn } from '@/lib/utils'import { baseProseClass } from '@/components/admin/editor'import { AdminEditorFontSize } from '@/components/admin/editor-font-size'import { AdminEditorToolbar, defaultEditorItems } from '@/components/admin/editor-toolbar'import { AdminRichEditor, starterKitProseClass } from '@/components/admin/rich-editor'const value = ref<JSONContent | string>('<p>選取文字後,用 toolbar 的 −/下拉/+ 調整字級。</p>')// 字級需自行注入官方 extension:FontSize 依賴 TextStyle,兩者都要const extensions = [TextStyle, FontSize]// 字級為 kindless slot item:靠具名 slot 自畫,不綁 handlerconst items: EditorToolbarItem[][] = [ ...defaultEditorItems, [{ slot: 'fontSize', icon: IconTextResize, label: '字級', tooltip: { text: '字級' } }]]</script><template> <admin-rich-editor v-slot="{ editor, handlers }" v-model="value" :extensions="extensions" :ui="{ base: cn(baseProseClass, starterKitProseClass) }" > <admin-editor-toolbar :editor :handlers="handlers" :items="items"> <template #fontSize> <admin-editor-font-size :editor="editor" /> </template> </admin-editor-toolbar> </admin-rich-editor></template><script setup lang="ts">import type { EditorToolbarItem } from '@/registry/admin/ui/editor-toolbar'import { IconTextResize } from '@tabler/icons-vue'import { FontSize, TextStyle } from '@tiptap/extension-text-style'import { ref } from 'vue'import { AdminEditorFontSize } from '@/registry/admin/ui/editor-font-size'import { AdminEditorToolbar, defaultEditorItems } from '@/registry/admin/ui/editor-toolbar'import { AdminRichEditor } from '@/registry/admin/ui/rich-editor'const value = ref('<p>內容</p>')// 自行注入官方 extension(FontSize 依賴 TextStyle)const extensions = [TextStyle, FontSize]// 字級是 kindless slot item:由具名 slot 渲染,不綁 handlerconst items: EditorToolbarItem[][] = [ ...defaultEditorItems, [{ slot: 'fontSize', icon: IconTextResize, label: '字級', tooltip: { text: '字級' } }]]</script><template> <admin-rich-editor v-slot="{ editor }" v-model="value" :extensions="extensions"> <admin-editor-toolbar :items="items"> <template #fontSize> <admin-editor-font-size :editor="editor" /> </template> </admin-editor-toolbar> </admin-rich-editor></template>無障礙:改用 rem 級距
預設級距以 px 寫入 inline font-size,不會隨使用者瀏覽器的根字級設定縮放。要符合無障礙需求,改透過 :sizes 傳入以 rem 為值的級距:label 仍是給人看的數字、value 寫 rem,套用後即隨根字級縮放。同時以 base-value 指定未設定字級時的起算基準(預設 '16px',rem 級距要改傳如 '1rem',否則基準查不到會 fallback 至級距中點)。
<script setup lang="ts">import type { JSONContent } from '@tiptap/core'import type { FontSizeOption } from '@/components/admin/editor-font-size'import type { EditorToolbarItem } from '@/components/admin/editor-toolbar'import { IconTextResize } from '@tabler/icons-vue'import { FontSize, TextStyle } from '@tiptap/extension-text-style'import { ref } from 'vue'import { cn } from '@/lib/utils'import { baseProseClass } from '@/components/admin/editor'import { AdminEditorFontSize } from '@/components/admin/editor-font-size'import { AdminEditorToolbar, defaultEditorItems } from '@/components/admin/editor-toolbar'import { AdminRichEditor, starterKitProseClass } from '@/components/admin/rich-editor'const value = ref<JSONContent | string>('<p>a11y 版:字級以 rem 寫入,隨使用者瀏覽器根字級縮放。</p>')const extensions = [TextStyle, FontSize]// a11y:label 仍給人看的數字(以 16px 根字級換算),value 寫 remconst remSizes: FontSizeOption[] = [ { label: '12', value: '0.75rem' }, { label: '14', value: '0.875rem' }, { label: '16', value: '1rem' }, { label: '18', value: '1.125rem' }, { label: '20', value: '1.25rem' }, { label: '24', value: '1.5rem' }, { label: '30', value: '1.875rem' }, { label: '36', value: '2.25rem' }]const items: EditorToolbarItem[][] = [ ...defaultEditorItems, [{ slot: 'fontSize', icon: IconTextResize, label: '字級', tooltip: { text: '字級(rem)' } }]]</script><template> <admin-rich-editor v-slot="{ editor, handlers }" v-model="value" :extensions="extensions" :ui="{ base: cn(baseProseClass, starterKitProseClass) }" > <admin-editor-toolbar :editor :handlers="handlers" :items="items"> <template #fontSize> <admin-editor-font-size base-value="1rem" :editor="editor" :sizes="remSizes" /> </template> </admin-editor-toolbar> </admin-rich-editor></template>import type { FontSizeOption } from '@/registry/admin/ui/editor-font-size'// label 是給人看的數字(以 16px 根字級換算),value 寫 remconst remSizes: FontSizeOption[] = [ { label: '14', value: '0.875rem' }, { label: '16', value: '1rem' }, { label: '18', value: '1.125rem' }, { label: '20', value: '1.25rem' }]<admin-editor-font-size base-value="1rem" :editor="editor" :sizes="remSizes" />API 參考
admin-editor-font-size
Props
| 名稱 | 型別 | 預設值 | 說明 |
|---|---|---|---|
editor* | Editor | — | — |
sizes | FontSizeOption[] | undefined | defaultFontSizes | 級距清單與順序(需由小到大);預設 `defaultFontSizes`(12~36 px) |
baseValue | string | undefined | DEFAULT_BASE_VALUE | unset 時 stepper 的起算基準,需與 `sizes` 內某個 `value` 嚴格相等;預設 `'16px'`,rem 級距請改傳如 `'1rem'` |
disabled | boolean | undefined | false | — |
class | unknown | — | — |
* 代表必填
注意事項
- extension 必須在建立編輯器時注入:
TextStyle與FontSize無法於編輯器建立後補上,未注入時字級控制不會生效。 - 級距需由小到大:
sizes陣列需依值遞增排列,stepper 的上/下一級與到頂到底停用皆依此順序判定。 - 未設定字級時顯示「預設」:游標所在文字未套字級時,下拉 trigger 顯示「預設」;選單頂端的「預設」項會移除 inline
font-size,回退 CSS 繼承。 - px vs rem:預設 px 不隨瀏覽器字級縮放;需 a11y 請改用 rem 級距並搭配
base-value(見上方)。
更新紀錄
- feat: 新增 tiptap editor 元件系列273a0d0