or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-tiptap--extension-mention

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

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@tiptap/extension-mention@3.4.x

To install, run

npx @tessl/cli install tessl/npm-tiptap--extension-mention@3.4.0

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(),
      },
    }),
  ],
});