├── .babelrc
├── .editorconfig
├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── example
├── example.js
└── index.html
├── package.json
└── src
├── ckeditor.js
└── index.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react"]
3 | }
4 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 |
3 | # A special property that should be specified at the top of the file outside of
4 | # any sections. Set to true to stop .editor config file search on current file
5 | root = true
6 |
7 | [*]
8 | # Indentation style
9 | # Possible values - tab, space
10 | indent_style = space
11 |
12 | # Indentation size in single-spaced characters
13 | # Possible values - an integer, tab
14 | indent_size = 2
15 |
16 | # Line ending file format
17 | # Possible values - lf, crlf, cr
18 | end_of_line = lf
19 |
20 | # File character encoding
21 | # Possible values - latin1, utf-8, utf-16be, utf-16le
22 | charset = utf-8
23 |
24 | # Denotes whether to trim whitespace at the end of lines
25 | # Possible values - true, false
26 | trim_trailing_whitespace = true
27 |
28 | # Denotes whether file should end with a newline
29 | # Possible values - true, false
30 | insert_final_newline = true
31 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | *.log
3 | .idea/
4 | .ipr
5 | .iws
6 | *~
7 | ~*
8 | *.diff
9 | *.patch
10 | *.bak
11 | .DS_Store
12 | Thumbs.db
13 | .project
14 | .*proj
15 | .svn/
16 | *.swp
17 | *.swo
18 | *.pyc
19 | *.pyo
20 | .build
21 | node_modules
22 | .cache
23 | dist
24 | assets/**/*.css
25 | build
26 | lib
27 | coverage
28 | yarn.lock
29 | example/bundle.js
30 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | *
2 | !lib/*
3 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Akash
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-ckeditor-component
2 |
3 | **React component for CKEditor**
4 |
5 | ## Installation
6 |
7 | [](https://npmjs.org/package/react-ckeditor-component)
8 |
9 | ## Usage
10 |
11 | ```js
12 | import CKEditor from "react-ckeditor-component";
13 |
14 | class Example extends Component {
15 | constructor(props) {
16 | super(props);
17 | this.updateContent = this.updateContent.bind(this);
18 | this.state = {
19 | content: 'content',
20 | }
21 | }
22 |
23 | updateContent(newContent) {
24 | this.setState({
25 | content: newContent
26 | })
27 | }
28 |
29 | onChange(evt){
30 | console.log("onChange fired with event info: ", evt);
31 | var newContent = evt.editor.getData();
32 | this.setState({
33 | content: newContent
34 | })
35 | }
36 |
37 | onBlur(evt){
38 | console.log("onBlur event called with event info: ", evt);
39 | }
40 |
41 | afterPaste(evt){
42 | console.log("afterPaste event called with event info: ", evt);
43 | }
44 |
45 | render() {
46 | return (
47 |
56 | )
57 | }
58 | }
59 | ```
60 |
61 | The package also includes an in-built example under the `/example` folder. Run the sample application by cloning project and running npm start.
62 |
63 | ## Props
64 |
65 |
66 |
67 |
68 | name |
69 | type |
70 | default |
71 | mandatory |
72 | description |
73 |
74 |
75 |
76 |
77 | content |
78 | any |
79 | |
80 | No |
81 | Default value to be set in CKEditor |
82 |
83 |
84 | onChange (Deprecated) |
85 | function |
86 | |
87 | No |
88 | Deprecated in v1.0.6. Is now handled via events prop. |
89 |
90 |
91 | config |
92 | object |
93 | |
94 | No |
95 | Configs to be passed in CKEditor |
96 |
97 |
98 | isScriptLoaded |
99 | boolean |
100 | false |
101 | No |
102 | Pass true if ckeditor script is already loaded in project |
103 |
104 |
105 | scriptUrl |
106 | string |
107 | Standard CKEditor |
108 | No |
109 | The CKEditor script that needs to be loaded. Pass a custom script with plugins if you need a customized CKEditor. |
110 |
111 |
112 | activeClass |
113 | string |
114 | |
115 | No |
116 | Any Css class to be used with CKEditor container div. |
117 |
118 |
119 | events (New) |
120 | object |
121 | |
122 | No |
123 | An object of custom event handlers so that you can listen to any CKEditor event (Added in v1.0.6) |
124 |
125 |
126 |
127 |
128 | Note- Starting v1.0.6, you can listen to `change` event directly by passing its event handler in `events` prop instead of passing a separate onChange prop. The onChange prop is now deprecated.
129 |
130 | ## License
131 |
132 | `react-ckeditor-component` is released under the `MIT license`.
133 |
--------------------------------------------------------------------------------
/example/example.js:
--------------------------------------------------------------------------------
1 | const React = require('react');
2 | const ReactDOM = require('react-dom');
3 | import CKEditor from "../src";
4 |
5 | class Example extends React.Component {
6 | constructor(props){
7 | super(props);
8 |
9 | //State initialization
10 | this.state = {
11 | content: "Hello World"
12 | };
13 | this.setContent = this.setContent.bind(this)
14 | }
15 |
16 | //------ Test for race condition ------ //
17 | setContent(){
18 | console.log("Setting content");
19 | this.setState({
20 | content: "Hello World " + Math.random()
21 | })
22 | }
23 |
24 | onChange(evt){
25 | console.log("onChange fired with event info: ",evt, "and data: ",evt.editor.getData());
26 | }
27 |
28 | onBlur(evt){
29 | console.log("onBlur fired with event info: ",evt);
30 | }
31 |
32 | afterPaste(evt){
33 | console.log("afterPaste fired with event info: ",evt);
34 | }
35 |
36 | render() {
37 | return (
38 |
39 |
49 | );
50 | }
51 | }
52 |
53 | ReactDOM.render(
54 | ,
55 | document.getElementById('example')
56 | );
57 |
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | React CKEditor Component
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-ckeditor-component",
3 | "version": "1.1.0",
4 | "description": "CKEditor component for React",
5 | "keywords": [
6 | "react",
7 | "component",
8 | "ckeditor",
9 | "react-ckeditor",
10 | "ckeditor-library",
11 | "ckeditor-component"
12 | ],
13 | "homepage": "https://github.com/codeslayer1/react-ckeditor",
14 | "repository": {
15 | "type": "git",
16 | "url": "https://github.com/codeslayer1/react-ckeditor.git"
17 | },
18 | "maintainers": [
19 | "codeslayer1"
20 | ],
21 | "author": "codeslayer1",
22 | "bugs": {
23 | "url": "https://github.com/codeslayer1/react-ckeditor/issues"
24 | },
25 | "licenses": "MIT",
26 | "scripts": {
27 | "prepublish": "babel --out-dir ./lib ./src",
28 | "test": "echo \"Error: no test specified\" && exit 1",
29 | "build-example": "browserify ./example/example.js -o ./example/bundle.js -t [ babelify --presets [ es2015 react ] ]",
30 | "serve-example": "http-server ./example/ -p 8080",
31 | "start": "npm run build-example; npm run serve-example",
32 | "compile": "rimraf lib/* && babel src -d lib"
33 | },
34 | "main": "./lib/index.js",
35 | "devDependencies": {
36 | "react": "^15.4.1",
37 | "react-dom": "^15.4.1",
38 | "http-server": "^0.9.0",
39 | "browserify": "^13.1.1",
40 | "babelify": "^7.3.0",
41 | "babel-cli": "^6.11.4",
42 | "babel-core": "^6.13.2",
43 | "babel-preset-es2015": "^6.9.0",
44 | "prop-types": "^15.5.4",
45 | "rimraf": "^2.5.4"
46 | },
47 | "dependencies": {
48 | "babel-plugin-transform-runtime": "^6.23.0",
49 | "babel-preset-react": "^6.16.0",
50 | "babel-runtime": "^6.11.6",
51 | "load-script": "^1.0.0"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/ckeditor.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import ReactDOM from 'react-dom';
4 | const loadScript = require('load-script');
5 |
6 | var defaultScriptUrl = 'https://cdn.ckeditor.com/4.6.2/standard/ckeditor.js';
7 |
8 | /**
9 | * @author codeslayer1
10 | * @description CKEditor component to render a CKEditor textarea with defined configs and all CKEditor events handler
11 | */
12 | class CKEditor extends React.Component {
13 | constructor(props) {
14 | super(props);
15 |
16 | //Bindings
17 | this.onLoad = this.onLoad.bind(this);
18 |
19 | //State initialization
20 | this.state = {
21 | isScriptLoaded: props.isScriptLoaded
22 | };
23 | }
24 |
25 | //load ckeditor script as soon as component mounts if not already loaded
26 | componentDidMount() {
27 | if (!this.state.isScriptLoaded) {
28 | loadScript(this.props.scriptUrl, this.onLoad);
29 | } else {
30 | this.onLoad();
31 | }
32 | }
33 |
34 | componentWillReceiveProps(props) {
35 | const editor = this.editorInstance;
36 | if (editor && editor.getData() !== props.content) {
37 | editor.setData(props.content);
38 | }
39 | }
40 |
41 | componentWillUnmount() {
42 | this.unmounting = true;
43 | }
44 |
45 | onLoad() {
46 | if (this.unmounting) return;
47 |
48 | this.setState({
49 | isScriptLoaded: true
50 | });
51 |
52 | if (!window.CKEDITOR) {
53 | console.error('CKEditor not found');
54 | return;
55 | }
56 |
57 | this.editorInstance = window.CKEDITOR.appendTo(
58 | ReactDOM.findDOMNode(this),
59 | this.props.config,
60 | this.props.content
61 | );
62 |
63 | //Register listener for custom events if any
64 | for (var event in this.props.events) {
65 | var eventHandler = this.props.events[event];
66 |
67 | this.editorInstance.on(event, eventHandler);
68 | }
69 | }
70 |
71 | render() {
72 | return ;
73 | }
74 | }
75 |
76 | CKEditor.defaultProps = {
77 | content: '',
78 | config: {},
79 | isScriptLoaded: false,
80 | scriptUrl: defaultScriptUrl,
81 | activeClass: '',
82 | events: {}
83 | };
84 |
85 | CKEditor.propTypes = {
86 | content: PropTypes.any,
87 | config: PropTypes.object,
88 | isScriptLoaded: PropTypes.bool,
89 | scriptUrl: PropTypes.string,
90 | activeClass: PropTypes.string,
91 | events: PropTypes.object
92 | };
93 |
94 | export default CKEditor;
95 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | module.exports = require('./ckeditor');
2 |
--------------------------------------------------------------------------------