Conversation
… column Merging all cells of a table left the rows below the first one with no cells, since the merged cell's rowspan covers them. prosemirror-tables expects that, and its own row spec is `(table_cell | table_header)*`. BlockNote's `tableRow` required at least one cell, so ProseMirror filled each emptied row with a new cell. Those filler cells collided with the rowspan, and the table gained an extra column instead of becoming a single cell. Closes TypeCellOS#1993
|
@adarshsm is attempting to deploy a commit to the TypeCell Team on Vercel. A member of the Team first needs to authorize it. |
Contributor
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
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 |
@blocknote/ariakit
@blocknote/code-block
@blocknote/core
@blocknote/diagram-block
@blocknote/mantine
@blocknote/math-block
@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
@blocknote/xl-typst-exporter
commit: |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #1993. If you select every cell in a table and merge them, you should get one cell spanning the whole table. Instead, each row gets a new empty cell in front of the merged one, so the table gains an extra column.
Rationale
prosemirror-tables'
mergeCellsdeletes the merged-away cells and gives the remaining cellcolspan = columnsandrowspan = rows. That leaves rows 2..n with no cells, because the rowspan covers all of their positions. prosemirror-tables' own row spec is(table_cell | table_header)*, which allows those empty rows. That's also why the merge works in the prosemirror-tables demo, where @YousefED couldn't reproduce this.BlockNote's
tableRowuses(tableCell | tableHeader)+. So whenmergeCellsdeletes the last cell of a row, ProseMirror fills the row with a new cell to keep the row valid. Those filler cells overlap the merged cell's rowspan, and the table ends up with the extra column.Output for a 2×2 table on
main, after merging all cells:With this change:
Changes
packages/core/src/blocks/Table/block.ts: change thetableRowcontent expression from+to*, matching prosemirror-tables, with a comment explaining why rows can be empty.packages/core/src/blocks/Table/TableExtension.test.ts: a test that merges every cell of a 2×3 table. It checks that the result is one cell (colspan: 3,rowspan: 2), that the second row has no cells, and that there are still 3 column widths.Impact
The schema only gets more permissive, so every existing document stays valid. A row covered by a rowspan from above shows up in the block API as
{ cells: [] }. That's the same as HTML, where a fully covered<tr>has no<td>s. I checked these paths with an empty row in a scratch test:replaceBlocksround-tripblocksToFullHTML/blocksToHTMLLossy(render<tr></tr>)tryParseHTMLToBlocks(parses back to[1, 0]cells)blocksToMarkdownLossy(fills in the grid)splitCellon the merged cell (restores the full grid)For the exporters: the ODT exporter already emits covered cells for empty rows through its
coveredBelowwalk, and the DOCX exporter passesrowSpanto docx.js, which inserts thevMergecontinuation cells itself.One thing to flag for collaboration: a client still on the old schema would treat a document with such an empty row as invalid. That only matters for mixed versions editing the same document.
Testing
main(row cell counts are[2, 1]instead of[1, 0]) and passes with the fix.packages/coreunit suite passes with the change (vp test --run, run withNODE_OPTIONS=--no-experimental-webstoragebecause of Node 26's built-inlocalStorage).vp fmt --checkandvp lint --type-awareare clean on the changed files.Checklist
🤖 Generated with Claude Code