Skip to content

Comments

fix: support nested blocks in editor value synchronization#2201

Open
christianhg wants to merge 1 commit intomainfrom
test/nested-blocks-apply-operation
Open

fix: support nested blocks in editor value synchronization#2201
christianhg wants to merge 1 commit intomainfrom
test/nested-blocks-apply-operation

Conversation

@christianhg
Copy link
Member

@christianhg christianhg commented Feb 18, 2026

Summary

Add nested block support to applyOperationToPortableText(). This function handles 8 Slate operation types but previously assumed a flat (depth-2) tree. With nested blocks (containers like table cells), operations can target nodes at depth 3+.

What changed

Helper functions (portable-text-node.ts)

  • getNode(): Generalized to walk arbitrary depth by following children arrays, instead of hardcoding path.length === 0/1/2.
  • getParent(): Now delegates to getNode() on the parent path, instead of hardcoding parentPath.length === 0/1.

Operation handlers (apply-operation-to-portable-text.ts)

  • New updateChildrenAtPath(): Immutably rebuilds the tree from root to any target parent node. Replaces updateTextBlockAtIndex() which only worked at the root level.
  • All 8 op handlers refactored: insert_text, remove_text, insert_node, remove_node, merge_node, split_node, set_node, move_node now use the generalized helpers instead of branching on path.length === 1 vs path.length === 2.

Root cause

Three hardcoded depth assumptions blocked nested block support:

  1. getNode() returned undefined for path.length > 2
  2. getParent() returned undefined for parent paths longer than 1
  3. Every op handler branched on path.length === 1 and path.length === 2 with a return root fallthrough

Tests (26 total)

  • Nested text blocks + spans (14 tests): All 8 operation types at depth 2-3
  • Nested inline objects (4 tests): insert_node, remove_node, set_node, move_node for inline objects inside text blocks inside containers
  • Nested block objects (4 tests): insert_node, remove_node, set_node, move_node for block objects as direct children of containers
  • Depth 4+ (4 tests): insert_text, remove_text, split_node, merge_node at depth 5 (table > row > cell > block > span)
  • All 55 existing tests pass unchanged (zero regressions)

@vercel
Copy link

vercel bot commented Feb 18, 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 18, 2026 3:09pm
portable-text-example-basic Ready Ready Preview, Comment Feb 18, 2026 3:09pm
portable-text-playground Ready Ready Preview, Comment Feb 18, 2026 3:09pm

Request Review

@changeset-bot
Copy link

changeset-bot bot commented Feb 18, 2026

🦋 Changeset detected

Latest commit: 3375c66

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

Operations targeting nodes inside nested block structures (e.g., text
inside table cells) are now handled correctly. Previously, only flat
document structures (depth 2) were supported. All 8 operation types
now work at arbitrary nesting depth.
@christianhg christianhg changed the title test: nested blocks for applyOperationToPortableText fix: support nested blocks in editor value synchronization Feb 18, 2026
@christianhg christianhg force-pushed the test/nested-blocks-apply-operation branch from 3375c66 to 037076a Compare February 18, 2026 15:04
@christianhg christianhg marked this pull request as ready for review February 18, 2026 15:06
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