or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

commands.mdconfiguration.mddata-management.mdeditor-lifecycle.mdindex.mdplugins.mduser-interface.md
tile.json

configuration.mddocs/

Configuration

Extensive configuration options for customizing editor behavior, toolbar setup, plugin selection, and feature-specific settings to tailor the editor to specific application needs.

Capabilities

Core Configuration

Essential configuration options for editor setup and behavior.

/**
 * Main editor configuration interface
 */
interface EditorConfig {
  /**
   * Array of plugin constructors to load
   */
  plugins?: Array<PluginConstructor>;
  
  /**
   * Additional plugins to load beyond builtinPlugins
   */
  extraPlugins?: Array<PluginConstructor>;
  
  /**
   * Plugins to exclude from builtinPlugins
   */
  removePlugins?: Array<string | PluginConstructor>;
  
  /**
   * Plugin substitutions for customization
   */
  substitutePlugins?: Array<SubstitutePluginDefinition>;
  
  /**
   * Initial content for the editor
   */
  initialData?: string | Record<string, string>;
  
  /**
   * UI language configuration
   */
  language?: string | LanguageConfig;
  
  /**
   * Commercial license key
   */
  licenseKey?: string;
  
  /**
   * Whether to update source element on destroy
   */
  updateSourceElementOnDestroy?: boolean;
  
  /**
   * Accessibility label for the editor
   */
  label?: string;
}

Usage Examples:

// Basic configuration
ClassicEditor.create(element, {
  initialData: '<p>Welcome to my editor!</p>',
  language: 'en',
  licenseKey: 'your-license-key-here'
});

// Plugin management
ClassicEditor.create(element, {
  // Add extra plugins
  extraPlugins: [CustomPlugin, AnotherPlugin],
  
  // Remove unwanted plugins
  removePlugins: ['MediaEmbed', 'Table'],
  
  // Replace built-in plugins
  substitutePlugins: [
    { from: 'Link', to: CustomLinkPlugin }
  ]
});

// Multi-language configuration
ClassicEditor.create(element, {
  language: {
    ui: 'en',
    content: 'es'
  }
});

Toolbar Configuration

Comprehensive toolbar customization options for buttons, separators, and grouping.

/**
 * Toolbar configuration options
 */
interface ToolbarConfig {
  /**
   * Array of toolbar items (button names and separators)
   */
  items?: string[];
  
  /**
   * Items to remove from default toolbar
   */
  removeItems?: string[];
  
  /**
   * Items to add to default toolbar
   */
  addItems?: string[];
  
  /**
   * Whether toolbar should group items when space is limited
   */
  shouldNotGroupWhenFull?: boolean;
  
  /**
   * Custom view class for toolbar
   */
  viewportTopOffset?: number;
}

Usage Examples:

// Custom toolbar items
ClassicEditor.create(element, {
  toolbar: {
    items: [
      'undo', 'redo',
      '|', // Separator
      'heading',
      '|',
      'bold', 'italic', 'strikethrough',
      '|',
      'link', 'uploadImage', 'insertTable',
      '|',
      'bulletedList', 'numberedList',
      '|',
      'outdent', 'indent',
      '|',
      'blockQuote', 'mediaEmbed'
    ]
  }
});

// Minimal toolbar
ClassicEditor.create(element, {
  toolbar: {
    items: ['bold', 'italic', 'link']
  }
});

// Remove specific items from default
ClassicEditor.create(element, {
  toolbar: {
    removeItems: ['uploadImage', 'insertTable', 'mediaEmbed']
  }
});

// Add custom items to default
ClassicEditor.create(element, {
  toolbar: {
    addItems: ['customButton', 'anotherCustomTool']
  }
});

// Disable toolbar grouping
ClassicEditor.create(element, {
  toolbar: {
    shouldNotGroupWhenFull: true
  }
});

Plugin-Specific Configuration

Configuration options for individual plugins included in the build.

/**
 * Image plugin configuration
 */
interface ImageConfig {
  toolbar?: string[];
  upload?: {
    types?: string[];
    allowMultipleFiles?: boolean;
  };
  insert?: {
    integrations?: string[];
  };
  styles?: {
    options?: Array<{
      name: string;
      title: string;
      icon?: string;
      className?: string;
    }>;
  };
  resizeOptions?: Array<{
    name: string;
    value: string | null;
    icon: string;
  }>;
  resizeUnit?: 'px' | '%';
}

/**
 * Table plugin configuration
 */
interface TableConfig {
  contentToolbar?: string[];
  tableToolbar?: string[];
  defaultHeadings?: {
    rows?: number;
    columns?: number;
  };
  tableProperties?: {
    borderColors?: ColorOption[];
    backgroundColors?: ColorOption[];
  };
  tableCellProperties?: {
    borderColors?: ColorOption[];
    backgroundColors?: ColorOption[];
  };
}

/**
 * Heading plugin configuration
 */
interface HeadingConfig {
  options?: Array<{
    model: string;
    view: string | HeadingElementDefinition;
    title: string;
    class?: string;
  }>;
}

/**
 * Link plugin configuration
 */
interface LinkConfig {
  addTargetToExternalLinks?: boolean;
  defaultProtocol?: string;
  decorators?: Record<string, LinkDecoratorDefinition>;
}

Usage Examples:

// Image configuration
ClassicEditor.create(element, {
  image: {
    // Image toolbar items
    toolbar: [
      'imageTextAlternative',
      'toggleImageCaption',
      '|',
      'imageStyle:inline',
      'imageStyle:block',
      'imageStyle:side',
      '|',
      'resizeImage'
    ],
    
    // Upload settings
    upload: {
      types: ['jpeg', 'png', 'gif', 'bmp', 'webp', 'tiff'],
      allowMultipleFiles: true
    },
    
    // Style options
    styles: {
      options: [
        'inline', 'alignLeft', 'alignRight',
        'alignCenter', 'alignBlockLeft', 'alignBlockRight',
        'block', 'side'
      ]
    },
    
    // Resize options
    resizeOptions: [
      {
        name: 'resizeImage:original',
        value: null,
        icon: 'original'
      },
      {
        name: 'resizeImage:50',
        value: '50',
        icon: 'medium'
      },
      {
        name: 'resizeImage:75',
        value: '75',
        icon: 'large'
      }
    ],
    
    resizeUnit: '%'
  }
});

// Table configuration
ClassicEditor.create(element, {
  table: {
    contentToolbar: [
      'tableColumn', 'tableRow', 'mergeTableCells',
      'tableProperties', 'tableCellProperties'
    ],
    
    defaultHeadings: {
      rows: 1,
      columns: 1
    },
    
    tableProperties: {
      borderColors: [
        { color: 'hsl(0, 0%, 90%)', label: 'Light grey' },
        { color: 'hsl(0, 0%, 60%)', label: 'Dark grey' },
        { color: 'hsl(0, 0%, 30%)', label: 'Very dark grey' },
        { color: 'hsl(0, 0%, 0%)', label: 'Black' }
      ],
      backgroundColors: [
        { color: 'hsl(0, 0%, 100%)', label: 'White' },
        { color: 'hsl(0, 0%, 90%)', label: 'Light grey' },
        { color: 'hsl(120, 75%, 60%)', label: 'Light green' },
        { color: 'hsl(60, 75%, 60%)', label: 'Light yellow' }
      ]
    }
  }
});

// Heading configuration
ClassicEditor.create(element, {
  heading: {
    options: [
      { model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },
      { model: 'heading1', view: 'h1', title: 'Heading 1', class: 'ck-heading_heading1' },
      { model: 'heading2', view: 'h2', title: 'Heading 2', class: 'ck-heading_heading2' },
      { model: 'heading3', view: 'h3', title: 'Heading 3', class: 'ck-heading_heading3' },
      { model: 'heading4', view: 'h4', title: 'Heading 4', class: 'ck-heading_heading4' }
    ]
  }
});

// Link configuration
ClassicEditor.create(element, {
  link: {
    // Add target="_blank" to external links
    addTargetToExternalLinks: true,
    
    // Default protocol for URLs without protocol
    defaultProtocol: 'https://',
    
    // Link decorators for additional attributes
    decorators: {
      openInNewTab: {
        mode: 'manual',
        label: 'Open in a new tab',
        attributes: {
          target: '_blank',
          rel: 'noopener noreferrer'
        }
      },
      downloadable: {
        mode: 'manual',
        label: 'Downloadable',
        attributes: {
          download: 'file'
        }
      }
    }
  }
});

Language Configuration

Configure editor UI language and content language settings.

/**
 * Language configuration options
 */
interface LanguageConfig {
  /**
   * UI language code
   */
  ui?: string;
  
  /**
   * Content language code
   */
  content?: string;
  
  /**
   * Text direction for content
   */
  textPartLanguage?: Array<{
    title: string;
    languageCode: string;
    textDirection?: 'ltr' | 'rtl';
  }>;
}

Usage Examples:

// Single language
ClassicEditor.create(element, {
  language: 'es' // Spanish UI and content
});

// Separate UI and content languages
ClassicEditor.create(element, {
  language: {
    ui: 'en',      // English interface
    content: 'ar'  // Arabic content
  }
});

// Multi-language content support
ClassicEditor.create(element, {
  language: {
    ui: 'en',
    content: 'en',
    textPartLanguage: [
      { title: 'Arabic', languageCode: 'ar', textDirection: 'rtl' },
      { title: 'French', languageCode: 'fr' },
      { title: 'Spanish', languageCode: 'es' }
    ]
  }
});

UI Configuration

Configure user interface behavior and appearance.

/**
 * UI configuration options
 */
interface UIConfig {
  /**
   * Viewport offset for sticky elements
   */
  viewportOffset?: {
    top?: number;
    right?: number;
    bottom?: number;
    left?: number;
  };
  
  /**
   * Poweredby configuration
   */
  poweredBy?: {
    position?: 'inside' | 'border';
    label?: string;
    side?: 'left' | 'right';
  };
}

Usage Examples:

// Viewport offset for sticky toolbar
ClassicEditor.create(element, {
  ui: {
    viewportOffset: {
      top: 50 // Account for fixed header
    }
  }
});

// Powered by customization
ClassicEditor.create(element, {
  ui: {
    poweredBy: {
      position: 'border',
      side: 'right',
      label: 'Custom Editor'
    }
  }
});

Advanced Configuration

Advanced configuration options for specific use cases.

/**
 * Advanced configuration options
 */
interface AdvancedConfig {
  /**
   * Mention plugin configuration
   */
  mention?: {
    feeds: Array<{
      marker: string;
      feed: string[] | Function;
      minimumCharacters?: number;
      itemRenderer?: Function;
    }>;
  };
  
  /**
   * Placeholder configuration
   */
  placeholder?: string;
  
  /**
   * Word count configuration
   */
  wordCount?: {
    onUpdate?: (stats: { characters: number; words: number }) => void;
    displayCharacters?: boolean;
    displayWords?: boolean;
  };
  
  /**
   * Autosave configuration
   */
  autosave?: {
    save: (editor: Editor) => Promise<void>;
    waitingTime?: number;
  };
}

Usage Examples:

// Placeholder text
ClassicEditor.create(element, {
  placeholder: 'Start typing your content here...'
});

// Word count tracking
ClassicEditor.create(element, {
  wordCount: {
    onUpdate: (stats) => {
      document.querySelector('#word-count').textContent = 
        `${stats.words} words, ${stats.characters} characters`;
    },
    displayWords: true,
    displayCharacters: true
  }
});

// Autosave configuration
ClassicEditor.create(element, {
  autosave: {
    save: async (editor) => {
      const data = editor.getData();
      await fetch('/api/autosave', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ content: data })
      });
    },
    waitingTime: 5000 // 5 seconds
  }
});

// Complete advanced configuration
ClassicEditor.create(element, {
  placeholder: 'Type something amazing...',
  
  mention: {
    feeds: [
      {
        marker: '@',
        feed: ['Alice', 'Bob', 'Charlie', 'Diana'],
        minimumCharacters: 1
      },
      {
        marker: '#',
        feed: async (queryText) => {
          const response = await fetch(`/api/tags?q=${queryText}`);
          return response.json();
        }
      }
    ]
  },
  
  wordCount: {
    onUpdate: (stats) => {
      console.log(`Content: ${stats.words} words, ${stats.characters} chars`);
    }
  }
});