index.tsx
Overview
This file implements a rich text prompt editor component using the Lexical framework. It provides an interactive text editing experience with syntax highlighting, variable insertion, and custom node support. The editor supports both single-line and multi-line modes, with an optional toolbar for inserting variables.
Key features include:
Rich text editing with headings, quotes, and code blocks.
Custom variable nodes that can be inserted via a toolbar or keyboard shortcuts.
Plugins to handle variable picking, paste events, and reacting to content changes.
Error boundary handling to maintain editor stability.
Internationalization support via
react-i18next.
This component is designed to be embedded wherever a rich prompt input is needed, such as in chatbots, flow builders, or form inputs that require dynamic content.
Detailed Explanation
Imports and Dependencies
Lexical modules: Core Lexical and React bindings (
LexicalComposer,ContentEditable,LexicalErrorBoundary,RichTextPlugin, etc.) provide the editor framework.Lexical nodes: Built-in nodes like
HeadingNode,QuoteNode,CodeNode, and customVariableNode.UI Components: Tooltip components from the local UI library, and utility functions like
cnfor conditional classNames.Plugins: Custom plugins for handling variable picking, paste events, and variable change detection.
Icons:
Variableicon fromlucide-reactfor the toolbar button.React hooks:
useState,useCallbackfor state and memoization.i18n:
useTranslationhook for localization.
Constants and Types
const Nodes: Array<Klass<LexicalNode>> = [
HeadingNode,
QuoteNode,
CodeHighlightNode,
CodeNode,
VariableNode,
];
Defines the custom node types supported by this editor instance, including custom
VariableNodeand standard rich text nodes.
type PromptContentProps = {
showToolbar?: boolean;
multiLine?: boolean;
};
Props to control whether the toolbar is shown and whether multi-line input is enabled.
type IProps = {
value?: string;
onChange?: (value?: string) => void;
placeholder?: ReactNode;
} & PromptContentProps;
Props for the main
PromptEditorcomponent, extendingPromptContentPropswith editor value, change callback, and placeholder content.
Functions and Components
onError
function onError(error: Error)
Purpose: Global error handler for Lexical editor updates.
Parameters:
error— the caught error object.Functionality: Logs the error to the console. Could be extended to report errors or throw to halt editor updates.
Usage: Passed to Lexical's
initialConfigto catch and handle runtime editor errors gracefully.
PromptContent
function PromptContent({
showToolbar = true,
multiLine = true,
}: PromptContentProps)
Purpose: Renders the editable content area and optional toolbar with variable insertion button.
Parameters:
showToolbar(defaulttrue): Show or hide the toolbar with variable button.multiLine(defaulttrue): Enable multi-line editing mode, affecting styling.
State:
isBlur(boolean): Tracks focus state to style the border accordingly.
Hooks:
useLexicalComposerContext()to get the Lexical editor instance.useTranslation()for i18n support.
Key Methods:
insertTextAtCursor(): Inserts a/string at the current cursor position inside the editor.handleVariableIconClick(): CallsinsertTextAtCursorwhen the variable icon is clicked.handleBlur()/handleFocus(): UpdateisBlurstate on editor focus changes.
Render:
A
sectionwith conditional border styling based on focus.Toolbar containing a
Variableicon wrapped in a tooltip that shows a localized tip.ContentEditablefrom Lexical for the editable text area with styling and event handlers for focus/blur.
Usage Example:
<PromptContent showToolbar={false} multiLine={false} />
Renders the content editable area without the toolbar and in single-line mode.
PromptEditor
export function PromptEditor({
value,
onChange,
placeholder,
showToolbar,
multiLine = true,
}: IProps)
Purpose: Main exported component that sets up the Lexical editor with configuration, plugins, and renders the
PromptContentcomponent inside.Parameters:
value: Optional initial text content (string).onChange: Callback invoked with the editor text content on updates.placeholder: Placeholder ReactNode for empty editor state.showToolbar: Whether to display the variable insertion toolbar.multiLine: Whether the editor is multi-line (defaulttrue).
Internal Details:
Creates
initialConfigfor LexicalComposer with namespace, theme, error handler, and node types.onValueChange: Callback to read Lexical editor state, extract root text content, and invokeonChangeprop.
Plugins used:
RichTextPlugin: WrapsPromptContentwith placeholder and error boundary.VariablePickerMenuPlugin: Manages variable picker UI.PasteHandlerPlugin: Custom paste event handling.VariableOnChangePlugin: Tracks changes to variables and triggersonValueChange.
Usage Example:
<PromptEditor
value="Hello world"
onChange={(text) => console.log(text)}
placeholder="Type your prompt here..."
showToolbar={true}
multiLine={false}
/>
Important Implementation Details
Lexical Framework: The editor is built on Lexical, a modern extensible text editor framework. Nodes like
HeadingNodeandVariableNodeextend the editor schema to support rich content.Custom Variable Insertion: Clicking the variable icon inserts a " /" string at the cursor, presumably triggering variable picker UI (managed by
VariablePickerMenuPlugin).Error Handling: All Lexical update errors are caught by
onErrorto prevent editor crashes.Localization: All user-facing strings like tooltips and placeholders use
react-i18nextfor translation support.Styling: Uses utility
cnfunction for conditional classNames, supporting dark mode and responsive behavior.Plugins Architecture: The editor leverages a modular plugin system to extend functionality like paste handling and variable change tracking, keeping the core component clean.
Interaction with Other Parts of the System
Custom Nodes & Plugins: Imports
VariableNode,VariableOnChangePlugin,VariablePickerMenuPlugin, andPasteHandlerPluginfrom relative paths, indicating these are custom modules extending Lexical editor capabilities specifically for variable management and paste behavior.UI Components: Uses local
Tooltipcomponents and utility functions from the project (@/components/ui/tooltip,@/lib/utils).Theme: Imports a
themeconfiguration object customizing the Lexical editor's look and feel.Icons: Uses
lucide-reactfor the variable icon, indicating shared UI iconography.Localization: Integrates with the app's i18n framework (
react-i18next), ensuring consistency with other UI texts.
Visual Diagram
The diagram below illustrates the component and plugin composition within the PromptEditor and its interaction with the PromptContent editable area.
componentDiagram
direction LR
class PromptEditor {
+value?: string
+onChange?: (string) => void
+placeholder?: ReactNode
+showToolbar?: boolean
+multiLine?: boolean
}
class LexicalComposer {
+initialConfig: InitialConfigType
}
class RichTextPlugin {
+contentEditable: ReactNode
+placeholder: ReactNode
+ErrorBoundary: ReactComponent
}
class PromptContent {
+showToolbar?: boolean
+multiLine?: boolean
}
class VariablePickerMenuPlugin {}
class PasteHandlerPlugin {}
class VariableOnChangePlugin {
+onChange: (EditorState) => void
}
PromptEditor --> LexicalComposer
LexicalComposer --> RichTextPlugin
RichTextPlugin --> PromptContent
LexicalComposer --> VariablePickerMenuPlugin
LexicalComposer --> PasteHandlerPlugin
LexicalComposer --> VariableOnChangePlugin
Summary
The index.tsx file provides a feature-rich, extensible prompt editor component built with Lexical. It integrates custom nodes and plugins to support variable insertion, rich text formatting, and paste handling, wrapped in a React component that supports localization and theming. This file serves as a key UI building block for applications requiring dynamic prompt inputs with variable support.