What is this post about?
From creating a simple comment input box with some basic features to creating a rich text editor for your CMS, finding the proper solution and development path can be challenging and time consumable. In this post, I'll introduce you to a way to create a rich text editor (RTE) with draft-js and contenidojs that will adapt to your UI library and your design principles.
What we're going to check? (Table of contents)
draft-js
introductioncontenidojs
contenidojs
+ TypeScriptcontenidojs
compatibility with different UI libs- How to build a simple RTE in
react
withcontenidojs
? contenidojs
+nextjs
Draft-JS (Powerful but confusing)
As the draft-js official website says, draft-js is a:
Rich Text Editor Framework for React
Although the draft-js home page example is basic, the true power that comes with it is a lot. You can almost create whatever you like to be your RTE. Draft-js lets you to do simple inline styling, media handling and add complicated stuffs like mentions and hashtags.
You'll indeed have a first-class rich text editor, but it takes a lot of effort and time for more complicated things. You'll be ok if you just need to add bold
and italic
styles for example. But things became harder to handle and understand when your needs of the editor is more than that. Unfortunately, the draft-js documentation isn't that comprehensive and sometimes you can't find your answers on the docs. This is the point that contenido-js
become handy.
ContenidoJS (A game changer for draft-js)
Contenidojs is a react library on top of draft-js. This means it will use draft-js as its core and add something that makes it more powerful and easier to use. If you have experience in using the redux and redux toolkit, You can feel the difference here as well. You can think of draft-js as redux and the contenidojs will be RTK (Redux Toolkit).
We'll check out the contenidojs library compatibility with Next.js and UI libraries later on in this article, but these are some of contenido's features and benefits:
- Basic inline styles as well as custom ones
- Ready-to-use utilities for headings, lists, blockquotes, and more.
- Ready-to-use utilities for handling media. (You'll get mad if you want to implement these just with
draft-js
) - Text alignment utilities
- Style, block type, and media clearance
- Shortcut support and customization
- Utilities to limit the user, count the editor entities
Check out the contenido's features here.
ContenidoJS and TypeScript
While draft-js
is written in JS and you need to add types to it manually, contenidojs
is written in TypeScript and you don't need to do extra stuffs for type handling.
ContenidoJS + UI Libraries and Styling
You may find a lot of packages and frameworks that offer you a solution to create and add an RTE to your project easily but there is a common issue and its styling. You may find customization in their docs but when you try to customize the editor you won't be able to customize them that much. Despite other libraries, contenidojs isn't an 'install and use' text editor. It will do all the editor-handling stuff and lets you focus on the UI. So you can easily build an RTE with your favorite UI library like Material-UI (MUI), Tailwind CSS, Bootstrap, Ant Design, Chakra UI, and ...
The main purpose is to give you the ability to create your custom look rich-text editor a lot faster and easier.
Contenido's Home Page
How to build a simple RTE in react
with contenidojs
?
This is an example of using contenidojs
in your code. For more examples check out the official docs.
Setup
- First we'll create a react app. TypeScript:
npx create-react-app contenidojs-tutorial --template typescript
JavaScript:
npx create-react-app contenidojs-tutorial
- Then install
draft-js
.
TypeScript:
npm i draft-js @types/draft-js
JavaScript:
npm i draft-js
- And finally install contenidojs: ```bash
npm i contenido
ContenidoJS is written in TypeScript and there is no need to install types for that.
### Usage
This is an example of an editor component with shortcuts and `bold`, `italic` and `underline` utilities.
```ts
import { useState } from 'react';
import { EditorState } from 'draft-js';
import {
Editor,
isBold,
toggleBold ,
isItalic,
toggleItalic,
isUnderline,
toggleUnderline,
getDefaultKeyBindingFn,
shortcutHandler
} from 'contenido';
const CustomEditor = () => {
const [editorState, setEditorState] =
useState(EditorState.createEmpty());
const toolbarButtons = [
{name: 'Bold', handler: toggleBold, detector: isBold},
{name: 'Italic', handler: toggleItalic, detector: isItalic},
{name: 'Underline', handler: toggleUnderline, detector: isUnderline},
]
return (
<>
<Editor
editorState={editorState}
onChange={setEditorState}
handleKeyCommand={shortcutHandler(setEditorState)}
keyBindingFn={getDefaultKeyBindingFn}
/>
{
toolbarButtons.map(btn => (
<button
key={btn.name}
onMouseDown={(e) => {
e.preventDefault();
btn.handler(editorState, setEditorState)
}}
style={{
color: btn.detector(editorState) ?
'skyblue'
:
'black'
}}
>
{btn.name}
</button>
))
}
</>
)
}
export default CustomEditor;
For more examples check out the official site.
ContenidoJS and Next.js
You can use contenidojs with SSR as well. The only thing that you need to pay attention is the very first state of your editor. Each block in draft-js state have a unique key. This may cause issues when you're using SSR frameworks for react like Next.js. To solve the issue (Base on this doc):
import { useState } from 'react';
import { EditorState } from 'draft-js';
import { Editor, emptyRawContentState } from 'contenido';
const emptyContentState = convertFromRaw(emptyRawContentState)
const Demo = () => {
const [editorState, setEditorState] = useState(
EditorState.createWithContent(emptyContentState)
);
return (
<Editor
editorState={editorState}
onChange={setEditorState}
editorRef={editorRef}
>
)
}
export default Demo;
Hi! I'm Hosein Pouyanmehr. I enjoy sharing what I learn and what I find interesting. Let's connect on LinkedIn.
See my code interests on GitHub.
Top comments (4)
am copy & paste this codes to my project. and if they work 'ill be the happiest person on office planet
😁😁
Did it work as you expected?
Yes man. thanks.
my manager thinks am the genius they've been looking for, if only they knew..... Hahahahahaaa!!
You're welcome,
Happy to hear that!