A rich text editor’s aim is to reduce the effort for users trying to express their formatting as valid HTML markup. A rich text editor enables the users the option to format their text.
Everyone has used a rich text editor at some point. So why not build one? Here are some of the most used rich text editor examples.
- Reddit, YouTube, hacker news comments.
- Online editors for producing content — writing blogs, tutorials, news, etc.
- Twitter tweets, mentions, hashtags, polls, lists, etc.
- Editing documents and excel sheets like Google docs, Microsoft Word, Dropbox paper.
In 2016, Facebook open-sourced their new rich text editor framework called Draft.js.
Here’s the Draft.js introductory talk. Worth the 25 minutes to understand what kind of problems the Facebook team ran into and solved.
Ian Storm Taylor created Slate.js shortly after Facebook open-sourced Draft.js.
Here’s a Hacker News thread discussion about Slate.js.
The arguments for creating Slate are sound. Let’s check it out by creating a rich text editor.
- Text editor, any will do, feel free to choose.
- NodeJS installed with NPM/Yarn.
Fire up your terminal and create a new React project with create-react-app.
Booting up our React app
Slate exposes a set of modules that you’ll use to build your editor. The most important of which is the
Editor component. The
Editor component is the fundamental layer everything will be built upon. Think of it as the root component for the whole editor.
Starting off we will create a folder
components directory we’ll create two files called
If we open the browser, this is what we should see.
No problem! The
Editor component expects an initial
value — as can be seen from the source code.
See the last
propType — it’s set to
Let’s add our initial value to the editor. We’ll dive into the exact model of the data later once we have a basic understand how slate works.
We should end up with
My first paragraph! rendered on our app.
At first the text looks like a simple
Try clicking on the text. What do you see?
Editable text — notice the complex hierarchy of DOM elements. This is all abstracted away from us under the hood and we can focus on building our “product”
The text is editable! Woah! In case you don’t have the React developer tools, here’s a link to the Chrome app store.
Note: Remember we added a
onChange event listener to our
onChangeevent listener is listening for keyboard events
- After catching a keystroke.
- We update the current state with the new keystroke
- dispatch the new state.
- Render new state on the screen.
Although, the editor is not very useful to us yet. We’re missing key features like formatting, saving our text somewhere and many more.
It’s common to have a big header, sub header, italic, bold,
code, etc formatted text.
Think about what are the steps for formatting text?
Common practice is to start with pressing a command key like ctrl or cmd. Pressing the command key tells the editor we’re editing and not typing.
For example, what we could do is the following: cmd ⌘+ b or alt + b is for adding bold to our selected text.
Our flow will look this:
- Listen for events/key strokes.
2. Distinguish the keys pressed, was it a
b and in what order? And what happens if indeed those were the keys pressed?
3. Trigger the actual text change with the desired formatting.
Let’s go— start by adding a
onKeyDown event for the
Editor and pass in the callback.
Adding the onKeyDown event listener
We know what key the user pressed. Let’s make something happen depending on which keystroke is being pressed.
Good, now we have all the logic in place. If the user pressed alt + b, change the text to bold. How do you think we should approach the styling?
One way to go is to create a new reusable component called
BoldMark.js which we can reuse every time we want bold text.
Creating a reusable component for bold text
importing and exporting the new component
Editor component has a prop called
renderMark which accepts a callback. Inside the
renderMark we can decide how to style the text.
Importing the BoldMark component
Go on, try it out! Select the text and press
Woohoo, it works! Notice the
BoldMark component being rendered inside the VDOM.
There’s an open question in the air, what happens if we change our mind? We want to undo the boldness.
Slate has you covered! Instead of adding the
addMark(‘bold’ ) — we can use
toggleMark method instead
toggleMark method in the browser
To top it off, can you do the same functionality, but for italic?
Create the italic mark component + import and export.
Next up, let’s include the functionality to our
Checking if the key press was i
And including the component to our
including a case for the italic mark type
Try it out!
Toggling between regular and italic font
We’re getting there! There is so much more we will accomplish.
Excellent job! See you at part II!
Source code on Github here.