No Preview

Sorry, but you either have no stories or none are selected somehow.

If the problem persists, check the browser console, or the terminal you've run Storybook from.

Using Draft.js EditorState and ContentState

Contents

Introduction to Draft.js

Installation

The TextEditor and Note components utilise the Draft.js framework to support creating and rendering rich-text content. As such, the framework has been added as a peer-dependency and consuming projects are required to install it if they wish to use either component, this can be done as an npm package.

npm install draft-js@^0.11.5

EditorState

The EditorState is an Immutable Record representing the the top-level object for the entire state of the Editor. Interacting with it will provide access to a wide range of useful information. This includes the current text ContentState, accessible via the getCurrentContent() method exposed as part of the API. It also provides access to the current SelectionState (getSelection()), the fully decorated representation of the contents (getCurrentInlineStyle() and getBlockTree()), undo/redo stacks and the most recent type of change made to the contents. For more information refer to the API documentation https://draftjs.org/docs/api-reference-editor-state.

Importing EditorState

The EditorState can be imported either directly from draft-js or alternatively it has been exposed as part of the TextEditor component's interface.

import { EditorState } from 'draft-js';
import { TextEditorState } from 'carbon-react/lib/components/text-editor';

Useful static methods

The framework surfaces a range of static methods for initialising the state:

  • EditorState.createEmpty(decorator?: DraftDecoratorType) - will intitialise the component with a new EditorState object with an empty ContentState and any Decorators passed to it.
  • EditorState.createWithContent(contentState: ContentState, decorator?: DraftDecoratorType) - is used to initialise the component with some existing ContentState and any Decorators and return a new EditorState object.
  • EditorState.create(config: EditorStateCreationConfig) - offers the same as createWithContent but enables initialising the EditorState from a config, affording you more fine grain control. For example, it is possible to define an intitial SelectionState using this static method.

Other useful methods

  • EditorState.push(editorState: EditorState, contentState: ContentState, changeType: EditorChangeType) - it is very unlikely that you will have a need to use this but if direct content changes are required they must be applied to the EditorState using this method. It returns a new EditorState object with the specified ContentState applied as the new currentContent, the changeType defines the operation being carried out on the state, see https://draftjs.org/docs/api-reference-editor-change-type for the defined options.
  • The current ContentState can be accessed by calling the getCurrentContent() instance method.
  • The current SelectionState can be accessed by calling the getSelection() instance method.

ContentState

ContentState is also an Immutable Record and represents the state of the editor's entire contents (text, block and inline styles, and entity ranges) and its two selection states (before and after rendering). There are range of useful methods accessible through ContentState that can provide information about the current content rendered in the editor, for more details it is best to refer to the API reference documentation https://draftjs.org/docs/api-reference-content-state.

Importing ContentState

The ContentState can be imported either directly from draft-js or alternatively it has been exposed as part of the TextEditor component's interface.

import { ContentState } from 'draft-js';
import { TextEditorContentState } from 'carbon-react/lib/components/text-editor';

Useful static methods

There are two static methods that facilitate creating ContentState:

  • createFromText(text: string, delimiter?: string) - will generate state from a given string paramater, passing an optional delimiter will define how the content blocks are split; if no delimiter is provided the method will default to using \n. This method will commonly be used with the createWithContent method surfaced by the EditorState like so:
const Foo = (props) => {
    const [state, setState] = useState(EditorState.createWithContent(ContentState.createFromText('text content')));

    return (
      <Editor editorState={ state } onChange={ (newState) => setState(newState)} />
    );
  };
  • createFromBlockArray(blocks: Array<ContentBlock>, entityMap: ?OrderedMap) - this method will produce a ContentState object from an array of ContentBlocks, an optional Immutable map of DraftEntity records can also be provided as the second argument. A ContentBlock is itself an Immutable Record that maintains the following information about a block: a string key, the entity type, the block's text and an Immutable characterList which maintains the styling and other data for each character. Commonly this method will be used in conjunction with Draft's data conversion methods (https://draftjs.org/docs/api-reference-data-conversion), below is an example of using it when converting html into ContentState using convertFromHTML.
const Foo = (props) => {
    const html = `<p>Lorem ipsum</p>`;
    const blocksFromHTML = convertFromHTML(html);
    const contentState = ContentState.createFromBlockArray(
      blocksFromHTML.contentBlocks,
      blocksFromHTML.entityMap
    );
    const [state, setState] = useState(EditorState.createWithContent(contentState);

    return (
      <Editor editorState={ state } onChange={ (newState) => setState(newState)} />
    );
  };