@veltdev/tiptap-velt-comments
Version:
Tiptap Extension to add Google Docs-style overlay comments to your Tiptap editor. Works with the Velt Collaboration SDK.
239 lines (226 loc) • 7.29 kB
TypeScript
import { CommentAnnotation } from '@veltdev/types';
import { Mark } from '@tiptap/core';
/**
* Common type definitions shared across the entire codebase.
* These types are SDK-agnostic and represent domain concepts.
*/
/**
* Context object for comment annotations.
* Contains text editor configuration and any additional context data.
*/
interface CommentAnnotationContext {
textEditorConfig?: {
text: string;
occurrence: number;
editorId?: string;
targetTextNodeId?: string;
};
[key: string]: unknown;
}
/**
* Request interface for addComment function.
* Matches legacy AddCommentRequest interface.
*/
interface AddCommentRequest {
editorId?: string;
editor: unknown;
context?: CommentAnnotationContext;
}
/**
* Request interface for renderComments function.
* Matches legacy RenderCommentsRequest interface.
*/
interface RenderCommentsRequest {
editor: unknown;
editorId?: string;
commentAnnotations?: CommentAnnotation[];
}
/**
* Add comment feature module.
*
* Purpose: End-to-end add comment orchestration.
* Orchestrates adapters and core to implement the add comment flow.
*
* Key responsibilities:
* - Get Velt comment element
* - Extract selection context from editor
* - Create comment via Velt SDK
* - Apply mark to editor document
* - Update state with annotation data
*
* Dependencies:
* - adapters/velt.ts (for Velt SDK calls)
* - adapters/host/doc.ts (for selection extraction, editor setup, and selection reset)
* - adapters/host/marks.ts (for mark application)
* - adapters/host/storage.ts (for mark application configuration)
* - core/state.ts (for state updates)
* - types/common.ts (for CommentAnnotationContext)
*
* IMPORTANT: This module MUST NOT import editor or Velt types directly.
* All SDK access goes through adapters.
*/
/**
* Adds a comment to the currently selected text in the editor.
*
* This is the main entry point for adding comments. It handles:
* - Extracting selection context from the editor
* - Creating the comment via Velt SDK
* - Applying marks to the editor if configured
* - Updating state with annotation data
*
* @param request - Object containing editorId (optional), editor, and context (optional)
* @returns Promise that resolves when the comment is added (or fails silently)
*
* @example
* ```typescript
* // Simple usage
* await addComment({ editor });
*
* // With editor ID
* await addComment({ editorId: 'my-editor', editor });
*
* // With custom context
* await addComment({
* editorId: 'my-editor',
* editor,
* context: {
* userId: 'user123',
* metadata: { source: 'web-app' }
* }
* });
* ```
*
* @remarks
* - Requires text to be selected in the editor
* - Requires Velt SDK to be available (window.Velt)
* - Marks are only applied if persistVeltMarks is FALSE in extension config (matching legacy behavior)
* - Fails silently if Velt SDK is unavailable or selection is invalid
*/
declare function addComment({ editorId, editor, context: clientContext, }: AddCommentRequest): Promise<void>;
/**
* Render comments feature module.
*
* Purpose: Public API entry point for rendering comment annotations.
* Orchestrates state updates, subscriptions, and delegates to commentRenderer.
*
* Key responsibilities:
* - Update state with new annotations
* - Subscribe to selected annotations from Velt
* - Delegate rendering logic to commentRenderer
*
* Dependencies:
* - adapters/velt.ts (for Velt SDK subscription)
* - adapters/host/doc.ts (for editor setup)
* - core/state.ts (for state management)
* - features/commentRenderer.ts (for rendering logic)
* - types/velt.ts (for CommentAnnotation)
* - utils/console.ts (for logging)
*
* IMPORTANT: This module MUST NOT import editor or Velt types directly.
* All SDK access goes through adapters.
*/
/**
* Renders comment annotations as marks in the editor.
*
* This function renders comment annotations as visual marks in the editor.
* It filters annotations for the specific editor and applies marks accordingly.
*
* @param request - Object containing editor, editorId (optional), and commentAnnotations (optional)
*
* @example
* ```typescript
* // Simple usage
* renderComments({ editor });
*
* // With editor ID
* renderComments({ editorId: 'my-editor', editor });
*
* // With annotations
* renderComments({
* editorId: 'my-editor',
* editor,
* commentAnnotations: [
* {
* annotationId: 'ann-123',
* context: {
* textEditorConfig: {
* text: 'Hello world',
* occurrence: 1,
* editorId: 'my-editor'
* }
* }
* }
* ]
* });
* ```
*
* @remarks
* - Only annotations with matching editorId are rendered
* - Automatically subscribes to selected annotations changes
* - Filters out terminal/resolved comments unless they're selected
* - Removes marks when comments become resolved
* - Re-applies marks when resolved comments are selected
*/
declare const renderComments: ({ editor, editorId, commentAnnotations, }: RenderCommentsRequest) => void;
/**
* Host adapter type definitions.
* These types represent editor-specific concepts.
* NOTE: This is the ONLY place where editor-specific types should be defined.
*/
/**
* Extension configuration options for VeltCommentsExtension.
*/
interface VeltCommentsExtensionConfig {
HTMLAttributes: Record<string, unknown>;
persistVeltMarks: boolean;
editorId?: string;
extensionName?: string;
}
/**
* Core extension module.
*
* Purpose: Extension factory that wires everything together.
* This is the ONLY place where Mark.create() is called.
*
* Key responsibilities:
* - Create Mark extension
* - Wire up transaction handler to updateContent feature
* - Register editor in registry on extension creation
* - Expose commands and storage
*
* Dependencies: adapters/host/marks.ts, features/updateContent.ts, core/registry.ts
*/
/**
* Creates the Mark extension.
* This is the main extension that integrates Velt comments with the editor.
*/
declare const VeltCommentsExtension: Mark<VeltCommentsExtensionConfig, any>;
/**
* Public API for Tiptap-Velt Comments extension.
*
* This module exports the public API surface for the v2 implementation.
*
* @example
* ```typescript
* import { TiptapVeltComments, addComment, renderComments } from 'tiptap-velt-comments';
*
* // Use the extension
* const editor = new Editor({
* extensions: [TiptapVeltComments.configure({ editorId: 'my-editor' })],
* });
*
* // Add a comment
* await addComment({ editorId: 'editor-id', editor, context: { customData: 'value' } });
*
* // Render existing comments
* renderComments({ editorId: 'editor-id', editor, commentAnnotations: annotations });
* ```
*/
declare module '@tiptap/core' {
interface Commands<ReturnType> {
tiptapVeltComments: {
setVeltComment: (annotationId?: string, multiThreadAnnotationId?: string, from?: number, to?: number) => ReturnType;
};
}
}
export { AddCommentRequest, CommentAnnotationContext, RenderCommentsRequest, VeltCommentsExtension as TiptapVeltComments, VeltCommentsExtensionConfig as TiptapVeltCommentsOptions, addComment, renderComments };