Skip to content

Commit

Permalink
Merge pull request #367 from ckeditor/ck/13542
Browse files Browse the repository at this point in the history
Feature: Migrate package to TypeScript. Closes ckeditor/ckeditor5#13542.

MAJOR BREAKING CHANGE: Integration now requires Editor version 37 or later.
  • Loading branch information
pomek committed Mar 29, 2023
2 parents 8dbce7c + 94347c2 commit 4f6c383
Show file tree
Hide file tree
Showing 48 changed files with 4,600 additions and 2,070 deletions.
24 changes: 21 additions & 3 deletions .eslintrc.js
Expand Up @@ -13,7 +13,6 @@ module.exports = {
'node': true,
'mocha': true
},
'parser': 'babel-eslint',
'extends': [
'eslint:recommended',
'ckeditor5',
Expand Down Expand Up @@ -45,7 +44,9 @@ module.exports = {
{
'files': [
'**/*.js',
'**/*.jsx'
'**/*.jsx',
'**/*.ts',
'**/*.tsx'
],
'rules': {
'ckeditor5-rules/ckeditor-error-message': 'off'
Expand All @@ -54,11 +55,28 @@ module.exports = {
{
'files': [
'tests/**/*.js',
'tests/**/*.jsx'
'tests/**/*.jsx',
'tests/**/*.ts',
'tests/**/*.tsx'
],
'rules': {
'no-unused-expressions': 'off'
}
},
{
'files': [
'demo*/**/*.ts',
'demo*/**/*.tsx'
],
'rules': {
'ckeditor5-rules/license-header': 'off'
}
},
{
files: [ '**/tests/**/*.ts', '**/tests/**/*.tsx' ],
rules: {
'@typescript-eslint/no-unused-expressions': 'off'
}
}
]
};
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -2,3 +2,4 @@ node_modules/
coverage/
dist/
.idea
.tmp
8 changes: 4 additions & 4 deletions .travis.yml
Expand Up @@ -13,11 +13,11 @@ before_install:
- export COVERALLS_SERVICE_JOB_ID=$( TRAVIS_JOB_ID )
- export START_TIME=$( date +%s )
install:
- npm install
- yarn install
script:
- npm run lint
- npm run build
- npm run coverage
- yarn run lint
- yarn run build
- yarn run coverage
- if [[ $TRAVIS_TEST_RESULT -eq 0 ]]; then cat coverage/lcov.info | ./node_modules/.bin/coveralls; fi
after_script:
- export END_TIME=$( date +%s )
Expand Down
34 changes: 34 additions & 0 deletions demo-react-16/index.html
@@ -0,0 +1,34 @@
<!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;
}
</style>
</head>

<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>

</html>


24 changes: 24 additions & 0 deletions demo-react-16/package.json
@@ -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-classic": "37.0.0-alpha.3",
"react": "^16.13.1",
"react-dom": "^16.13.1"
},
"devDependencies": {
"@types/react": "^16.14.35",
"@types/react-dom": "^16.9.18",
"@vitejs/plugin-react": "^3.1.0",
"typescript": "^4.9.3",
"vite": "^4.2.0"
}
}
File renamed without changes
61 changes: 61 additions & 0 deletions demo-react-16/src/App.tsx
@@ -0,0 +1,61 @@
import React, { type ReactNode } from 'react';
import EditorDemo from './EditorDemo';
import ContextDemo from './ContextDemo';

type AppState = {
demo: 'editor' | 'context';
};

const editorContent = `
<h2>Sample</h2>
<p>This is an instance of the <a href="https://ckeditor.com/docs/ckeditor5/latest/builds/guides/overview.html#classic-editor">
classic editor build</a>.
</p>
<figure class="image">
<img src="/sample.jpg" alt="CKEditor 5 Sample image." />
</figure>
<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>
`;

// eslint-disable-next-line @typescript-eslint/ban-types
export default class App extends React.Component<{}, AppState> {
public state: AppState = {
demo: 'editor'
};

public render(): ReactNode {
return (
<React.StrictMode>
<h1>CKEditor 5 – React Component – development sample</h1>

<div className="buttons" style={{ textAlign: 'center' }}>
<button
onClick={ () => this.showDemo( 'editor' ) }
disabled={ this.state.demo == 'editor' }
>
Editor demo
</button>

<button
onClick={ () => this.showDemo( 'context' ) }
disabled={ this.state.demo == 'context' }
>
Context demo
</button>
</div>
{
this.state.demo == 'editor' ?
<EditorDemo content={ editorContent }/> :
<ContextDemo content={ editorContent }/>
}
</React.StrictMode>
);
}

private showDemo( demo: AppState[ 'demo' ] ) {
this.setState( {
demo
} );
}
}
87 changes: 87 additions & 0 deletions demo-react-16/src/ContextDemo.tsx
@@ -0,0 +1,87 @@
import React, { type ReactNode } from 'react';
import ClassicEditor from '@ckeditor/ckeditor5-build-classic';
import { CKEditor, CKEditorContext } from '@ckeditor/ckeditor5-react';

type ContextDemoProps = {
content: string;
};

type ContextDemoState = {
editor1: ClassicEditor | null;
editor2: ClassicEditor | null;
};

export default class ContextDemo extends React.Component<ContextDemoProps, ContextDemoState> {
public state: ContextDemoState = {
editor1: null,
editor2: null
};

public render(): ReactNode {
return (
<>
<h2 className="subtitle">Editor Context Demo</h2>
<p className="info">Component&apos;s events are logged to the console.</p>

<CKEditorContext context={ ClassicEditor.Context }>
<div className="buttons">
<button
onClick={ () => this.simulateError( this.state.editor1! ) }
disabled={ !this.state.editor1 }
>
Simulate an error in the first editor
</button>
</div>

<CKEditor
editor={ ClassicEditor }
data={ this.props.content }

onReady={ editor => {
window.editor2 = editor;

console.log( 'event: onReady' );
console.log( 'Editor is ready to use! You can use "editor1" variable to play with it.' );

this.setState( { editor1: editor } );
} }
/>

<div className="buttons">
<button
onClick={ () => this.simulateError( this.state.editor2! ) }
disabled={ !this.state.editor2 }
>
Simulate an error in the second editor
</button>
</div>

<CKEditor
editor={ ClassicEditor }
data="<h2>Another Editor</h2><p>... in common Context</p>"

onReady={ editor => {
window.editor1 = editor;

console.log( 'event: onReady' );
console.log( 'Editor is ready to use! You can use "editor2" variable to play with it.' );

this.setState( { editor2: editor } );
} }
/>
</CKEditorContext>
</>
);
}

private simulateError( editor: ClassicEditor ) {
setTimeout( () => {
const err: any = new Error( 'foo' );

err.context = editor;
err.is = () => true;

throw err;
} );
}
}

0 comments on commit 4f6c383

Please sign in to comment.