React Wrapper for the amazing SunEditor (A lightweight and powerful WYSIWYG editor in vanilla JavaScript)
$ npm install --save suneditor @sameem/react-suneditor # make sure to install suneditor yourselfimportReactfrom'react';importSunEditorfrom'@sameem/react-suneditor';import"suneditor/css/editor"// Import Sun Editor's CSS Fileimport"suneditor/css/contents";// Import Sun Editor's CSS FileconstMyComponent=props=>{return(<div><p> My Other Contents </p><SunEditor/></div>);};exportdefaultMyComponent;To use @sameem/react-suneditor with Next.js, please use the dynamic import syntax like below:
importReactfrom'react';importdynamicfrom"next/dynamic";import"suneditor/css/editor"// Import Sun Editor's CSS Fileimport"suneditor/css/contents";// Import Sun Editor's CSS FileconstSunEditor=dynamic(()=>import("@sameem/react-suneditor"),{ssr: false,});constMyComponent=props=>{return(<div><p> My Other Contents </p><SunEditor/></div>);};exportdefaultMyComponent;Note:@sameem/react-suneditor doesn't expose the core object in the callback functions such as onScroll etc. This is because it can be easily retrieved by using the getSunEditorInstance like below.
// Javascript VersionimportReact,{useRef,useEffect}from"react";importSunEditorfrom'@sameem/react-suneditor';import"suneditor/css/editor"// Import Sun Editor's CSS Fileimport"suneditor/css/contents";// Import Sun Editor's CSS FileconstMyComponent=props=>{/** * @type {React.MutableRefObject<SunEditor>} get type definitions for editor */consteditor=useRef();// The sunEditor parameter will be set to the core suneditor instance when this function is calledconstgetSunEditorInstance=(sunEditor)=>{editor.current=sunEditor;};return(<div><p> My Other Contents </p><SunEditorgetSunEditorInstance={getSunEditorInstance}/></div>);};exportdefaultMyComponent;// Typescript VersionimportReact,{useRef,useEffect}from"react";importSunEditorfrom'@sameem/react-suneditor';importSunEditorCorefrom"suneditor/src/lib/core";import"suneditor/css/editor"// Import Sun Editor's CSS Fileimport"suneditor/css/contents";// Import Sun Editor's CSS FileconstMyComponent=props=>{consteditor=useRef<SunEditorCore>();// The sunEditor parameter will be set to the core suneditor instance when this function is calledconstgetSunEditorInstance=(sunEditor: SunEditorCore)=>{editor.current=sunEditor;};return(<div><p> My Other Contents </p><SunEditorgetSunEditorInstance={getSunEditorInstance}/></div>);};exportdefaultMyComponent;lang
Language of editor
//...render(){return<SunEditorlang="en"/>// Default is en// lang prop can be one of the strings provided in this array ["en", "da", "de", "es", "fr", "ja", "ko", "pt_br", "ru", "zh_cn", "ro", "pl", "ckb", "lv", "se", "ua", "he", "it"]// Alternatively, an object of your language can be passed to this prop. To learn how to do it refer to the bottom of the page}name
HTML form name of editor
This is used to set the HTML form name of the editor. This means on HTML form submission, it will be submitted together with contents of the editor by the name provided.
//...render(){return<SunEditorname="my-editor"/>}defaultValue
Set Editor's default value
//...// Sets the default value of the editor.// This is useful if you don't want the onChange method to be called on render.// If you want the onChange method to be called on render please use the setContents proprender(){return<SunEditordefaultValue="<p>The editor's default value</p>"/>}width
Set Editor's width
//...// px and percentage values are accepted// eg width="100%" or width="500px"// default is 100%render(){return<SunEditorwidth="100%"/>}height
Set Editor's height
//...// px and percentage values are accepted// eg height="100%" or height="100px"render(){return<SunEditorheight="100%"/>}placeholder
Set Editor's placeholder
//...render(){return<SunEditorplaceholder="Please type here..."/>}autoFocus
Should editor focus when initialized
//...render(){return<SunEditorautoFocus={true}/>}setOptions
Set Options (Settings) for the editorClick to see all options available
Important Note: Some toolbar buttons in suneditor require specific plugins to make them work properly. For example when you specify 'font' in the button list, you will need to import the required plugin from suneditor. @sameem/react-suneditor by default loads all plugins. To change this behaviour, you can pass a plugin list of only the plugins you would like to load to the plugin option. This will override the default behaviour. To disable the loading of all plugins, set the setAllPlugins prop to false. Read More by clicking this.
importSunEditor,{buttonList}from"@sameem/react-suneditor";/* buttonList.basic = basic buttons for wordprocessing buttonList.formatting = most tools used for formatting - This is the default option buttonList.complex = contains most of the buttons*///...render(){return<SunEditorsetOptions={{height: 200,buttonList: buttonList.formatting// Or Array of button list, eg. [['font', 'align'], ['image']]// plugins: [font] set plugins, all plugins are set by default// Other option}}/>}setAllPlugins
Sets all plugins used by buttons. Default value is true
importSunEditor,{buttonList}from"@sameem/react-suneditor";//...render(){return<SunEditorsetAllPlugins={false}/>// When set to false, you must explicitly set required plugins}setContents
Set Editor's Content
Note: To set the initial contents of the editor without calling the onChange event please use the defaultValue prop.
setContents is used to set the contents of the editor programmatically. You must be aware that, when the setContents's prop changes, the onChange event is triggered.
//...render(){return<SunEditorsetContents="My contents"/>}appendContents
Append Editor Content
//...render(){return<SunEditorappendContents="My contents"/>}setDefaultStyle
Set the default style of the editor's edit area
//...render(){return<SunEditorsetDefaultStyle="font-family: cursive; font-size: 10px;"/>}disable
Disable Editor
//...render(){// set to false to enable, default value is falsereturn<SunEditordisable={true}/>}hide
Hide Editor
//...render(){// set to false to hide, default value is falsereturn<SunEditorhide={true}/>}hideToolbar
Hide Editor Toolbar
//...render(){// set to false to hide toolbar, default value is falsereturn<SunEditorhideToolbar={true}/>}disableToolbar
Disable Editor Toolbar
//...render(){// set to false to enable toolbar, default value is falsereturn<SunEditordisableToolbar={true}/>}Note that you need to bind the function passed to the event in the constructor if you are using a class Component, or use arrow functions instead. This is just how react works. Otherwise it won't work. This documentation assumes you bind all your class component methods to the constructor. Eg below:
constructor(props){super(props);this.handleChange=this.handleChange.bind(this)}onChange
Has the content inside the editor been changed?
handleChange(content){console.log(content);//Get Content Inside Editor}render(){return<SunEditoronChange={handleChange}/>}onScroll
Has the editor been scrolled?
handleScroll(event){console.log(event);//Get the scroll event}render(){return<SunEditoronScroll={handleScroll}/>}onClick
Has the editor been clicked?
handleClick(event){console.log(event);//Get the click event}render(){return<SunEditoronClick={handleClick}/>}onMouseDown
Has the mouse is pressed and not yet released?
handleMouseDown(event){console.log(event);//Get the click event}render(){return<SunEditoronMouseDown={handleMouseDown}/>}onInput
Has the editor received input?
handleInput(event){console.log(event);//Get the click event}render(){return<SunEditoronInput={handleInput}/>}onKeyUp
Has the key been released up in the editor?
handleKeyUp(event){console.log(event);//Get the keyup event}render(){return<SunEditoronKeyUp={handleKeyUp}/>}onFocus
Has the editor been focused?
handleFocus(event){console.log(event);//Get the focus event}render(){return<SunEditoronFocus={handleFocus}/>}onBlur
Has the editor been blurred?
From the second parameter you can get the contents of the editor.
handleBlur(event,editorContents){console.log(event,editorContents);//Get the blur event}render(){return<SunEditoronBlur={handleBlur}/>}onLoad
Has the editor been reloaded with setOptions?
handleLoad(reload){console.log(reload);//Boolean}render(){return<SunEditoronLoad={handleLoad}/>}onKeyDown
Has the key been pressed down in the editor?
handleKeyDown(event){console.log(event);//Get the keydown event}render(){return<SunEditoronKeyDown={handleKeyDown}/>}onDrop
Has something been dropped into the editor?
handleDrop(event){console.log(event);//Get the drop event}render(){return<SunEditoronDrop={handleDrop}/>}onImageUploadBefore
Before an image is uploaded into the editor
handleImageUploadBefore(files,info,uploadHandler){// uploadHandler is a functionconsole.log(files,info)}render(){return<SunEditoronImageUploadBefore={handleImageUploadBefore}/>}onImageUpload
Has an image been uploaded into the editor?
handleImageUpload(targetImgElement,index,state,imageInfo,remainingFilesCount){console.log(targetImgElement,index,state,imageInfo,remainingFilesCount)}render(){return<SunEditoronImageUpload={handleImageUpload}/>}onImageUploadError
Has an image uploaded to the editor resulted in an error?
handleImageUploadError(errorMessage,result){console.log(errorMessage,result)}render(){return<SunEditoronImageUploadError={handleImageUploadError}/>}onVideoUploadBefore
Before a video is uploaded to the editor
handleVideoUploadBefore(files,info,uploadHandler){// uploadHandler is a functionconsole.log(files,info)}render(){return<SunEditoronVideoUploadBefore={handleVideoUploadBefore}/>}onVideoUpload
Has an image been uploaded into the editor?
handleVideoUpload(targetElement,index,state,info,remainingFilesCount){console.log(targetElement,index,state,info,remainingFilesCount)}render(){return<SunEditoronVideoUpload={handleVideoUpload}/>}onVideoUploadError
Has a video uploaded to the editor resulted in an error?
handleVideoUploadError(errorMessage,result){console.log(errorMessage,result)}render(){return<SunEditoronVideoUploadError={handleVideoUploadError}/>}onAudioUploadBefore
Before an audio is uploaded to the editor
handleAudioUploadBefore(files,info,uploadHandler){// uploadHandler is a functionconsole.log(files,info)}render(){return<SunEditoronAudioUploadBefore={handleAudioUploadBefore}/>}onAudioUpload
Has an audio been uploaded into the editor?
handleAudioUpload(targetElement,index,state,info,remainingFilesCount){console.log(targetElement,index,state,info,remainingFilesCount)}render(){return<SunEditoronAudioUpload={handleAudioUpload}/>}onAudioUploadError
Has an audio uploaded to the editor resulted in an error?
handleAudioUploadError(errorMessage,result){console.log(errorMessage,result)}render(){return<SunEditoronAudioUploadError={handleAudioUploadError}/>}onResizeEditor
Has the editor been resized?
handleOnResizeEditor(height,prevHeight){console.log(height,prevHeight)}render(){return<SunEditoronResizeEditor={handleOnResizeEditor}/>}onCopy
Has something been copied from the suneditor?
handleCopy(e,clipboardData){console.log(e,clipboardData)}render(){return<SunEditoronCopy={handleCopy}/>}onCut
Has something been cut from the suneditor?
handleCut(e,clipboardData){console.log(e,clipboardData)}render(){return<SunEditoronCut={handleCut}/>}onPaste
Has something been pasted into the suneditor?
handlePaste(e,cleanData,maxCharCount){console.log(e,cleanData,maxCharCount)}render(){return<SunEditoronPaste={handlePaste}/>}imageUploadHandler
Replaces the default callback function of the image upload
imageUploadHandler(xmlHttpRequest,info,core){console.log(xmlHttpRequest,info,core)}render(){return<SunEditorimageUploadHandler={imageUploadHandler}/>}toggleCodeView
An event when toggling between code view and wysiwyg view
toggleCodeView(isCodeView){console.log(isCodeView)}render(){return<SunEditortoggleCodeView={toggleCodeView}/>}toggleFullScreen
An event when toggling full screen
toggleFullScreen(isFullScreen){console.log(isFullScreen)}render(){return<SunEditortoggleFullScreen={toggleFullScreen}/>}showInline
Called just before the inline toolbar is positioned and displayed on the screen.
showInline(toolbar,context){console.log(toolbar,context)}render(){return<SunEditorshowInline={showInline}/>}showController
Called just after the controller is positioned and displayed on the screen.
showController(name,controllers){console.log(name,controllers)}render(){return<SunEditorshowController={showController}/>}You can translate the object below to any other language and pass it to the lang prop to set your locale language if it is not part of the strings of array above.
Note: You will be aided by your editor's intellisense.
Note If you are using an object like below, you need to make sure that you memoize it so that it doesn't run setOptions every time the editor re-renders. You can do this using useRef or useMemo
{code: 'en',toolbar: {default: 'Default',save: 'Save',font: 'Font',formats: 'Formats',fontSize: 'Size',bold: 'Bold',underline: 'Underline',italic: 'Italic',strike: 'Strike',subscript: 'Subscript',superscript: 'Superscript',removeFormat: 'Remove Format',fontColor: 'Font Color',hiliteColor: 'Highlight Color',indent: 'Indent',outdent: 'Outdent',align: 'Align',alignLeft: 'Align left',alignRight: 'Align right',alignCenter: 'Align center',alignJustify: 'Align justify',list: 'List',orderList: 'Ordered list',unorderList: 'Unordered list',horizontalRule: 'Horizontal line',hr_solid: 'Solid',hr_dotted: 'Dotted',hr_dashed: 'Dashed',table: 'Table',link: 'Link',math: 'Math',image: 'Image',video: 'Video',audio: 'Audio',fullScreen: 'Full screen',showBlocks: 'Show blocks',codeView: 'Code view',undo: 'Undo',redo: 'Redo',preview: 'Preview',print: 'print',tag_p: 'Paragraph',tag_div: 'Normal (DIV)',tag_h: 'Header',tag_blockquote: 'Quote',tag_pre: 'Code',template: 'Template',lineHeight: 'Line height',paragraphStyle: 'Paragraph style',textStyle: 'Text style',imageGallery: 'Image gallery',dir_ltr: 'Left to right',dir_rtl: 'Right to left',mention: 'Mention'},dialogBox: {linkBox: {title: 'Insert Link',url: 'URL to link',text: 'Text to display',newWindowCheck: 'Open in new window',downloadLinkCheck: 'Download link',bookmark: 'Bookmark'},mathBox: {title: 'Math',inputLabel: 'Mathematical Notation',fontSizeLabel: 'Font Size',previewLabel: 'Preview'},imageBox: {title: 'Insert image',file: 'Select from files',url: 'Image URL',altText: 'Alternative text'},videoBox: {title: 'Insert Video',file: 'Select from files',url: 'Media embed URL, YouTube/Vimeo'},audioBox: {title: 'Insert Audio',file: 'Select from files',url: 'Audio URL'},browser: {tags: 'Tags',search: 'Search',},caption: 'Insert description',close: 'Close',submitButton: 'Submit',revertButton: 'Revert',proportion: 'Constrain proportions',basic: 'Basic',left: 'Left',right: 'Right',center: 'Center',width: 'Width',height: 'Height',size: 'Size',ratio: 'Ratio'},controller: {edit: 'Edit',unlink: 'Unlink',remove: 'Remove',insertRowAbove: 'Insert row above',insertRowBelow: 'Insert row below',deleteRow: 'Delete row',insertColumnBefore: 'Insert column before',insertColumnAfter: 'Insert column after',deleteColumn: 'Delete column',fixedColumnWidth: 'Fixed column width',resize100: 'Resize 100%',resize75: 'Resize 75%',resize50: 'Resize 50%',resize25: 'Resize 25%',autoSize: 'Auto size',mirrorHorizontal: 'Mirror, Horizontal',mirrorVertical: 'Mirror, Vertical',rotateLeft: 'Rotate left',rotateRight: 'Rotate right',maxSize: 'Max size',minSize: 'Min size',tableHeader: 'Table header',mergeCells: 'Merge cells',splitCells: 'Split Cells',HorizontalSplit: 'Horizontal split',VerticalSplit: 'Vertical split'},menu: {spaced: 'Spaced',bordered: 'Bordered',neon: 'Neon',translucent: 'Translucent',shadow: 'Shadow',code: 'Code'}}Special Thanks to JiHong88 for the suneditor package.
Pull requests are welcome
@sameem/react-suneditor may be freely distributed under the MIT license.