Merge pull request #836 from SuanmoSuanyangTechnology/feature/ui_upgrade_zy

fix(web): editor init
This commit is contained in:
yingzhao
2026-04-09 12:33:33 +08:00
committed by GitHub
3 changed files with 21 additions and 30 deletions

View File

@@ -149,8 +149,8 @@ const Editor: FC<LexicalEditorProps> =({
<HistoryPlugin />
<CommandPlugin />
<AutocompletePlugin options={options} />
<CharacterCountPlugin setCount={setCount} onChange={onChange} />
<InitialValuePlugin value={value} options={options} />
<CharacterCountPlugin setCount={setCount} />
<InitialValuePlugin value={value} options={options} onChange={onChange} />
<BlurPlugin />
</div>
</LexicalComposer>

View File

@@ -1,41 +1,22 @@
import { useEffect, useRef } from 'react';
import { useEffect } from 'react';
import { $getRoot, $isParagraphNode } from 'lexical';
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
import { $isVariableNode } from '../nodes/VariableNode';
const CharacterCountPlugin = ({ setCount, onChange }: { setCount: (count: number) => void; onChange?: (value: string) => void }) => {
const CharacterCountPlugin = ({ setCount }: { setCount: (count: number) => void }) => {
const [editor] = useLexicalComposerContext();
const onChangeRef = useRef(onChange);
onChangeRef.current = onChange;
useEffect(() => {
return editor.registerUpdateListener(({ editorState, tags }) => {
if (tags.has('programmatic')) return;
editorState.read(() => {
const root = $getRoot();
let serializedContent = '';
// Traverse all nodes and serialize properly
const paragraphs: string[] = [];
root.getChildren().forEach(child => {
if ($isParagraphNode(child)) {
let paragraphContent = '';
child.getChildren().forEach(node => {
if ($isVariableNode(node)) {
paragraphContent += node.getTextContent();
} else {
paragraphContent += node.getTextContent();
}
});
paragraphs.push(paragraphContent);
paragraphs.push(child.getChildren().map(n => n.getTextContent()).join(''));
}
});
serializedContent = paragraphs.join('\n');
setCount(serializedContent.length);
onChangeRef.current?.(serializedContent);
setCount(paragraphs.join('\n').length);
});
});
}, [editor, setCount]);

View File

@@ -6,7 +6,7 @@
*/
import { useEffect, useRef } from 'react';
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
import { $getRoot, $createParagraphNode, $createTextNode } from 'lexical';
import { $getRoot, $createParagraphNode, $createTextNode, $isParagraphNode } from 'lexical';
import { $createVariableNode } from '../nodes/VariableNode';
import { type Suggestion } from '../plugin/AutocompletePlugin'
@@ -14,24 +14,34 @@ import { type Suggestion } from '../plugin/AutocompletePlugin'
interface InitialValuePluginProps {
value: string;
options?: Suggestion[];
onChange?: (value: string) => void;
}
const InitialValuePlugin: React.FC<InitialValuePluginProps> = ({ value, options = [] }) => {
const InitialValuePlugin: React.FC<InitialValuePluginProps> = ({ value, options = [], onChange }) => {
const [editor] = useLexicalComposerContext();
const prevValueRef = useRef<string>('');
const isUserInputRef = useRef(false);
const optionsRef = useRef(options);
optionsRef.current = options;
const onChangeRef = useRef(onChange);
onChangeRef.current = onChange;
useEffect(() => {
return editor.registerUpdateListener(({ editorState, tags }) => {
if (tags.has('programmatic')) return;
editorState.read(() => {
const root = $getRoot();
const textContent = root.getTextContent();
if (textContent !== prevValueRef.current) {
const paragraphs: string[] = [];
root.getChildren().forEach(child => {
if ($isParagraphNode(child)) {
paragraphs.push(child.getChildren().map(n => n.getTextContent()).join(''));
}
});
const text = paragraphs.join('\n');
if (text !== prevValueRef.current) {
isUserInputRef.current = true;
prevValueRef.current = textContent;
prevValueRef.current = text;
onChangeRef.current?.(text);
}
});
});