添加文本标记按钮

Available for free

一个用于切换文本标记的按钮,如粗体、斜体、下划线等。

安装

您可以通过 Tiptap CLI(适用于 Vite 或 Next.js)添加该组件。

npx @tiptap/cli@latest add mark-button

组件

<MarkButton />

一个预构建的 React 组件,用于切换特定标记类型的文本格式。

用法

import { useEditor, EditorContent, EditorContext } from '@tiptap/react'
import { StarterKit } from '@tiptap/starter-kit'
import { Underline } from '@tiptap/extension-underline'
import { Superscript } from '@tiptap/extension-superscript'
import { Subscript } from '@tiptap/extension-subscript'
import { MarkButton } from '@/components/tiptap-ui/mark-button'

import '@/components/tiptap-node/code-block-node/code-block-node.scss'
import '@/components/tiptap-node/paragraph-node/paragraph-node.scss'

export default function MyEditor() {
  const editor = useEditor({
    immediatelyRender: false,
    extensions: [StarterKit, Underline, Superscript, Subscript],
    content: `
        <p>
            <strong>粗体</strong> 用于强调,使用 <code>**</code> 或 <code>⌘+B</code> 或 <code>B</code> 按钮。
        </p>
        <p>
            <em>斜体</em> 用于细微差别,使用 <code>*</code> 或 <code>⌘+I</code> 或 <code>I</code> 按钮。
        </p>
        <p>
            <s>删除线</s> 用于显示修订,使用 <code>~~</code> 或 <code>~~S~~</code> 按钮。
        </p>
        <p>
            <code>代码</code> 用于代码片段,使用 <code>:</code> 或 <code>⌘+⇧+C</code> 或 <code>C</code> 按钮。
        </p>
        <p>
            <u>下划线</u> 用于强调,使用 <code>⌘+U</code> 或 <code>U</code> 按钮。
        </p>
        <p>
            <sup>上标</sup> 用于脚注,使用 <code>⌘+.</code> 或 <code>.</code> 按钮。
        </p>
        <p>
            <sub>下标</sub> 用于化学公式,使用 <code>⌘+,</code> 或 <code>,</code> 按钮。
        </p>
        `,
  })

  return (
    <EditorContext.Provider value={{ editor }}>
      <MarkButton
        editor={editor}
        type="bold"
        text="Bold"
        hideWhenUnavailable={true}
        showShortcut={true}
        onToggled={() => console.log('Mark toggled!')}
      />
      <MarkButton type="italic" />
      <MarkButton type="strike" />
      <MarkButton type="code" />
      <MarkButton type="underline" />
      <MarkButton type="superscript" />
      <MarkButton type="subscript" />

      <EditorContent editor={editor} role="presentation" />
    </EditorContext.Provider>
  )
}

属性

名称类型默认值描述
editorEditor | nullnullTiptap 编辑器实例
type'bold' | 'italic' | 'strike' | 'code' | 'underline' | 'superscript' | 'subscript'必填要切换的标记类型
textstring-显示在图标旁边的文本
hideWhenUnavailablebooleanfalse如果不可用,按钮是否隐藏
onToggled() => void-成功切换标记后触发的回调
showShortcutbooleanfalse是否显示键盘快捷键提示徽章

钩子

useMark()

一个自定义钩子,可以让你构建自己的标记按钮,完全控制渲染和行为。

用法

import { useMark } from '@/components/tiptap-ui/mark-button'
import { parseShortcutKeys } from '@/lib/tiptap-utils'
import { Badge } from '@/components/tiptap-ui-primitive/badge'

function MyMarkButton() {
  const { isVisible, isActive, canToggle, handleMark, label, shortcutKeys, Icon } = useMark({
    editor: myEditor,
    type: 'bold',
    hideWhenUnavailable: true,
    onToggled: () => console.log('Mark toggled!'),
  })

  if (!isVisible) return null

  return (
    <button
      onClick={handleMark}
      disabled={!canToggle}
      aria-label={label}
      aria-pressed={isActive}
      title={label}
    >
      <Icon />
      {label}
      {shortcutKeys && <Badge>{parseShortcutKeys({ shortcutKeys })}</Badge>}
    </button>
  )
}

属性

名称类型默认值描述
editorEditor | nullundefinedTiptap 编辑器实例
typeMark必填要切换的标记类型
hideWhenUnavailablebooleanfalse当标记不可切换时是否隐藏按钮
onToggled() => voidundefined成功切换标记后触发的回调

返回值

名称类型描述
isVisibleboolean按钮是否应被渲染
isActiveboolean当前是否激活了该标记类型
canToggleboolean是否允许切换该标记
handleMark() => boolean切换标记的函数,返回是否成功
labelstring格式化后的显示名称(例如“Bold”,“Italic”)
shortcutKeysstring该标记的键盘快捷键
IconReact.FC标记按钮的图标组件

工具函数

canToggleMark(editor, type)

检查当前编辑器状态下指定的标记类型是否可以切换。

参数:

  • editor: Editor | null - Tiptap 编辑器实例
  • type: Mark - 要检查的标记类型

返回: boolean - 是否可以切换该标记

import { canToggleMark } from '@/components/tiptap-ui/mark-button'

const canToggle = canToggleMark(editor, 'bold') // 检查是否可以切换粗体

toggleMark(editor, type)

程序化切换指定类型的标记格式。

参数:

  • editor: Editor | null - Tiptap 编辑器实例
  • type: Mark - 要切换的标记类型

返回: boolean - 切换是否成功

import { toggleMark } from '@/components/tiptap-ui/mark-button'

const success = toggleMark(editor, 'italic')
if (success) {
  console.log('斜体标记切换成功!')
}

isMarkActive(editor, type)

检查指定标记类型当前是否处于激活状态。

参数:

  • editor: Editor | null - Tiptap 编辑器实例
  • type: Mark - 要检查的标记类型

返回: boolean - 标记是否激活

import { isMarkActive } from '@/components/tiptap-ui/mark-button'

const active = isMarkActive(editor, 'underline')

getFormattedMarkName(type)

获取标记类型的格式化显示名称。

参数:

  • type: Mark - 标记类型

返回: string - 格式化后的名称(例如 “Bold”,“Italic”)

import { getFormattedMarkName } from '@/components/tiptap-ui/mark-button'

const name = getFormattedMarkName('bold') // 返回 "Bold"
const name2 = getFormattedMarkName('superscript') // 返回 "Superscript"

shouldShowButton(props)

根据编辑器状态和配置确定是否应显示标记按钮。

参数:

  • props: object
    • editor: Editor | null - Tiptap 编辑器实例
    • type: Mark - 标记类型
    • hideWhenUnavailable: boolean - 不可用时是否隐藏按钮

返回: boolean - 是否应显示按钮

import { shouldShowButton } from '@/components/tiptap-ui/mark-button'

const shouldShow = shouldShowButton({
  editor,
  type: 'bold',
  hideWhenUnavailable: true,
})

键盘快捷键

每种标记类型都有自己的键盘快捷键:

  • Cmd/Ctrl + B:切换粗体
  • Cmd/Ctrl + I:切换斜体
  • Cmd/Ctrl + U:切换下划线
  • Cmd/Ctrl + Shift + S:切换删除线
  • Cmd/Ctrl + E:切换代码
  • Cmd/Ctrl + .:切换上标
  • Cmd/Ctrl + ,:切换下标

当使用 <MarkButton /> 组件或 useMark() 钩子时,快捷键会自动注册。

依赖项

  • @tiptap/react - 核心 Tiptap React 集成
  • @tiptap/starter-kit - 包含标记支持的基础 Tiptap 扩展
  • @tiptap/extension-underline - 下划线标记扩展
  • @tiptap/extension-superscript - 上标标记扩展
  • @tiptap/extension-subscript - 下标标记扩展
  • react-hotkeys-hook - 键盘快捷键管理

使用的参考组件

  • use-tiptap-editor(钩子)
  • button(原语)
  • badge(原语)
  • tiptap-utils(库)
  • bold-icon(图标)
  • italic-icon(图标)
  • underline-icon(图标)
  • strike-icon(图标)
  • code-2-icon(图标)
  • superscript-icon(图标)
  • subscript-icon(图标)