0

I'm trying to figure out Lexical but the docs are not great at all (despite the project looking very nice). I'm trying to add content into the editor automatically by getting my users to press some buttons, or some divs with content inside.

I have no idea how to make that work, anyone some inspiration ?

Here's some code :

    import {$getRoot, $getSelection} from 'lexical';
    import {useEffect} from 'react';
    import { LexicalComposer } from "@lexical/react/LexicalComposer";
    import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
    import { ContentEditable } from "@lexical/react/LexicalContentEditable";
    import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin";
    import { AutoFocusPlugin } from "@lexical/react/LexicalAutoFocusPlugin";
    import LexicalErrorBoundary from "@lexical/react/LexicalErrorBoundary";
    import TreeViewPlugin from "./editor/TreeViewPlugin";
    import ToolbarPlugin from "./editor/ToolbarPlugin";
    import { HeadingNode, QuoteNode } from "@lexical/rich-text";
    import { TableCellNode, TableNode, TableRowNode } from "@lexical/table";
    import { ListItemNode, ListNode } from "@lexical/list";
    import { CodeHighlightNode, CodeNode } from "@lexical/code";
    import { AutoLinkNode, LinkNode } from "@lexical/link";
    import { LinkPlugin } from "@lexical/react/LexicalLinkPlugin";
    import { ListPlugin } from "@lexical/react/LexicalListPlugin";
    import { MarkdownShortcutPlugin } from "@lexical/react/LexicalMarkdownShortcutPlugin";
    import { TRANSFORMERS } from "@lexical/markdown";
    import {OnChangePlugin} from '@lexical/react/LexicalOnChangePlugin';
    
    import ListMaxIndentLevelPlugin from "./editor/ListMaxIndentLevelPlugin";
    import CodeHighlightPlugin from "./editor/CodeHighlightPlugin";
    import AutoLinkPlugin from "./editor/AutoLinkPlugin";
    import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
    
    const editorConfig = {
        // The editor theme
        //theme: ExampleTheme,
        // Handling of errors during update
        onError(error) {
          throw error;
        },
        // Any custom nodes go here
        nodes: [
          HeadingNode,
          ListNode,
          ListItemNode,
          QuoteNode,
          CodeNode,
          CodeHighlightNode,
          TableNode,
          TableCellNode,
          TableRowNode,
          AutoLinkNode,
          LinkNode
        ]
      };
      
    
    
    function onChange(editorState) {
        editorState.read(() => {
          // Read the contents of the EditorState here.
          const root = $getRoot();
          const selection = $getSelection();
      
          // console.log(root, selection);
          console.log(root.getTextContent());
    
        });
      }
    
    
    
    
    const MyEditor = () => {
    
        // const [editor] = useLexicalComposerContext();
        
    
        const initialConfig = {
            namespace: 'MyEditor',
            theme: {
                paragraph: 'mb-1', // tailwind classes work!
            },
            onError(error) {
                throw error;
            },
        };
        
          function Placeholder() {
            return <div className="editor-placeholder">Enter your text...</div>;
          }
    
    
          const addStuff = () => {
    
            editor.update(() => {
                // // Get the current selection in the editor
                // const selection = $getSelection();
        
                // // Insert the text at the current selection
                // if (selection) {
                //     selection.insertText("test added");
                // }
    
                const root = $getRoot();
    
                // Get the selection from the EditorState
                const selection = $getSelection();
    
                // Create a new ParagraphNode
                const paragraphNode = $createParagraphNode();
    
                // Create a new TextNode
                const textNode = $createTextNode('Hello world');
    
                // Append the text node to the paragraph
                paragraphNode.append(textNode);
    
                // Finally, append the paragraph to the root
                root.append(paragraphNode);
            });
    
    
          }
          
          
          return (
            <>
                <div onClick={addStuff} >Click me to add stuff</div>
                
                <LexicalComposer initialConfig={editorConfig}>
                <div className="editor-container">
                    <ToolbarPlugin />
                    <div className="editor-inner">
                    <RichTextPlugin
                        contentEditable={<ContentEditable className="editor-input" />}
                        placeholder={<Placeholder />}
                        ErrorBoundary={LexicalErrorBoundary}
                    />
                    <HistoryPlugin />
                    <TreeViewPlugin />
                    <AutoFocusPlugin />
                    <CodeHighlightPlugin />
                    <ListPlugin />
                    <LinkPlugin />
                    <AutoLinkPlugin />
                    <ListMaxIndentLevelPlugin maxDepth={7} />
                    <MarkdownShortcutPlugin transformers={TRANSFORMERS} />
                    <OnChangePlugin onChange={onChange} />
                    </div>
                </div>
                </LexicalComposer>
            </>
          );
    
    }
    
    export default MyEditor;
Tibo
  • 621
  • 1
  • 8
  • 24

1 Answers1

0

The way I would approach this is:

  • register a custom command INSERT_CUSTOM_TEXT
  • Make sure to import
    • $insertNodeToNearestRoot from @lexical/utils
    • $insertNodes from lexical
const INSERT_CUSTOM_TEXT: LexicalCommand<string> = createCommand();

editor.registerCommand(
  INSERT_CUSTOM_TEXT,
  () => {
          const paragraphNode = $createParagraphNode();
          const textNode = $createTextNode('Hello world');
          $insertNodes(textNode)
          paragraphNode.append(textNode);
          $insertNodeToNearestRoot(paragraphNode);
  },
  COMMAND_PRIORITY_NORMAL,
);
  • Create a Plugin called AddContentLinkPlugin
  • Have the Plugin return your link with an onClick attached
  • In the onClick call editor.dispatchCommand to fire INSERT_CUSTOM_TEXT command
function AddContentLinkPlugin() {
  const [editor] = useLexicalComposerContext();
  return (<div onClick={(e) => { editor.dispatchCommand(INSERT_CUSTOM_TEXT, e); }}>
            Add text to editor
          </div>)
}

You can then add this plugin directly in your LexicalComposer definition. For example:

<LexicalComposer initialConfig={editorConfig}>
//...
  <AddContentLinkPlugin />
//...
</LexicalComposer>