style(web): translate the comments in the src/views directory into English
This commit is contained in:
@@ -1,3 +1,14 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 16:25:17
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 16:25:17
|
||||
*/
|
||||
/**
|
||||
* Rich text editor component using Lexical framework
|
||||
* Provides text editing with insert, append, clear, and scroll capabilities
|
||||
*/
|
||||
|
||||
import {forwardRef, useImperativeHandle } from 'react';
|
||||
import clsx from 'clsx';
|
||||
import { LexicalComposer } from '@lexical/react/LexicalComposer';
|
||||
@@ -6,25 +17,44 @@ import { ContentEditable } from '@lexical/react/LexicalContentEditable';
|
||||
import { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';
|
||||
import { $getSelection, $getRoot, $createParagraphNode, $createTextNode, $isParagraphNode, $isTextNode } from 'lexical';
|
||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
||||
|
||||
import InitialValuePlugin from './plugin/InitialValuePlugin'
|
||||
import LineBreakPlugin from './plugin/LineBreakPlugin';
|
||||
import InsertTextPlugin from './plugin/InsertTextPlugin';
|
||||
|
||||
/**
|
||||
* Editor ref methods exposed to parent components
|
||||
*/
|
||||
export interface EditorRef {
|
||||
/** Insert text at current cursor position */
|
||||
insertText: (text: string) => void;
|
||||
/** Append text to the end of content */
|
||||
appendText: (text: string) => void;
|
||||
/** Clear all editor content */
|
||||
clear: () => void;
|
||||
/** Scroll editor to bottom */
|
||||
scrollToBottom: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Editor component props
|
||||
*/
|
||||
interface LexicalEditorProps {
|
||||
/** Additional CSS class names */
|
||||
className?: string;
|
||||
/** Placeholder text when editor is empty */
|
||||
placeholder?: string;
|
||||
/** Initial editor value */
|
||||
value?: string;
|
||||
/** Callback when content changes */
|
||||
onChange?: (value: string) => void;
|
||||
/** Editor height in pixels */
|
||||
height?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lexical editor theme configuration
|
||||
*/
|
||||
const theme = {
|
||||
paragraph: 'editor-paragraph',
|
||||
text: {
|
||||
@@ -33,6 +63,9 @@ const theme = {
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Editor content component with Lexical context
|
||||
*/
|
||||
const EditorContent = forwardRef<EditorRef, LexicalEditorProps>(({
|
||||
className = '',
|
||||
value,
|
||||
@@ -41,6 +74,13 @@ const EditorContent = forwardRef<EditorRef, LexicalEditorProps>(({
|
||||
}, ref) => {
|
||||
const [editor] = useLexicalComposerContext();
|
||||
|
||||
/**
|
||||
* Expose editor methods to parent component
|
||||
* - insertText: Insert at cursor position
|
||||
* - appendText: Append to end of content
|
||||
* - clear: Clear all content
|
||||
* - scrollToBottom: Scroll to bottom
|
||||
*/
|
||||
useImperativeHandle(ref, () => ({
|
||||
insertText: (text: string) => {
|
||||
editor.update(() => {
|
||||
@@ -109,6 +149,10 @@ const EditorContent = forwardRef<EditorRef, LexicalEditorProps>(({
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Main editor wrapper component
|
||||
* Initializes Lexical composer with configuration
|
||||
*/
|
||||
const Editor = forwardRef<EditorRef, LexicalEditorProps>((props, ref) => {
|
||||
const initialConfig = {
|
||||
namespace: 'Editor',
|
||||
|
||||
@@ -1,20 +1,34 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 16:24:59
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 16:24:59
|
||||
*/
|
||||
/**
|
||||
* Initial Value Plugin
|
||||
* Sets the initial content of the Lexical editor
|
||||
* Only updates when the value prop changes
|
||||
*/
|
||||
|
||||
import { type FC, useEffect, useRef } from 'react';
|
||||
import { $getRoot, $createParagraphNode, $createTextNode } from 'lexical';
|
||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
||||
|
||||
// 设置初始值的插件
|
||||
/**
|
||||
* Plugin to set initial editor value
|
||||
*/
|
||||
const InitialValuePlugin: FC<{ value?: string }> = ({ value }) => {
|
||||
const [editor] = useLexicalComposerContext();
|
||||
const lastValueRef = useRef<string | undefined>(undefined);
|
||||
|
||||
useEffect(() => {
|
||||
// 只有当value真正发生变化时才更新
|
||||
// Only update when value actually changes
|
||||
if (lastValueRef.current !== value) {
|
||||
editor.update(() => {
|
||||
const root = $getRoot();
|
||||
const currentText = root.getTextContent();
|
||||
|
||||
// 如果当前内容和新值相同,则不更新
|
||||
// If current content matches new value, don't update
|
||||
if (currentText === (value || '')) {
|
||||
return;
|
||||
}
|
||||
@@ -26,7 +40,7 @@ const InitialValuePlugin: FC<{ value?: string }> = ({ value }) => {
|
||||
paragraph.append(textNode);
|
||||
root.append(paragraph);
|
||||
} else {
|
||||
// 当value为undefined或空时,创建一个空段落
|
||||
// When value is undefined or empty, create an empty paragraph
|
||||
const paragraph = $createParagraphNode();
|
||||
root.append(paragraph);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,22 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 16:25:05
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 16:25:05
|
||||
*/
|
||||
/**
|
||||
* Insert Text Plugin
|
||||
* Provides functionality to insert text at the current cursor position
|
||||
*/
|
||||
|
||||
import { forwardRef, useImperativeHandle } from 'react';
|
||||
import { $getSelection } from 'lexical';
|
||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
||||
import type { EditorRef } from '../index'
|
||||
|
||||
// 插入文本的插件
|
||||
const InsertTextPlugin = forwardRef<EditorRef>((_, ref) => {
|
||||
/**
|
||||
* Plugin to insert text at cursor position
|
||||
*/
|
||||
const InsertTextPlugin = forwardRef<{ insertText: (text: string) => void; }>((_, ref) => {
|
||||
const [editor] = useLexicalComposerContext();
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
|
||||
@@ -1,8 +1,22 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 16:25:09
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 16:25:09
|
||||
*/
|
||||
/**
|
||||
* Line Break Plugin
|
||||
* Handles line breaks and triggers onChange callback when editor content changes
|
||||
* Converts \n escape sequences to actual line breaks
|
||||
*/
|
||||
|
||||
import { type FC, useEffect } from 'react';
|
||||
import { $getRoot } from 'lexical';
|
||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
||||
|
||||
// 处理换行的插件
|
||||
/**
|
||||
* Plugin to handle line breaks and content changes
|
||||
*/
|
||||
const LineBreakPlugin: FC<{ onChange?: (value: string) => void }> = ({ onChange }) => {
|
||||
const [editor] = useLexicalComposerContext();
|
||||
|
||||
@@ -11,7 +25,7 @@ const LineBreakPlugin: FC<{ onChange?: (value: string) => void }> = ({ onChange
|
||||
editorState.read(() => {
|
||||
const root = $getRoot();
|
||||
const textContent = root.getTextContent();
|
||||
// 将\n转换为实际换行
|
||||
// Convert \n to actual line breaks
|
||||
const processedContent = textContent.replace(/\\n/g, '\n');
|
||||
onChange?.(processedContent);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user