fix(table): prevent crash when pressing Enter in a table cell#2793
fix(table): prevent crash when pressing Enter in a table cell#2793y-temp4 wants to merge 2 commits into
Conversation
…llOS#2792) The table Enter handler added in TypeCellOS#2685 only handled the case where a cell exists below the cursor. In several edge cases it returned `false` and fell through to the default `splitBlock` handler, which resolves the nearest block container of a cell to the outer `blockContainer` wrapping the whole table and then calls `tr.split(pos, 2, ...)` deep inside the cell. Splitting a tableCell this way is invalid and throws `TransformError: Cannot join tableCell onto blockContainer`, crashing the editor. The crashing edge cases were: - cursor in a cell on the last row (no cell below); - a non-empty text selection inside a last-row cell; - a multi-cell `CellSelection` (the head resolves to a `tableRow`, bypassing the previous `tableParagraph` guard entirely). Use `isInTable` to detect being inside a table (which also covers multi-cell selections), move to the cell below when there is one, and always consume the Enter key while inside a table so it never falls through to `splitBlock`. On the last row Enter is now a no-op. Adds regression tests covering all the crashing cases and confirming the existing "move to cell below" behavior is preserved. Closes TypeCellOS#2792 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
@y-temp4 is attempting to deploy a commit to the TypeCell Team on Vercel. A member of the Team first needs to authorize it. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
💤 Files with no reviewable changes (2)
📝 WalkthroughWalkthroughRefactors table Enter handling to always consume Enter inside tables and safely handle missing below-cells; adds Vitest tests that simulate Enter and verify selection moves for middle rows and no-op safe behavior for last-row cursor, text selections, and multi-cell selections. ChangesTable Enter Key Behavior Fix
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
nperez0111
left a comment
There was a problem hiding this comment.
This looks right to me, the AI generated comments are annoying though, they are not saying anything useful to someone reading the code now
@blocknote/ariakit
@blocknote/code-block
@blocknote/core
@blocknote/mantine
@blocknote/react
@blocknote/server-util
@blocknote/shadcn
@blocknote/xl-ai
@blocknote/xl-docx-exporter
@blocknote/xl-email-exporter
@blocknote/xl-multi-column
@blocknote/xl-odt-exporter
@blocknote/xl-pdf-exporter
commit: |
|
Thanks for the review. I removed the redundant generated comments and kept only the required Vitest environment annotation. |
Summary
Fixes a crash where pressing Enter inside a table cell throws
TransformError: Cannot join tableCell onto blockContainerand leaves the editor in an unrecoverable state.Closes #2792.
Symptom & minimal reproduction
Reproducible on the official demo (no app-specific code needed): https://www.blocknotejs.org/demo#pwls9
It also reproduces by:
CellSelection) and pressing Enter.Stack trace
Cause
The table-specific Enter handler in
packages/core/src/blocks/Table/TableExtension.ts(added in #2685, "feat: Enter moves selection to cell below in tables (BLO-1006)") only handles the case where a cell exists below the cursor. In several edge cases it returnsfalseand falls through to the defaultsplitBlockhandler.splitBlockTrresolves the nearest block container of a cell to the outerblockContainerthat wraps the whole table (whose content — the table — is non-empty, so the "empty block" early-outs don't apply), and then callstr.split(pos, 2, ...)at a position deep inside the cell. Splitting atableCellat depth 2 is invalid, so ProseMirror throwsCannot join tableCell onto blockContainer.Edge cases that triggered the fallback (and therefore the crash):
!$nextCell→false).CellSelection) — the selection head resolves to atableRow, so the handler's previous$head.parent.type.name === "tableParagraph"guard was bypassed entirely.Fix
isInTableinstead of checking that the cursor's parent is atableParagraph. This also covers multi-cell selections, where the head resolves to atableRow.splitBlockhandler. On the last row, Enter is now a no-op.Affected versions
@blocknote/core0.51.2 and 0.51.3 (latest). The regression was introduced in 0.50.0 by #2685.Tests
Adds
packages/core/src/blocks/Table/TableExtension.test.tswith regression tests that:CellSelectionno longer crashes.All
@blocknote/coretests pass (449 passed / 3 skipped), and lint + build (tsc) succeed.Summary by CodeRabbit
Bug Fixes
Tests