question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Plugin-supplied components cannot be placed above editor

See original GitHub issue

As currently written, the plugins-editor only initializes plugins (attaching them to get/setEditorState functions) when the Editor component is first rendered. This means that any components supplied by plugins (like the CharCounter, WordCounter, etc of the counter plugin) cannot be placed above the Editor in a rendering method, since their first render will then be uninitialized and will crash on looking for non-existent methods (store.getEditorState is not a function).

To me, it seems limiting to require that all controls be placed below the Editor.

There are at least a couple of workarounds. For the counter plugin (to take one exampe), the components could simply check for initialization before attempting to access the bound methods:

So this line:

  const count = this.getCharCount(store.getEditorState());

could become

    let count = 0;
    if (store.getEditorState) {
      count = this.getCharCount(store.getEditorState());
    }

This kind of fix allows the components to be placed above the Editor, but still leaves an unusual difficulty with the components not remaining fully synced to the Editor’s state in all cases. Specifically, it seems that the controls (like the character count) can end up lagging behind by a single rendering cycle when something else updates the editor.

In my plugin, I needed to ensure that formatting buttons (particularly the inline ones like Bold) always correctly reflect an active / inactive state based on the current cursor position, and placing them above the editor with only the above fix left repeated issues with lagging behind a render.

I ended up solving it by having all my plugin’s components internally subscribed to re-render whenever a changed EditorState arrives, but this approach still requires the additional step, when using the plugin, of adding its callback into your onChange function.

//  in your component using the richButtons plugin
 onChange(editorState) {
  this.setState({content: editorState}, () => {
    richButtonsPlugin.onEditorChange(editorState); // re-renders the buttons as needed
  });
}

It seems that the plugin-editor itself should perhaps have another way of connecting a plugin to subscribe directly to EditorState changes, making the relative position of Editor and buttons truly irrelevant and all changes easily propagable to any plugin-supplied components and controls. Thoughts?

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:7
  • Comments:13 (7 by maintainers)

github_iconTop GitHub Comments

3reactions
juliankrispelcommented, Sep 26, 2017

Imo - we should remove state management and leave it up to userland - too many opinions about state management - makes draft-js-plugins kind of a turn-off for some

2reactions
nikgrafcommented, Jun 19, 2016

This in indeed is a problem & I didn’t anticipate it.

Possible solutions I can think of right now:

  1. Some plugins don’t actually need to plugins. For example the counters e.g. WordCounter could simply be Components receiving the editorState as a prop. /cc @adrianmc
import Editor from 'draft-js-plugins-editor';
import WordCounter from 'draft-js-counter/WordCounter';

<WordCounter editorState={this.state.editorState} />
<Editor editorState={this.state.editorState} />

Still some plugins like the Mention plugin also need other things than the editorState e.g. boundingRect https://github.com/draft-js-plugins/draft-js-plugins/blob/master/draft-js-mention-plugin/src/MentionSuggestionsPortal/index.js#L22 and passing all of that might becomes annoying.

  1. The second solution is the one where a re-render is forced or update internal state like you did in your plugin. This makes plugin development inherently harder.

Does your plugin actually need to be a plugin or would it work well with the first approach?

I don’t see a magic bullet solution right now 😞 Any other ideas? /cc @adrianmc @mjrussell @bkniffler

Read more comments on GitHub >

github_iconTop Results From Across the Web

Customising toolbars - Draftail
Disable the toolbar to save space if your editor only supports a ... (Plugin-supplied components cannot be placed above editor, #311).
Read more >
Cannot place parts in PCB editor 16.2 - Cadence Community
I am a newbie and am trying to design my first PCB. I've made my schematic, pads, footprints, generating netlist and even created...
Read more >
[JENKINS-26801] nested wariables not expanded
When using publish over ssh plugin the nested variables are not expanded in the fielad remote directory and exec command. I have the...
Read more >
1951 calls to t() | bootstrap.inc | Drupal 8.2.x
Tests attempting to uninstall a module that has installed dependents. DirectoryTest::testFileCheckLocalDirectoryHandling in core/tests/Drupal/KernelTests/Core/ ...
Read more >
Gutenprint - Top Quality Printer Drivers Files - SourceForge
Gutenprint currently supports over 2500 printer models. ... the GIMP image editor, replacing the Gimp-Print 4.2-based plugin supplied with GIMP 1.2, 2.0, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found