Skip to content

refactor(core): use the new position helpers in the keyboard shortcuts - #3101

Open
YousefED wants to merge 1 commit into
refactor/block-info-apifrom
block-info-api/position-helpers
Open

YousefED wants to merge 1 commit into
refactor/block-info-apifrom
block-info-api/position-helpers

Conversation

@YousefED

@YousefED YousefED commented Sep 21, 2026 •

Copy link
Copy Markdown
Collaborator

Three follow-ups on top of #3051, all behaviour-preserving. Based on that branch, so the diff is just these changes.

1. tableContentCaretPos no longer escapes the module

Both callers in KeyboardShortcutsExtension checked contentKind === "table" themselves and then called the table helper — re-making the decision blockEdgePos already makes:

if (info.contentKind === "table") {
  ...setTextSelection(tableContentCaretPos(info.content, "end"))
} else if (info.contentKind === "none") {
  ...setNodeSelection(info.content.beforePos)
} else {
  ...setTextSelection(info.content.afterPos - 1)
}

All three arms are blockEdgePos, whose non-table path returns exactly contentStart / contentEnd. Each site is now one call plus the null case — content with no caret, i.e. an image — which is the only thing the helper can't decide for you. The +4 table offset is back to living in one place instead of three, and the function is module-private again.

2. The keyboard shortcuts use contentStart / contentEnd

BlockInfo gained those fields in #3051 precisely so callers stop writing the arithmetic, but this file still did it by hand in twelve places (content.beforePos + 1, content.afterPos - 1) — every one a "is the caret at the start/end of this block's content?" check.

Replacing them turned out to make content unused in five of the destructures, so those shrank too:

const { block, content, contentStart } = blockInfo;   →   const { block, contentStart } = blockInfo;

3. A comment on getInsertionPos's lazy-blockGroup branch

Reading if (!info.children) it isn't obvious why hardcoding wrapIn: blockGroup is safe, or why hasContent is tested when it can't be false. Both follow from the BlockInfo union — the container arm makes children required, so only a regular block reaches that branch, and the hasContent test is there to narrow the union so content can be read. The comment says so.

Verification

Behaviour-preserving, checked against both main and #3051 with two differential harnesses — identical scenarios run on each branch and the outputs diffed:

result
core: 1,025 scenarios (keyboard at many offsets over 8 document shapes, block API, navigation, conversions, selection, undo/redo) vs #3051 before these changes 0 differences
core: same, vs main 0 differences
columns: 737 scenarios over 4 layouts, vs #3051 before these changes 0 differences

Plus core 796, multi-column 82, tests 908, type-aware lint clean.

Net −56 / +39 across the two files.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Improved Backspace and Delete behavior at block boundaries.
    • Caret repositioning now works more consistently across text selections, node selections, tables, empty content, and inline content.
  • Refactor

    • Simplified internal handling of block-edge positions without changing block editing commands or overall shortcut behavior.

Three follow-ups on the BlockInfo refactor, all behaviour-preserving.

`tableContentCaretPos` is no longer exported: both callers checked
`contentKind === "table"` themselves and then called it, duplicating the
branch `blockEdgePos` already makes. They now ask `blockEdgePos` for the
edge, so the table offset lives in one place instead of three.

The keyboard shortcuts computed a block's content edges by hand in twelve
places (`content.beforePos + 1` / `content.afterPos - 1`) rather than
reading `contentStart` / `contentEnd`, which the refactor added for
exactly that. Replacing them left `content` unused in five destructures.

`getInsertionPos`'s lazy-blockGroup branch says why only a regular block
reaches it, so `wrapIn: blockGroup` reads as implied rather than assumed,
and why the `hasContent` check is there to narrow the union.
@vercel

vercel Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
blocknote Ready Ready Preview Sep 21, 2026 10:00am UTC
blocknote-website Ready Ready Preview Sep 21, 2026 10:00am UTC

Request Review

@coderabbitai

coderabbitai Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 128f0c29-5b36-4cd1-a68f-5cd4bc18ea39

📥 Commits

Reviewing files that changed from the base of the PR and between 70fc8f6 and 862e4ea.

📒 Files selected for processing (2)
  • packages/core/src/api/getBlockInfoFromPos.ts
  • packages/core/src/extensions/tiptap-extensions/KeyboardShortcuts/KeyboardShortcutsExtension.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

Keyboard shortcut boundary checks now use contentStart and contentEnd. Backspace and Delete relocation now use blockEdgePos. The table caret helper is no longer exported.

Changes

Keyboard boundary handling

Layer / File(s) Summary
Position API cleanup
packages/core/src/api/getBlockInfoFromPos.ts
tableContentCaretPos is now module-private. The insertion fallback comment now describes regular-block handling.
Keyboard shortcut boundary updates
packages/core/src/extensions/tiptap-extensions/KeyboardShortcuts/KeyboardShortcutsExtension.ts
Block-start and block-end checks use contentStart and contentEnd. Backspace and Delete relocation use blockEdgePos for text and node selections.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Refactor

Suggested reviewers: nperez0111

Merge Risk: ⚪ Minimal · up to 862e4

This refactor centralizes keyboard boundary handling without a supplied correctness, data-integrity, security, or availability concern. It is mergeable.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: refactoring keyboard shortcut position handling to use the new position helpers.
Description check ✅ Passed The description clearly covers the rationale, implementation changes, behavior impact, and extensive verification results. It does not use the template headings or include the checklist, but the missi…
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 2 files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A rabbit reads each line,
The patch grows clear beneath the moon,
Small changes hop in place,
Tests guard the garden path,
Reviews bloom before the dawn.

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

@blocknote/ariakit

npm i https://pkg.pr.new/@blocknote/ariakit@3101

@blocknote/code-block

npm i https://pkg.pr.new/@blocknote/code-block@3101

@blocknote/core

npm i https://pkg.pr.new/@blocknote/core@3101

@blocknote/diagram-block

npm i https://pkg.pr.new/@blocknote/diagram-block@3101

@blocknote/mantine

npm i https://pkg.pr.new/@blocknote/mantine@3101

@blocknote/math-block

npm i https://pkg.pr.new/@blocknote/math-block@3101

@blocknote/react

npm i https://pkg.pr.new/@blocknote/react@3101

@blocknote/server-util

npm i https://pkg.pr.new/@blocknote/server-util@3101

@blocknote/shadcn

npm i https://pkg.pr.new/@blocknote/shadcn@3101

@blocknote/xl-ai

npm i https://pkg.pr.new/@blocknote/xl-ai@3101

@blocknote/xl-docx-exporter

npm i https://pkg.pr.new/@blocknote/xl-docx-exporter@3101

@blocknote/xl-email-exporter

npm i https://pkg.pr.new/@blocknote/xl-email-exporter@3101

@blocknote/xl-multi-column

npm i https://pkg.pr.new/@blocknote/xl-multi-column@3101

@blocknote/xl-odt-exporter

npm i https://pkg.pr.new/@blocknote/xl-odt-exporter@3101

@blocknote/xl-pdf-exporter

npm i https://pkg.pr.new/@blocknote/xl-pdf-exporter@3101

@blocknote/xl-typst-exporter

npm i https://pkg.pr.new/@blocknote/xl-typst-exporter@3101

commit: 862e4ea

@github-actions

github-actions Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://TypeCellOS.github.io/BlockNote/pr-preview/pr-3101/

Built to branch gh-pages at 2026-09-22 10:14 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

This branch was successfully deployed

2 active deployments
Preview – blocknote-website — 862e4ea6 Deployed Sep 21, 2026 by vercel[bot]
Preview – blocknote — 862e4ea6 Deployed Sep 21, 2026 by vercel[bot]
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.

2 participants