Skip to content

fix: unify internal selection normalization#2483

Merged
christianhg merged 1 commit intomainfrom
remove-to-slate-range
Apr 9, 2026
Merged

fix: unify internal selection normalization#2483
christianhg merged 1 commit intomainfrom
remove-to-slate-range

Conversation

@christianhg
Copy link
Copy Markdown
Member

@christianhg christianhg commented Apr 9, 2026

toSlateRange existed to normalize selection points: resolving block-level paths to span-level paths, recovering from missing children, and clamping offsets. After the keyed paths refactor, the type conversion aspect was meaningless since EditorSelection and Range are structurally identical. The function was really just selection normalization wrapped in a misleading name.

This replaces it with resolveSelection(editor, selection) in apply-selection.ts. Every call site goes from 8 lines of snapshot assembly boilerplate to a single function call.

The core resolveSelectionPoint function is rewritten to use getNode and getLeaf instead of manual depth-2 path reconstruction. This makes it work at any depth, including inside containers:

  • getNode resolves the path to a real node in the tree
  • If the node is a leaf (span, inline object, block object), return it with clamped offset
  • If the node is a text block with a block-level offset, blockOffsetToSpanSelectionPoint resolves to the exact span position
  • Otherwise getLeaf descends to the nearest leaf child
  • If the path doesn't resolve (child was removed), fall back to the first leaf of the block

No container special case needed. getNode and getLeaf are already depth-agnostic through getChildren.

The DOM bridge function (DOMEditor.toSlateRange / ReactEditor.toSlateRange) is unrelated and unchanged.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 9, 2026

🦋 Changeset detected

Latest commit: 0552fb6

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
Copy Markdown

vercel bot commented Apr 9, 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 Apr 9, 2026 11:38am
portable-text-example-basic Ready Ready Preview, Comment Apr 9, 2026 11:38am
portable-text-playground Ready Ready Preview, Comment Apr 9, 2026 11:38am

Request Review

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

📦 Bundle Stats — @portabletext/editor

Compared against main (3201611d)

@portabletext/editor

Metric Value vs main (3201611)
Internal (raw) 762.5 KB -2.9 KB, -0.4%
Internal (gzip) 144.2 KB -492 B, -0.3%
Bundled (raw) 1.36 MB -2.9 KB, -0.2%
Bundled (gzip) 304.9 KB -270 B, -0.1%
Import time 94ms -1ms, -1.4%

@portabletext/editor/behaviors

Metric Value vs main (3201611)
Internal (raw) 467 B -
Internal (gzip) 207 B -
Bundled (raw) 424 B -
Bundled (gzip) 171 B -
Import time 2ms -0ms, -1.3%

@portabletext/editor/plugins

Metric Value vs main (3201611)
Internal (raw) 2.5 KB -
Internal (gzip) 910 B -
Bundled (raw) 2.3 KB -
Bundled (gzip) 839 B -
Import time 8ms -0ms, -1.5%

@portabletext/editor/selectors

Metric Value vs main (3201611)
Internal (raw) 60.5 KB -
Internal (gzip) 9.5 KB -9 B, -0.1%
Bundled (raw) 56.9 KB -
Bundled (gzip) 8.7 KB -1 B, -0.0%
Import time 6ms -0ms, -2.3%

@portabletext/editor/utils

Metric Value vs main (3201611)
Internal (raw) 24.2 KB -
Internal (gzip) 4.7 KB -3 B, -0.1%
Bundled (raw) 22.2 KB -
Bundled (gzip) 4.4 KB -4 B, -0.1%
Import time 5ms -0ms, -3.2%

🗺️ . · ./behaviors · ./plugins · ./selectors · ./utils · Artifacts

Details
  • Import time regressions over 10% are flagged with ⚠️
  • Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.

@christianhg christianhg force-pushed the remove-to-slate-range branch from 319c02a to cd667b8 Compare April 9, 2026 10:52
@christianhg christianhg changed the title refactor: replace toSlateRange with resolveSelection fix: unify internal selection normalization Apr 9, 2026
@christianhg christianhg closed this Apr 9, 2026
@christianhg christianhg force-pushed the remove-to-slate-range branch from a961273 to 3201611 Compare April 9, 2026 11:24
@christianhg christianhg reopened this Apr 9, 2026
@christianhg christianhg force-pushed the remove-to-slate-range branch from c46a9f4 to 9138c07 Compare April 9, 2026 11:34
@christianhg christianhg enabled auto-merge (rebase) April 9, 2026 11:37
@christianhg christianhg disabled auto-merge April 9, 2026 11:44
@christianhg christianhg merged commit 1f4dbd1 into main Apr 9, 2026
16 of 17 checks passed
@christianhg christianhg deleted the remove-to-slate-range branch April 9, 2026 11:44
@ecoscript ecoscript bot mentioned this pull request Apr 9, 2026
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