docs/api/slate/editor-transforms.mdx
Transforms are helper functions that manipulate a Plate document.
duplicateNodesDuplicates nodes at a location and inserts them after that location.
<API name="duplicateNodes"> <APIOptions type="DuplicateNodesOptions"> <APIItem name="...options" type="InsertNodesOptions" optional> `insertNodes` options. </APIItem> <APIItem name="at" type="At" optional> Location to duplicate from and insert after. Defaults to selection. </APIItem> <APIItem name="block" type="boolean" optional> If true, duplicates blocks above location. Ignored if `nodes` provided. </APIItem> <APIItem name="nodes" type="NodeEntry[]" optional> Specific nodes to duplicate. Takes precedence over `block`. </APIItem> </APIOptions> </API>insertFragmentInsert a fragment of nodes at a location.
<API name="insertFragment"> <APIParameters> <APIItem name="fragment" type="N[]"> Fragment of nodes to insert. </APIItem> <APIItem name="options" type="InsertFragmentOptions" optional /> </APIParameters> <APIOptions type="InsertFragmentOptions"> <APIItem name="at" type="At" optional> Location to insert at. Defaults to selection. </APIItem> <APIItem name="hanging" type="boolean" optional> Whether range is hanging. </APIItem> <APIItem name="voids" type="boolean" optional> Allow insertion in void nodes. </APIItem> </APIOptions> </API>insertNodeInsert a single node atomically.
<API name="insertNode"> <APIParameters> <APIItem name="node" type="N"> Node to insert. </APIItem> <APIItem name="options" type="InsertNodesOptions" optional /> </APIParameters> </API>insertNodesInsert one or more nodes atomically.
<API name="insertNodes"> <APIParameters> <APIItem name="nodes" type="N | N[]"> Node(s) to insert. </APIItem> <APIItem name="options" type="InsertNodesOptions" optional /> </APIParameters> <APIOptions type="InsertNodesOptions"> <APIItem name="...options" type="QueryOptions" optional> Common query options. </APIItem> <APIItem name="batchDirty" type="boolean" optional /> <APIItem name="hanging" type="boolean" optional /> <APIItem name="nextBlock" type="boolean" optional> Insert after the current block if `removeEmpty` caused it to be removed. </APIItem> <APIItem name="removeEmpty" type="QueryNodeOptions | boolean" optional> Remove the current block if empty. Defaults to removing an empty paragraph, but can be customized. </APIItem> <APIItem name="select" type="boolean" optional> Select inserted nodes. </APIItem> <APIItem name="voids" type="boolean" optional> Allow insertion in void nodes. </APIItem> </APIOptions> </API>liftNodesLift nodes at the specified location upwards in the document tree. If necessary, the parent node is split.
<API name="liftNodes"> <APIOptions type="LiftNodesOptions"> <APIItem name="...options" type="QueryOptions" optional /> <APIItem name="mode" type="'highest' | 'lowest'" optional /> <APIItem name="voids" type="boolean" optional /> </APIOptions> </API>mergeNodesMerge a node at the specified location with the previous node at the same depth. Resulting empty container nodes are removed.
<API name="mergeNodes"> <APIOptions type="MergeNodesOptions"> <APIItem name="...options" type="QueryOptions" optional /> <APIItem name="hanging" type="boolean" optional /> </APIOptions> </API>moveNodesMove the nodes from an origin to a destination.
<API name="moveNodes"> <APIOptions type="MoveNodesOptions"> <APIItem name="...options" type="QueryOptions" optional /> <APIItem name="to" type="Path"> Destination path. </APIItem> <APIItem name="children" type="boolean" optional> Move only children of the node at the location. </APIItem> <APIItem name="fromIndex" type="number" optional> Start index of the children to move. Default is 0. </APIItem> <APIItem name="mode" type="'highest' | 'lowest'" optional /> <APIItem name="voids" type="boolean" optional /> </APIOptions> </API>removeNodesRemove nodes at a location.
<API name="removeNodes"> <APIOptions type="RemoveNodesOptions"> <APIItem name="...options" type="QueryOptions" optional /> <APIItem name="children" type="boolean" optional> When true, remove all children of the node at the specified location. </APIItem> <APIItem name="hanging" type="boolean" optional /> <APIItem name="previousEmptyBlock" type="boolean" optional> Remove the previous empty block if it exists. </APIItem> <APIItem name="mode" type="'highest' | 'lowest'" optional /> <APIItem name="voids" type="boolean" optional /> </APIOptions> </API>replaceNodesReplace nodes at a location with new nodes.
<API name="replaceNodes"> <APIParameters> <APIItem name="nodes" type="N | N[]"> The new node(s) to insert. </APIItem> <APIItem name="options" type="ReplaceNodesOptions" optional /> </APIParameters> <APIOptions type="ReplaceNodesOptions"> <APIItem name="...options" type="InsertNodesOptions" optional> `insertNodes` options. </APIItem> <APIItem name="children" type="boolean" optional> Replace all children of the node at the specified location instead of the node itself. </APIItem> <APIItem name="removeNodes" type="Omit<RemoveNodesOptions, 'at'>" optional> Options for removing nodes before the replacement. </APIItem> </APIOptions> </API>resetReset the editor state including history, selection and children.
<API name="reset"> <APIOptions type="ResetOptions"> <APIItem name="...options" type="ReplaceNodesOptions" optional> `replaceNodes` options. </APIItem> <APIItem name="children" type="boolean" optional> When true, only reset the children without clearing history/operations. </APIItem> </APIOptions> </API>setNodesSet properties on nodes.
<API name="setNodes"> <APIParameters> <APIItem name="props" type="Partial<NodeProps<N>>"> Properties to set. Use `undefined` to unset. </APIItem> <APIItem name="options" type="SetNodesOptions" optional /> </APIParameters> <APIOptions type="SetNodesOptions"> <APIItem name="...options" type="QueryOptions" optional /> <APIItem name="compare" type="(prop: Partial<Descendant>, node: Partial<Descendant>) => boolean" optional /> <APIItem name="hanging" type="boolean" optional /> <APIItem name="marks" type="boolean" optional> When true, only apply to text nodes in non-void or markable void nodes. </APIItem> <APIItem name="merge" type="(prop: Partial<Descendant>, node: Partial<Descendant>) => object" optional /> <APIItem name="mode" type="'highest' | 'lowest'" optional /> <APIItem name="split" type="boolean" optional /> <APIItem name="voids" type="boolean" optional /> </APIOptions> </API>splitNodesSplit nodes at a location.
<API name="splitNodes"> <APIOptions type="SplitNodesOptions"> <APIItem name="...options" type="QueryOptions" optional /> <APIItem name="always" type="boolean" optional /> <APIItem name="height" type="number" optional /> <APIItem name="mode" type="'highest' | 'lowest'" optional /> <APIItem name="voids" type="boolean" optional /> </APIOptions> </API>toggleBlockToggle the block type at a location.
<API name="toggleBlock"> <APIParameters> <APIItem name="type" type="string"> The block type to toggle. </APIItem> <APIItem name="options" type="ToggleBlockOptions" optional /> </APIParameters> <APIOptions type="ToggleBlockOptions"> <APIItem name="...options" type="SetNodesOptions" optional> Options to pass to `setNodes`. </APIItem> <APIItem name="defaultType" type="string" optional> The default block type when untoggling. Defaults to paragraph. </APIItem> <APIItem name="someOptions" type="EditorNodesOptions" optional> Options for determining if the block is active. </APIItem> <APIItem name="wrap" type="boolean" optional> If true, toggles wrapping with `type`. Otherwise, sets the block type directly. </APIItem> </APIOptions> </API>unsetNodesRemove properties from nodes.
<API name="unsetNodes"> <APIParameters> <APIItem name="props" type="string | string[]"> Property key(s) to remove. </APIItem> <APIItem name="options" type="UnsetNodesOptions" optional /> </APIParameters> <APIOptions type="UnsetNodesOptions"> <APIItem name="...options" type="QueryOptions" optional /> <APIItem name="hanging" type="boolean" optional /> <APIItem name="mode" type="'highest' | 'lowest'" optional /> <APIItem name="split" type="boolean" optional /> <APIItem name="voids" type="boolean" optional /> </APIOptions> </API>unwrapNodesUnwrap a node at a location. If necessary, the parent node is split.
<API name="unwrapNodes"> <APIOptions type="UnwrapNodesOptions"> <APIItem name="...options" type="QueryOptions" optional /> <APIItem name="hanging" type="boolean" optional /> <APIItem name="split" type="boolean" optional /> <APIItem name="mode" type="'highest' | 'lowest'" optional /> <APIItem name="voids" type="boolean" optional /> </APIOptions> </API>wrapNodesWrap nodes at a location in the element container.
deleteDelete text at a location.
<API name="delete"> <APIOptions type="DeleteTextOptions"> <APIItem name="at" type="At" optional /> <APIItem name="distance" type="number" optional> Number of characters (or other unit) to delete. Default is 1. </APIItem> <APIItem name="hanging" type="boolean" optional /> <APIItem name="reverse" type="boolean" optional> If true, delete backward. </APIItem> <APIItem name="unit" type="'character' | 'word' | 'line' | 'block'" optional> Unit to delete by. </APIItem> <APIItem name="voids" type="boolean" optional /> </APIOptions> </API>deleteBackwardDelete text backward.
<API name="deleteBackward"> <APIParameters> <APIItem name="unit" type="'character' | 'word' | 'line' | 'block'" optional> Defaults to `'character'`. </APIItem> </APIParameters> </API>deleteForwardDelete text forward.
<API name="deleteForward"> <APIParameters> <APIItem name="unit" type="'character' | 'word' | 'line' | 'block'" optional> Defaults to `'character'`. </APIItem> </APIParameters> </API>deleteFragmentDelete a fragment of nodes.
<API name="deleteFragment"> <APIOptions type="EditorFragmentDeletionOptions"> <APIItem name="direction" type="'forward' | 'backward'" optional> Direction to delete. </APIItem> </APIOptions> </API>insertTextInsert text at a location, optionally with marks. The behavior depends on the provided options:
at is specified in options, inserts at that location regardless of selectionmarks is true (default) and editor has marks, inserts text with those marksat nor selection exists, no text is insertedinsertBreakInsert a block break at the current selection.
insertSoftBreakInsert a soft break at the current selection. A soft break is a new line in the current block.
deselectUnset the selection.
moveMove the selection's point forward or backward.
<API name="move"> <APIOptions type="object"> <APIItem name="distance" type="number" optional> How many units to move. Defaults to 1. </APIItem> <APIItem name="unit" type="'offset' | 'character' | 'word' | 'line'" optional> Defaults to `'character'`. </APIItem> <APIItem name="reverse" type="boolean" optional> Move backward if true. </APIItem> <APIItem name="edge" type="'anchor' | 'focus' | 'start' | 'end'" optional> Which edge to move. </APIItem> </APIOptions> </API>addMarkAdd a custom property to the leaf text nodes within non-void nodes or void nodes that editor.markableVoid() allows in the current selection. If the selection is currently collapsed, the marks will be added to the editor.marks property instead, and applied when text is inserted next.
addMarksAdd multiple marks to the current selection.
editor.tf.addMarks({ bold: true, italic: true })
editor.tf.addMarks({ bold: subscript }, { remove: 'superscript' })
editor.tf.addMarks({ bold: true }, { remove: ['italic', 'underline'] })
removeMarkRemove a mark from text in the selection.
<API name="removeMark"> <APIParameters> <APIItem name="key" type="string"> Mark key to remove. </APIItem> </APIParameters> </API>removeMarksRemove marks from text nodes in the current selection or from editor.marks. The behavior depends on the selection state and options:
editor.markseditor.marksat option):
editor.tf.removeMarks() // remove all marks
editor.tf.removeMarks('bold') // remove the 'bold' mark
editor.tf.removeMarks(['bold','italic'])
editor.tf.removeMarks('bold', { at: range })
toggleMarkToggle a mark on or off in the current selection. If the mark exists, removes it. If it doesn't exist:
remove optiontrueeditor.tf.toggleMark('bold') // Toggle bold on/off
editor.tf.toggleMark('subscript', { remove: 'superscript'}) // Remove superscript before adding subscript
collapseCollapse the selection to a point.
<API name="collapse"> <APIOptions type="object"> <APIItem name="edge" type="'anchor' | 'focus' | 'start' | 'end'" optional> Edge to collapse to. Defaults to `'anchor'`. </APIItem> </APIOptions> </API>deselectUnset the current selection.
moveMove the selection's point.
<API name="move"> <APIOptions type="object"> <APIItem name="distance" type="number" optional> Defaults to 1. </APIItem> <APIItem name="unit" type="'offset' | 'character' | 'word' | 'line'" optional> Defaults to `'character'`. </APIItem> <APIItem name="reverse" type="boolean" optional> If true, move backward. </APIItem> <APIItem name="edge" type="'anchor' | 'focus' | 'start' | 'end'" optional> Which edge to move. </APIItem> </APIOptions> </API>selectSet the selection to a new value specified by at. When a selection already exists, this method just calls setSelection.
editor.tf.select(at)
editor.tf.select(at, { edge: 'end' })
editor.tf.select(at, { edge: 'start' })
setPointSet new properties on one of the selection's points.
<API name="setPoint"> <APIParameters> <APIItem name="props" type="Partial<Point>"> Point properties to update. </APIItem> <APIItem name="options" type="object" optional /> </APIParameters> <APIOptions type="object"> <APIItem name="edge" type="'anchor' | 'focus' | 'start' | 'end'" optional> Which edge of the selection to set. </APIItem> </APIOptions> </API>setSelectionSet new properties on an active selection. Since the value is a Partial<Range>, this method can only handle updates to an existing selection. If there is no active selection the operation will be void. Use select if you'd like to create a selection when there is none.
blurBlur the editor.
deselectDOMDeselect the editor's DOM selection in addition to deselect.
focusFocus the editor.
editor.tf.focus()
editor.tf.focus({ edge: 'end' })
editor.tf.focus({ edge: 'endEditor' })
insertDataInsert data from a DataTransfer into the editor. Calls:
insertFragmentData(editor: ReactEditor, data: DataTransfer)insertTextData(editor: ReactEditor, data: DataTransfer)insertFragmentDataInsert fragment data from a DataTransfer into the editor.
insertTextDataInsert text data from a DataTransfer into the editor.
setFragmentDataSets data from the currently selected fragment on a DataTransfer.
redoRedo to the next saved state.
undoUndo to the previous saved state.
setSplittingOncewithMergingApply a series of changes inside a synchronous fn, These operations will
be merged into the previous history.
withNewBatchApply a series of changes inside a synchronous fn, ensuring that the first
operation starts a new batch in the history. Subsequent operations will be
merged as usual.
withoutMergingApply a series of changes inside a synchronous fn, without merging any of
the new operations into previous save point in the history.
withoutSavingApply a series of changes inside a synchronous fn, without saving any of
their operations into the history.
applyApply an operation in the editor.
<API name="apply"> <APIParameters> <APIItem name="operation" type="Operation<N>"> Operation to apply. </APIItem> </APIParameters> </API>normalizeNodeNormalize a node according to the editor's schema.
<API name="normalizeNode"> <APIParameters> <APIItem name="entry" type="NodeEntry<N>"> The node entry to normalize. </APIItem> <APIItem name="options" type="{ operation?: Operation }" optional /> </APIParameters> <APIOptions type="{ operation?: Operation }"> <APIItem name="operation" type="Operation" optional> The triggering operation. </APIItem> </APIOptions> </API>normalizeNormalize dirty nodes in the editor.
<API name="normalize"> <APIOptions type="EditorNormalizeOptions"> <APIItem name="force" type="boolean" optional> When true, forcibly re-normalize all nodes. </APIItem> <APIItem name="operation" type="Operation" optional /> </APIOptions> </API>withoutNormalizingCall a function, deferring normalization until after it completes.
<API name="withoutNormalizing"> <APIParameters> <APIItem name="fn" type="() => void"> A synchronous function to execute without normalization in between operations. </APIItem> </APIParameters> <APIReturns type="boolean"> True if normalization was performed afterwards. </APIReturns> </API>moveLineHandle ArrowUp and ArrowDown keyboard events.
Default behavior: Returns false (allows Plate's default line movement).
Usage:
const plugin = createPlatePlugin({
key: 'myPlugin',
}).overrideEditor(() => ({
transforms: {
moveLine: ({ reverse }) => {
// Custom line movement logic
if (reverse) {
// Handle ArrowUp
} else {
// Handle ArrowDown
}
return true; // Prevent default
},
},
}));
tabHandle Tab and Shift+Tab keyboard events.
Default behavior: Returns false (allows default browser tab navigation).
Usage:
const plugin = createPlatePlugin({
key: 'myPlugin',
}).overrideEditor(() => ({
transforms: {
tab: ({ reverse }) => {
if (reverse) {
// Handle Shift+Tab (usually outdent)
editor.tf.outdent();
} else {
// Handle Tab (usually indent)
editor.tf.indent();
}
return true; // Prevent default
},
},
}));
selectAllHandle Cmd+A / Ctrl+A keyboard events.
Default behavior: Returns false (allows default browser select all).
Usage:
const plugin = createPlatePlugin({
key: 'myPlugin',
}).overrideEditor(() => ({
transforms: {
selectAll: () => {
// Custom select all logic
const blockEntry = editor.api.block();
if (blockEntry) {
editor.tf.select(blockEntry[1]);
return true; // Prevent default
}
return false; // Allow default
},
},
}));
escapeHandle Escape keyboard events.
Default behavior: Returns false (allows default browser escape handling).
Usage:
const plugin = createPlatePlugin({
key: 'myPlugin',
}).overrideEditor(() => ({
transforms: {
escape: () => {
// Custom escape logic (e.g., exit special mode)
if (editor.api.inSpecialMode()) {
editor.tf.exitSpecialMode();
return true; // Prevent default
}
return false; // Allow default
},
},
}));