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)