-
Notifications
You must be signed in to change notification settings - Fork 100
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #390 from ckeditor/ck/257
Feature: Introduced the integration with multi-root editor by providing `useMultiRootEditor` hook. See the new samples to learn more. Closes #257.
- Loading branch information
Showing
30 changed files
with
3,709 additions
and
619 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
|
||
<head> | ||
<meta charset="utf-8"> | ||
<title>CKEditor 5 – React Component – demo</title> | ||
<style> | ||
body { | ||
max-width: 800px; | ||
margin: 20px auto; | ||
} | ||
|
||
p.info, h1, h2.subtitle { | ||
text-align: center; | ||
} | ||
|
||
.buttons { | ||
margin: 10px 0; | ||
} | ||
|
||
.buttons button { | ||
margin-right: 5px; | ||
} | ||
|
||
.flex { | ||
display: flex; | ||
gap: 10px; | ||
margin-top: 10px; | ||
} | ||
|
||
.flex > div { | ||
overflow: auto; | ||
width: 100%; | ||
height: auto; | ||
} | ||
|
||
.ck.ck-content.ck-editor__editable.ck-editor__editable_inline { | ||
border: 1px solid black; | ||
border-collapse: collapse; | ||
margin-top: 10px; | ||
} | ||
|
||
.ck-read-only { | ||
opacity: 0.5; | ||
} | ||
</style> | ||
</head> | ||
|
||
<body> | ||
<div id="root"></div> | ||
<script type="module" src="/src/main.tsx"></script> | ||
</body> | ||
|
||
</html> | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"name": "demo", | ||
"private": true, | ||
"version": "0.0.0", | ||
"type": "module", | ||
"scripts": { | ||
"dev": "vite", | ||
"build": "tsc && vite build", | ||
"preview": "vite preview" | ||
}, | ||
"dependencies": { | ||
"@ckeditor/ckeditor5-react": "file:..", | ||
"@ckeditor/ckeditor5-build-multi-root": "^40.1.0" | ||
}, | ||
"devDependencies": { | ||
"@types/react": "^18.0.28", | ||
"@types/react-dom": "^18.0.11", | ||
"@vitejs/plugin-react": "^3.1.0", | ||
"react": "^18.2.0", | ||
"react-dom": "^18.2.0", | ||
"typescript": "^4.9.3", | ||
"vite": "^4.2.0" | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import React, { useState } from 'react'; | ||
import MultiRootEditorDemo from './MultiRootEditorDemo'; | ||
import MultiRootEditorRichDemo from './MultiRootEditorRichDemo'; | ||
import ContextMultiRootEditorDemo from './ContextMultiRootEditorDemo'; | ||
|
||
type Demo = 'editor' | 'rich' | 'context'; | ||
|
||
const multiRootEditorContent = { | ||
intro: '<h2>Sample</h2><p>This is an instance of the ' + | ||
'<a href="https://ckeditor.com/docs/ckeditor5/latest/builds/guides/overview.html#classic-editor">multi-root editor build</a>.</p>', | ||
content: '<p>It is the custom content</p><figure class="image"><img src="/sample.jpg" alt="CKEditor 5 Sample image."></figure>', | ||
outro: '<p>You can use this sample to validate whether your ' + | ||
'<a href="https://ckeditor.com/docs/ckeditor5/latest/builds/guides/development/custom-builds.html">custom build</a> works fine.</p>' | ||
}; | ||
|
||
const rootsAttributes = { | ||
intro: { | ||
row: '1', | ||
order: 10 | ||
}, | ||
content: { | ||
row: '1', | ||
order: 20 | ||
}, | ||
outro: { | ||
row: '2', | ||
order: 10 | ||
} | ||
}; | ||
|
||
export default function App(): JSX.Element { | ||
const [ demo, setDemo ] = useState<Demo>( 'editor' ); | ||
|
||
const renderDemo = () => { | ||
switch ( demo ) { | ||
case 'context': | ||
return <ContextMultiRootEditorDemo />; | ||
case 'editor': | ||
return <MultiRootEditorDemo data={multiRootEditorContent} rootsAttributes={rootsAttributes} />; | ||
case 'rich': | ||
return <MultiRootEditorRichDemo data={multiRootEditorContent} rootsAttributes={rootsAttributes} />; | ||
} | ||
}; | ||
|
||
return ( | ||
<> | ||
<h1>CKEditor 5 – useMultiRootEditor – development sample</h1> | ||
|
||
<div className="buttons" style={ { textAlign: 'center' } }> | ||
<button | ||
onClick={ () => setDemo( 'editor' ) } | ||
disabled={ demo == 'editor' } | ||
> | ||
Editor demo | ||
</button> | ||
|
||
<button | ||
onClick={ () => setDemo( 'rich' ) } | ||
disabled={ demo == 'rich' } | ||
> | ||
Rich integration demo | ||
</button> | ||
|
||
<button | ||
onClick={ () => setDemo( 'context' ) } | ||
disabled={ demo == 'context' } | ||
> | ||
Context demo | ||
</button> | ||
</div> | ||
{ renderDemo() } | ||
</> | ||
); | ||
} |
125 changes: 125 additions & 0 deletions
125
demo-multiroot-react-18/src/ContextMultiRootEditorDemo.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
import React from 'react'; | ||
import MultiRootEditor from '@ckeditor/ckeditor5-build-multi-root'; | ||
|
||
import { useMultiRootEditor, type MultiRootHookProps, CKEditorContext } from '@ckeditor/ckeditor5-react'; | ||
|
||
export default function ContextMultiRootEditorDemo(): JSX.Element { | ||
return ( | ||
<> | ||
{ /* @ts-expect-error: Caused by linking to parent project and conflicting react types */ } | ||
<CKEditorContext context={ MultiRootEditor.Context }> | ||
<ContextEditorDemo /> | ||
</CKEditorContext> | ||
</> | ||
); | ||
} | ||
|
||
function ContextEditorDemo(): JSX.Element { | ||
const editorProps: Partial<MultiRootHookProps> = { | ||
editor: MultiRootEditor, | ||
|
||
onChange: ( event, editor ) => { | ||
console.log( 'event: onChange', { event, editor } ); | ||
}, | ||
onBlur: ( event, editor ) => { | ||
console.log( 'event: onBlur', { event, editor } ); | ||
}, | ||
onFocus: ( event, editor ) => { | ||
console.log( 'event: onFocus', { event, editor } ); | ||
} | ||
}; | ||
|
||
// First editor initialization. | ||
const { | ||
editor: editor1, editableElements: editableElements1, toolbarElement: toolbarElement1 | ||
} = useMultiRootEditor( { | ||
...editorProps, | ||
data: { | ||
intro: '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>', | ||
content: '<p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>' | ||
}, | ||
|
||
onReady: editor => { | ||
window.editor1 = editor; | ||
|
||
console.log( 'event: onChange', { editor } ); | ||
} | ||
} as MultiRootHookProps ); | ||
|
||
// Second editor initialization. | ||
const { | ||
editor: editor2, editableElements: editableElements2, toolbarElement: toolbarElement2 | ||
} = useMultiRootEditor( { | ||
...editorProps, | ||
data: { | ||
notes: '<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>' | ||
}, | ||
|
||
onReady: editor => { | ||
window.editor2 = editor; | ||
|
||
console.log( 'event: onChange', { editor } ); | ||
} | ||
} as MultiRootHookProps ); | ||
|
||
// Function to simulate an error in the editor. | ||
// It is used for testing purposes to trigger the Watchdog to restart the editor. | ||
// Remove it in the actual integration. | ||
const simulateError = ( editor: MultiRootEditor ) => { | ||
setTimeout( () => { | ||
const err: any = new Error( 'foo' ); | ||
|
||
err.context = editor; | ||
err.is = () => true; | ||
|
||
throw err; | ||
} ); | ||
}; | ||
|
||
return ( | ||
<> | ||
<h2 className="subtitle">Context Multi-root Editor Demo</h2> | ||
<p className="info"> | ||
This sample demonstrates integration with CKEditorContext.<br /> | ||
</p> | ||
<p className="info">Component's events are logged to the console.</p> | ||
<hr /><br /> | ||
|
||
<div> | ||
<div className="buttons"> | ||
<button | ||
onClick={ () => simulateError( editor1! ) } | ||
disabled={ !editor1 } | ||
> | ||
Simulate an error in first editor | ||
</button> | ||
</div> | ||
|
||
{ toolbarElement1 } | ||
|
||
<div className="flex"> | ||
{ editableElements1 } | ||
</div> | ||
</div> | ||
|
||
<br /> | ||
|
||
<div> | ||
<div className="buttons"> | ||
<button | ||
onClick={ () => simulateError( editor2! ) } | ||
disabled={ !editor2 } | ||
> | ||
Simulate an error in second editor | ||
</button> | ||
</div> | ||
|
||
{ toolbarElement2 } | ||
|
||
<div className="flex"> | ||
{ editableElements2 } | ||
</div> | ||
</div> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import React from 'react'; | ||
import MultiRootEditor from '@ckeditor/ckeditor5-build-multi-root'; | ||
|
||
import { useMultiRootEditor, type MultiRootHookProps } from '@ckeditor/ckeditor5-react'; | ||
|
||
type EditorDemoProps = { | ||
data: Record<string, string>; | ||
rootsAttributes: Record<string, Record<string, unknown>>; | ||
}; | ||
|
||
export default function MultiRootEditorDemo( props: EditorDemoProps ): JSX.Element { | ||
const editorProps: MultiRootHookProps = { | ||
editor: MultiRootEditor, | ||
data: props.data | ||
}; | ||
|
||
const { | ||
editor, toolbarElement, editableElements, | ||
data, setData, | ||
attributes, setAttributes | ||
} = useMultiRootEditor( editorProps ); | ||
|
||
return ( | ||
<> | ||
<h2 className="subtitle">Multi-root Editor Demo</h2> | ||
<p className="info"> | ||
This sample demonstrates the minimal React application that uses multi-root editor integration.<br /> | ||
You may use it as a starting point for your application. | ||
</p> | ||
<hr /><br /> | ||
|
||
<div> | ||
{ toolbarElement } | ||
|
||
{ editableElements } | ||
</div> | ||
</> | ||
); | ||
} |
Oops, something went wrong.