Selection
Selection provides commands for programmatic selection (setSelection, selectNode, selectParentNode, extendSelection) and storage helpers for reading the current selection state (getText, getNode, isEmpty, getRange, getCursor). All storage functions read directly from the current editor state, always returning up-to-date values.
Not included in StarterKit. Add it separately.
import { Editor, Document, Paragraph, Text, Selection } from '@domternal/core';import '@domternal/theme';
const editor = new Editor({ element: document.getElementById('editor')!, extensions: [Document, Paragraph, Text, Selection], content: '<p>Select some text in this editor.</p>',});
// Read selected texteditor.on('selectionUpdate', () => { const text = editor.storage.selection.getText(); if (text) console.log('Selected:', text);});import { Component, signal, inject, NgZone } from '@angular/core';import { DomternalEditorComponent } from '@domternal/angular';import { Editor, Document, Paragraph, Text, Selection } from '@domternal/core';
@Component({ selector: 'app-editor', imports: [DomternalEditorComponent], templateUrl: './editor.html',})export class EditorComponent { private zone = inject(NgZone); editor = signal<Editor | null>(null); selectedText = signal(''); extensions = [Document, Paragraph, Text, Selection];
onEditorCreated(editor: Editor) { this.editor.set(editor); editor.on('selectionUpdate', () => { this.zone.run(() => { this.selectedText.set(editor.storage.selection.getText()); }); }); }}<domternal-editor [extensions]="extensions" (editorCreated)="onEditorCreated($event)"/><p>Selected: {{ selectedText() }}</p>import { Domternal, useCurrentEditor, useEditorState } from '@domternal/react';import { Document, Paragraph, Text, Selection } from '@domternal/core';
function SelectedText() { const { editor } = useCurrentEditor(); const selectedText = useEditorState(editor, (ed) => ed.storage.selection?.getText() ?? '', ); return <p>Selected: {selectedText}</p>;}
export default function Editor() { return ( <Domternal extensions={[Document, Paragraph, Text, Selection]} > <Domternal.Content /> <SelectedText /> </Domternal> );}import { Editor, Document, Paragraph, Text, Selection } from '@domternal/core';
const editor = new Editor({ element: document.getElementById('editor')!, extensions: [Document, Paragraph, Text, Selection],});
// Set a text selection (positions 5 to 10)editor.commands.setSelection(5, 10);
// Collapse to cursor at position 5editor.commands.setSelection(5);
// Select a node at position 0editor.commands.selectNode(0);
// Select the parent node of the current selectioneditor.commands.selectParentNode();
// Extend selection to the start or end of the documenteditor.commands.extendSelection('start');editor.commands.extendSelection('end');
// Read selection stateconst { getText, getNode, isEmpty, getRange, getCursor } = editor.storage.selection;console.log(getText()); // selected text contentconsole.log(isEmpty()); // true if cursor is collapsedconsole.log(getRange()); // { from: 5, to: 10 }console.log(getCursor()); // null (range selection) or position numberOptions
Section titled “Options”Selection has no configurable options.
Commands
Section titled “Commands”setSelection
Section titled “setSelection”Creates a text selection between two positions. If only from is provided, creates a collapsed cursor at that position. Returns false if the positions are out of bounds.
// Range selectioneditor.commands.setSelection(5, 10);
// Collapsed cursoreditor.commands.setSelection(5);
// With chainingeditor.chain().focus().setSelection(5, 10).run();selectNode
Section titled “selectNode”Creates a node selection at the given position. The position must point to the start of a node. Returns false if the position is out of bounds or no node exists there.
editor.commands.selectNode(0); // select the first nodeselectParentNode
Section titled “selectParentNode”Selects the nearest parent node of the current selection that is selectable (selectable !== false in the node spec). Walks up the document tree from the current depth. Returns false if no selectable parent is found.
editor.commands.selectParentNode();extendSelection
Section titled “extendSelection”Extends the current selection in the given direction. Does not collapse the selection, only moves one edge.
editor.commands.extendSelection('left'); // extend from edge one position lefteditor.commands.extendSelection('right'); // extend to edge one position righteditor.commands.extendSelection('start'); // extend from edge to document starteditor.commands.extendSelection('end'); // extend to edge to document end| Direction | Behavior |
|---|---|
left | Moves from one position left (clamped to document start) |
right | Moves to one position right (clamped to document end) |
start | Moves from to the start of the document |
end | Moves to to the end of the document |
The start and end directions use Selection.atStart() and Selection.atEnd() from ProseMirror to find the first/last valid text position, handling nested structures correctly.
Storage
Section titled “Storage”Access selection helpers via editor.storage.selection:
| Method | Returns | Description |
|---|---|---|
getText() | string | Selected text content. Uses doc.textBetween(from, to, ' ') with space as block separator. |
getNode() | PMNode | null | The selected node if it’s a NodeSelection, otherwise null. |
isEmpty() | boolean | true if the selection is collapsed (cursor, no range). |
getRange() | { from: number; to: number } | Current selection positions. |
getCursor() | number | null | Cursor position if collapsed, null if range selection. |
const { getText, getNode, isEmpty, getRange, getCursor } = editor.storage.selection;
console.log(getText()); // "selected text"console.log(getNode()); // null (or PMNode for node selections)console.log(isEmpty()); // falseconsole.log(getRange()); // { from: 5, to: 18 }console.log(getCursor()); // null (range selection)All storage functions read directly from editor.state on each call, so they always return the current value without caching.
Keyboard shortcuts
Section titled “Keyboard shortcuts”Selection does not register any keyboard shortcuts.
Input rules
Section titled “Input rules”Selection does not register any input rules.
Toolbar items
Section titled “Toolbar items”Selection does not register any toolbar items.
How it works
Section titled “How it works”Storage initialization
Section titled “Storage initialization”The storage functions are initialized in the onCreate hook. Each function reads from editor.state when called:
getText(): callsdoc.textBetween(from, to, ' ')with a space separator between blocksgetNode(): checks if the selection is aNodeSelectionand returnsselection.nodeisEmpty(): returnsstate.selection.emptygetRange(): returns{ from: state.selection.from, to: state.selection.to }getCursor(): returnsselection.fromonly if the selection is empty, otherwisenull
Command chain compatibility
Section titled “Command chain compatibility”All commands use tr.doc and tr.selection instead of state.doc and state.selection. This ensures correct behavior when commands are chained, since prior commands in the chain may have modified the document (changing positions and document size).
Bounds checking
Section titled “Bounds checking”setSelection validates that positions are within [0, tr.doc.content.size]. selectNode validates that the position is within bounds and that a node exists at that position. Both return false for invalid positions without throwing.
extendSelection clamping
Section titled “extendSelection clamping”The left and right directions clamp to the document boundaries using Selection.atStart(doc).from and Selection.atEnd(doc).to, which find the first and last valid text positions. This handles nested structures (like doc > blockquote > paragraph) where position 0 or doc.content.size may not be a valid text position.
Exports
Section titled “Exports”import { Selection } from '@domternal/core';import type { SelectionOptions, SelectionStorage } from '@domternal/core';| Export | Type | Description |
|---|---|---|
Selection | Extension | The selection extension |
SelectionOptions | TypeScript type | Options for Selection.configure() (empty) |
SelectionStorage | TypeScript type | Shape of editor.storage.selection |
Source
Section titled “Source”@domternal/core - Selection.ts