CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tiptap--vue-3

Vue 3 components and composables for building rich text editors with tiptap

Pending
Overview
Eval results
Files

editor-management.mddocs/

Editor Management

Core editor functionality with Vue 3 reactive state integration for building rich text editors.

Capabilities

Editor Class

The Vue 3-specific editor class that extends the core tiptap editor with reactive state management.

/**
 * Vue 3 editor class with reactive state management
 * Extends the core tiptap editor with Vue-specific features
 */
class Editor extends CoreEditor {
  constructor(options?: Partial<EditorOptions>);
  
  /** Get the current reactive editor state */
  get state(): EditorState;
  
  /** Get the reactive extension storage */
  get storage(): Storage;
  
  /** Vue content component reference */
  contentComponent: ContentComponent | null;
  
  /** Vue app context for provide/inject */
  appContext: AppContext | null;
  
  /**
   * Register a ProseMirror plugin with reactive state updates
   * @param plugin - The plugin to register
   * @param handlePlugins - Optional plugin handling function
   * @returns Updated editor state
   */
  registerPlugin(
    plugin: Plugin,
    handlePlugins?: (newPlugin: Plugin, plugins: Plugin[]) => Plugin[]
  ): EditorState;
  
  /**
   * Unregister a ProseMirror plugin with reactive state updates
   * @param nameOrPluginKey - Plugin name or key to unregister
   * @returns Updated editor state or undefined
   */
  unregisterPlugin(nameOrPluginKey: string | PluginKey): EditorState | undefined;
}

interface ContentComponent {
  ctx: ComponentPublicInstance;
}

Key Features:

  • Reactive state using Vue's debounced ref system
  • Automatic Vue app context integration
  • Plugin registration with reactive updates
  • markRaw wrapping for performance optimization

Usage Examples:

import { Editor } from "@tiptap/vue-3";
import StarterKit from "@tiptap/starter-kit";

// Create editor instance
const editor = new Editor({
  content: '<p>Hello World!</p>',
  extensions: [StarterKit],
  onUpdate: ({ editor }) => {
    console.log('Content updated:', editor.getHTML());
  },
});

// Access reactive state
console.log(editor.state.doc.textContent);

// Register plugins dynamically
import { Plugin } from "@tiptap/pm/state";

const customPlugin = new Plugin({
  key: new PluginKey('custom'),
  // plugin implementation
});

editor.registerPlugin(customPlugin);

useEditor Composable

Vue 3 composition API hook for creating and managing editor instances with automatic lifecycle management.

/**
 * Vue 3 composable for creating and managing editor instances
 * Handles mounting, unmounting, and cleanup automatically
 * @param options - Editor configuration options
 * @returns Reactive reference to editor instance
 */
function useEditor(options?: Partial<EditorOptions>): Ref<Editor | undefined>;

Lifecycle Management:

  • Creates editor instance on component mount
  • Clones DOM content before cleanup to prevent data loss
  • Destroys editor instance on component unmount
  • Returns reactive reference that updates with editor state

Usage Examples:

<template>
  <div v-if="editor">
    <EditorContent :editor="editor" />
  </div>
</template>

<script setup>
import { useEditor, EditorContent } from "@tiptap/vue-3";
import StarterKit from "@tiptap/starter-kit";

// Basic usage
const editor = useEditor({
  content: '<p>Initial content</p>',
  extensions: [StarterKit],
});

// With reactive options
import { ref, watch } from 'vue';

const content = ref('<p>Dynamic content</p>');
const editable = ref(true);

const editor = useEditor({
  content: content.value,
  editable: editable.value,
  extensions: [StarterKit],
  onUpdate: ({ editor }) => {
    content.value = editor.getHTML();
  },
});

// Watch for option changes
watch([content, editable], ([newContent, newEditable]) => {
  if (editor.value) {
    editor.value.commands.setContent(newContent);
    editor.value.setEditable(newEditable);
  }
});
</script>

Editor Configuration

interface EditorOptions {
  /** Initial content as HTML string, JSON object, or Node */
  content?: Content;
  
  /** Array of extensions to use */
  extensions?: Extensions;
  
  /** Whether the editor is editable */
  editable?: boolean;
  
  /** Auto-focus behavior */
  autofocus?: FocusPosition | boolean;
  
  /** Enable input rules */
  enableInputRules?: boolean;
  
  /** Enable paste rules */
  enablePasteRules?: boolean;
  
  /** Enable content parse */
  enableContentCheck?: boolean;
  
  /** Event callbacks */
  onCreate?: (props: EditorEvents['create']) => void;
  onUpdate?: (props: EditorEvents['update']) => void;
  onSelectionUpdate?: (props: EditorEvents['selectionUpdate']) => void;
  onTransaction?: (props: EditorEvents['transaction']) => void;
  onFocus?: (props: EditorEvents['focus']) => void;
  onBlur?: (props: EditorEvents['blur']) => void;
  onDestroy?: () => void;
  
  /** DOM element to mount to */
  element?: Element;
  
  /** Enable drop cursor */
  enableDropCursor?: boolean;
  
  /** Enable gap cursor */
  enableGapCursor?: boolean;
  
  /** Injectable items for dependency injection */
  injectCSS?: boolean;
  
  /** Transform pasted content */
  transformPastedText?: (text: string) => string;
  transformPastedHTML?: (html: string) => string;
  transformClipboardText?: (text: string) => string;
}

type Content = string | JSONContent | HTMLContent | null;
type Extensions = Extension[];
type FocusPosition = 'start' | 'end' | 'all' | number | boolean | null;

Install with Tessl CLI

npx tessl i tessl/npm-tiptap--vue-3

docs

core-editor-api.md

editor-management.md

index.md

menu-components.md

vue-components.md

vue-renderers.md

tile.json