Table of Contents
- Create a simple react app
- Create a simple architecture
- Install all necessary dependencies
- Create and configure the Editor component
- Use it
Create a simple react app
npx create-react-app wyswig-editor --typescript
cd wyswig-editor
yarn start
Create a simple architecture
-> In the terminal execute following:
cd src && mkdir components editor
Install all necessary dependencies
-> Using Yarn:
yarn add react-draft-wysiwyg draft-js draftjs-to-html @types/react-draft-wysiwyg @types/draftjs @types/draft-to-html
-> Using Npm:
npm install react-draft-wysiwyg draft-js draftjs-to-html @types/react-draft-wysiwyg @types/draftjs @types/draft-to-html
-> Without Typescript only:
yarn add react-draft-wysiwyg draft-js draftjs-to-html
Create and configure the Editor component
-> src/components/WysiwygEditor.tsx
import React, { Fragment, useCallback } from 'react';
import { Editor as ReactWysiwygEditor } from 'react-draft-wysiwyg';
import { useEditor, useEditorConfig } from '../../editor';
export const WysiwygEditor = () => {
const { editorOptions } = useEditorConfig();
const {
editorState,
setEditorState,
enteredText,
setEnteredText,
convertedHtml,
getEditorText,
} = useEditor();
const handleEditorStateChange = useCallback(
(editorState) => {
const text = getEditorText(editorState.getCurrentContent());
setEditorState(editorState);
setEnteredText(text);
},
[getEditorText, setEditorState, setEnteredText]
);
return (
<Fragment>
<ReactWysiwygEditor
editorState={editorState}
onEditorStateChange={handleEditorStateChange}
placeholder="Type here..."
toolbar={editorOptions}
/>
<textarea
className="textarea"
disabled
value={editorState && convertedHtml}
/>
<div>Editor text: {enteredText}</div>
</Fragment>
);
};
-> src/utils/helpers/constants.ts
export const DEFAULT_IMAGE_SIZE = {
height: '500',
width: '500',
};
export const EDITOR_OPTIONS = [
'inline',
'blockType',
'list',
'textAlign',
'history',
'image',
];
-> src/utils/helpers/index.ts
export * from './constants';
-> src/editor/hooks/index.ts
export * from './useEditor';
export * from './useEditorConfig';
-> src/editor/hooks/useEditor.ts
import { ContentState, convertToRaw, EditorState } from 'draft-js';
import draftToHtml from 'draftjs-to-html';
import { useCallback, useState } from 'react';
export const useEditor = () => {
const [editorState, setEditorState] = useState<EditorState>(
EditorState.createEmpty() || null
);
const [enteredText, setEnteredText] = useState<string>('');
const [uploadImages, setUploadImages] = useState<any>([]);
const getEditorText = useCallback(
(raw: ContentState) => raw.getPlainText(),
[]
);
const rawData = convertToRaw(editorState.getCurrentContent());
const convertedHtml = draftToHtml(rawData);
return {
enteredText,
setEnteredText,
editorState,
setEditorState,
convertedHtml,
rawData,
getEditorText,
};
};
-> src/editor/hooks/useEditorConfig.ts
import { useCallback } from 'react';
import { DEFAULT_IMAGE_SIZE, EDITOR_OPTIONS } from '../../utils';
export const useEditorConfig = () => {
const makeEditorOptions = useCallback(() => {
return {
options: EDITOR_OPTIONS,
image: {
alt: { present: true, mandatory: true },
defaultSize: DEFAULT_IMAGE_SIZE,
},
blockType: { inDropdown: true },
inline: { inDropdown: false },
list: { inDropdown: false },
textAlign: { inDropdown: false },
link: { inDropdown: false },
history: { inDropdown: false },
};
}, []);
const editorOptions = makeEditorOptions();
return { editorOptions };
};
Use it
-> App.tsx
import React from 'react';
import { WysiwygEditor } from './components';
import './App.css';
const App = () => {
return (
<>
<WysiwygEditor />
</>
);
}
export default App;
-> App.css
.App {
margin-left: 20px;
}
.textarea {
width: 35vw;
height: 20vh;
}
Now you can see the result:
Useful links:
React official docs
React Wysiwyg Editor
Thank you for reading this article! I hope you find it useful🚀
Top comments (0)