React-Draft-WYSIWYG: A Rich Text Editor for React
`react-draft-wysiwyg` is a popular React component that provides a powerful and customizable WYSIWYG (What You See Is What You Get) rich text editor. It is built on top of Facebook's `draft-js` library, which is a framework for building rich text editors in React. While `draft-js` offers a low-level API for editor state management, `react-draft-wysiwyg` abstracts much of that complexity, offering a ready-to-use, feature-rich user interface.
# Key Features:
1. Rich Text Formatting: Supports common formatting options like bold, italic, underline, strikethrough, monospace, font size, font family, and text color.
2. Block Types: Allows for different block types such as headings (h1-h6), blockquotes, code blocks, unordered lists, and ordered lists.
3. Alignment and Indentation: Provides controls for text alignment (left, center, right, justify) and indentation.
4. Links and Images: Easy insertion and management of hyperlinks and images, often with built-in upload capabilities or URL embedding.
5. Undo/Redo History: Standard undo and redo functionalities.
6. Full-Screen Mode: A toggle to expand the editor to full screen for better focus.
7. Customizable Toolbar: The toolbar is highly customizable, allowing developers to choose which controls to display and even create custom controls.
8. Internationalization (i18n): Supports multiple languages for the toolbar and editor messages.
9. Markdown Support: Can convert content to Markdown or HTML for persistence.
10. Accessibility: Designed with accessibility in mind.
# Why Use It?
- Simplifies Rich Text Editing: Instead of building an editor from scratch with `draft-js`, `react-draft-wysiwyg` provides a full-featured UI out-of-the-box, significantly reducing development time.
- Leverages Draft.js Power: It benefits from `draft-js`'s immutable editor state, robust content management, and extensibility, while offering a developer-friendly API.
- Highly Customizable: Despite being a complete solution, it offers extensive customization options for the toolbar, styling, and even integrating custom blocks.
- Active Community & Maintenance: It's a widely used library with good community support and ongoing maintenance.
# How It Works:
At its core, `react-draft-wysiwyg` manages the editor's content and selection using `EditorState` objects from `draft-js`. The `Editor` component takes an `editorState` prop (an immutable record that represents the full state of the editor) and an `onEditorStateChange` callback. When a user interacts with the editor, a new `EditorState` is generated, which you then pass back to the `Editor` component to re-render it. This controlled component pattern is typical for React inputs.
To integrate it into a React application, you typically install both `react-draft-wysiwyg` and `draft-js`.
Installation:
`npm install react-draft-wysiwyg draft-js`
or
`yarn add react-draft-wysiwyg draft-js`
And don't forget to import its CSS for proper styling: `import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css';`
Example Code
import React, { useState } from 'react';
import { EditorState, convertToRaw, ContentState } from 'draft-js';
import { Editor } from 'react-draft-wysiwyg';
import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css'; // Import the editor's CSS
function MyWysiwygEditor() {
// Initialize editorState with an empty editor
const [editorState, setEditorState] = useState(() =>
EditorState.createEmpty()
);
// Callback function to update editorState when content changes
const onEditorStateChange = (newEditorState) => {
setEditorState(newEditorState);
};
// Function to log the raw content of the editor to the console
const logEditorContent = () => {
const contentState = editorState.getCurrentContent();
console.log('Raw Editor Content:', convertToRaw(contentState));
};
return (
<div style={{
border: '1px solid #ddd',
minHeight: '350px',
padding: '10px',
borderRadius: '5px',
fontFamily: 'Arial, sans-serif'
}}>
<h2 style={{ textAlign: 'center', color: '#333' }}>React Draft WYSIWYG Editor Example</h2>
<Editor
editorState={editorState}
onEditorStateChange={onEditorStateChange}
wrapperClassName="demo-wrapper"
editorClassName="demo-editor"
toolbarClassName="demo-toolbar"
placeholder="Start typing your rich text here..."
toolbar={{
options: [
'inline', 'blockType', 'fontSize', 'fontFamily', 'list',
'textAlign', 'colorPicker', 'link', 'image', 'history'
],
inline: { inDropdown: false, options: ['bold', 'italic', 'underline', 'strikethrough', 'monospace'] },
list: { inDropdown: true },
textAlign: { inDropdown: true },
link: { inDropdown: true, options: ['link', 'unlink'] },
image: {
uploadEnabled: true,
urlEnabled: true,
alignmentEnabled: true,
uploadCallback: (file) => {
return new Promise(
(resolve, reject) => {
// Simulate image upload
setTimeout(() => {
resolve({ data: { link: URL.createObjectURL(file) } });
}, 500);
}
);
},
previewImage: true,
inputAccept: 'image/gif,image/jpeg,image/jpg,image/png,image/svg',
alt: { present: false, mandatory: false },
defaultSize: { height: 'auto', width: 'auto' },
},
history: { inDropdown: false, options: ['undo', 'redo'] },
}}
/>
<button
onClick={logEditorContent}
style={{
marginTop: '15px',
padding: '10px 20px',
backgroundColor: '#007bff',
color: 'white',
border: 'none',
borderRadius: '5px',
cursor: 'pointer',
fontSize: '16px',
fontWeight: 'bold'
}}
>
Log Editor Content to Console
</button>
<div style={{ marginTop: '25px', borderTop: '1px solid #eee', paddingTop: '15px' }}>
<h3>Current Raw Content (JSON Preview):</h3>
<pre style={{
backgroundColor: '#f8f8f8',
padding: '15px',
borderRadius: '5px',
border: '1px solid #ddd',
overflowX: 'auto',
whiteSpace: 'pre-wrap',
wordWrap: 'break-word'
}}>
{JSON.stringify(convertToRaw(editorState.getCurrentContent()), null, 2)}
</pre>
</div>
</div>
);
}
export default MyWysiwygEditor;








react-draft-wysiwyg