English | 简体中文
A ProseMirror-first table engine for full HTML table structures.
This project is designed for editors that need to preserve and manipulate richer HTML table semantics than the default ProseMirror/Tiptap table model, including:
captioncolgroupcoltheadtbodytfoottrthtd
packages/core ProseMirror schema helpers, table model types, grid utilities, and commands
packages/tiptap Tiptap v3 node extensions and command wrappers built on top of the core packageA Vue 3 + Tiptap v3 playground is available in examples/vue3-tiptap-table.
Online:
Local:
npm install
npm run dev --workspace vue3-tiptap-table-demoThe playground includes a full HTML table with caption, colgroup, thead, tbody, and tfoot, plus toolbar buttons for row/column editing, header toggles, cell navigation, and table selection commands.
npm install prosemirror-html-tableFor Tiptap projects:
npm install tiptap-html-table prosemirror-html-tableThe schema foundation supports the full structural shape of HTML tables:
htmlTable
├── htmlTableCaption?
├── htmlTableColgroup?
│ └── htmlTableCol+
├── htmlTableHead?
│ └── htmlTableRow+
├── htmlTableBody+
│ └── htmlTableRow+
└── htmlTableFoot?
└── htmlTableRow+Rows contain htmlTableHeaderCell and htmlTableCell nodes, which render as th and td.
createHtmlTableGrid maps thead, tbody, and tfoot rows into one logical grid. It tracks row index, column index, section name, rowspan, colspan, and whether a slot is the anchor of a spanning cell.
import { createHtmlTableGrid } from 'prosemirror-html-table';
const grid = createHtmlTableGrid(tableNode);The core package currently exposes these table commands:
import {
addColumnAfter,
addColumnBefore,
addRowAfter,
addRowBefore,
deleteColumn,
deleteRow,
deleteTable,
fixTables,
goToNextCell,
goToPreviousCell,
insertHtmlTable,
mergeCells,
mergeOrSplit,
selectCell,
selectColumn,
selectRow,
selectTable,
setCellAttribute,
splitCell,
toggleHeaderCell,
toggleHeaderColumn,
toggleHeaderRow,
} from 'prosemirror-html-table';Supported command set:
insertHtmlTable
addRowBefore
addRowAfter
deleteRow
addColumnBefore
addColumnAfter
deleteColumn
deleteTable
mergeCells
splitCell
mergeOrSplit
fixTables
setCellAttribute
toggleHeaderCell
toggleHeaderRow
toggleHeaderColumn
goToNextCell
goToPreviousCell
selectCell
selectRow
selectColumn
selectTableThese commands use the section-aware grid internally. They now cover dedicated cell selection, rectangular merge, merged-cell splitting, and full-table normalization through fixTables.
Header commands convert between htmlTableHeaderCell and htmlTableCell while preserving cell attributes, content, and marks.
Selection commands use a dedicated CellSelection for cell, row, and column ranges, while whole-table selection still uses NodeSelection.
The Tiptap package now includes:
- custom table node view with optional wrapper
- column resize handles
- persisted colgroup / colwidth state
- selected-cell decorations
- Tab / Shift-Tab navigation
- Shift-Arrow cell-range expansionAvailable options:
{
HTMLAttributes: {},
resizable: true,
renderWrapper: true,
handleWidth: 6,
cellMinWidth: 120,
lastColumnResizable: true,
allowTableNodeSelection: true,
}import { Editor } from '@tiptap/core';
import { HtmlTableExtensions } from 'tiptap-html-table';
const editor = new Editor({
extensions: [
// Add your document, paragraph, text, and other base extensions here.
...HtmlTableExtensions,
],
});
editor.commands.insertHtmlTable({
rows: 3,
cols: 3,
withHeaderRow: true,
withCaption: true,
captionText: 'Demo table',
});
editor.commands.addHtmlTableRowAfter();
editor.commands.addHtmlTableColumnAfter();
editor.commands.deleteHtmlTableRow();
editor.commands.deleteHtmlTableColumn();
editor.commands.setHtmlTableCellAttribute('colspan', 2);
editor.commands.toggleHtmlTableHeaderCell();
editor.commands.toggleHtmlTableHeaderRow();
editor.commands.toggleHtmlTableHeaderColumn();
editor.commands.goToNextHtmlTableCell();
editor.commands.goToPreviousHtmlTableCell();
editor.commands.selectHtmlTableCell();
editor.commands.selectHtmlTableRow();
editor.commands.selectHtmlTableColumn();
editor.commands.selectHtmlTable();
editor.commands.mergeHtmlTableCells();
editor.commands.splitHtmlTableCell();
editor.commands.mergeOrSplitHtmlTableCells();
editor.commands.fixHtmlTables();
editor.commands.deleteHtmlTable();goToNextHtmlTableCell and goToPreviousHtmlTableCell support optional cycling:
editor.commands.goToNextHtmlTableCell({ cycle: true });The next major areas are:
1. optional UI components for row and column controls
2. richer keyboard shortcuts and copy/paste behavior
3. copy/paste cell ranges
4. row and column move / duplicate controlsnpm install
npm run lint
npm run typecheck
npm test
npm run buildRun the Vue demo:
npm run dev --workspace vue3-tiptap-table-demoMIT