[lexical-utils][lexical-playground] Bug Fix: Double paragraph creation when exiting a nested code block#8684
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
potatowagon
left a comment
There was a problem hiding this comment.
Reviewed by Navi (Tater Thoughts Bobblehead) on behalf of @potatowagon.
Assessment: LGTM ✅ — Bug fix in @lexical/utils preventing double paragraph creation when arrow-key escaping from nested code blocks (e.g. code block inside a layout column).
What I checked:
-
Core fix (
packages/lexical-utils/src/index.ts): Removes.selectEnd()from both$onEscapeUpand$onEscapeDownhelpers. Previously,containerNode.insertBefore($createParagraphNode()).selectEnd()was creating a paragraph AND moving selection to it. But the calling code (e.g. layout column's escape handler) would ALSO create/select a paragraph — resulting in double paragraphs. The fix returnstrue(event consumed) without moving selection, letting the caller handle cursor placement. This is correct becauseinsertBefore/insertAfterreturns the inserted node, and thetruereturn signals the command was handled. -
Behavioral safety: The functions return
truewhich stops command propagation. The parent context (layout, collapsible, etc.) that calls these utils is responsible for cursor placement. Removing.selectEnd()is safe because the callers already handle selection after the escape — the double-creation was the bug. -
Test coverage:
- New e2e test in
CodeBlock.spec.mjs(116 lines): Creates a layout with 2 columns, inserts a code block in column 1, presses ArrowRight/ArrowDown at end, asserts a single paragraph is created inside the layout item (not outside). Tests both arrow keys. Properly skips Firefox (known layout interaction issues) and collab mode. - Existing test in
ColumnLayoutBackspaceAtEnd.spec.mjsupdated: adds Firefox skip (matching the new test), minor title text fix (keys→key).
- New e2e test in
-
Edge cases considered:
- ArrowRight at end of code = escape down ✓
- ArrowDown at last line of code = escape down ✓
- Both directions (up/down) fixed symmetrically ✓
- Layout items with multiple children won't be affected (guard checks
firstDescendant/lastDescendant)
-
www compat:
$onEscapeUp/$onEscapeDownare exported from@lexical/utils. The behavioral change (no longer auto-selecting the new paragraph) could theoretically affect www consumers that relied on the selection side-effect. However, since the function returnstrueand callers are expected to handle post-escape behavior themselves, this is a bug fix, not a breaking change. Any www consumer that was seeing double paragraphs will benefit. -
CI: ALL GREEN — unit 22.x ✅, unit 24.x ✅, browser ✅, integrity ✅, e2e canary chromium ✅, CLA ✅, Vercel ✅.
Ready to approve.
Description
Follow-up #8393
When inserting new paragraphs, calls to
selectEndwere added to the$onEscapeDownand$onEscapeUphandlers as a workaround to pass the tests in Firefox #8393 (comment). This results in an undesirable effect where the selection moves outside the element and its container, which also has$onEscapeUp/$onEscapeDownhandlersTest plan
Before
Screen.Recording.2026-06-12.at.03.21.25.mov
After
Added e2e test for a nested code block inside LayoutContainer
Screen.Recording.2026-06-12.at.03.20.28.mov