英文:
LexicalJS text editor : how can I allow users to add text pressing buttons
问题
我正在尝试理解 Lexical,但文档实在不太好(尽管项目看起来非常不错)。我正在尝试通过让我的用户按一些按钮或一些包含内容的 div 来自动将内容添加到编辑器中。
我不知道如何使其工作,有人能提供一些灵感吗?
以下是一些代码:
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 = {
// 编辑器主题
// theme: ExampleTheme,
// 在更新过程中处理错误
onError(error) {
throw error;
},
// 自定义节点在这里添加
nodes: [
HeadingNode,
ListNode,
ListItemNode,
QuoteNode,
CodeNode,
CodeHighlightNode,
TableNode,
TableCellNode,
TableRowNode,
AutoLinkNode,
LinkNode
]
};
function onChange(editorState) {
editorState.read(() => {
// 在这里读取 EditorState 的内容
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 类可以使用!
},
onError(error) {
throw error;
},
};
function Placeholder() {
return <div className="editor-placeholder">输入您的文本...</div>;
}
const addStuff = () => {
editor.update(() => {
// // 获取编辑器中当前的选择
// const selection = $getSelection();
// // 在当前选择位置插入文本
// if (selection) {
// selection.insertText("test added");
// }
const root = $getRoot();
// 从 EditorState 获取选择
const selection = $getSelection();
// 创建新的 ParagraphNode
const paragraphNode = $createParagraphNode();
// 创建新的 TextNode
const textNode = $createTextNode('Hello world');
// 将文本节点附加到段落中
paragraphNode.append(textNode);
// 最后,将段落附加到根节点
root.append(paragraphNode);
});
}
return (
<>
<div onClick={addStuff}>点击我添加内容</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;
希望这可以帮助你添加内容到 Lexical 编辑器中。
英文:
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;
答案1
得分: 1
以下是翻译好的部分:
我处理这个的方式是:
- 注册一个自定义命令
INSERT_CUSTOM_TEXT
- 确保导入以下内容:
- 从
@lexical/utils
导入$insertNodeToNearestRoot
- 从
lexical
导入$insertNodes
- 从
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,
);
- 创建一个名为
AddContentLinkPlugin
的插件 - 使插件返回带有 onClick 附加的链接
- 在 onClick 中调用
editor.dispatchCommand
以触发INSERT_CUSTOM_TEXT
命令
function AddContentLinkPlugin() {
const [editor] = useLexicalComposerContext();
return (<div onClick={(e) => { editor.dispatchCommand(INSERT_CUSTOM_TEXT, e); }}>
向编辑器添加文本
</div>)
}
然后,您可以直接将此插件添加到您的 LexicalComposer 定义中。例如:
<LexicalComposer initialConfig={editorConfig}>
//...
<AddContentLinkPlugin />
//...
</LexicalComposer>
英文:
The way I would approach this is:
- register a custom command
INSERT_CUSTOM_TEXT
- Make sure to import
$insertNodeToNearestRoot
from@lexical/utils
$insertNodes
fromlexical
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 fireINSERT_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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论