Major Changes
-
- Remove
slate
,slate-dom
,slate-react
,slate-history
andslate-hyperscript
from your dependencies. It's now part of this package and@udecode/plate
. All exports remain the same or have equivalents (see below). - Renamed
createTEditor
tocreateEditor
. createEditor
now returns an editor (Editor
) with all queries undereditor.api
and transforms undereditor.tf
. You can see or override them at a glance. For example, we now useeditor.tf.setNodes
instead of importingsetNodes
. This marks the completion of generic typing and the removal of error throws fromslate
,slate-dom
, andslate-history
queries/transforms, without forking implementations. We’ve also reduced the number of queries/transforms by merging a bunch of them.
The following interfaces from
slate
andslate-dom
are now part ofEditor
:-
Editor
,EditorInterface
-
Transforms
-
HistoryEditor
(noop, unchanged),HistoryEditorInterface
-
DOMEditor
(noop, unchanged),DOMEditorInterface
-
editor.findPath
now returnsDOMEditor.findPath
(memo) and falls back tofindNodePath
(traversal, less performant) if not found. -
Removed the first parameter (
editor
) from:editor.hasEditableTarget
editor.hasSelectableTarget
editor.isTargetInsideNonReadonlyVoid
editor.hasRange
editor.hasTarget
-
editor.api.node(options)
(previouslyfindNode
)at
option is nowat ?? editor.selection
instead ofat ?? editor.selection ?? []
. That means if you want to lookup the entire document, you need to pass[]
explicitly. -
Removed
setNode
in favor ofsetNodes
(you can now pass aTNode
toat
directly). -
Removed
setElements
in favor ofsetNodes
. -
Removed unused
isWordAfterTrigger
,setBlockAboveNode
,setBlockAboveTexts
,setBlockNodes
,getPointNextToVoid
. -
Replaced
Path
from slate withPath
(type) andPathApi
(static methods). -
Replaced
Operation
from slate withOperation
(type) andOperationApi
(static methods). -
Replaced
Point
from slate withPoint
(type) andPointApi
(static methods). -
Replaced
Text
from slate withTText
(type) andTextApi
(static methods). We also exportText
type likeslate
but we don't recommend it as it's conflicting with the DOM type. -
Replaced
Range
from slate withTRange
(type) andRangeApi
(static methods). We also exportRange
type likeslate
but we don't recommend it as it's conflicting with the DOM type. -
Replaced
Location
from slate withTLocation
(type) andLocationApi
(static methods). We also exportLocation
type likeslate
but we don't recommend it as it's conflicting with the DOM type. -
Replaced
Span
from slate withSpan
(type) andSpanApi
(static methods). -
Replaced
Node
from slate withTNode
(type) andNodeApi
(static methods). We also exportNode
type likeslate
but we don't recommend it as it's conflicting with the DOM type. -
Replaced
Element
from slate withTElement
(type) andElementApi
(static methods). We also exportElement
type likeslate
but we don't recommend it as it's conflicting with the DOM type. -
Signature change:
editor.tf.toggle.block({ type, ...options })
->editor.tf.toggleBlock(type, options)
editor.tf.toggle.mark({ key, clear })
->editor.tf.toggleMark(key, { remove: clear })
-
Moved editor functions:
addMark
->editor.tf.addMark
addRangeMarks
->editor.tf.setNodes(props, { at, marks: true })
blurEditor
->editor.tf.blur
collapseSelection
->editor.tf.collapse
createDocumentNode
->editor.api.create.value
(core)createNode
->editor.api.create.block
createPathRef
->editor.api.pathRef
createPointRef
->editor.api.pointRef
createRangeRef
->editor.api.rangeRef
deleteBackward({ unit })
->editor.tf.deleteBackward(unit)
deleteForward({ unit })
->editor.tf.deleteForward(unit)
deleteFragment
->editor.tf.deleteFragment
deleteText
->editor.tf.delete
deselect
->editor.tf.deselect
deselectEditor
->editor.tf.deselectDOM
duplicateBlocks
->editor.tf.duplicateNodes({ nodes })
findDescendant
->editor.api.descendant
findEditorDocumentOrShadowRoot
->editor.api.findDocumentOrShadowRoot
findEventRange
->editor.api.findEventRange
findNode(options)
->editor.api.node(options)
findNodeKey
->editor.api.findKey
findNodePath
->editor.api.findPath
findPath
->editor.api.findPath
focusEditor
->editor.tf.focus({ at })
focusEditorEdge
->editor.tf.focus({ at, edge: 'startEditor' | 'endEditor' })
getAboveNode
->editor.api.above
getAncestorNode
->editor.api.block({ highest: true })
getBlockAbove
->editor.api.block({ at, above: true })
oreditor.api.block()
ifat
is not a pathgetBlocks
->editor.api.blocks
getEdgeBlocksAbove
->editor.api.edgeBlocks
getEdgePoints
->editor.api.edges
getEditorString
->editor.api.string
getEditorWindow
->editor.api.getWindow
getEndPoint
->editor.api.end
getFirstNode
->editor.api.first
getFragment
->editor.api.fragment
getFragmentProp(fragment, options)
->editor.api.prop({ nodes, ...options})
getLastNode
->editor.api.last
getLastNodeByLevel(level)
->editor.api.last([], { level })
getLeafNode
->editor.api.leaf
getLevels
->editor.api.levels
getMark
->editor.api.mark
getMarks
->editor.api.marks
getNextNode
->editor.api.next
getNextNodeStartPoint
->editor.api.start(at, { next: true })
getNodeEntries
->editor.api.nodes
getNodeEntry
->editor.api.node(at, options)
getNodesRange
->editor.api.nodesRange
getParentNode
->editor.api.parent
getPath
->editor.api.path
getPathRefs
->editor.api.pathRefs
getPoint
->editor.api.point
getPointAfter
->editor.api.after
getPointBefore
->editor.api.before
getPointBeforeLocation
->editor.api.before
getPointRefs
->editor.api.pointRefs
getPositions
->editor.api.positions
getPreviousBlockById
->editor.api.previous({ id, block: true })
getPreviousNode
->editor.api.previous
getPreviousNodeEndPoint
->editor.api.end({ previous: true })
getPreviousSiblingNode
->editor.api.previous({ at, sibling: true })
getRange
->editor.api.range
getRangeBefore
->editor.api.range('before', to, { before })
getRangeFromBlockStart
->editor.api.range('start', to)
getRangeRefs
->editor.api.rangeRefs
getSelectionFragment
->editor.api.fragment(editor.selection, { structuralTypes })
getSelectionText
->editor.api.string()
getStartPoint
->editor.api.start
getVoidNode
->editor.api.void
hasBlocks
->editor.api.hasBlocks
hasEditorDOMNode
->editor.api.hasDOMNode
hasEditorEditableTarget
->editor.api.hasEditableTarget
hasEditorSelectableTarget
->editor.api.hasSelectableTarget
hasEditorTarget
->editor.api.hasTarget
hasInlines
->editor.api.hasInlines
hasTexts
->editor.api.hasTexts
insertBreak
->editor.tf.insertBreak
insertData
->editor.tf.insertData
insertElements
->editor.tf.insertNodes<TElement>
insertEmptyElement
->editor.tf.insertNodes(editor.api.create.block({ type }))
insertFragment
->editor.tf.insertFragment
insertNode
->editor.tf.insertNode
insertNodes
->editor.tf.insertNodes
insertText
->editor.tf.insertText
isAncestorEmpty
->editor.api.isEmpty
isBlock
->editor.api.isBlock
isBlockAboveEmpty
->editor.api.isEmpty(editor.selection, { block: true })
isBlockTextEmptyAfterSelection
->editor.api.isEmpty(editor.selection, { after: true })
isCollapsed(editor.selection)
->editor.api.isCollapsed()
isComposing
->editor.api.isComposing
isDocumentEnd
->editor.api.isEditorEnd
isEdgePoint
->editor.api.isEdge
isEditor
->editor.api.isEditor
isEditorEmpty
->editor.api.isEmpty()
isEditorFocused
->editor.api.isFocused
isEditorNormalizing
->editor.api.isNormalizing
isEditorReadOnly
->editor.api.isReadOnly
isElementEmpty
->editor.api.isEmpty
isElementReadOnly
->editor.api.elementReadOnly
isEndPoint
->editor.api.isEnd
isExpanded(editor.selection)
->editor.api.isCollapsed()
isInline
->editor.api.isInline
isMarkableVoid
->editor.api.markableVoid
isMarkActive
->editor.api.hasMark(key)
isPointAtWordEnd
->editor.api.isAt({ at, word: true, end: true })
isRangeAcrossBlocks
->editor.api.isAt({ at, blocks: true })
isRangeInSameBlock
->editor.api.isAt({ at, block: true })
isRangeInSingleText
->editor.api.isAt({ at, text: true })
isSelectionAtBlockEnd
->editor.api.isAt({ end: true })
isSelectionAtBlockStart
->editor.api.isAt({ start: true })
isSelectionCoverBlock
->editor.api.isAt({ block: true, start: true, end: true })
isSelectionExpanded
->editor.api.isExpanded()
isStartPoint
->editor.api.isStart
isTargetinsideNonReadonlyVoidEditor
->editor.api.isTargetInsideNonReadonlyVoid
isTextByPath
->editor.api.isText(at)
isVoid
->editor.api.isVoid
liftNodes
->editor.tf.liftNodes
mergeNodes
->editor.tf.mergeNodes
moveChildren
->editor.tf.moveNodes({ at, to, children: true, fromIndex, match: (node, path) => boolean })
moveNodes
->editor.tf.moveNodes
moveSelection
->editor.tf.move
normalizeEditor
->editor.tf.normalize
removeEditorMark
->editor.tf.removeMark
removeEditorText
->editor.tf.removeNodes({ text: true, empty: false })
removeEmptyPreviousBlock
->editor.tf.removeNodes({ previousEmptyBlock: true })
removeMark(options)
->editor.tf.removeMarks(keys, options)
removeNodeChildren
->editor.tf.removeNodes({ at, children: true })
removeNodes
->editor.tf.removeNodes
removeSelectionMark
->editor.tf.removeMarks()
replaceNode(editor, { nodes, insertOptions, removeOptions })
->editor.tf.replaceNodes(nodes, { removeNodes, ...insertOptions })
select
->editor.tf.select
selectEndOfBlockAboveSelection
->editor.tf.select(editor.selection, { edge: 'end' })
selectNodes
->editor.tf.select(editor.api.nodesRange(nodes))
setFragmentData
->editor.tf.setFragmentData
setMarks(marks, clear)
->editor.tf.addMarks(marks, { remove: string | string[] })
setNodes
->editor.tf.setNodes
setPoint
->editor.tf.setPoint
setSelection
->editor.tf.setSelection
someNode
->editor.api.some(options)
splitNodes
->editor.tf.splitNodes
toDOMNode
->editor.api.toDOMNode
toDOMPoint
->editor.api.toDOMPoint
toDOMRange
->editor.api.toDOMRange
toggleWrapNodes
->editor.tf.toggleBlock(type, { wrap: true })
toSlateNode
->editor.api.toSlateNode
toSlatePoint
->editor.api.toSlatePoint
toSlateRange
->editor.api.toSlateRange
unhangCharacterRange
->editor.api.unhangRange(range, { character: true })
unhangRange
->editor.api.unhangRange
unsetNodes
->editor.tf.unsetNodes
unwrapNodes
->editor.tf.unwrapNodes
withoutNormalizing
->editor.tf.withoutNormalizing
wrapNodeChildren
->editor.tf.wrapNodes(element, { children: true })
wrapNodes
->editor.tf.wrapNodes
resetEditor
->editor.tf.reset
resetEditorChildren
->editor.tf.reset({ children: true })
selectEditor
->editor.tf.select([], { focus, edge })
selectSiblingNodePoint
->editor.tf.select(at, { next, previous })
-
Moved to
NodeApi.
:getNextSiblingNodes(parentEntry, path)
->NodeApi.children(editor, path, { from: path.at(-1) + 1 })
getFirstNodeText
->NodeApi.firstText
getFirstChild([node, path])
->NodeApi.firstChild(editor, path)
getLastChild([node, path])
->NodeApi.lastChild(editor, path)
getLastChildPath([node, path])
->NodeApi.lastChild(editor, path)
isLastChild([node, path], childPath)
->NodeApi.isLastChild(editor, childPath)
getChildren([node, path])
->Array.from(NodeApi.children(editor, path))
getCommonNode
->NodeApi.common
getNode
->NodeApi.get
getNodeAncestor
->NodeApi.ancestor
getNodeAncestors
->NodeApi.ancestors
getNodeChild
->NodeApi.child
getNodeChildren
->NodeApi.children
getNodeDescendant
->NodeApi.descendant
getNodeDescendants
->NodeApi.descendants
getNodeElements
->NodeApi.elements
getNodeFirstNode
->NodeApi.first
getNodeFragment
->NodeApi.fragment
getNodeLastNode
->NodeApi.last
getNodeLeaf
->NodeApi.leaf
getNodeLevels
->NodeApi.levels
getNodeParent
->NodeApi.parent
getNodeProps
->NodeApi.extractProps
getNodes
->NodeApi.nodes
getNodeString
->NodeApi.string
getNodeTexts
->NodeApi.texts
hasNode
->NodeApi.has
hasSingleChild
->NodeApi.hasSingleChild
isAncestor
->NodeApi.isAncestor
isDescendant
->NodeApi.isDescendant
isNode
->NodeApi.isNode
isNodeList
->NodeApi.isNodeList
nodeMatches
->NodeApi.matches
-
Moved to
ElementApi.
:elementMatches
->ElementApi.matches
isElement
->ElementApi.isElement
isElementList
->ElementApi.isElementList
-
Moved to
TextApi.
:isText
->TextApi.isText(at)
-
Moved to
RangeApi.
:isCollapsed
->RangeApi.isCollapsed
isExpanded
->RangeApi.isExpanded
-
Moved to
PathApi.
:isFirstChild
->!PathApi.hasPrevious
getPreviousPath
->PathApi.previous
-
Moved to
PointApi.
:getPointFromLocation({ at, focus })
->PointApi.get(at, { focus })
-
Moved from
@udecode/plate/react
to@udecode/plate
:Hotkeys
-
Upgraded to
zustand@5
andzustand-x@5
:- Replace
createZustandStore('name')(initialState)
withcreateZustandStore(initialState, { mutative: true, name: 'name' })
- All plugin stores now use zustand-mutative for immutable state updates, which is faster than
immer
.
- Replace
Types:
- Rename the following types:
TEditor
->Editor
TOperation
->Operation
TPath
->Path
TNodeProps
->NodeProps
TNodeChildEntry
->NodeChildEntry
TNodeEntry
->NodeEntry
TDescendant
->Descendant
TDescendantEntry
->DescendantEntry
TAncestor
->Ancestor
TAncestorEntry
->AncestorEntry
TElementEntry
->ElementEntry
TTextEntry
->TextEntry
- Query/transform options now use generic
V extends Value
instead ofE extends Editor
. getEndPoint
,getEdgePoints
,getFirstNode
,getFragment
,getLastNode
,getLeafNode
,getPath
,getPoint
,getStartPoint
can returnundefined
if not found (suppressing error throws).NodeApi.ancestor
,NodeApi.child
,NodeApi.common
,NodeApi.descendant
,NodeApi.first
,NodeApi.get
,NodeApi.last
,NodeApi.leaf
,NodeApi.parent
,NodeApi.getIf
,PathApi.previous
returnundefined
if not found instead of throwing- Replace
NodeOf
type withDescendantOf
ineditor.tf.setNodes
editor.tf.unsetNodes
,editor.api.previous
,editor.api.node
,editor.api.nodes
,editor.api.last
- Enhanced
editor.tf.setNodes
:- Added
marks
option to handle mark-specific operations - When
marks: true
:- Only applies to text nodes in non-void nodes or markable void nodes
- Automatically sets
split: true
andvoids: true
- Handles both expanded ranges and collapsed selections in markable voids
- Replaces
addRangeMarks
functionality
- Added
- Remove
Minor Changes
- #3920 by @zbeyens –
- Merged
@udecode/slate-react
and@udecode/slate-utils
queries and transforms into this package. editor.insertNode
: added anoptions
parameter.- Added
| TNode
to theat
type of the following methods’ options:editor.api.above
,editor.api.edges
,editor.api.string
,editor.api.end
,editor.api.first
,editor.api.fragment
,editor.api.last
,editor.api.leaf
,editor.api.levels
,editor.api.next
,editor.api.nodes
,editor.api.node
,editor.api.parent
,editor.api.path
,editor.api.point
,editor.api.after
,editor.api.before
,editor.api.positions
,editor.api.previous
,editor.api.range
,editor.api.start
,editor.api.void
,editor.tf.insertNode
,editor.tf.delete
,editor.tf.focus
,editor.tf.insertFragment
,editor.tf.insertNodes
,editor.tf.insertText
,editor.tf.liftNodes
,editor.tf.mergeNodes
,editor.tf.moveNodes
,editor.tf.removeNodes
,editor.tf.select
,editor.tf.setNodes
,editor.tf.splitNodes
,editor.tf.unsetNodes
,editor.tf.unwrapNodes
,editor.tf.wrapNodes
match
query option: Addedtext
andempty
options.- Added
id
option to query options for finding nodes by id. - Added
text?: boolean
option to match only text nodes. - Added
empty?: boolean
option to match only empty nodes.
- Added
- Merged