├── .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 | [![react-ckeditor-component](https://nodei.co/npm/react-ckeditor-component.png)](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 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 |
nametypedefaultmandatorydescription
contentanyNoDefault value to be set in CKEditor
onChange (Deprecated)functionNoDeprecated in v1.0.6. Is now handled via events prop.
configobjectNoConfigs to be passed in CKEditor
isScriptLoadedbooleanfalseNoPass true if ckeditor script is already loaded in project
scriptUrlstringStandard CKEditorNoThe CKEditor script that needs to be loaded. Pass a custom script with plugins if you need a customized CKEditor.
activeClassstringNoAny Css class to be used with CKEditor container div.
events (New)objectNoAn object of custom event handlers so that you can listen to any CKEditor event (Added in v1.0.6)
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 | --------------------------------------------------------------------------------