docs/solutions/logic-errors/2026-05-09-empty-target-fragment-paste-keeps-first-block-wrapper.md
Lexical's native CopyAndPaste.spec.mjs includes a useful block-format row:
copy two paragraphs, paste them into an empty quote, keep the first paragraph in
the quote, and place the second paragraph after it.
Slate v2's single-empty-block fragment path replaced the target quote with the incoming paragraph fragment, losing the target wrapper.
block-quote followed by a paragraph.Handle multi-text-block fragments before the generic block-fragment replacement
inside getSingleEmptyBlockFragmentReplacement:
if (
fragment.length > 1 &&
fragment.every((node) => isTextBlockElement(editor, node))
) {
const [firstFragmentBlock, ...tailBlocks] = fragment as Element[]
const children = [
{
...onlyEditorNode,
children: firstFragmentBlock.children.map(cloneDescendant),
},
...tailBlocks.map(cloneDescendant),
] as Value
return {
children,
previousChildren: editorChildren,
selection: getFragmentEndSelection(children),
}
}
The target empty text block owns the first pasted text block wrapper. After that first landing, remaining pasted blocks should keep their source shape and live after the target block.
This preserves the already-documented single text-block policy: when a single text block replaces a target text block, the target wrapper wins. The new rule only extends that policy to the first block of a multi-block fragment.