Skip to content

v0.45.0#8580

Merged
etrepum merged 1 commit into
mainfrom
0.45.0__release
May 28, 2026
Merged

v0.45.0#8580
etrepum merged 1 commit into
mainfrom
0.45.0__release

Conversation

@etrepum

@etrepum etrepum commented May 28, 2026

Copy link
Copy Markdown
Collaborator

v0.45.0 is a monthly release with several breaking changes around selection and reconcile semantics, a major new experimental DOMImportExtension API for composable HTML import that replaces importDOM, a generalized DOMSlot and DOM render override surface, new HistoryExtension ergonomics (canUndo/canRedo signals, maxDepth), notable reconciler/selection performance work, and a wide range of bug fixes across IME, mobile keyboards, list/code/table editing, and markdown round-tripping.

Breaking Changes

lexical — Shadow root inclusion in $getReconciledDirection (#8479)

$getReconciledDirection now walks through shadow roots when resolving the reconciled dir attribute on a node, so nested ShadowRoot-style elements (e.g. tables) inherit direction consistently with regular elements. Callers that relied on direction inheritance stopping at shadow roots will need to update.

lexical / @lexical/rich-text — Backspace at block start preserves the current block (#8493)

Pressing Backspace at the start of a non-empty block previously merged the current block into the previous block, which discarded the current block's type/format. The new behavior merges the previous block's children into the current block instead, preserving the current block's type (heading, list item, quote, etc.). A new $mergeBlockBackward helper on RangeSelection is exposed for custom command handlers that want the same behavior.

lexical — Selection adjustment in removeFromParent callers (#8501)

LexicalNode.replace, insertBefore, insertAfter, and related callers that move a node between parents now correctly adjust the current selection to follow the moved node instead of leaving the selection pointing at the (now empty) original slot. This may change selection state observed by transforms or update listeners that previously relied on the stale offsets.

@lexical/markdown — Apply markdown shortcuts on composition-committed triggers (#8503)

Markdown shortcuts (e.g. *, _, ~) typed via IME composition now trigger after the composition is committed, not just on raw beforeinput. This fixes shortcuts being silently dropped during Japanese / Korean / Chinese input but may also fire shortcuts in some flows that previously didn't.

@lexical/extension / @lexical/rich-text / @lexical/plain-textNormalizeInlineElementsExtension (#8497)

registerRichText and registerPlainText now register a transform that removes empty inline elements (e.g. LinkNode, formatted TextNode wrappers with no children) instead of leaving them in the tree. The transform is also exported as NormalizeInlineElementsExtension from @lexical/extension for use with extension-based setups. Editors that intentionally kept empty inline wrappers will need to disable the extension or override the transform. See Included Extensions.

lexical / @lexical/extension / @lexical/rich-text / @lexical/plain-textNormalizeTripleClickSelectionExtension (#8520)

The "triple-click selects the whole paragraph including the trailing newline" normalization has moved out of LexicalEvents and into a new NormalizeTripleClickSelectionExtension registered by both rich-text and plain-text. The core LexicalEditor no longer performs this normalization on its own, so editors that bypass registerRichText / registerPlainText (or the equivalent extensions) need to register the extension explicitly to keep the previous behavior. See Included Extensions.

lexical / @lexical/html / @lexical/selection / @lexical/utils / @lexical/playground — Generalized DOMSlot and DOMRenderExtension override surface (#8519)

DOMSlot is now generalized so child slots can be expressed for arbitrary DOM containers (not just the direct child element), and $createDOM, $updateDOM, $exportDOM, $getDOMSlot etc. all flow through the new override surface. The previously-exported AutocompleteNode in the playground has been replaced by a VisibleLineBreakExtension that demonstrates the new override surface, and markSelection in @lexical/utils has been rewritten on top of the generalized slot API. Custom nodes that override getDOMSlot to return a non-element wrapper now have a real way to express that. See the DOMRenderExtension docs.

New APIs

@lexical/htmlDOMImportExtension (experimental) (#8528)

A new DOMImportExtension replaces the legacy node-class importDOM static method with a composable middleware-style API. Rules declare a CSS-selector-style matcher, an optional schema for child handling, and a DOMImportFn that builds Lexical nodes from the matching DOM. Many helpers ship alongside it: $distributeInlineWrapper, ImportSession, DOMPreprocessFn for source-specific cleanup (Word, VS Code, etc.), and full TypeScript types for rules, captures, and contexts. A new dev-examples/dom-import showcase wires it up to a Word/VS Code paste flow. The legacy importDOM continues to work; new code can opt in to DOMImportExtension for richer composition and explicit ordering. The companion ClipboardDOMImportExtension (in @lexical/clipboard) routes text/html pastes through the new pipeline. See the DOMImportExtension guide and the "Migrating from importDOM" section.

@lexical/html / @lexical/playground — Conditional DOM render overrides (#8575)

domOverride now supports disabledForEditor and disabledForSession predicates so render overrides can be conditionally skipped on a per-editor or per-session basis (e.g. only apply during export, or only when a feature flag is on). Useful when one extension provides multiple overrides whose applicability depends on context that isn't known at registration time. See the DOMRenderExtension docs.

lexicalElementNode import/export of data-lexical-indent (#8536)

ElementNode now uniformly imports and exports the data-lexical-indent attribute so any subclass round-trips its indent level through HTML without having to override exportDOM / importDOM (fixes the long-standing #7729 regression around indented headings/paragraphs).

lexical — Infinite recursion detection in update listeners (#8542)

Update listeners and update transforms that re-trigger themselves are now caught by a runtime guard that throws a descriptive error after a configurable number of nested updates, instead of hanging the tab. See Updates and Listeners.

@lexical/historycanUndo / canRedo ReadonlySignals (#8465)

HistoryExtension's output now exposes canUndo and canRedo as ReadonlySignal<boolean>s so toolbar buttons can subscribe directly without polling historyState or duplicating the priority/state bookkeeping. See Extension Signals.

@lexical/historymaxDepth option (#8537)

HistoryExtension accepts a new maxDepth option that bounds the undo stack. Older entries are evicted FIFO when the depth is exceeded. See the new "Tuning HistoryExtension for memory and long sessions" docs.

@lexical/markdown$convertSelectionToMarkdownString (#8395)

Counterpart to $convertToMarkdownString that serializes only the current selection (or any caller-provided range) to a markdown string, useful for "copy as markdown" toolbar actions and for selection-scoped AI prompts.

lexical / @lexical/list$setFormatFromDOM (#8460)

A new $setFormatFromDOM helper extracts text-align / dir from a DOM element and applies it to an ElementNode. ListItemNode.importDOM now uses it to correctly import alignment for list items pasted from external sources.

@lexical/listListNode.createListItemNode (#8427)

ListNode exposes a createListItemNode factory that is now used by children-normalization, so ListNode subclasses can supply a custom ListItemNode subclass without monkey-patching the normalizer.

@lexical/rich-textescapeFormatTriggers on RichTextExtension (#8383)

RichTextExtension now accepts an escapeFormatTriggers config (a ReadonlySignal<EscapeFormatTriggerConfig>) that opts text-format escape behavior in/out per trigger (enter, click, arrow, space, tab). With it enabled, typing at the boundary of a formatted text node "escapes" the active format (bold, italic, code, etc.), matching the typing experience in Google Docs / Notion. Disabled by default. See Included Extensions.

@lexical/extension / @lexical/playgroundClickAfterLastBlockExtension (#8549)

New ClickAfterLastBlockExtension inserts a fresh paragraph when the user clicks below the last block (and places the caret in it), so single-block editors and short documents don't strand the user with no easy way to start a new line.

@lexical/code-prism / @lexical/code-shikinull Tokenizer.defaultLanguage (#8553)

Tokenizer.defaultLanguage may now be null to indicate that code blocks without an explicit language should round-trip through markdown without injecting a default language tag (e.g. ```javascript). Preserves CommonMark's "no fence info" form on export.

@lexical/code-core / @lexical/code-shiki / @lexical/code-prism — Outdent space-indented code lines (#8445)

Shift+Tab in a code block now correctly outdents space-indented lines (not just tab-indented), respecting the tokenizer's configured indent width.

@lexical/react — Optional async onClose for LexicalTypeaheadMenuPlugin (#8489)

LexicalTypeaheadMenuPlugin's onClose may now return a Promise, useful for handlers that need to await network or animation work before tearing down the menu.

@lexical/clipboardGetClipboardDataExtension export (#8431)

GetClipboardDataExtension is now exported from @lexical/clipboard for use as a peer dependency from custom clipboard handlers.

@lexical/website — Server-rendered "Copy page" Markdown button (#8570)

Every docs page now has a server-rendered "Copy page as Markdown" button (and a matching ?raw URL) so AI assistants and humans can grab the raw markdown without scraping the rendered HTML.

Highlights

Core:

HTML / DOM:

Code:

Clipboard:

Extension:

History:

Link / List:

Markdown:

React:

Rich Text / Plain Text:

Table:

Yjs:

Playground:

Website / Examples:

Infrastructure:

What's Changed

New Contributors

Full Changelog: v0.44.0...v0.45.0

@vercel

vercel Bot commented May 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
lexical Ready Ready Preview, Comment May 28, 2026 6:51pm
lexical-playground Ready Ready Preview, Comment May 28, 2026 6:51pm

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label May 28, 2026
@etrepum etrepum added the extended-tests Run extended e2e tests on a PR label May 28, 2026
@etrepum etrepum marked this pull request as ready for review May 28, 2026 15:28
@etrepum etrepum closed this May 28, 2026
@etrepum etrepum reopened this May 28, 2026
@etrepum etrepum added this pull request to the merge queue May 28, 2026
Merged via the queue into main with commit adf8f20 May 28, 2026
42 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. extended-tests Run extended e2e tests on a PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants