Editor Component¶
Overview¶
The Editor component is a sophisticated rich text editing interface built on the Lexical framework. It provides advanced document editing capabilities with real-time formatting, evidence citation, requirement tracking, and AI-assisted content generation.
Features¶
- Rich Text Editing: Full-featured text editor with formatting, styles, and multimedia support
- Evidence Highlighting: Ability to highlight and link evidence to support document claims
- Requirement Tracking: Integration with tender requirements for tracking completion status
- Real-time Collaboration: Supports multiple users editing simultaneously
- Document Versioning: Tracks document history and revisions
- AI-Assisted Writing: Integration with AI services for content suggestions and improvements
- Customisable Toolbar: Context-sensitive formatting options
Implementation¶
The component is built using React with the Lexical editor framework and integrates with the BidScript backend for document management.
import { useEffect, useState, useRef } 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 { LinkPlugin } from "@lexical/react/LexicalLinkPlugin";
import { ListPlugin } from "@lexical/react/LexicalListPlugin";
import { TabIndentationPlugin } from "@lexical/react/LexicalTabIndentationPlugin";
import LexicalErrorBoundary from "@lexical/react/LexicalErrorBoundary";
import { useWorkspaceContext } from "@/components/Editor/WorkspaceContext";
import { ToolbarPlugin } from "@/components/Editor/plugins/ToolbarPlugin";
import { HighlightPlugin } from "@/components/Editor/plugins/HighlightPlugin";
import { RestoreEditorStatePlugin } from "@/components/Editor/plugins/restoreEditorStatePlugin";
import { ExportEditorStatePlugin } from "@/components/Editor/plugins/exportEditorStatePlugin";
import { theme } from "@/components/Editor/themes/ExampleTheme";
Props¶
| Prop | Type | Description |
|---|---|---|
initialState |
string | null | Initial editor content state (serialized JSON) |
readOnly |
boolean | Whether the editor is in read-only mode |
onChange |
function | Callback function when content changes |
onSave |
function | Callback function when content is saved |
requirements |
Requirement[] | Array of requirements to track in the document |
highlightedEvidence |
Evidence[] | Array of evidence citations to highlight |
State Management¶
The component manages several state variables through a combination of internal state and context providers:
// Editor state management
const { editorState, setEditorState } = useWorkspaceContext();
const [isEditorReady, setIsEditorReady] = useState<boolean>(false);
const [activeFormatters, setActiveFormatters] = useState<FormatterState>({
bold: false,
italic: false,
underline: false,
strikethrough: false,
code: false,
highlight: false,
});
// Content tracking
const [wordCount, setWordCount] = useState<number>(0);
const [charCount, setCharCount] = useState<number>(0);
const [requirementCoverage, setRequirementCoverage] = useState<number>(0);
// Collaboration state
const [collaborators, setCollaborators] = useState<Collaborator[]>([]);
const [pendingChanges, setPendingChanges] = useState<Change[]>([]);
Lexical Configuration¶
The Lexical editor is configured with custom nodes and plugins:
const initialConfig = {
namespace: "BidScriptEditor",
theme,
onError: handleEditorError,
nodes: [
HeadingNode,
ListNode,
ListItemNode,
QuoteNode,
CodeNode,
CodeHighlightNode,
TableNode,
TableCellNode,
TableRowNode,
AutoLinkNode,
LinkNode,
HighlightNode,
],
};
Editor Plugins¶
The editor utilizes several custom plugins for enhanced functionality:
<LexicalComposer initialConfig={initialConfig}>
<div className="editor-container">
<ToolbarPlugin />
<div className="editor-inner">
<RichTextPlugin
contentEditable={<ContentEditable className="editor-input" />}
placeholder={<Placeholder />}
ErrorBoundary={LexicalErrorBoundary}
/>
<HistoryPlugin />
<AutoFocusPlugin />
<ListPlugin />
<LinkPlugin />
<TabIndentationPlugin />
<HighlightPlugin highlightedEvidence={highlightedEvidence} />
<RestoreEditorStatePlugin initialState={initialState} />
<ExportEditorStatePlugin onChange={handleEditorChange} />
<ChangeAnalysisPlugin requirements={requirements} />
</div>
</div>
</LexicalComposer>
Methods¶
// Editor state management
const handleEditorChange = (editorState) =>
// Updates editor state and processes changes
const saveEditorContent = async () =>
// Saves the current editor content to the server
// Formatting functions
const applyFormat = (format, value) =>
// Applies specified formatting to selected text
const insertLink = (url, text) =>
// Inserts a hyperlink at the current cursor position
// Evidence and requirements
const highlightEvidence = (evidenceId, text) =>
// Highlights text and links it to specific evidence
const checkRequirementCoverage = () =>
// Analyzes content for requirement coverage
Usage Example¶
import { Editor } from "@/components/workspace/Editor";
import { useWorkspaceContext } from "@/components/Editor/WorkspaceContext";
const DocumentEditor = () => {
const { editorState, requirements, evidence } = useWorkspaceContext();
return (
<div className="document-editor">
<h2>Document Editor</h2>
<Editor
initialState={editorState}
requirements={requirements}
highlightedEvidence={evidence}
onChange={handleEditorChange}
onSave={handleSaveDocument}
/>
</div>
);
};
Dependencies¶
// Core editor dependencies
import { LexicalComposer } from "@lexical/react/LexicalComposer";
import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
// BidScript custom components
import { useWorkspaceContext } from "@/components/Editor/WorkspaceContext";
import { ToolbarPlugin } from "@/components/Editor/plugins/ToolbarPlugin";
import { HighlightPlugin } from "@/components/Editor/plugins/HighlightPlugin";
Notes¶
- Optimised for performance with large documents
- Implements custom nodes for BidScript-specific features
- Uses WebSockets for real-time collaboration
- Supports keyboard shortcuts for common operations
- Includes accessibility features for inclusive editing experience