Ad-hoc minor release with important bug fixes and some enabling features. The most important fix is in #7341 - where under certain conditions nodes may not be updated in the DOM at all.
Breaking Changes
NodeSelection default delete handler #7323
If you have any $onDelete
handlers copied from the playground for KEY_DELETE_COMMAND
and KEY_BACKSPACE_COMMAND
, you can delete them all now. If you leave them in, it will have similar bugs as prior to this PR.
The default KEY_DELETE_COMMAND
and KEY_BACKSPACE_COMMAND
handlers now event.preventDefault()
and call DELETE_CHARACTER_COMMAND
for NodeSelection
(in addition to the existing RangeSelection
behavior).
The DELETE_CHARACTER_COMMAND
handler now handles NodeSelection by calling the new NodeSelection.deleteNodes()
method which places a new RangeSelection
where the first selected node was (if any, and if it was the current selection) and then removes all of the selected nodes.
RootNode and ListItemNode splice #7341
This PR moves the incorrectly overridden append
methods for RootNode
and ListNode
and moves it to the ElementNode
's primitive splice
method. For RootNode this means that the exception you'd get for appending a leaf node to the root will be thrown in all situations when that node is inserted, rather than just append. For ListNode
this means that the automatic ListItemNode
wrapping applies in all situations when children are inserted into the node, not just append.
$insertNodeToNearestRoot changes #7342
Previously $insertNodeToNearestRoot
could create empty ElementNode
when splitting the current node, now it respects canBeEmpty()
and will not split in those cases (e.g. ListNode
).
ListItemNode CSS #7325
The approach used in #7024 (since v0.26.0) to have a ListItemNode
bullet inherit the style of the first text node was too broad, the inline style on the ListItemNode
cascades to all of its children. The only way around this is to change the approach.
To retain this feature, you need to add CSS to your theme to specifically style the marker pseudo-element based on these new custom properties. Here's an example from the playground css:
.PlaygroundEditorTheme__listItem::marker {
color: var(--listitem-marker-color);
background-color: var(--listitem-marker-background-color);
font-family: var(--listitem-marker-font-family);
font-size: var(--listitem-marker-font-size);
}
TableCellNode importDOM #7318
The importDOM
implementation for TableCellNode
has been corrected to behave as other Lexical roots do with regard to converting <br>
tags to LineBreakNode
and wrapping runs of top-level inline nodes (including inline decorators) with ParagraphNode
. If you have any specific workarounds accounting for the previous behavior, you can remove them. The one difference from other import paths is that a solitary <br>
(e.g. <td><br></td>
) is converted to an empty ParagraphNode
rather than a ParagraphNode
containing a LineBreakNode
.
getDOMSlot #7336
If you're using the undocumented internal getDOMSlot API, you may need to change your types. There is now a type parameter for ElementDOMSlot so that the element property can be specialized.
Highlights
Core:
- 🆕 #7321 Add
mutatedNodes
toUpdateListener
payload - 🆕 #7323 Add a default delete handler for
NodeSelection
- this allowed a lot of boilerplate code to be deleted, and all of the existing implementations were subtly broken - ✅ #7341 Fix bug in transformer loop that would cause nodes not to get reconciled
- ✅ #7342 Handle
canBeEmpty()
in$splitNodes
- 🆕 #7344 Apply
RootNode
transforms last
List:
- ✅ #7325 Move
ListItemNode
text style inheritance to CSS custom properties
Tables:
React:
- ✅ #7315 Remove unused direct dependencies
- 🆕 #7338 Add
onElementChanged
callback to DraggableBlockPlugin
Playground:
- ✅ #7337 Table actions should clear selection instead of moving it to the beginning
- 🆕 #7338 Add "+" button to DraggableBlockPlugin
Utils:
- 🆕 #7340 Add a type predicate to
objectKlassEquals
New APIs
UpdateListenerPayload mutatedNodes #7321
A mutatedNodes
property is now present in the UpdateListener
payload. This was done to accommodate the use case when you want to have a MutationListener that listens to all nodes (this is useful in combination with NodeState)
NodeSelection deleteNodes #7323
NodeSelection.deleteNodes()
was added to support the default delete handler
RootNode node transform #7344
There is now an ordering guarantee that RootNode node transforms are called last, and documentation about the special case that RootNode is always considered intentionally dirty when any other node is dirty
@lexical/react/LexicalDraggableBlockPlugin onElementChanged #7338
An onElementChanged
prop was added to make it possible to implement the "+" button in the playground
What's Changed
- v0.27.2 by @etrepum in #7314
- [lexical-react]: Chore: remove unused dependencies from @lexical/react by @AlessioGr in #7315
- [lexical-editor][Bug fix] Add LexicalEditor.hasNode to flow typing to match typescript by @Zhangerr in #7320
- [Breaking Change][lexical][lexical-table] Bug Fix: Scrollable TableNode updateDOM fixes and getDOMSlot type refactoring by @etrepum in #7336
- [lexical] Feature: Add mutatedNodes to UpdateListener payload by @etrepum in #7321
- [Breaking Change][lexical-list] Bug Fix: Move ListItemNode text style inheritance to custom properties and CSS by @etrepum in #7325
- [Breaking Change][lexical][lexical-playground] Feature: Add a default delete handler for NodeSelection by @etrepum in #7323
- [lexical-playground] Table actions should clear selection instead of moving it to the beginning by @etrepum in #7337
- [lexical-utils] Feature: Add type predicate to objectKlassEquals by @2wheeh in #7340
- [Breaking Change][lexical] Bug Fix: Fix bug in transformer loop that would cause nodes not to get reconciled by @etrepum in #7341
- [Breaking Change][lexical-table] Bug Fix: Table cell line breaks behave differently from the intended HTML behavior. by @dineug in #7318
- [Breaking Change][lexical][lexical-utils]: Bug Fix: Handle canBeEmpty in $splitNodes by @etrepum in #7342
- [lexical-playground][lexical-react] Feature: Push Draggable Element to Parent by @sescandell in #7338
- [lexical-website] Docs: Fix broken links to React Rich Collab Example by @etrepum in #7347
- [lexical] Feature: Apply RootNode transforms last by @etrepum in #7344
New Contributors
- @Zhangerr made their first contribution in #7320
- @dineug made their first contribution in #7318
- @sescandell made their first contribution in #7338
Full Changelog: v0.27.2...v0.28.0