CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-lexical

Lexical is an extensible text editor framework that provides excellent reliability, accessible and performance.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

index.mddocs/

Lexical

Lexical is an extensible JavaScript text editor framework with an emphasis on reliability, accessibility, and performance. It provides a dependency-free editor engine that allows for powerful text editing implementations with immutable state management, plugin architecture, and advanced features like collaborative editing support.

Package Information

  • Package Name: lexical
  • Package Type: npm
  • Language: JavaScript/TypeScript
  • Installation: npm install lexical

Core Imports

import { createEditor, $getRoot, $getSelection } from "lexical";
import { $createTextNode, $createParagraphNode } from "lexical";

For CommonJS:

const { createEditor, $getRoot, $getSelection } = require("lexical");

Basic Usage

import { createEditor, $getRoot, $createParagraphNode, $createTextNode } from "lexical";

// Create an editor instance
const config = {
  namespace: 'MyEditor',
  theme: {
    // Optional theming
  },
  onError: (error) => {
    console.error(error);
  },
};

const editor = createEditor(config);

// Associate with a DOM element
const contentEditable = document.getElementById('editor');
editor.setRootElement(contentEditable);

// Update editor content
editor.update(() => {
  const root = $getRoot();
  const paragraph = $createParagraphNode();
  const text = $createTextNode('Hello, Lexical!');
  
  paragraph.append(text);
  root.append(paragraph);
});

// Listen for updates
editor.registerUpdateListener(({ editorState }) => {
  editorState.read(() => {
    // Read the current editor state
    const root = $getRoot();
    console.log(root.getTextContent());
  });
});

Architecture

Lexical is built around several key components:

  • Editor Instance: Core editor that manages state, DOM binding, and operations
  • Editor State: Immutable state container representing the current document state
  • Node System: Tree-based node structure for representing content (Text, Element, Paragraph, etc.)
  • Selection System: Sophisticated selection handling with Range and Node selections
  • Command System: Event-driven architecture for handling user interactions and programmatic changes
  • Caret System: Advanced caret positioning and navigation for precise text manipulation
  • DOM Reconciler: Efficient DOM updates through state diffing and reconciliation

Capabilities

Editor Management

Core editor functionality for creating, configuring, and managing Lexical editor instances.

function createEditor(config?: CreateEditorArgs): LexicalEditor;

interface CreateEditorArgs {
  namespace?: string;
  theme?: EditorThemeClasses;
  onError?: (error: Error) => void;
  nodes?: ReadonlyArray<Klass<LexicalNode> | LexicalNodeReplacement>;
  editorState?: EditorState;
  html?: HTMLConfig;
  editable?: boolean;
}

interface LexicalEditor {
  setRootElement(rootElement: null | HTMLElement): void;
  getEditorState(): EditorState;
  setEditorState(editorState: EditorState, options?: EditorSetOptions): void;
  update(updateFn: () => void, options?: EditorUpdateOptions): void;
  read(readFn: () => T): T;
  focus(callbackFn?: () => void): void;
  blur(): void;
  isEditable(): boolean;
  setEditable(editable: boolean): void;
}

Editor Management

Node System

Comprehensive node types and utilities for representing and manipulating document content.

abstract class LexicalNode {
  getKey(): NodeKey;
  getType(): string;
  clone(): LexicalNode;
  createDOM(config: EditorConfig): HTMLElement;
  updateDOM(prevNode: this, dom: HTMLElement, config: EditorConfig): boolean;
  exportJSON(): SerializedLexicalNode;
  exportDOM(editor: LexicalEditor): DOMExportOutput;
}

class TextNode extends LexicalNode {
  constructor(text: string, key?: NodeKey);
  getTextContent(): string;
  setTextContent(text: string): this;
  hasFormat(type: TextFormatType): boolean;
  toggleFormat(type: TextFormatType): this;
}

class ElementNode extends LexicalNode {
  getChildren(): Array<LexicalNode>;
  getChildrenSize(): number;
  append(...nodesToAppend: LexicalNode[]): this;
  select(anchorOffset?: number, focusOffset?: number): RangeSelection;
}

Node System

Selection System

Advanced selection management with Range and Node selections, providing precise control over user selection and programmatic selection manipulation.

function $getSelection(): BaseSelection | null;
function $setSelection(selection: BaseSelection): void;
function $createRangeSelection(): RangeSelection;
function $createNodeSelection(): NodeSelection;

interface RangeSelection extends BaseSelection {
  anchor: Point;
  focus: Point;
  getTextContent(): string;
  insertText(text: string): void;
  insertNodes(nodes: LexicalNode[]): void;
  removeText(): void;
}

interface NodeSelection extends BaseSelection {
  getNodes(): LexicalNode[];
  add(key: NodeKey): void;
  delete(key: NodeKey): void;
  clear(): void;
}

Selection System

Command System

Comprehensive command system for handling user interactions, keyboard events, and programmatic editor operations.

function createCommand<T>(type?: string): LexicalCommand<T>;

interface LexicalEditor {
  registerCommand<P>(
    command: LexicalCommand<P>,
    listener: CommandListener<P>,
    priority: CommandListenerPriority
  ): () => void;
  
  dispatchCommand<P>(command: LexicalCommand<P>, payload: P): boolean;
}

// Built-in Commands
const FORMAT_TEXT_COMMAND: LexicalCommand<TextFormatType>;
const INSERT_PARAGRAPH_COMMAND: LexicalCommand<void>;
const DELETE_CHARACTER_COMMAND: LexicalCommand<boolean>;
const UNDO_COMMAND: LexicalCommand<void>;
const REDO_COMMAND: LexicalCommand<void>;

Command System

State Management

Immutable editor state management with node state capabilities for advanced use cases.

interface EditorState {
  read<T>(callbackFn: () => T): T;
  clone(selection?: BaseSelection): EditorState;
  toJSON(): SerializedEditorState;
}

// Node State Management
function createState<T>(config: StateValueConfig<T>): StateConfig<T>;
function $getState<T>(node: LexicalNode, stateConfig: StateConfig<T>): T;
function $setState<T>(node: LexicalNode, stateConfig: StateConfig<T>, value: T): void;

State Management

Utilities and Helpers

Essential utility functions for DOM operations, node manipulation, and editor interaction.

function $getRoot(): RootNode;
function $getNodeByKey(key: NodeKey): LexicalNode | null;
function $createTextNode(text?: string): TextNode;
function $createParagraphNode(): ParagraphNode;

// DOM Utilities
function isLexicalEditor(editor: unknown): editor is LexicalEditor;
function getNearestEditorFromDOMNode(node: Node): LexicalEditor | null;
function $getNearestNodeFromDOMNode(node: Node): LexicalNode | null;

Utilities and Helpers

Caret System

Advanced caret positioning and navigation system for precise text manipulation and cursor movement.

interface TextPointCaret {
  type: 'text-point';
  node: TextNode;
  offset: number;
}

interface SiblingCaret {
  type: 'sibling';
  node: LexicalNode;
  direction: 'next' | 'previous';
}

function $getTextPointCaret(node: TextNode, offset: number): TextPointCaret;
function $getSiblingCaret(node: LexicalNode, direction: CaretDirection): SiblingCaret;
function $setSelectionFromCaretRange(range: CaretRange): void;

Caret System

Constants

/** Text formatting constants */
const IS_BOLD: number;
const IS_ITALIC: number;
const IS_STRIKETHROUGH: number;
const IS_UNDERLINE: number;
const IS_CODE: number;
const IS_SUBSCRIPT: number;
const IS_SUPERSCRIPT: number;
const IS_HIGHLIGHT: number;
const IS_ALL_FORMATTING: number;

/** Node state key for internal state management */
const NODE_STATE_KEY: string;

/** Mapping of text format types to numeric values */
const TEXT_TYPE_TO_FORMAT: Record<string, number>;

/** Update tags for categorizing editor updates */
const HISTORIC_TAG: string;
const HISTORY_PUSH_TAG: string;
const HISTORY_MERGE_TAG: string;
const PASTE_TAG: string;
const COLLABORATION_TAG: string;
const SKIP_COLLAB_TAG: string;
const SKIP_SCROLL_INTO_VIEW_TAG: string;
const SKIP_DOM_SELECTION_TAG: string;
const FOCUS_TAG: string;

Types

type NodeKey = string;
type TextFormatType = 'bold' | 'italic' | 'strikethrough' | 'underline' | 'code' | 'subscript' | 'superscript' | 'highlight';
type ElementFormatType = 'left' | 'center' | 'right' | 'justify' | 'start' | 'end';
type CommandListenerPriority = 0 | 1 | 2 | 3 | 4;
type UpdateTag = string;

interface EditorThemeClasses {
  paragraph?: string;
  text?: {
    bold?: string;
    italic?: string;
    underline?: string;
    strikethrough?: string;
    underlineStrikethrough?: string;
    code?: string;
    highlight?: string;
    subscript?: string;
    superscript?: string;
  };
}

interface SerializedLexicalNode {
  type: string;
  version: number;
}

interface SerializedEditorState {
  root: SerializedRootNode;
}

docs

caret-system.md

command-system.md

editor-management.md

index.md

node-system.md

selection-system.md

state-management.md

utilities-helpers.md

tile.json