One of the features that we at Propeller miss in Draft.js out-of-the-box is the possibility to clear the stylings of selected text, leaving plain text inside the editor. We believe this behaviour is commonly used and our users may expect this feature to be on it’s place. As always in order to add this feature you would need to spend significant amount of time digging into Draft.js documentation in order to find required information.
This post describes what steps you should take in order to add this behaviour into your project.
As always, there is a npm package available for you not to implement everything manually.
All editing in Draft.js may be divided into 3 groups:
In order to clean the text up we need to take care of all of these groups.
This one is pretty simple. First, we need to define a list of styles which we support in the project (in our case — Bold, Italic and Underline texts). Next, we need to call a method called removeInlineStyles
of Modifier
module that comes as a part of Draft.js package. Obviously enough, this method allows us to remove specified inline style from the selected range. So we need to call it for each item of our styles
array.
To simplify the code, we would use reduce
method here. If you are not familiar with it — you can read about it here.
Note that we use 2 different editorStates
here — the argument we pass in the function which represents current state of the editor and EditorState
which should be imported from Draft.js itself along with Modifier
module.
push
method is used to create a new EditorState
object with applied contentWithoutStyles
as a content of the editor.
Note the third parameter we pass to push
method(a string change-inline-style
). This parameter is called changeType
and Draft.js uses it to specify a correct undo/redo behaviour. This particular one means that inline style has been applied or removed for one or more characters.
This one is even easier. We don’t need to build any additional array of styles or use any iteration functions. Instead we need to call applyEntity
method of the exact same Modifier
module. This method allows us to apply an entity to the selected range. In order to remove all entities we need to pass null
as a third argument to this function.
And again you may notice that we use apply-entity
as a change type in EditorState.push()
call. This one means an entity has been applied or removed to one or more characters.
The complex one. In order to remove different block types(headers, list items, code blocks etc.) from the selection range and preserve the text we need to change the type of each block to be unstyled
. You can read more about what a block is and why it has different types here. This post is not 100% actual nowadays but it gives right mindset to better understand how Draft.js works.
And the best way to change the type of block is to go through all of them and to call a change function for each singe one of them.
First, we need to get all the blocks from the selection range. Here we may want to use getSelectedBlocksMap
method from [draftjs-utils](https://github.com/jpuri/draftjs-utils)
package.
Next we need to detect whether we want to perform any action on the block. In our case we need to check the block type and we do so by calling getType
method of the block. So if the block has any type (blockType !== ‘unstyled’
) — the block should be updated.
Once we find a block to update we need to change it’s type. Here we need to update the selection range to select whole block(you can use text length here to set the end index of the selection range).
Now we need to call setBlockType
method of Modifier
module to update the type of the block and get new contentState
and then we need to push it to the EditorState
. This functions expects to get a blockType
parameter which in our case should be unstyled
as we want to wipe all of the edits. The change type for this operation is change-block-type
. I guess by now you get what it means :)
Let’s combine it all together and use reduce
method to simplify the code so we run EditorState.push()
only once like we’ve done in Inline Styles
section.
All set now! Let’s get all these functions to work! I would recommend to use flow function of lodash
package or any of the alternatives here because it would drastically increase the readability of the code. Let’s try it out:
And here is the result:
We select all the text, hit ‘Clear’ button and all editing is removed!
If you’ve read this post till this moment you may also want to check my previous post about Draft.js enchantment and apply it to your project as well.