or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

cloud-integration.mdcontext-management.mdindex.mdmulti-root-editor.mdsingle-root-editor.md
tile.json

single-root-editor.mddocs/

Single-Root Editor

The CKEditor React component provides comprehensive integration for single-root CKEditor 5 instances with advanced lifecycle management, error handling, and watchdog functionality.

Capabilities

CKEditor Component

Main React class component for integrating CKEditor 5 in single-root scenarios.

/**
 * React class component for CKEditor 5 integration
 * Provides comprehensive lifecycle management and error handling
 */
class CKEditor<TEditor extends Editor> extends React.Component<Props<TEditor>> {
  /** Access to the watchdog instance managing the editor */
  get watchdog(): EditorWatchdog<TEditor> | EditorWatchdogAdapter<TEditor> | null;
  
  /** Access to the current editor instance */
  get editor(): Editor | null;
}

interface Props<TEditor extends Editor> {
  /** CKEditor constructor and related classes */
  editor: {
    create(...args: any): Promise<TEditor>;
    EditorWatchdog: typeof EditorWatchdog;
    ContextWatchdog: typeof ContextWatchdog;
  };
  
  /** Editor configuration object */
  config?: EditorConfig;
  
  /** Initial content data */
  data?: string;
  
  /** Read-only mode toggle */
  disabled?: boolean;
  
  /** Watchdog configuration for error recovery */
  watchdogConfig?: WatchdogConfig;
  
  /** Disable watchdog functionality */
  disableWatchdog?: boolean;
  
  /** Callback fired when editor is ready */
  onReady?: (editor: TEditor) => void;
  
  /** Callback fired after editor is destroyed */
  onAfterDestroy?: (editor: TEditor) => void;
  
  /** Error handling callback */
  onError?: (error: Error, details: ErrorDetails) => void;
  
  /** Content change callback */
  onChange?: (event: EventInfo, editor: TEditor) => void;
  
  /** Focus event callback */
  onFocus?: (event: EventInfo, editor: TEditor) => void;
  
  /** Blur event callback */
  onBlur?: (event: EventInfo, editor: TEditor) => void;
  
  /** Context metadata for shared context scenarios */
  contextItemMetadata?: CKEditorConfigContextMetadata;
  
  /** Component identifier for React reconciliation */
  id?: any;
}

Usage Examples:

import React, { useState } from 'react';
import { CKEditor } from '@ckeditor/ckeditor5-react';
import { ClassicEditor } from 'ckeditor5';

// Basic usage
function BasicEditor() {
  const [data, setData] = useState('<p>Initial content</p>');

  return (
    <CKEditor
      editor={ClassicEditor}
      data={data}
      config={{
        toolbar: ['bold', 'italic', 'link']
      }}
      onChange={(event, editor) => {
        setData(editor.getData());
      }}
    />
  );
}

// Advanced usage with all options
function AdvancedEditor() {
  const [data, setData] = useState('');
  const [disabled, setDisabled] = useState(false);

  return (
    <CKEditor
      editor={ClassicEditor}
      data={data}
      disabled={disabled}
      config={{
        toolbar: ['bold', 'italic', 'link', 'bulletedList', 'numberedList'],
        placeholder: 'Start typing...'
      }}
      watchdogConfig={{
        crashNumberLimit: 5
      }}
      onReady={(editor) => {
        console.log('Editor ready:', editor);
      }}
      onChange={(event, editor) => {
        setData(editor.getData());
      }}
      onError={(error, details) => {
        console.error('Editor error:', error, details);
      }}
      onFocus={(event, editor) => {
        console.log('Editor focused');
      }}
      onBlur={(event, editor) => {
        console.log('Editor blurred');
      }}
      onAfterDestroy={(editor) => {
        console.log('Editor destroyed');
      }}
    />
  );
}

// Disabled/read-only editor
function ReadOnlyEditor() {
  return (
    <CKEditor
      editor={ClassicEditor}
      data="<p>This content is read-only</p>"
      disabled={true}
      config={{
        toolbar: []
      }}
    />
  );
}

EditorWatchdogAdapter

Adapter class that aligns context watchdog API with editor watchdog API for unified error handling.

/**
 * Adapter for aligning context watchdog with editor watchdog API
 */
class EditorWatchdogAdapter<TEditor extends Editor> {
  constructor(contextWatchdog: ContextWatchdog);
  
  /** Set the editor creator function */
  setCreator(creator: AdapterEditorCreatorFunction): void;
  
  /** Create editor instance with configuration */
  create(sourceElementOrData: HTMLElement | string, config: EditorConfig): Promise<unknown>;
  
  /** Register event listener (currently supports 'error' event) */
  on(event: string, callback: (data: { error: Error; causesRestart?: boolean }) => void): void;
  
  /** Destroy the editor instance */
  destroy(): Promise<unknown>;
  
  /** Access to the current editor instance */
  get editor(): TEditor;
}

type AdapterEditorCreatorFunction<TEditor = Editor> = (
  elementOrData: HTMLElement | string | Record<string, string> | Record<string, HTMLElement>,
  config: EditorConfig
) => Promise<TEditor>;

Error Handling Types

interface ErrorDetails {
  /** Phase when error occurred */
  phase: 'initialization' | 'runtime';
  
  /** Whether the error will cause editor restart */
  willEditorRestart?: boolean;
}

Error Handling Example:

import React from 'react';
import { CKEditor } from '@ckeditor/ckeditor5-react';
import { ClassicEditor } from 'ckeditor5';

function EditorWithErrorHandling() {
  const handleError = (error: Error, details: ErrorDetails) => {
    console.error(`Editor error in ${details.phase} phase:`, error.message);
    
    if (details.willEditorRestart) {
      console.log('Editor will restart automatically');
    } else {
      console.log('Manual intervention may be required');
    }
    
    // Custom error reporting
    reportErrorToService(error, details);
  };

  return (
    <CKEditor
      editor={ClassicEditor}
      data="<p>Content with error handling</p>"
      onError={handleError}
      watchdogConfig={{
        crashNumberLimit: 3,
        onErrorCallback: (error) => {
          console.log('Watchdog error callback:', error);
        }
      }}
    />
  );
}

Context Integration

When using CKEditor within a CKEditorContext, the component automatically integrates with the shared context for resource optimization.

import React from 'react';
import { CKEditor, CKEditorContext } from '@ckeditor/ckeditor5-react';
import { ClassicEditor, Context } from 'ckeditor5';

function EditorsWithSharedContext() {
  return (
    <CKEditorContext context={Context} contextWatchdog={Context.ContextWatchdog}>
      <CKEditor
        editor={ClassicEditor}
        data="<p>First editor</p>"
        contextItemMetadata={{ name: 'editor1' }}
      />
      <CKEditor
        editor={ClassicEditor}
        data="<p>Second editor</p>"
        contextItemMetadata={{ name: 'editor2' }}
      />
    </CKEditorContext>
  );
}