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

context-management.mddocs/

Context Management

CKEditorContext provides a React context provider for sharing CKEditor 5 context and resources between multiple editor instances, enabling efficient resource utilization and collaborative editing scenarios.

Capabilities

CKEditorContext Component

React functional component that manages shared CKEditor 5 context for multiple editor instances.

/**
 * Context provider for managing shared CKEditor 5 context
 * Enables resource sharing between multiple editor instances
 */
function CKEditorContext<TContext extends Context = Context>(
  props: Props<TContext>
): ReactElement | null;

interface Props<TContext extends Context> {
  /** Unique identifier for the context instance */
  id?: string;
  
  /** Flag indicating if layout is ready for context initialization */
  isLayoutReady?: boolean;
  
  /** Context constructor function */
  context?: { create(...args: any): Promise<TContext> };
  
  /** ContextWatchdog constructor for error handling */
  contextWatchdog: typeof ContextWatchdog<TContext>;
  
  /** Watchdog configuration for error recovery */
  watchdogConfig?: WatchdogConfig;
  
  /** Context configuration object */
  config?: ContextConfig;
  
  /** Callback fired when context is ready */
  onReady?: (context: TContext, watchdog: ContextWatchdog<TContext>) => void;
  
  /** Error handling callback */
  onError?: (error: Error, details: ErrorDetails) => void;
  
  /** Callback fired when initialized editors map changes */
  onChangeInitializedEditors?: (editorsMap: Map<string, Editor>) => void;
  
  /** Child components that will have access to the context */
  children?: ReactNode;
}

Usage Examples:

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

// Basic context usage
function BasicContextUsage() {
  return (
    <CKEditorContext 
      context={Context}
      contextWatchdog={Context.ContextWatchdog}
    >
      <CKEditor
        editor={ClassicEditor}
        data="<p>First editor in context</p>"
      />
      <CKEditor
        editor={ClassicEditor}
        data="<p>Second editor in context</p>"
      />
    </CKEditorContext>
  );
}

// Advanced context with configuration
function AdvancedContextUsage() {
  const handleContextReady = (context: Context, watchdog: ContextWatchdog<Context>) => {
    console.log('Context is ready:', context);
    console.log('Watchdog state:', watchdog.state);
  };

  const handleContextError = (error: Error, details: ErrorDetails) => {
    console.error('Context error:', error);
    console.log('Will context restart:', details.willContextRestart);
  };

  const handleEditorsChange = (editorsMap: Map<string, Editor>) => {
    console.log('Editors in context:', editorsMap.size);
  };

  return (
    <CKEditorContext
      id="main-context"
      context={Context}
      contextWatchdog={Context.ContextWatchdog}
      config={{
        plugins: ['Essentials', 'Bold', 'Italic'],
        toolbar: ['bold', 'italic']
      }}
      watchdogConfig={{
        crashNumberLimit: 5
      }}
      onReady={handleContextReady}
      onError={handleContextError}
      onChangeInitializedEditors={handleEditorsChange}
    >
      <div>
        <h3>Editor 1</h3>
        <CKEditor
          editor={ClassicEditor}
          data="<p>Content 1</p>"
          contextItemMetadata={{ name: 'editor1', type: 'main' }}
        />
      </div>
      
      <div>
        <h3>Editor 2</h3>
        <CKEditor
          editor={ClassicEditor}
          data="<p>Content 2</p>"
          contextItemMetadata={{ name: 'editor2', type: 'secondary' }}
        />
      </div>
    </CKEditorContext>
  );
}

Context State Management

Hook and utilities for accessing and managing context watchdog state.

Note: These utilities are internal and not re-exported through the main package index. They must be imported directly from the built context module if needed externally:

import { 
  useCKEditorWatchdogContext,
  ContextWatchdogContext,
  isContextWatchdogValue,
  isContextWatchdogInitializing,
  isContextWatchdogReadyToUse
} from "@ckeditor/ckeditor5-react/dist/context/ckeditorcontext.js";

These are primarily used internally by the CKEditorContext component and are not intended for general external use.

/**
 * Hook for accessing the current context watchdog value
 */
function useCKEditorWatchdogContext(): ContextWatchdogValue | null;

/**
 * React context for sharing watchdog state
 */
const ContextWatchdogContext: React.Context<ContextWatchdogValue | null>;

/**
 * Represents the value of the ContextWatchdog in the CKEditor context
 */
type ContextWatchdogValue<TContext extends Context = Context> =
  | {
      status: 'initializing';
    }
  | {
      status: 'initialized';
      watchdog: ContextWatchdog<TContext>;
    }
  | {
      status: 'error';
      error: ErrorDetails;
    };

type ContextWatchdogValueStatus = ContextWatchdogValue['status'];

Context State Usage:

import React from 'react';
import { useCKEditorWatchdogContext } from '@ckeditor/ckeditor5-react/dist/context/ckeditorcontext.js';

function ContextStatusDisplay() {
  const contextValue = useCKEditorWatchdogContext();

  if (!contextValue) {
    return <div>No context available</div>;
  }

  switch (contextValue.status) {
    case 'initializing':
      return <div>Context is initializing...</div>;
      
    case 'initialized':
      return (
        <div>
          <p>Context is ready!</p>
          <p>Watchdog state: {contextValue.watchdog.state}</p>
        </div>
      );
      
    case 'error':
      return (
        <div>
          <p>Context error occurred</p>
          <p>Error: {contextValue.error}</p>
        </div>
      );
  }
}

Context State Validators

Utility functions for checking context watchdog state.

/**
 * Checks if the given object is of type ContextWatchdogValue
 */
function isContextWatchdogValue(obj: any): obj is ContextWatchdogValue;

/**
 * Checks if the provided object is a context watchdog value with the specified status
 */
function isContextWatchdogValueWithStatus<S extends ContextWatchdogValueStatus>(
  status: S
): (obj: any) => obj is ExtractContextWatchdogValueByStatus<S>;

/**
 * Checks if the context watchdog is currently initializing
 */
function isContextWatchdogInitializing(obj: any): obj is ExtractContextWatchdogValueByStatus<'initializing'>;

/**
 * Checks if the context watchdog is ready to use
 * Prevents race conditions between watchdog and context state
 */
function isContextWatchdogReadyToUse(obj: any): obj is ExtractContextWatchdogValueByStatus<'initialized'>;

type ExtractContextWatchdogValueByStatus<S extends ContextWatchdogValueStatus> = Extract<
  ContextWatchdogValue,
  { status: S }
>;

Error Handling in Context

type ErrorDetails = {
  /** Phase when error occurred */
  phase: 'initialization' | 'runtime';
  
  /** Whether the context will restart */
  willContextRestart: boolean;
};

Context Error Handling Example:

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

function ContextWithErrorHandling() {
  const [contextStatus, setContextStatus] = useState('initializing');
  const [errorInfo, setErrorInfo] = useState(null);

  const handleContextError = (error: Error, details: ErrorDetails) => {
    console.error('Context error:', error);
    setErrorInfo({ error: error.message, details });
    
    if (details.phase === 'initialization') {
      setContextStatus('failed');
    } else if (details.willContextRestart) {
      setContextStatus('restarting');
    }
  };

  const handleContextReady = (context: Context) => {
    setContextStatus('ready');
    setErrorInfo(null);
    console.log('Context ready with plugins:', context.plugins.getPluginNames());
  };

  return (
    <div>
      <div>Context Status: {contextStatus}</div>
      {errorInfo && (
        <div style={{ color: 'red' }}>
          Error: {errorInfo.error} (Phase: {errorInfo.details.phase})
        </div>
      )}
      
      <CKEditorContext
        context={Context}
        contextWatchdog={Context.ContextWatchdog}
        config={{
          plugins: ['Essentials', 'Bold', 'Italic', 'Link']
        }}
        watchdogConfig={{
          crashNumberLimit: 3,
          onErrorCallback: (error) => {
            console.log('Watchdog callback:', error);
          }
        }}
        onReady={handleContextReady}
        onError={handleContextError}
      >
        <CKEditor
          editor={ClassicEditor}
          data="<p>Editor within error-handled context</p>"
        />
      </CKEditorContext>
    </div>
  );
}

Layout Readiness Control

Control context initialization based on layout readiness.

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

function ConditionalContextInitialization() {
  const [isLayoutReady, setIsLayoutReady] = useState(false);

  useEffect(() => {
    // Simulate layout preparation
    const timer = setTimeout(() => {
      setIsLayoutReady(true);
    }, 1000);

    return () => clearTimeout(timer);
  }, []);

  return (
    <div>
      {!isLayoutReady && <div>Preparing layout...</div>}
      
      <CKEditorContext
        context={Context}
        contextWatchdog={Context.ContextWatchdog}
        isLayoutReady={isLayoutReady}
        onReady={() => console.log('Context ready after layout prepared')}
      >
        <CKEditor
          editor={ClassicEditor}
          data="<p>Editor initialized after layout ready</p>"
        />
      </CKEditorContext>
    </div>
  );
}