skills/xiaolai/vmark/tiptap-editor

tiptap-editor

SKILL.md

Tiptap Editor API Patterns

Overview

This skill documents proper Tiptap API usage patterns for vmark development. It helps distinguish when to use Tiptap's high-level API vs direct ProseMirror access.

When to Use Tiptap API

Always prefer Tiptap API for:

  • Format commands (bold, italic, underline, etc.)
  • Block type changes (heading, paragraph, code block)
  • List operations (bullet, ordered, toggle, indent/outdent)
  • Table operations via Tiptap table extension
  • Content insertion and replacement
  • Editor state queries (isActive, getAttributes)

Tiptap patterns to use:

// Direct commands
editor.commands.toggleBold()
editor.commands.setHeading({ level: 2 })
editor.commands.setContent(doc, { emitUpdate: false })

// Chained commands (for multiple operations)
editor.chain().focus().setHeading({ level: 2 }).run()
editor.chain().focus().toggleMark("underline").run()

// State queries
editor.isActive("blockquote")
editor.isActive("heading", { level: 2 })
editor.getAttributes("link")

When Direct ProseMirror is Appropriate

Use ProseMirror directly for:

  • Markdown conversion layer (proseMirrorToMdast.ts, mdastToProseMirror.ts)
  • Multi-cursor/selection subclassing (MultiSelection.ts)
  • Custom node views
  • Low-level transaction manipulation
  • Schema-level operations

Known Issues in vmark

1. cursorHandlers.ts Block Boundary Issue

src/hooks/mcpBridge/cursorHandlers.ts uses doc.textContent which flattens the document and loses block boundaries. The correct approach is to use $pos helpers:

// WRONG - loses block structure
const text = doc.textContent;

// RIGHT - respects block boundaries
const $pos = doc.resolve(from);
const currentNode = $pos.parent;
const blockStart = $pos.before($pos.depth);
const blockEnd = $pos.after($pos.depth);

2. Cursor Sync Drift After WYSIWYG Edits

sourceLine attributes are only set on initial parse. After WYSIWYG edits that add/remove blocks, line numbers no longer match the source. This is a known limitation.

3. HtmlNodeView.ts Store Issue

src/plugins/markdownArtifacts/HtmlNodeView.ts writes cursor info to wrong store.

References

  • references/patterns.md - Detailed API patterns and $pos usage
  • references/examples.md - Real code examples from vmark codebase

Workflow

  1. Identify operation type (format, block, selection, traversal)
  2. Check if Tiptap has a built-in command for it
  3. Use editor.commands.xxx() for single operations
  4. Use editor.chain().focus().xxx().run() when focus is needed or chaining
  5. For node traversal, use doc.resolve(pos) to get $pos helpers
  6. For state queries, use editor.isActive() or editor.getAttributes()
Weekly Installs
89
Repository
xiaolai/vmark
GitHub Stars
150
First Seen
Feb 15, 2026
Installed on
github-copilot87
codex87
opencode87
gemini-cli86
cursor86
kimi-cli84