or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

configuration.mdcore-plugins.mdindex.mdui-components.md
tile.json

configuration.mddocs/

Configuration System

The configuration system provides flexible setup options for mention functionality including feed configuration, keyboard behavior, and dropdown appearance.

Capabilities

Main Configuration Interface

The primary configuration interface for the mention feature.

/**
 * The configuration of the mention feature.
 * Used in editor configuration under the 'mention' key.
 */
interface MentionConfig {
    /**
     * The list of mention feeds supported by the editor.
     * Each feed must use a different marker character.
     */
    feeds: Array<MentionFeed>;
    
    /**
     * Custom commit keys for confirming mention selection.
     * @default [13, 9] // [Enter, Tab]
     */
    commitKeys?: Array<number>;
    
    /**
     * Maximum number of visible mentions in dropdown.
     * @default 10
     */
    dropdownLimit?: number;
}

Usage Examples:

import { ClassicEditor } from "@ckeditor/ckeditor5-editor-classic";
import { Mention } from "@ckeditor/ckeditor5-mention";

ClassicEditor.create(editorElement, {
    plugins: [Mention],
    mention: {
        feeds: [
            {
                marker: '@',
                feed: ['@alice', '@bob', '@charlie']
            },
            {
                marker: '#',
                feed: async (searchString) => {
                    return await fetchHashtags(searchString);
                }
            }
        ],
        commitKeys: [13, 32], // Enter and Space
        dropdownLimit: 15
    }
});

Mention Feed Configuration

Configuration for individual mention feeds that define how mentions are triggered and populated.

/**
 * The mention feed descriptor defining a single mention type.
 * Each feed handles one marker character (like '@' or '#').
 */
interface MentionFeed {
    /**
     * The character which triggers autocompletion for mention.
     * Must be a single character.
     */
    marker: string;
    
    /**
     * Autocomplete items. Provide an array for static configuration
     * or a function for dynamic data retrieval.
     */
    feed: Array<MentionFeedItem> | MentionFeedbackCallback;
    
    /**
     * Minimum characters after marker before showing suggestions.
     * @default 0
     */
    minimumCharacters?: number;
    
    /**
     * Custom function for rendering mention items in dropdown.
     */
    itemRenderer?: MentionItemRenderer;
    
    /**
     * Feed-specific dropdown limit, overrides global dropdownLimit.
     */
    dropdownLimit?: number;
}

Usage Examples:

// Static feed with simple strings
const userFeed: MentionFeed = {
    marker: '@',
    feed: ['@alice', '@bob', '@charlie', '@david'],
    minimumCharacters: 2
};

// Dynamic feed with async callback
const hashtagFeed: MentionFeed = {
    marker: '#',
    feed: async (searchString: string) => {
        const response = await fetch(`/api/hashtags?q=${searchString}`);
        const hashtags = await response.json();
        return hashtags.map(tag => `#${tag.name}`);
    },
    minimumCharacters: 1,
    dropdownLimit: 20
};

// Feed with object items and custom renderer
const mentionFeed: MentionFeed = {
    marker: '@',
    feed: [
        { id: '@alice', text: 'Alice Johnson', avatar: '/avatars/alice.jpg' },
        { id: '@bob', text: 'Bob Wilson', avatar: '/avatars/bob.jpg' }
    ],
    itemRenderer: (item) => {
        const div = document.createElement('div');
        div.innerHTML = `
            <img src="${item.avatar}" alt="${item.text}" />
            <span>${item.text}</span>
        `;
        return div;
    }
};

Feed Item Types

Types that define the structure of mention feed items.

/**
 * Union type representing a mention feed item.
 * Can be a simple string or a structured object.
 */
type MentionFeedItem = string | MentionFeedObjectItem;

/**
 * Object-based mention item with required ID and optional display text.
 */
interface MentionFeedObjectItem {
    /**
     * Unique ID of the mention. Must start with the marker character.
     */
    id: string;
    
    /**
     * Text inserted into the editor when creating a mention.
     * If not provided, the id will be used.
     */
    text?: string;
    
    /**
     * Additional properties for custom data storage.
     */
    [key: string]: unknown;
}

Feed Callback Types

Function types for dynamic mention data retrieval and custom rendering.

/**
 * Function that returns mention items based on search input.
 * Can return items synchronously or asynchronously via Promise.
 */
type MentionFeedbackCallback = (
    searchString: string
) => Array<MentionFeedItem> | Promise<Array<MentionFeedItem>>;

/**
 * Function that renders a mention item as an HTML element or string.
 * Used for customizing the appearance of items in the dropdown.
 */
type MentionItemRenderer = (
    item: MentionFeedObjectItem
) => HTMLElement | string;

Usage Examples:

// Synchronous callback
const syncFeed: MentionFeedbackCallback = (searchString) => {
    const allUsers = ['@alice', '@bob', '@charlie', '@david'];
    return allUsers.filter(user => 
        user.toLowerCase().includes(searchString.toLowerCase())
    );
};

// Asynchronous callback with error handling
const asyncFeed: MentionFeedbackCallback = async (searchString) => {
    try {
        const response = await fetch(`/api/users/search?q=${searchString}`);
        if (!response.ok) throw new Error('Failed to fetch users');
        
        const users = await response.json();
        return users.map(user => ({
            id: `@${user.username}`,
            text: user.displayName,
            userId: user.id,
            department: user.department
        }));
    } catch (error) {
        console.error('Error fetching mention feed:', error);
        return [];
    }
};

// Custom item renderer with rich HTML
const customRenderer: MentionItemRenderer = (item) => {
    const wrapper = document.createElement('div');
    wrapper.className = 'custom-mention-item';
    
    if (typeof item === 'object' && item.avatar) {
        wrapper.innerHTML = `
            <img src="${item.avatar}" class="mention-avatar" />
            <div class="mention-info">
                <div class="mention-name">${item.text || item.id}</div>
                <div class="mention-role">${item.role || ''}</div>
            </div>
        `;
    } else {
        wrapper.textContent = item.text || item.id;
    }
    
    return wrapper;
};

Configuration Patterns

Multiple Feed Types

// Configuration with different mention types
const config: MentionConfig = {
    feeds: [
        // User mentions
        {
            marker: '@',
            feed: fetchUsers,
            minimumCharacters: 2,
            itemRenderer: renderUser
        },
        // Hashtag mentions  
        {
            marker: '#',
            feed: fetchHashtags,
            minimumCharacters: 1
        },
        // Issue references
        {
            marker: '#',
            feed: fetchIssues,
            minimumCharacters: 0
        }
    ],
    commitKeys: [13, 9, 32], // Enter, Tab, Space
    dropdownLimit: 12
};

Advanced Feed Configuration

// Complex feed with caching and debouncing
const createAdvancedFeed = (): MentionFeed => {
    const cache = new Map<string, MentionFeedItem[]>();
    
    return {
        marker: '@',
        feed: async (searchString: string) => {
            // Check cache first
            if (cache.has(searchString)) {
                return cache.get(searchString)!;
            }
            
            // Fetch from API
            const results = await fetchWithRetry(`/api/users?q=${searchString}`);
            cache.set(searchString, results);
            
            return results;
        },
        minimumCharacters: 2,
        dropdownLimit: 10,
        itemRenderer: (item) => {
            // Custom rendering with accessibility
            const button = document.createElement('button');
            button.setAttribute('role', 'option');
            button.setAttribute('aria-label', `Mention ${item.text || item.id}`);
            button.textContent = item.text || item.id;
            return button;
        }
    };
};

Key Features

  1. Multiple Feed Support: Different markers (@, #, etc.) with separate configurations
  2. Flexible Data Sources: Static arrays, synchronous callbacks, and asynchronous promises
  3. Custom Rendering: Full control over dropdown item appearance
  4. Keyboard Customization: Configurable commit keys for different workflows
  5. Performance Controls: Dropdown limits and minimum character thresholds
  6. Type Safety: Full TypeScript support with proper type inference