CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tiptap--extension-mention

Mention extension for Tiptap rich text editor that enables @-mention functionality with customizable suggestion handling

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

index.mddocs/

Tiptap Mention Extension

The @tiptap/extension-mention package provides a mention extension for the Tiptap rich text editor framework. It enables developers to implement @-mention functionality that integrates with Tiptap's suggestion system to provide real-time mention suggestions and rendering.

Package Information

  • Package Name: @tiptap/extension-mention
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @tiptap/extension-mention @tiptap/core @tiptap/pm @tiptap/suggestion
  • Peer Dependencies: @tiptap/core, @tiptap/pm, @tiptap/suggestion

Core Imports

import { Mention } from "@tiptap/extension-mention";

For default import:

import Mention from "@tiptap/extension-mention";

For utility functions:

import { getSuggestionOptions } from "@tiptap/extension-mention";

Basic Usage

import { Editor } from "@tiptap/core";
import { Mention } from "@tiptap/extension-mention";

const editor = new Editor({
  extensions: [
    Mention.configure({
      HTMLAttributes: {
        class: "mention",
      },
      suggestion: {
        items: ({ query }) => {
          return [
            { id: 1, label: "Alice" },
            { id: 2, label: "Bob" },
            { id: 3, label: "Charlie" },
          ].filter(item => 
            item.label.toLowerCase().startsWith(query.toLowerCase())
          );
        },
        render: () => {
          // Custom render implementation
          return {
            onStart: (props) => {},
            onUpdate: (props) => {},
            onKeyDown: (props) => {},
            onExit: () => {},
          };
        },
      },
    }),
  ],
});

Architecture

The Mention extension is built around several key components:

  • Node Extension: Extends Tiptap's Node class to create inline, atomic mention nodes
  • Suggestion Integration: Seamlessly integrates with @tiptap/suggestion for real-time mention UI
  • Multi-trigger Support: Supports multiple trigger characters (@, #, etc.) simultaneously
  • Attribute System: Stores mention data (id, label, trigger char) as structured node attributes
  • Rendering Pipeline: Flexible text and HTML rendering with customizable templates
  • Keyboard Handling: Smart backspace behavior for mention deletion and navigation

Capabilities

Main Extension Class

Core mention extension that creates mention nodes in the editor.

/**
 * Main mention extension class implementing ProseMirror node functionality
 */
export const Mention: Node<MentionOptions>;

Utility Functions

Utility functions for configuring mention suggestions.

/**
 * Returns the suggestion options for a trigger of the Mention extension
 * @param options Configuration options for the suggestion
 * @returns Complete suggestion options for the trigger
 */
export function getSuggestionOptions(options: GetSuggestionOptionsOptions): SuggestionOptions;

Extension Configuration

Configure the mention extension with options for rendering, suggestions, and behavior.

interface MentionOptions<SuggestionItem = any, Attrs extends Record<string, any> = MentionNodeAttrs> {
  /** HTML attributes for mention nodes @default {} */
  HTMLAttributes: Record<string, any>;
  
  /** Function to render the text content of a mention */
  renderText: (props: {
    options: MentionOptions<SuggestionItem, Attrs>;
    node: ProseMirrorNode;
    suggestion: SuggestionOptions | null;
  }) => string;
  
  /** Function to render the HTML of a mention */
  renderHTML: (props: {
    options: MentionOptions<SuggestionItem, Attrs>;
    node: ProseMirrorNode;
    HTMLAttributes: Record<string, any>;
    suggestion: SuggestionOptions | null;
  }) => DOMOutputSpec;
  
  /** Whether to delete the trigger character with backspace @default false */
  deleteTriggerWithBackspace: boolean;
  
  /** Multiple trigger configurations for different mention types @default [] */
  suggestions: Array<Omit<SuggestionOptions<SuggestionItem, Attrs>, 'editor'>>;
  
  /** Single trigger configuration (use suggestions for multiple triggers) @default {} */
  suggestion: Omit<SuggestionOptions<SuggestionItem, Attrs>, 'editor'>;
  
  /** @deprecated Use renderText and renderHTML instead */
  renderLabel?: (props: {
    options: MentionOptions<SuggestionItem, Attrs>;
    node: ProseMirrorNode;
    suggestion: SuggestionOptions | null;
  }) => string;
}

Mention Node Attributes

Attributes stored on mention nodes for data persistence and rendering.

interface MentionNodeAttrs {
  /** Identifier for the mentioned item, stored as data-id attribute */
  id: string | null;
  
  /** Display label for the mention, stored as data-label attribute */
  label?: string | null;
  
  /** Trigger character that activated this mention, stored as data-mention-suggestion-char @default '@' */
  mentionSuggestionChar?: string;
}

interface GetSuggestionOptionsOptions {
  /** The Tiptap editor instance */
  editor: Editor;
  
  /** The suggestion options configuration provided to the Mention extension */
  overrideSuggestionOptions: Omit<SuggestionOptions, 'editor'>;
  
  /** The name of the Mention extension */
  extensionName: string;
  
  /** The character that triggers the suggestion */
  char?: string;
}

Types

External Dependencies

The extension relies on types from its peer dependencies:

  • Editor from @tiptap/core - The main Tiptap editor instance
  • DOMOutputSpec from @tiptap/pm/model - ProseMirror DOM output specification
  • ProseMirrorNode from @tiptap/pm/model - ProseMirror node with attributes
  • SuggestionOptions from @tiptap/suggestion - Configuration for suggestion functionality

Usage Examples:

import { Editor } from "@tiptap/core";
import { Mention } from "@tiptap/extension-mention";

// Basic mention setup
const editor = new Editor({
  extensions: [
    Mention.configure({
      HTMLAttributes: {
        class: "mention",
      },
      suggestion: {
        items: ({ query }) => {
          return users.filter(user => 
            user.name.toLowerCase().includes(query.toLowerCase())
          );
        },
        render: () => ({
          onStart: (props) => {
            // Show suggestion popup
          },
          onUpdate: (props) => {
            // Update suggestions
          },
          onKeyDown: (props) => {
            // Handle keyboard navigation
            if (props.event.key === "Enter") {
              return true; // Handled
            }
            return false;
          },
          onExit: () => {
            // Hide popup
          },
        }),
      },
    }),
  ],
});

// Multiple trigger characters
const editorWithMultipleTriggers = new Editor({
  extensions: [
    Mention.configure({
      suggestions: [
        {
          char: "@",
          items: ({ query }) => getUserSuggestions(query),
          render: () => createUserMentionRenderer(),
        },
        {
          char: "#",
          items: ({ query }) => getTagSuggestions(query),
          render: () => createTagMentionRenderer(),
        },
      ],
    }),
  ],
});

// Custom rendering
const editorWithCustomRender = new Editor({
  extensions: [
    Mention.configure({
      renderText: ({ node, suggestion }) => {
        return `${suggestion?.char ?? "@"}${node.attrs.label ?? node.attrs.id}`;
      },
      renderHTML: ({ node, HTMLAttributes, suggestion }) => {
        return [
          "span",
          {
            ...HTMLAttributes,
            "data-type": "mention",
            "data-id": node.attrs.id,
            class: "custom-mention",
          },
          `${suggestion?.char ?? "@"}${node.attrs.label ?? node.attrs.id}`,
        ];
      },
      suggestion: {
        items: ({ query }) => getMentionItems(query),
        render: () => createMentionRenderer(),
      },
    }),
  ],
});

docs

index.md

tile.json