This is the second in an ongoing series of posts.
- draft-js pieces
- draft-js EditorState
- draft-js ContentState
- draft-js ContentBlock
- draft-js SelectionState
- draft-js highlight text
- draft-js styling a ContentBlock
The Draft-js component is called Editor.js and serves as a location to set the initial state of the component. At a minimum it takes an EditorState and an onChange callback. If your Editor is to be blank you can call
const myEditorState = EditorState.createEmpty()
which is a static method off of EditorState.
State of your document
However you chose to maintain the state in your react app, the state you maintain for the document is the EditorState. The signature for the onChange event is
so you receive EditorState and this is your window into draft.js with your instance of EditorState you can effect the state of your document in many different ways. There are a number of static functions found through out draft.js and most of them act on an EditorState. Thus, you want to keep your EditorState in your applications state management.
Persisting and Recreating a document
If you are have a previously saved document, the chances are you saved it using
const myRawState = convertToRaw(myEditorState)
which is a function that you import from draft-js. This call takes the rather large instance of EditorState and strips it down to just a representation of the ContentBlocks. It strips out the per character metadata, the undo/redo history, selections, decorators etc. and leaves you with just enough to recreate the document completely. You can then persist this object in a database.
When you want to bring the document back you would then similarly call convertFromRaw which you import from draft-js.
const myContentState = convertFromRaw(myRawState)
The result of this is an instance of ContentState. ContentState is essentially the EditorState without the undo/redo, selection etc. It doesn’t have the historical or contextual date I guess you’d say. Once you have the ContentState you can call the static method createWithContent off of EditorState.
const myEditorState = EditorState createWithContent(myContentState)
The EditorState also has some methods to help you interact with the document. It has a method
const mySelectionState = myEditorState.getSelection()
The SelectionState has information about the currently selected section of the document. If your cursor is just blinking, then it will contain an startingOffset and endingOffset that are the same and correspond to the number of characters from the beginning of the ContentBlock. If, however, you have selected a portion of text the SelectionState startingOffset and endingOffset will be the character position of the first character in the selection and the last character in the selection relative to the beginning of the content block.
I wont go into too much detail about SelectionState here, but essentially a selection is one of the two main ways of interacting with the document, the other being via ContentBlocks which roughly correspond to paragraphs.
Another method on EditorState is
const myCurrentInlineStyle = myEditorState.getCurrentInlineStyle
myCurrentInlineStyle will be a collection of strings that represent the inlineStyles that will be applied to the next character that is typed.
You can use this to assess the current style of an area of selected text. By looking at the collection you can tell what state of styling is being applied to the area and you can add or remove inlineStyles to the selection. This is more complicated than I’m making it sound, and you’ll want to read my post about SelectionState as it will go into much more detail.
The last two methods that I will go over and the last two instance methods on the EditorState are
const myCurrentContent = myEditorState.getCurrentContent()
const myContentBlocks = myEditorState.getBlockTree()
I will go into ContentState more in the next post but it is essentially a more targeted version of the EditorState if you will. It has many more instance methods for interacting with ContentBlocks and Selections. Generally you will interact with those two parts of the document via the ContentState but the getCurrentSelection() and getBlockTree() give you two convenient methods for checking what you have. e.g. check if your selection is a span of more than one 0 characters and if so get the ContentState and do something.
The BlockTree is a collection that represents all of the ContentBlocks in your document. Again the ContentState is a finer grained tool for dealing with these but if you just need some information about the blocks this is a convenient function.
That’s all I can stand to type today. But to summarize, the Editor.js Component takes an EditorState object to instantiate. That object can either be an empty EditorState via the EditorState.createEmpty() method, or one you have reinstated from a persisted copy of the raw ContentState via the imported functions convertToRaw() and convertFromRaw()
Once you have your EditorState you have 4 instance methods to use.
- getCurrentContent() which retrieves the ContentState a finer grained tool for manipulating the document
- getSelection() which retrieves the SelectionState which represents the characters that have been selected in the document or just the location of the cursor if none have been selected
- getCurrentInlineStyle() which returns a collection of the styles that have been applied to the selection or if no selection the styles that will be applied to the next character typed
- getBlockTree() which returns a collection of the ContentBlocks that make up your document.
Next time I will go over the ContentState which I hope will be shorter 🙂