編輯器

Editor Font Size

參考
toolbar 字級控制:−/下拉/+。

安裝

Terminal
pnpm dlx shadcn-vue add @admin/editor-font-sizepnpm add @tiptap/extension-text-style
import { 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——
sizesFontSizeOption[] | undefineddefaultFontSizes級距清單與順序(需由小到大);預設 `defaultFontSizes`(12~36 px)
baseValuestring | undefinedDEFAULT_BASE_VALUEunset 時 stepper 的起算基準,需與 `sizes` 內某個 `value` 嚴格相等;預設 `'16px'`,rem 級距請改傳如 `'1rem'`
disabledboolean | undefinedfalse—
classunknown——

* 代表必填

注意事項

  • extension 必須在建立編輯器時注入:TextStyle 與 FontSize 無法於編輯器建立後補上,未注入時字級控制不會生效。
  • 級距需由小到大:sizes 陣列需依值遞增排列,stepper 的上/下一級與到頂到底停用皆依此順序判定。
  • 未設定字級時顯示「預設」:游標所在文字未套字級時,下拉 trigger 顯示「預設」;選單頂端的「預設」項會移除 inline font-size,回退 CSS 繼承。
  • px vs rem:預設 px 不隨瀏覽器字級縮放;需 a11y 請改用 rem 級距並搭配 base-value(見上方)。

更新紀錄

  • feat: 新增 tiptap editor 元件系列273a0d0