CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tiptap--suggestion

Suggestion plugin for Tiptap that provides triggered autocomplete functionality for mentions, hashtags, and other contextual suggestions

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

Tiptap Suggestion

Tiptap Suggestion is a utility plugin for Tiptap editors that enables triggered autocomplete functionality such as mentions, hashtags, slash commands, and other contextual suggestions. It provides a flexible ProseMirror plugin that detects trigger characters and offers lifecycle hooks for rendering custom suggestion interfaces.

Package Information

  • Package Name: @tiptap/suggestion
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @tiptap/suggestion

Core Imports

import { Suggestion, exitSuggestion, findSuggestionMatch, SuggestionPluginKey } from "@tiptap/suggestion";

For default import:

import Suggestion from "@tiptap/suggestion";

For CommonJS:

const { Suggestion, exitSuggestion, findSuggestionMatch, SuggestionPluginKey } = require("@tiptap/suggestion");

Basic Usage

import { Editor } from "@tiptap/core";
import { Suggestion } from "@tiptap/suggestion";

const editor = new Editor({
  // ... other config
});

// Create a suggestion plugin for mentions
const mentionSuggestion = Suggestion({
  editor: editor,
  char: '@',
  items: ({ query }) => {
    return [
      { id: 1, label: 'John Doe' },
      { id: 2, label: 'Jane Smith' },
      { id: 3, label: 'Bob Wilson' }
    ].filter(item => 
      item.label.toLowerCase().includes(query.toLowerCase())
    );
  },
  render: () => ({
    onStart: (props) => {
      // Create and show suggestion dropdown
      console.log('Suggestion started', props.query);
    },
    onUpdate: (props) => {
      // Update suggestion dropdown with new items
      console.log('Suggestion updated', props.items);
    },
    onExit: () => {
      // Hide suggestion dropdown
      console.log('Suggestion exited');
    },
    onKeyDown: ({ event }) => {
      // Handle keyboard navigation
      if (event.key === 'ArrowUp' || event.key === 'ArrowDown') {
        return true; // Handled
      }
      return false; // Not handled
    }
  }),
  command: ({ editor, range, props }) => {
    // Insert the selected mention
    editor.chain().focus().insertContentAt(range, `@${props.label}`).run();
  },
});

// Add the plugin to your editor
editor.registerPlugin(mentionSuggestion);

Capabilities

Suggestion Plugin Creation

Creates a ProseMirror plugin that handles suggestion functionality with customizable behavior and rendering.

/**
 * Creates a suggestion plugin for Tiptap editors
 * @param options - Configuration options for the suggestion behavior
 * @returns ProseMirror Plugin instance
 */
function Suggestion<I = any, TSelected = any>(
  options: SuggestionOptions<I, TSelected>
): Plugin<any>;

interface SuggestionOptions<I = any, TSelected = any> {
  /** The plugin key for the suggestion plugin (default: SuggestionPluginKey) */
  pluginKey?: PluginKey;
  /** The editor instance (required) */
  editor: Editor;
  /** The character that triggers the suggestion (default: '@') */
  char?: string;
  /** Allow spaces in the suggestion query (default: false) */
  allowSpaces?: boolean;
  /** Allow the trigger character to be included in the query (default: false) */
  allowToIncludeChar?: boolean;
  /** Allowed prefix characters before trigger (default: [' ']) */
  allowedPrefixes?: string[] | null;
  /** Only match suggestions at the start of the line (default: false) */
  startOfLine?: boolean;
  /** HTML tag name for decoration node (default: 'span') */
  decorationTag?: string;
  /** CSS class for decoration node (default: 'suggestion') */
  decorationClass?: string;
  /** Content for decoration node (default: '') */
  decorationContent?: string;
  /** CSS class when decoration is empty (default: 'is-empty') */
  decorationEmptyClass?: string;
  /** Function called when suggestion is selected */
  command?: (props: { editor: Editor; range: Range; props: TSelected }) => void;
  /** Function returning suggestion items array */
  items?: (props: { query: string; editor: Editor }) => I[] | Promise<I[]>;
  /** Function returning render lifecycle hooks */
  render?: () => {
    /** Called before suggestion starts */
    onBeforeStart?: (props: SuggestionProps<I, TSelected>) => void;
    /** Called when suggestion starts */
    onStart?: (props: SuggestionProps<I, TSelected>) => void;
    /** Called before suggestion updates */
    onBeforeUpdate?: (props: SuggestionProps<I, TSelected>) => void;
    /** Called when suggestion updates */
    onUpdate?: (props: SuggestionProps<I, TSelected>) => void;
    /** Called when suggestion exits */
    onExit?: (props: SuggestionProps<I, TSelected>) => void;
    /** Called on keydown events, return true if handled */
    onKeyDown?: (props: SuggestionKeyDownProps) => boolean;
  };
  /** Function determining if suggestion should be active */
  allow?: (props: { editor: Editor; state: EditorState; range: Range; isActive?: boolean }) => boolean;
  /** Custom match finding function */
  findSuggestionMatch?: typeof findSuggestionMatch;
}

Suggestion Match Finding

Finds suggestion matches in text based on configurable trigger patterns.

/**
 * Finds suggestion matches in text based on trigger configuration
 * @param config - Trigger configuration object
 * @returns SuggestionMatch object or null if no match found
 */
function findSuggestionMatch(config: Trigger): SuggestionMatch;

interface Trigger {
  /** Trigger character */
  char: string;
  /** Whether to allow spaces in queries */
  allowSpaces: boolean;
  /** Whether to include trigger character in queries */
  allowToIncludeChar: boolean;
  /** Array of allowed prefix characters */
  allowedPrefixes: string[] | null;
  /** Whether to only match at line start */
  startOfLine: boolean;
  /** ProseMirror resolved position */
  $position: ResolvedPos;
}

type SuggestionMatch = {
  /** Range object with from/to positions */
  range: Range;
  /** Matched query string (excluding trigger character) */
  query: string;
  /** Full matched text (including trigger character) */
  text: string;
} | null;

Programmatic Exit

Programmatically exits suggestion mode.

/**
 * Programmatically exits the suggestion mode
 * @param view - EditorView instance
 * @param pluginKeyRef - PluginKey instance (default: SuggestionPluginKey)
 */
function exitSuggestion(view: EditorView, pluginKeyRef?: PluginKey): void;

Default Plugin Key

Default PluginKey instance used by the suggestion plugin when no custom pluginKey is provided.

/**
 * Default plugin key for the suggestion plugin
 * Used when no custom pluginKey is specified in SuggestionOptions
 */
const SuggestionPluginKey: PluginKey<any>;

Types

Core Interfaces

interface SuggestionProps<I = any, TSelected = any> {
  /** The editor instance */
  editor: Editor;
  /** The range of the suggestion text */
  range: Range;
  /** Current query string (excluding trigger character) */
  query: string;
  /** Full suggestion text (including trigger character) */
  text: string;
  /** Array of suggestion items */
  items: I[];
  /** Function to execute selected suggestion */
  command: (props: TSelected) => void;
  /** HTML element of the decoration node */
  decorationNode: Element | null;
  /** Function returning DOMRect for positioning */
  clientRect?: (() => DOMRect | null) | null;
}

interface SuggestionKeyDownProps {
  /** EditorView instance */
  view: EditorView;
  /** KeyboardEvent */
  event: KeyboardEvent;
  /** Current suggestion range */
  range: Range;
}

External Dependencies

// From @tiptap/core
interface Editor { /* Tiptap editor instance */ }
interface Range { from: number; to: number; }

// From @tiptap/pm/state
class Plugin { /* ProseMirror plugin class */ }
class PluginKey { /* ProseMirror plugin key class */ }
interface EditorState { /* ProseMirror editor state */ }

// From @tiptap/pm/view
interface EditorView { /* ProseMirror editor view */ }

// From @tiptap/pm/model
interface ResolvedPos { /* ProseMirror resolved position */ }

Usage Examples

Hashtag Suggestions

import { Suggestion } from "@tiptap/suggestion";

const hashtagSuggestion = Suggestion({
  editor: myEditor,
  char: '#',
  items: ({ query }) => {
    return ['javascript', 'typescript', 'react', 'vue']
      .filter(tag => tag.includes(query.toLowerCase()))
      .map(tag => ({ tag }));
  },
  render: () => ({
    onStart: (props) => {
      // Show hashtag dropdown
    },
    onUpdate: (props) => {
      // Update hashtag list
    },
    onExit: () => {
      // Hide dropdown
    }
  }),
  command: ({ editor, range, props }) => {
    editor.chain().focus().insertContentAt(range, `#${props.tag}`).run();
  }
});

Slash Commands

import { Suggestion } from "@tiptap/suggestion";

const slashCommandSuggestion = Suggestion({
  editor: myEditor,
  char: '/',
  startOfLine: true,
  items: ({ query }) => {
    return [
      { title: 'Heading 1', command: 'heading', level: 1 },
      { title: 'Heading 2', command: 'heading', level: 2 },
      { title: 'Bullet List', command: 'bulletList' },
    ].filter(item => 
      item.title.toLowerCase().includes(query.toLowerCase())
    );
  },
  command: ({ editor, range, props }) => {
    editor.chain().focus().deleteRange(range);
    
    if (props.command === 'heading') {
      editor.chain().setHeading({ level: props.level }).run();
    } else if (props.command === 'bulletList') {
      editor.chain().toggleBulletList().run();
    }
  }
});

Custom Match Pattern

import { Suggestion, findSuggestionMatch } from "@tiptap/suggestion";

const customSuggestion = Suggestion({
  editor: myEditor,
  char: '$',
  allowSpaces: true,
  allowedPrefixes: [' ', '(', '['],
  findSuggestionMatch: (config) => {
    // Custom matching logic
    return findSuggestionMatch(config);
  },
  items: ({ query }) => {
    // Return variable suggestions
    return variables.filter(v => v.name.includes(query));
  }
});
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@tiptap/suggestion@3.4.x
Publish Source
CLI
Badge
tessl/npm-tiptap--suggestion badge