draft-js-plugins / draft-js-plugins

React Plugin Architecture for Draft.js including Slack-Like Emojis, FB-Like Mentions and Stickers

Home Page:https://www.draft-js-plugins.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Static toolbar is not initialised/updated soon enough when rendered above the Editor

ab-pm opened this issue · comments

The toolbar store

const store = createStore<StoreItemMap>();
is initialised from the initialize hook only when the <Editor> is rendered/mounted, and the editor.props.editorState that is returned by getEditorState of the PluginFunctions
getEditorState = (): EditorState => this.props.editorState;
is similarly only updated when the <Editor> is rendered by React.

This causes various problems when the <StaticToolbar> is rendered above (before) the <Editor> in an application. When the buttons in the toolbar try to access the editor state, they either

  • get no state at all, because getEditorState is still undefined.
    See e.g. inline style buttons explicitly working around this issue in
    // we check if this.props.getEditorstate is undefined first in case the button is rendered before the editor
    const styleIsActive = (): boolean =>
    props.getEditorState &&
    props.getEditorState().getCurrentInlineStyle().has(style);
  • get stale state from the previous render, which e.g. contains the wrong selection

This is very annoying. As a workaround, I needed to do

<Toolbar>{(props) => {
   props.getEditorState = () => this.state.myEditorState;
   return <>
      … // buttons with {...props}
   </>
}}</Toolbar>

I think the <Toolbar>s (not just the static one, also the inline and side toolbars, although those are less likely to be affected) should

  • subscribe to the getEditorState part of the store
  • not render children when getEditorState is still missing
  • use onChange(newState) { store.updateItem('getEditorState', () => newState); } in addition to the initialize hook

What do you think?

Reproducible Demo

See https://codesandbox.io/s/jolly-bird-hzc9m6?file=/src/Editor.js - try placing the cursor on the text and move around

The problem is that the toolbar is placed and rendered before the editor that updates the status. If you move the toolbar after the editor, everything works as expected.
The best solution I have seen so far is to place the toolbar after the editor and change the order via CSS.
Currently I have no idea for a simple solution without rewriting the plugin. If you want to take care of the problem I would be happy about a merge request

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days.

It's still a bug, even if it hasn't been fixed in 60 days.

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days.

It's still a bug, even if it hasn't been fixed in 120 days.