Skip to content

fix: resolve block path correctly when dropping block on inline object#2364

Draft
christianhg wants to merge 1 commit intomainfrom
fix/dnd-block-on-inline-v2
Draft

fix: resolve block path correctly when dropping block on inline object#2364
christianhg wants to merge 1 commit intomainfrom
fix/dnd-block-on-inline-v2

Conversation

@christianhg
Copy link
Member

When a schema allows the same type name (e.g. image) as both a block object and an inline object, dropping a block image onto an inline object turns it into an inline image instead of inserting it as a block. The root cause is in operation.insert.block.ts where the start/end block resolution uses path.length <= start.path.length, which can match inline nodes (path length 2) when the DnD handler has already moved the selection inside a text block at the inline object's position. The insert.block operation then inserts at the inline object's path rather than the containing block's path.

The fix changes both start and end block resolution to path.length === 1, ensuring insert.block always resolves top-level blocks. This is consistent with how the rest of the operation already treats these paths (e.g. endBlockPath[0]!).

The test sets up a schema with image in both blockObjects and inlineObjects, creates a document with a text block containing an inline image and a separate block image, then drops the block image onto the inline object and verifies it remains a top-level block.

When a block object (e.g. image) is dropped onto an inline object, the
insert.block operation resolved the start/end block using
`path.length <= selection.path.length`, which could match inline nodes
(path length 2) when the selection was inside a text block. This caused
the block to be inserted at the inline object's path instead of the
containing block's path, effectively turning a block object into an
inline object.

The fix changes both start and end block resolution to use
`path.length === 1`, ensuring insert.block always resolves top-level
blocks. The existing code already assumes top-level paths in many places
(e.g. `endBlockPath[0]!`).
@changeset-bot
Copy link

changeset-bot bot commented Mar 12, 2026

🦋 Changeset detected

Latest commit: c08eba9

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

@vercel
Copy link

vercel bot commented Mar 12, 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 Mar 12, 2026 8:01pm
portable-text-example-basic Ready Ready Preview, Comment Mar 12, 2026 8:01pm
portable-text-playground Ready Ready Preview, Comment Mar 12, 2026 8:01pm

Request Review

@github-actions
Copy link
Contributor

github-actions bot commented Mar 12, 2026

📦 Bundle Stats — @portabletext/editor

Compared against main (6ea7b6df)

@portabletext/editor

Metric Value vs main (6ea7b6d)
Internal (raw) 773.2 KB -30 B, -0.0%
Internal (gzip) 144.3 KB -10 B, -0.0%
Bundled (raw) 1.38 MB -30 B, -0.0%
Bundled (gzip) 307.2 KB -10 B, -0.0%
Import time 92ms +2ms, +1.7%

@portabletext/editor/behaviors

Metric Value vs main (6ea7b6d)
Internal (raw) 467 B -
Internal (gzip) 207 B -
Bundled (raw) 424 B -
Bundled (gzip) 171 B -
Import time 6ms +0ms, +1.6%

@portabletext/editor/plugins

Metric Value vs main (6ea7b6d)
Internal (raw) 2.5 KB -
Internal (gzip) 910 B -
Bundled (raw) 2.3 KB -
Bundled (gzip) 839 B -
Import time 11ms +0ms, +1.8%

@portabletext/editor/selectors

Metric Value vs main (6ea7b6d)
Internal (raw) 60.2 KB -
Internal (gzip) 9.4 KB -
Bundled (raw) 56.7 KB -
Bundled (gzip) 8.6 KB -
Import time 10ms +0ms, +0.5%

@portabletext/editor/utils

Metric Value vs main (6ea7b6d)
Internal (raw) 24.2 KB -
Internal (gzip) 4.7 KB -
Bundled (raw) 22.2 KB -
Bundled (gzip) 4.4 KB -
Import time 9ms -0ms, -0.6%
Details
  • Import time regressions over 10% are flagged with ⚠️
  • Treemap artifacts are attached to the CI run for detailed size analysis
  • Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.

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