2

I'm making a rich text editor with Lexical react. I'm reasonably experienced in React. My problem is I can't get the editor to flip between editable and readonly modes. It's stuck in whatever mode it's set when I first load the app. Here is the code snippet - as you can see, I print out the "editable" value and confirm it changes between true and false correctly (but the editor mode doesn't change with it):

  editorConfig = {
    ...
    editable: editable,
  }
  console.log(`editable is ${editable}`);
  return (
    <LexicalComposer initialConfig={editorConfig}>

Any help is appreciated!

Tony Jiang
  • 442
  • 5
  • 16

2 Answers2

2

You need to use useLexicalComposerContext in some place wrapped by LexicalComposer to get editor and update its state like this.

import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";

export default function MyStateChangeButtons() {
  const [editor] = useLexicalComposerContext();

  return (
    <div>
      <button onClick={() => editor.setEditable(true)}>
        make editable true
      </button>
      <button onClick={() => editor.setEditable(false)}>
        make editable false
      </button>
    </div>
  );
}

This is how you can call MyStateChangeButtons component inside LexicalComposer:

<LexicalComposer initialConfig={editorConfig}>
  <div className="editor-container">
    <PlainTextPlugin
      contentEditable={<ContentEditable className="editor-input" />}
      placeholder={<Placeholder />}
    />
    <OnChangePlugin onChange={onChange} />
    <HistoryPlugin />
    <TreeViewPlugin />
    <EmoticonPlugin />
    <MyCustomAutoFocusPlugin />
  </div>
  <MyStateChangeButtons />
</LexicalComposer>

You can take a look at this sandbox for a live working example of this solution.

Ahmet Emre Kilinc
  • 5,489
  • 12
  • 30
  • 42
  • 1
    Thank you! This solved my problem. I sort of had some inkling of the plugin mechanism, but had never written one. I ended up including it in the same file as the composer (like how it's done in this example https://github.com/facebook/lexical/discussions/2583). – Tony Jiang Sep 19 '22 at 02:57
0
function TextLoader({ note, editable = false }) {
  const [editor] = useLexicalComposerContext();

  useEffect(() => {
    // defines whether the editor is on edit or read mode
    editor.setEditable(editable);    if (note) {
      editor.setEditorState(editor.parseEditorState(note.body));
    }
  }, [editor, note, editable]);

  return null;
}

<LexicalComposer initialConfig={editorConfig}>
  <div className="editor-container">
    <div className="editor-inner">
      <RichTextPlugin
        contentEditable={<ContentEditable className="editor-input" />}
        placeholder={<Placeholder />}
      />
    </div>
  </div>
  <TextLoader note={note} editable={editable} />
</LexicalComposer>
Dan
  • 1,518
  • 5
  • 20
  • 48