Valentin Vucea
Valentin Vucea

Reputation: 139

Multiple draft-js-plugins editors on the same page don't work

I'm trying to use multiple rich text editors in a React form. I built the editor component using draft-js and also I integrated the inline toolbar from draft-js-plugins. Because this is a react-hook-form I wrapped the editor inside a Controller component.

The problem I have is that the InlineToolbar is displayed only for the last editor component in page.

Based on the draft-js-plugins documentation the initialization of the toolbar should happen outside the component so this is what I did:

const inlineToolbarPlugin = createInlineToolbarPlugin();
const { InlineToolbar } = inlineToolbarPlugin;
const plugins = [inlineToolbarPlugin];

function RichTextEditor({ control, name }) {
  return (
    <div>
      <Controller
        name={name}
        control={control}
        render={({ field: { value, onChange } }) => {
          const newValue = value || EditorState.createEmpty();
          return (
            <>
              <Editor
                editorState={newValue}
                onChange={onChange}
                plugins={plugins}
              />
              <InlineToolbar />
            </>
          );
        }}
      />
    </div>
  );
}

A complete CodeSandbox example here: CodeSandbox link

Upvotes: 2

Views: 720

Answers (1)

Sohaib Alqasem
Sohaib Alqasem

Reputation: 256

Each editor get's its own plugins.

You can solve this issue ether by creating different plugin for each editor instance and pass them to the editor OR with create a function for creating a plugin inside the editor component and every time we init a editor we create a new plugin instance

So, this is the first solution:

  const inlineToolbarPlugin1 = createInlineToolbarPlugin();
  const { InlineToolbar:Tool1 } = inlineToolbarPlugin1;

  const inlineToolbarPlugin2 = createInlineToolbarPlugin();
  const { InlineToolbar:Tool2 } = inlineToolbarPlugin2;

And pass them into your custom editor components.


Second solution:

  import React from "react";
import { Controller } from "react-hook-form";
import { EditorState } from "draft-js";
import PropTypes from "prop-types";
import Editor from "@draft-js-plugins/editor";
import createInlineToolbarPlugin from "@draft-js-plugins/inline-toolbar";
import "@draft-js-plugins/inline-toolbar/lib/plugin.css";
import "draft-js/dist/Draft.css";

const createtoolbarplugin = () => {
  const InlineToolbarPlugin = createInlineToolbarPlugin();
  const InlineToolbar = InlineToolbarPlugin.InlineToolbar;
  return {
    InlineToolbarPlugin,
    InlineToolbar
  };
};

function AnotherRichTextEditor({ control, aName }) {
  const [{ InlineToolbarPlugin, InlineToolbar }] = React.useState(() => {
    const { InlineToolbar, InlineToolbarPlugin } = createtoolbarplugin();
    return {
      InlineToolbarPlugin,
      InlineToolbar
    };
  });

  return (
    <div
      style={{
        border: "1px solid #ccc",
        minHeight: 30,
        padding: 10
      }}
    >
      <Controller
        name={aName}
        control={control}
        render={({ field: { value, onChange } }) => {
          const newValue = value || EditorState.createEmpty();
          return (
            <>
              <Editor
                editorState={newValue}
                onChange={onChange}
                plugins={[InlineToolbarPlugin]}
              />
              <InlineToolbar />
            </>
          );
        }}
      />
    </div>
  );
}

AnotherRichTextEditor.propTypes = {
  control: PropTypes.object,
  aName: PropTypes.string
};

export default AnotherRichTextEditor;

Hope That's help

Upvotes: 1

Related Questions