Skip to content

fix: forward on insert.text breaks undo batching#2243

Merged
christianhg merged 2 commits intomainfrom
fix/forward-undo-batching
Mar 6, 2026
Merged

fix: forward on insert.text breaks undo batching#2243
christianhg merged 2 commits intomainfrom
fix/forward-undo-batching

Conversation

@christianhg
Copy link
Member

@christianhg christianhg commented Feb 23, 2026

Problem

When a behavior uses forward(event) on insert.text with a second action set, each typed character becomes its own undo step instead of merging with adjacent characters.

This breaks the expected undo behavior for any behavior that observes text insertion without modifying it (e.g., a behavior that forwards the text and then checks the block content to update styles).

Root cause

performEvent sets a unique undoStepId for every insert.text event because it's synthetic (not in nativeBehaviorEventTypes). Without custom behaviors, the default handler clears undoStepId before running the operation, so consecutive characters merge via the history plugin's merge heuristic. But when a behavior forwards the event, defaultBehaviorOverwritten = true and the clearing never happens. Each character gets a unique undoStepId, preventing history merge.

Fix

Add a merge heuristic in undo-step.ts for the case where consecutive operations have different defined undoStepIds. When both IDs are defined but different, and the operations are consecutive insert_text at adjacent offsets on the same path (or consecutive remove_text), merge them into the same undo step. This matches the existing merge behavior for the undefined ID case.

This approach avoids changing performEvent and preserves the existing undo step separation for:

  • Custom events forwarding to insert.block (different op types, not insert_text)
  • Input rule transformations (the transformation creates a new undo step boundary between the forwarded text and the rule application)

Testing

Two new browser tests verify the fix:

  • Forwarding insert.text preserves undo batching
  • Forwarding insert.text with side effect preserves undo batching

@vercel
Copy link

vercel bot commented Feb 23, 2026

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

Project Deployment Actions Updated (UTC)
portable-text-editor-documentation Ready Ready Preview, Comment Feb 24, 2026 0:39am
portable-text-example-basic Ready Ready Preview, Comment Feb 24, 2026 0:39am
portable-text-playground Ready Ready Preview, Comment Feb 24, 2026 0:39am

Request Review

@changeset-bot
Copy link

changeset-bot bot commented Feb 23, 2026

🦋 Changeset detected

Latest commit: cb518a9

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 11 packages
Name Type
@portabletext/editor Patch
@portabletext/plugin-character-pair-decorator Patch
@portabletext/plugin-emoji-picker Patch
@portabletext/plugin-input-rule Patch
@portabletext/plugin-markdown-shortcuts Patch
@portabletext/plugin-one-line Patch
@portabletext/plugin-paste-link Patch
@portabletext/plugin-sdk-value Patch
@portabletext/plugin-typeahead-picker Patch
@portabletext/plugin-typography Patch
@portabletext/toolbar Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant