Skip to Content

Editor State

useEditorState() creates the state used by a Theodore editor. Call it in your component and pass the returned object to Theodore through the required editorState prop.

import { Theodore, useEditorState } from 'theodore-js'; import 'theodore-js/style.css'; export function MessageInput() { const editorState = useEditorState(); return <Theodore editorState={editorState} />; }

The hook does not accept any arguments.

Reading editor content

editorState.tree contains Theodore’s structured representation of the current content. Use the exported convertTreeToText helper when you need plain text. See Utility Functions for its complete reference.

import { convertTreeToText } from 'theodore-js'; const text = convertTreeToText(editorState.tree);

The tree can contain internal node objects, including temporary ghost nodes used for suggestions. Avoid mutating the tree or its nodes directly.

Subscribing to changes

Use editorState.subscribe(listener) to observe subsequent content or selection updates. It returns an unsubscribe function. Subscribing does not immediately emit the current state.

import { useEffect } from 'react'; import { convertTreeToText, Theodore, type EditorSelection, useEditorState, } from 'theodore-js'; export function MessageInput() { const editorState = useEditorState(); const subscribe = editorState.subscribe; useEffect( () => subscribe({ onTreeChange: (tree) => { console.log('Content:', convertTreeToText(tree)); }, onSelectionChange: (selection: EditorSelection) => { console.log('Selection:', selection); }, }), [subscribe], ); return <Theodore editorState={editorState} />; }

Returning the unsubscribe function directly from useEffect, as shown above, removes the listener when the component unmounts or the subscription changes.

Listener callbacks

Pass an EditorStateListener object containing either or both callbacks:

type EditorStateListener = { onSelectionChange?: (selection: EditorSelection) => void; onTreeChange?: (tree: TheodoreTree) => void; };

onTreeChange

Called with the updated TheodoreTree whenever the editor tree changes. Use convertTreeToText(tree) when you only need its plain-text content.

onSelectionChange

Called with the updated EditorSelection whenever the editor selection changes. A selection contains its start and end node indexes and character offsets, or is null when no editor selection is active:

type EditorSelection = { startSelection: { nodeIndex: number; offset: number; }; endSelection: { nodeIndex: number; offset: number; }; } | null;

A collapsed cursor has identical start and end positions. A range selection has different start and end positions.

Reading the initial state

Subscribing only reports subsequent changes. Read editorState.tree for the current content tree and call editorState.selectionHandle.getSelection() for the current selection before subscribing if you also need initial values.

Resetting the editor

Call editorState.reset() to clear the content, restore the initial selection, reset node indexing, and discard undo history:

editorState.reset();

Code that already uses a TheodoreHandle can call resetEditor() instead. Both operations reset the same editor state.

Low-level fields

EditorState also exposes setTree, assignNodeIndex, historyHandle, and selectionHandle for the editor implementation. Most applications should use TheodoreHandle, subscribe, and the exported conversion or selection helpers instead of modifying these low-level fields directly.

Last updated on