Skip to content

feat(tiptap): add native table support with round-trip MDC conversion#444

Open
nvdai2401 wants to merge 3 commits into
nuxt-content:mainfrom
nvdai2401:maico/tiptap-table-support
Open

feat(tiptap): add native table support with round-trip MDC conversion#444
nvdai2401 wants to merge 3 commits into
nuxt-content:mainfrom
nvdai2401:maico/tiptap-table-support

Conversation

@nvdai2401
Copy link
Copy Markdown

@nvdai2401 nvdai2401 commented Apr 30, 2026

Summary

Adds native TipTap table editing to the Studio editor, ported to the new comark-based AST system from #355.

Users can:

  • Type /table to insert a 2×2 table with a header row
  • Click into cells and type, navigate with Tab/Shift+Tab
  • Open existing markdown files with GFM tables and edit them as TipTap tables
  • Use Notion-style grip handles on column/row borders to insert, delete columns/rows, or delete the table
  • Round-trip table content through comark ↔ markdown without data loss

Approach

Uses upstream @tiptap/extension-table (pinned to 3.22.4 to match @tiptap/core) with native ProseMirror rendering — no custom NodeView.

Comark conversion

  • comarkToTiptap: maps table/thead/tbody/tr/th/td comark elements to TipTap table/tableRow/tableHeader/tableCell nodes, flattening thead/tbody wrappers
  • tiptapToComark: reverses the conversion, splitting rows into thead/tbody based on cell type and unwrapping single-paragraph cells

Notion-style grip handles

  • TiptapTableGrips.vue renders grip buttons centered on column top borders and row left borders when the cursor is in a table
  • Each grip opens a UDropdownMenu with labeled actions (Insert left/right, Insert above/below, Delete column/row, Delete table)
  • Opening a grip selects the full column/row via ProseMirror CellSelection, giving visual feedback
  • useTableGrips.ts composable encapsulates table geometry calculation and cell selection logic

What's in scope (v1)

  • Insert/edit native tables via /table slash command
  • Round-trip comark ↔ TipTap conversion for GFM tables
  • Notion-style column/row grip handles with labeled dropdown menus
  • Editor styles (borders, padding, header background, dark mode, cell selection highlight)
  • Slash menu de-dup for project-defined <UTable> components

Not in scope (deferred)

  • Column resizing (resizable: false for v1)
  • Cell merging/splitting
  • Duplicate column/row
  • Clear contents

Test plan

  • Integration test: simple table round-trip (markdown → comark → TipTap → comark → markdown)
  • Integration test: bold + link inside cells
  • Integration test: empty cells
  • Integration test: single-column table
  • Unit test: editor suggestion items include table
  • Manual: /table insertion in dev playground
  • Manual: cell editing, Tab navigation
  • Manual: grip handle dropdown actions (insert/delete column/row/table)
  • Manual: column/row selection highlight on grip click
  • Manual: open existing markdown file with GFM table — renders as editable table
  • Manual: round-trip back to markdown matches GFM table syntax

Notable implementation details

  • Vite optimizeDeps: @tiptap/extension-table excluded, @tiptap/pm/tables included — prevents prosemirror-tables from loading twice
  • Version pinning: @tiptap/extension-table@3.22.4 must match @tiptap/core@3.22.4 (peer dependency)
  • Grip positioning: Grips are absolutely positioned relative to the editor container using getBoundingClientRect calculations, recalculated on every editor transaction via requestAnimationFrame debouncing
  • Legacy bridge compatibility: Tables survive the MarkdownRoot → ComarkTree conversion in dev mode via the existing legacy bridge in host.ts

🤖 Generated with Claude Code

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Apr 30, 2026

@nvdai2401 is attempting to deploy a commit to the Nuxt Team on Vercel.

A member of the Team first needs to authorize it.

@nvdai2401 nvdai2401 force-pushed the maico/tiptap-table-support branch from ad3b249 to 7486e13 Compare April 30, 2026 07:56
@nvdai2401 nvdai2401 marked this pull request as ready for review April 30, 2026 08:07
@nvdai2401
Copy link
Copy Markdown
Author

Hey @larbish @TotomInc, I created this PR to add native table support to the Studio editor. It’s been a long-standing gap and I tried to keep the change as minimal and idiomatic as possible.

What’s in: /table slash command inserts a 2x2 GFM table; cells are editable with Tab navigation; existing markdown tables render as editable tables; full round-trip through MDC ↔ markdown (4 integration tests). A floating bubble menu inside tables exposes add/delete row/column and toggle-header actions. Drag-handle “Turn into” is force-disabled for tables (otherwise ProseMirror would silently swap the table for a paragraph).

What I’d appreciate eyes on:

  • Vite optimizeDeps in src/app/vite.config.ts: I had to exclude: ['@tiptap/extension-table'] and include: ['@tiptap/pm/tables'] so prosemirror-tables only loads once. Without it, dev mode threw Duplicate use of selection JSON ID cell. Open to a cleaner approach if you have one.
  • vitest.config.ts alias + src/module/tsconfig.json: small infra changes I needed to run tests on Node 20 without a full dev:prepare. Benign on Node 22 CI but happy to drop them if you prefer.
    Slash menu de-dup (useTiptapEditor.ts): a project-defined <UTable> would have collided with our native handler — I added a NATIVE_OVERRIDE_COMPONENTS set to filter it out. Let me know if there’s a more established pattern for this.

Out of scope for v1: column resizing, cell merging/splitting. Happy to tackle those in a follow-up.

Branch is up to date with main, all 247 tests pass.

@larbish
Copy link
Copy Markdown
Contributor

larbish commented Apr 30, 2026

Hello @nvdai2401, thanks a lot for this PR! That's a great feature.

I'm currently finishing this PR about migrating the nuxt studio parser to comark.dev.

This has a big impact on the transformation between TipTap AST and Comark AST (and no more legacy MDC AST).

I should merge it really soon and I'll provide a skill I've maintained during the all migration so you can easily adapt your PR once this branch is merged.

I'll keep you posted!

@Rigo-m
Copy link
Copy Markdown

Rigo-m commented May 3, 2026

Round-trip mdc conversion is a big upgrade to studio, can actually enable bigger patterns (e.g.: kanban boards and other components)

@nvdai2401
Copy link
Copy Markdown
Author

Hey @larbish, any updates on #355. Could you give an ETA?

@larbish
Copy link
Copy Markdown
Contributor

larbish commented May 13, 2026

Hey @nvdai2401, I did merge the comark PR. You can now update your PR to match the new comark logic.

I also just pushed a skill that can help: #456

Don't hesitate if you need help 🙏

Port the table feature from the pre-comark branch to work with the new
comark-based AST system introduced in nuxt-content#355.

- Add comark↔TipTap table conversion (table/thead/tbody/tr/th/td)
- Register TipTap table extensions (Table, TableRow, TableCell, TableHeader)
- Add floating BubbleMenu for row/column operations
- Add table to slash menu and disable Turn Into for table nodes
- Filter project-registered <UTable> from slash menu to avoid duplicates
- Add editor styles for table rendering and cell selection
- Add table integration tests with comark round-trip assertions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@nvdai2401 nvdai2401 force-pushed the maico/tiptap-table-support branch from b94b4cc to 33dec5d Compare May 14, 2026 07:30
Replace the flat icon-only BubbleMenu toolbar with column/row grip handles
that appear on the table borders when a cell is focused. Each grip opens a
labeled dropdown menu with Insert/Delete actions and highlights the full
column or row via ProseMirror CellSelection.

- Add useTableGrips composable for table geometry and cell selection
- Add TiptapTableGrips component with column grips (top border) and
  row grips (left border), each with UDropdownMenu
- Pin @tiptap/extension-table to 3.22.4 to match @tiptap/core version
- Remove old TiptapTableMenu BubbleMenu component

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@nvdai2401
Copy link
Copy Markdown
Author

Hey @larbish, I've updated the PR and also updated the toolbar menu. Ready for review
https://www.loom.com/share/188662fc01c54c8d964b7b99478d04bd

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 19, 2026

npm i https://pkg.pr.new/nuxt-studio@444

commit: 3e229f4

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 19, 2026

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

Project Deployment Actions Updated (UTC)
content-studio Error Error May 19, 2026 0:37am
nuxt.studio Ready Ready Preview May 19, 2026 0:37am

@nvdai2401
Copy link
Copy Markdown
Author

Hey @larbish, any comments on this PR? Could I know when we would merge it?

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.

3 participants