Now Available: Notion-like editor templateNotion-style editor for Tiptap Cloud

Mark Button

Available for free

A fully accessible mark button for Tiptap editors. Easily toggle text formatting marks like bold, italic, strikethrough, and more with keyboard shortcut support and flexible customization options.

Installation

Add the component via the Tiptap CLI:

npx @tiptap/cli@latest add mark-button

Components

<MarkButton />

A prebuilt React component that toggles mark formatting for a specific mark type.

Usage

import { EditorContent, EditorContext, useEditor } 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>Bold</strong> for emphasis with <code>**</code> or <code>⌘+B</code> or the <code>B</code> button.
        </p>
        <p>
            <em>Italic</em> for subtle nuances with <code>*</code> or <code>⌘+I</code> or the <code>I</code> button.
        </p>
        <p>
            <s>Strikethrough</s> to show revisions with <code>~~</code> or the <code>~~S~~</code> button.
        </p>
        <p>
            <code>Code</code> for code snippets with <code>:</code> or <code>⌘+⇧+C</code> or the <code>C</code> button.
        </p>
        <p>
            <u>Underline</u> for emphasis with <code>⌘+U</code> or the <code>U</code> button.
        </p>
        <p>
            <sup>Superscript</sup> for footnotes with <code>⌘+.</code> or the <code>.</code> button.
        </p>
        <p>
            <sub>Subscript</sub> for chemical formulas with <code>⌘+,</code> or the <code>,</code> button.
        </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>
  )
}

Props

NameTypeDefaultDescription
editorEditor | nullundefinedThe Tiptap editor instance
typeMarkrequiredThe type of mark ("bold", "italic", "strike", etc.)
textstringundefinedOptional text label for the button
hideWhenUnavailablebooleanfalseHides the button when mark toggle is not available
onToggled() => voidundefinedCallback fired after a successful mark toggle
showShortcutbooleanfalseShows a keyboard shortcut badge (if available)

Hooks

useMark()

A custom hook to build your own mark button with full control over rendering and behavior.

Usage

function MyMarkButton() {
  const { isVisible, isActive, canToggle, handleMark, label, shortcutKeys, Icon, formattedName } =
    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={formattedName}
    >
      <Icon />
      {formattedName}
      {shortcutKeys && <Badge>{parseShortcutKeys({ shortcutKeys })}</Badge>}
    </button>
  )
}

Props

NameTypeDefaultDescription
editorEditor | nullundefinedThe Tiptap editor instance
typeMarkrequiredThe type of mark to toggle
hideWhenUnavailablebooleanfalseHides the button if mark toggle is not available
onToggled() => voidundefinedCallback fired after a successful mark toggle

Return Values

NameTypeDescription
isVisiblebooleanWhether the button should be rendered
isActivebooleanIf the specific mark type is currently active
canTogglebooleanIf the mark toggle is currently allowed
handleMark() => booleanFunction to toggle mark formatting
labelstringAccessible label text for the button
shortcutKeysstringKeyboard shortcut for the specific mark type
IconReact.FCIcon component for the mark button
formattedNamestringFormatted display name (e.g., "Bold", "Italic")

Utilities

canToggleMark(editor, type)

Checks if a specific mark type can be toggled in the current editor state.

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

const canToggle = canToggleMark(editor, 'bold') // Check if bold can be toggled

toggleMark(editor, type)

Programmatically toggles mark formatting for the specified type.

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

const success = toggleMark(editor, 'italic')
if (success) {
  console.log('Italic mark toggled successfully!')
}

isMarkActive(editor, type)

Checks if a specific mark type is currently active.

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

const active = isMarkActive(editor, 'underline')

getFormattedMarkName(type)

Gets the formatted display name for a mark type.

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

const name = getFormattedMarkName('bold') // Returns "Bold"
const name2 = getFormattedMarkName('strikethrough') // Returns "Strikethrough"

Keyboard Shortcuts

Each mark type has its own keyboard shortcut:

  • Cmd/Ctrl + B: Toggle bold
  • Cmd/Ctrl + I: Toggle italic
  • Cmd/Ctrl + U: Toggle underline
  • Cmd/Ctrl + Shift + S: Toggle strikethrough
  • Cmd/Ctrl + E: Toggle code
  • Cmd/Ctrl + .: Toggle superscript
  • Cmd/Ctrl + ,: Toggle subscript

The shortcuts are automatically registered when using either the <MarkButton /> component or the useMark() hook.

Requirements

Dependencies

  • @tiptap/react - Core Tiptap React integration
  • @tiptap/starter-kit - Basic Tiptap extensions including mark support
  • @tiptap/extension-underline - Underline mark extension
  • @tiptap/extension-superscript - Superscript mark extension
  • @tiptap/extension-subscript - Subscript mark extension
  • react-hotkeys-hook - Keyboard shortcut management

Referenced Components

  • use-tiptap-editor (hook)
  • button (primitive)
  • badge (primitive)
  • tiptap-utils (lib)
  • bold-icon (icon)
  • italic-icon (icon)
  • underline-icon (icon)
  • strike-icon (icon)
  • code-2-icon (icon)
  • superscript-icon (icon)
  • subscript-icon (icon)