Skip to content

[lexical] Bug Fix: Preserve pasted paragraph alignment when merging into destination block#8438

Open
matingathani wants to merge 4 commits into
facebook:mainfrom
matingathani:fix/paste-preserve-alignment
Open

[lexical] Bug Fix: Preserve pasted paragraph alignment when merging into destination block#8438
matingathani wants to merge 4 commits into
facebook:mainfrom
matingathani:fix/paste-preserve-alignment

Conversation

@matingathani

Copy link
Copy Markdown

Description

When pasting a paragraph with center/right alignment into a non-empty paragraph, the pasted block's format (alignment) was discarded because only the block's children (text nodes) were merged into the destination. This PR transfers the pasted block's format to the destination block before merging when the destination does not already have an explicit format.

Closes #8101

Test plan

Before

Copying a center-aligned paragraph and pasting into another paragraph would reset alignment to default (left).

After

The pasted content preserves its original alignment when the destination block does not have an explicit format set.

Copilot AI review requested due to automatic review settings May 1, 2026 03:22
@vercel

vercel Bot commented May 1, 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 2, 2026 7:16pm
lexical-playground Ready Ready Preview, Comment May 2, 2026 7:16pm

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 1, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a Lexical paste/merge edge case where a pasted block’s alignment (element format) could be dropped when the paste operation merges only the pasted block’s children into an existing destination block, by transferring the pasted block’s format to the destination when the destination has no explicit format.

Changes:

  • Preserve pasted block alignment by copying formatType to the destination block during merge when the destination has no explicit format.
  • Expand block-DOM detection to include details/summary.
  • Harden HTML import by wrapping hoisted inline/text children in paragraphs when there is no block ancestor, with new unit tests covering the behavior.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/lexical/src/LexicalSelection.ts Copies pasted block format to the destination block before merging children when the destination has no explicit format.
packages/lexical/src/tests/unit/HTMLCopyAndPaste.test.ts Adds a copy/paste test intended to ensure centered alignment is preserved.
packages/lexical/src/LexicalUtils.ts Treats details and summary as block DOM nodes.
packages/lexical-html/src/index.ts Wraps hoisted inline/text children in paragraphs when importing unknown/unconverted DOM nodes without a block ancestor.
packages/lexical-html/src/tests/unit/LexicalHtml.test.ts Adds tests for importDOM behavior around unknown block/nested elements and summary.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/lexical-html/src/__tests__/unit/LexicalHtml.test.ts Outdated
Comment thread packages/lexical-html/src/index.ts Outdated
Comment thread packages/lexical/src/__tests__/unit/HTMLCopyAndPaste.test.ts

@etrepum etrepum left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has merge conflicts and unrelated changes (looks like from #8437)

@etrepum etrepum left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests aren't really comprehensive enough to confirm that it doesn't have edge cases, there are failed PRs for this feature that you could look at for examples of what those cases are.

Cover four additional edge cases beyond the existing center-into-empty test:
- Right-aligned paragraph pasted into empty destination (right alignment preserved)
- Center-aligned pasted into non-empty right-aligned destination (destination format not overridden)
- Multiple paragraphs with mixed alignment each preserve their own format
- Unaligned pasted paragraph adds no text-align to destination
@matingathani matingathani force-pushed the fix/paste-preserve-alignment branch from 4f019a2 to 7fea4f3 Compare May 2, 2026 00:44
@matingathani

Copy link
Copy Markdown
Author

Thanks for the review @etrepum. Addressed both points:

Merge conflicts / unrelated changes: Branch has been rebased on main. Looking at the diff, there were no leaked changes from #8437 — the PR only touched LexicalSelection.ts and HTMLCopyAndPaste.test.ts.

Tests: Expanded from 1 to 5 test cases covering the following scenarios:

  1. Center-aligned paste into empty paragraph → center alignment preserved (original test)
  2. Right-aligned paste into empty paragraph → right alignment preserved
  3. Center-aligned paste into non-empty right-aligned paragraph → destination keeps right alignment (pasted format does NOT override, which is the key correctness property of the fix)
  4. Multiple paragraphs with mixed alignment → each paragraph independently gets its own alignment (center first, right second)
  5. Unaligned paste into empty paragraph → no text-align style added to destination

Case 3 verifies the guard condition firstBlock.getFormatType() === '' works correctly — only applies the pasted block's format when the destination has no explicit alignment.

Let me know if there are additional edge cases from the previously failed PRs you'd like covered.

@potatowagon

Copy link
Copy Markdown
Contributor

Review: Preserve Pasted Paragraph Alignment When Merging Into Destination Block

Reviewed by: Navi (AI review assistant for @potatowagon)

Summary

When pasting a paragraph with explicit alignment (center, right, etc.) into an empty paragraph, the alignment is now preserved on the destination block. Previously, the pasted content's format was lost during the merge operation.

What I Verified

  • Logic correctness: The condition firstToInsert.getFormatType() !== '' && firstBlock.getFormatType() === '' correctly ensures: (1) the pasted block has an explicit format, and (2) the destination block has no explicit format (empty string = default/left). This avoids overwriting user-set alignment.
  • Non-empty paragraph safety: When the destination has existing content AND its own format, the paste preserves the destination's format — verified by the test pasting an aligned paragraph does not override destination alignment when destination already has explicit alignment.
  • Multi-paragraph paste: Subsequent pasted paragraphs (beyond the first merge) are inserted as new blocks, preserving their individual alignments — confirmed by test.
  • Test coverage: 5 comprehensive unit tests covering empty/non-empty destinations, single/multi paragraph paste, and format preservation vs override scenarios.
  • CI status: All e2e and integration tests pass.

Note

This PR may overlap with #8310 which addresses the same issue (paste alignment for non-empty paragraphs). The approaches differ slightly — this one is more conservative (only applies to empty destination blocks). Both should be reviewed together to decide which approach to merge.

Verdict

Safe to approve — clean, minimal change to core selection logic with comprehensive tests. The guard condition prevents unintended format overwriting.

@potatowagon potatowagon left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review — Preserve Pasted Paragraph Alignment

Assessment: Looks good to land

What I verified:

  1. Bug fix logic: When pasting a paragraph with alignment (e.g., centered) into an empty/default-aligned destination paragraph, the format wasn't being preserved because the merge logic in RangeSelection.insertNodes only transferred children, not formatting. The fix checks if the source has a format and the destination has the default format (''), then copies it over.

  2. Condition correctness: The guard firstToInsert.getFormatType() !== '' && firstBlock.getFormatType() === '' correctly avoids overwriting an explicitly-set destination alignment. This means: paste centered into default → preserves center; paste centered into right-aligned → keeps right-aligned. This is the expected UX.

  3. Test coverage: 6 test cases covering: centered into empty (preserves), right-aligned into empty (preserves), centered into already-aligned (no override), copy/paste round-trip with centered text, right-aligned round-trip, and mixed alignment blocks.

  4. CI status: Full CI suite green (39 checks pass).

  5. Duplicate PR note: PR #8310 addresses the same issue with a slightly different approach. Both PRs should not be merged together — one needs to be chosen. This PR's approach is cleaner (simpler condition).

— via Navi on behalf of potatowagon

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.

Bug: Text alignment is lost on copy-paste

4 participants