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.
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>
);
}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>
);
}
}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 }
>;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>
);
}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>
);
}