Cursor & Selections
If you want to know which block(s) the user is currently editing, you can do so using cursor positions and selections.
Text Cursor
The text cursor is the blinking vertical line you see when typing in the editor. BlockNote uses TextCursorPosition
objects to give you information about the block it's in as well as those around it:
type TextCursorPosition = {
block: Block;
prevBlock: Block | undefined;
nextBlock: Block | undefined;
};
block:
The block currently containing the text cursor. If the cursor is in a nested block, this is the block at the deepest possible nesting level.
prevBlock:
The previous block at the same nesting level. Undefined if the block containing the text cursor is the first child of its parent, or the first block in the editor.
nextBlock:
The next block at the same nesting level. Undefined if the block containing the text cursor is the last child of its parent, or the last block in the editor.
Getting Text Cursor Position
You can get a snapshot of the current text cursor position using the following call:
getTextCursorPosition(): TextCursorPosition;
// Usage
const textCursorPosition = editor.getTextCursorPosition();
returns:
A snapshot of the current text cursor position.
Setting Text Cursor Position
You can set the text cursor position to the start or end of an existing block using the following call:
setTextCursorPosition(
targetBlock: BlockIdentifier,
placement: "start" | "end" = "start"
): void;
// Usage
editor.setTextCursorPosition(targetBlock, placement);
targetBlock:
The identifier of an existing block that the text cursor should be moved to.
placement:
Whether the text cursor should be placed at the start or end of the block.
Throws an error if the target block could not be found.
Selections
When you highlight content using the mouse or keyboard, this is called a selection. BlockNote uses Selection
objects to show which blocks the current selection spans across:
type Selection = {
blocks: Block[];
};
blocks:
The blocks currently spanned by the selection, including nested blocks.
Getting Selection
You can get a snapshot of the current selection using the following call:
getSelection(): Selection | undefined;
// Usage
const selection = editor.getSelection();
returns:
A snapshot of the current selection, or undefined
if no selection is active.
Setting Selection
You update the selection to span from one block to another using the following call:
setSelection(startBlock: BlockIdentifier, endBlock: BlockIdentifier): void;
// Usage
editor.setSelection(startBlockIdentifier, endBlockIdentifier);
startBlock:
The identifier of the block where the selection should start.
endBlock:
The identifier of the block where the selection should end.
Both startBlock
and endBlock
must point to a block with content. The updated selection will span from the start of the first block to the end of the last block.
Getting Selected Blocks
The demo below displays the blocks in the current selection as JSON below the editor. If a selection isn't active, it displays the block containing the text cursor instead.
import { Block } from "@blocknote/core";
import "@blocknote/core/fonts/inter.css";
import { useCreateBlockNote } from "@blocknote/react";
import { BlockNoteView } from "@blocknote/mantine";
import "@blocknote/mantine/style.css";
import { useState } from "react";
import "./styles.css";
export default function App() {
// Stores the selected blocks as an array of Block objects.
const [blocks, setBlocks] = useState<Block[]>([]);
// Creates a new editor instance.
const editor = useCreateBlockNote({
initialContent: [
{
type: "paragraph",
content: "Welcome to this demo!",
},
{
type: "paragraph",
content: "Select different blocks to see the JSON change below",
},
{
type: "paragraph",
},
],
});
// Renders the editor instance.
return (
<div className={"wrapper"}>
<div>BlockNote Editor:</div>
<div className={"item"}>
<BlockNoteView
editor={editor}
onSelectionChange={() => {
const selection = editor.getSelection();
// Get the blocks in the current selection and store on the state. If
// the selection is empty, store the block containing the text cursor
// instead.
if (selection !== undefined) {
setBlocks(selection.blocks);
} else {
setBlocks([editor.getTextCursorPosition().block]);
}
}}
/>
</div>
<div>Selection JSON:</div>
<div className={"item bordered"}>
<pre>
<code>{JSON.stringify(blocks, null, 2)}</code>
</pre>
</div>
</div>
);
}