Skip to content

fix(text-editor): prevent content loss when pasting tables into cells - #4084

Open
john-traas wants to merge 1 commit into
mainfrom
fix/lime-19624-table-paste-content-loss
Open

fix(text-editor): prevent content loss when pasting tables into cells#4084
john-traas wants to merge 1 commit into
mainfrom
fix/lime-19624-table-paste-content-loss

Conversation

@john-traas

@john-traas john-traas commented May 25, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds a new table-paste-plugin registered before prosemirror-tables' tableEditing() so its destructive cell-grid paste cannot run when the caret is a plain TextSelection inside an existing cell
  • When the user pastes content containing a table while the caret is inside a cell, the plugin inserts the entire pasted slice — the table along with any surrounding paragraphs, in their original order — as fresh siblings immediately after the enclosing table, leaving every existing cell, paragraph, and trailing row intact
  • A range selection inside a cell is replaced by the paste (the selected text is deleted, and the pasted content lands after the enclosing table)
  • All other paste paths (CellSelection, outside-table, slices with no top-level table) fall through to the existing default behavior

Closes part of lime-19624 / Lundalogik/crm-client#1050. The reported bug is "pasting table rows in the Conversations composer deletes other rows"

Test plan

  • Unit suite passes: npm run test:spec -- table-paste-plugin
  • Full text-editor specs pass: npm run test:spec -- src/components/text-editor
  • In npm start, open text-editor-with-tables example, copy 2-3 rows from Excel, paste, then place caret inside a cell and paste again — no rows are deleted
  • Copy a table together with a paragraph (both orders) and paste inside a cell — everything lands after the table, nothing is lost
  • Reproduce reporter sequence (paste → Enter → type → paste again) and verify all intermediate paragraphs survive
  • Confirm existing CellSelection cell-grid replace still works (select multiple cells, paste a table — selected cells replaced as before)

Summary by CodeRabbit

  • New Features

    • Added support for pasting complete tables after existing tables in the editor.
    • Preserves surrounding content and places the cursor near the newly inserted table.
    • Automatically creates a trailing paragraph when needed.
    • Unsupported paste content and selections continue to use the default editor behavior.
  • Tests

    • Added comprehensive coverage for table paste scenarios and selection handling.

@coderabbitai

coderabbitai Bot commented May 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@john-traas, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 2 minutes

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 7415c9b2-a07d-4c6b-a5fb-d8ea9f3e0320

📥 Commits

Reviewing files that changed from the base of the PR and between f98d034 and 32a399e.

📒 Files selected for processing (4)
  • src/components/text-editor/prosemirror-adapter/editor-tables.spec.ts
  • src/components/text-editor/prosemirror-adapter/plugins/table-paste-plugin.spec.ts
  • src/components/text-editor/prosemirror-adapter/plugins/table-paste-plugin.ts
  • src/components/text-editor/prosemirror-adapter/plugins/table-plugin.ts
📝 Walkthrough

Walkthrough

Adds a ProseMirror plugin that inserts complete pasted tables after the containing table. Wires the plugin into enabled table editing. Adds tests for supported and unsupported selections and paste content.

Changes

Table paste handling

Layer / File(s) Summary
Table paste interception and plugin wiring
src/components/text-editor/prosemirror-adapter/plugins/table-paste-plugin.ts, src/components/text-editor/prosemirror-adapter/plugins/table-plugin.ts
The new plugin handles complete table slices pasted from caret selections inside tables. It inserts the table after the containing table, updates the selection, scrolls into view, and dispatches the transaction. The table plugin enables it before tableEditing().
Paste behavior validation
src/components/text-editor/prosemirror-adapter/plugins/table-paste-plugin.spec.ts
Tests cover table insertion, surrounding content, trailing paragraphs, non-table slices, CellSelection, and selections outside tables.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested labels: released

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: preventing content loss when pasting tables into cells.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/lime-19624-table-paste-content-loss

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

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

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a content-loss bug in the text editor where pasting a table while the caret is inside an existing cell would destructively replace surrounding rows/paragraphs. A new table-paste-plugin registered before prosemirror-tables' tableEditing() intercepts that specific case and inserts the pasted table as a fresh sibling after the enclosing table.

Changes:

  • Adds table-paste-plugin.ts that intercepts paste only when selection is a TextSelection inside a table and the pasted slice starts with a <table>, inserting the pasted table as a new sibling block after the enclosing table.
  • Registers the new plugin before tableEditing() in getTableEditingPlugins.
  • Adds spec coverage for the in-cell paste, preservation of surrounding content, non-table slice fallthrough, CellSelection fallthrough, and outside-table fallthrough.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
src/components/text-editor/prosemirror-adapter/plugins/table-paste-plugin.ts New plugin that intercepts in-cell table pastes and inserts them as siblings after the enclosing table.
src/components/text-editor/prosemirror-adapter/plugins/table-plugin.ts Registers the new paste plugin ahead of tableEditing().
src/components/text-editor/prosemirror-adapter/plugins/table-paste-plugin.spec.ts Unit tests covering the new plugin's gate conditions and insertion behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions

Copy link
Copy Markdown

Documentation has been published to https://lundalogik.github.io/lime-elements/versions/PR-4084/

@john-traas john-traas self-assigned this Jun 18, 2026
@john-traas
john-traas marked this pull request as ready for review August 3, 2026 11:51

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/components/text-editor/prosemirror-adapter/plugins/table-paste-plugin.ts`:
- Around line 5-13: Reorder the module so the public createTablePastePlugin
export appears before the private sliceStartsWithTable helper, leaving both
implementations and behavior unchanged.
- Around line 19-46: Restrict the table-paste interception in handlePaste to
collapsed TextSelection instances by returning false when state.selection.empty
is false. Keep the existing table and slice checks unchanged so only a caret
inside a table can trigger table insertion.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a578c5d9-039c-4197-9459-c249e593e82d

📥 Commits

Reviewing files that changed from the base of the PR and between 19e3292 and f98d034.

📒 Files selected for processing (3)
  • src/components/text-editor/prosemirror-adapter/plugins/table-paste-plugin.spec.ts
  • src/components/text-editor/prosemirror-adapter/plugins/table-paste-plugin.ts
  • src/components/text-editor/prosemirror-adapter/plugins/table-plugin.ts

Comment thread src/components/text-editor/prosemirror-adapter/plugins/table-paste-plugin.ts Outdated
Comment thread src/components/text-editor/prosemirror-adapter/plugins/table-paste-plugin.ts Outdated
@john-traas
john-traas force-pushed the fix/lime-19624-table-paste-content-loss branch 2 times, most recently from 719cf73 to 3872c97 Compare August 19, 2026 08:11
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