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
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