[lexical-text] Bug Fix: a text entity keeps the style and detail of the text it replaces - #9130
Merged
etrepum merged 1 commit intoSep 9, 2026
Conversation
…he text it replaces The forward transform only carried format onto the node createNode returns, so style and detail were dropped when text was promoted to an entity. $replaceWithSimpleText already carries all three the other way, so anything lost here can never be restored once the match breaks.
Om-singhaI
requested review from
acywatson,
etrepum,
fantactuka,
ivailop7,
potatowagon and
zurfyx
as code owners
September 8, 2026 00:45
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
etrepum
approved these changes
Sep 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
registerLexicalTextEntitycarries onlyformatfrom theTextNodeit promotes onto the nodecreateNodereturns.styleanddetailare dropped, so a hashtag or a keyword typed inside colored text comes out with the color stripped.Reproduction, using the test entity node already in the package's unit test:
After the transform runs, the entity node is bold, but
getStyle()is''andisDirectionless()isfalse.The inconsistency is inside this same function.
$replaceWithSimpleTextalready chains.setFormat().setStyle().setDetail()when it turns an entity back into plain text.$createAutoLinkNode_in@lexical/linkcopies all three as well, off an almost identicalsplitTextsequence. The forward path is the only one that stops atformat.That asymmetry makes the loss permanent, since the reverse path can only give back what the entity node holds. I logged both ends of a full trip on
main:Bold survives typing a hashtag and then editing it back to plain text. The color and the directionless flag don't.
The fix chains
setStyleandsetDetailonto thesetFormatthat's already there.One thing worth calling out: the call is unconditional, so if a caller's
createNodesets a style itself, an unstyled source now overwrites it with''. I kept it unconditional on purpose. ThesetFormatline has always done exactly that toformat, andKeywordNodein the playground already documents that behavior as the contract it relies on. Makingstyleconditional would strand a caller's style on the entity node, and the reverse transform would then copy that style onto the plain text the user is left with, which is worse. Neither caller in this repo setsstyleordetailincreateNode.Test plan
New unit test in
packages/lexical-text/src/__tests__/unit/registerLexicalTextEntity.test.ts, next to the existing test that covers the reverse direction.Before
Dropping the style assertion so the next one runs shows
detailis gone too:After
The packages around it, all green:
I read the e2e specs instead of running them.
Keywords.spec.mjsassertsstyle="cursor: default;"on the keyword span, and that comes fromKeywordNode.createDOM, not from the node's style. Carrying an empty style over changes nothing there:createDOMskips the write when the style is'',updateDOMskips it when the style hasn't changed, andsetDOMStyleFromCSSsets individual properties rather than replacingcssText, socursoris never clobbered either way.Hashtags.spec.mjsand the hashtag regression specs assert no style attribute at all, and none of these specs applies a text color before typing. I don't expect any of those snapshots to move.