Skip to main content

Overview

The Table extension provides comprehensive table support with features like column resizing, cell merging, row and column manipulation, and cell selection. Built on top of prosemirror-tables, it offers a powerful table editing experience.

Installation

import { defineTable } from '@prosekit/extensions'

Basic Usage

import { defineTable } from '@prosekit/extensions'
import { createEditor } from '@prosekit/core'

const editor = createEditor({
  extensions: [
    defineTable(),
    // ... other extensions
  ],
})

Table Structure

Tables consist of three node types:
  • table: The container node
  • tableRow: Represents a row in the table
  • tableCell: Regular data cell
  • tableHeaderCell: Header cell for column/row headers

Commands

Creating Tables

insertTable

Inserts a new table with specified dimensions.
editor.commands.insertTable({
  rows: 3,
  cols: 3,
  withHeaderRow: true,
})
Options:
  • rows: Number of rows to create
  • cols: Number of columns to create
  • withHeaderRow: Whether to include a header row (default: true)

Adding Rows and Columns

addTableRowAbove

Adds a row above the current selection.
editor.commands.addTableRowAbove()

addTableRowBelow

Adds a row below the current selection.
editor.commands.addTableRowBelow()

addTableColumnBefore

Adds a column before the current selection.
editor.commands.addTableColumnBefore()

addTableColumnAfter

Adds a column after the current selection.
editor.commands.addTableColumnAfter()

Deleting Elements

deleteTable

Deletes the entire table.
editor.commands.deleteTable()

deleteTableRow

Deletes the current row.
editor.commands.deleteTableRow()

deleteTableColumn

Deletes the current column.
editor.commands.deleteTableColumn()

deleteCellSelection

Deletes the content of selected cells.
editor.commands.deleteCellSelection()

Cell Operations

mergeTableCells

Merges selected cells into a single cell.
editor.commands.mergeTableCells()

splitTableCell

Splits a merged cell back into individual cells.
editor.commands.splitTableCell()

Selection Commands

selectTable

Selects the entire table.
editor.commands.selectTable(options?: SelectTableOptions)

selectTableRow

Selects an entire row.
editor.commands.selectTableRow(options?: SelectTableRowOptions)

selectTableColumn

Selects an entire column.
editor.commands.selectTableColumn(options?: SelectTableColumnOptions)

selectTableCell

Selects a specific cell.
editor.commands.selectTableCell(options?: SelectTableCellOptions)

Moving Rows and Columns

moveTableRow

Moves the current row up or down.
editor.commands.moveTableRow({ direction: 'up' })
editor.commands.moveTableRow({ direction: 'down' })

moveTableColumn

Moves the current column left or right.
editor.commands.moveTableColumn({ direction: 'left' })
editor.commands.moveTableColumn({ direction: 'right' })

exitTable

Moves the cursor out of the table.
editor.commands.exitTable()

Cell Attributes

Table cells support the following attributes:
interface CellAttrs {
  /**
   * Number of columns this cell spans.
   */
  colspan?: number
  
  /**
   * Number of rows this cell spans.
   */
  rowspan?: number
  
  /**
   * Array of column widths for each spanned column.
   */
  colwidth?: number[] | null
}

Styling

The extension includes default styles that can be imported:
import '@prosekit/extensions/table/style.css'

CSS Classes

The following CSS classes are applied:
.ProseMirror .tableWrapper {
  overflow-x: auto;
}

.ProseMirror table {
  width: 100%;
  overflow: hidden;
  border-collapse: collapse;
  table-layout: fixed;
}

.ProseMirror td,
.ProseMirror th {
  box-sizing: border-box;
  position: relative;
  padding-right: 0.75rem;
  padding-left: 0.75rem;
  border-width: 1px;
  vertical-align: top;
}

.ProseMirror .selectedCell {
  border: 1px double hsl(210, 100%, 56%);
  background-color: hsla(210, 100%, 56%, 20%);
}

.ProseMirror .column-resize-handle {
  position: absolute;
  top: 0;
  right: -2px;
  bottom: 0;
  width: 4px;
  background-color: HighlightText;
  pointer-events: none;
}

Utilities

The extension exports utility functions:

findTable

Finds the table node that contains the current selection.
import { findTable } from '@prosekit/extensions'

const table = findTable(state.selection)

isCellSelection

Checks if the current selection is a cell selection.
import { isCellSelection } from '@prosekit/extensions'

if (isCellSelection(state.selection)) {
  // Handle cell selection
}

Complete Example

import { createEditor } from '@prosekit/core'
import { defineTable } from '@prosekit/extensions'
import '@prosekit/extensions/table/style.css'

const editor = createEditor({
  extensions: [defineTable()],
})

// Insert a 3x3 table with header row
editor.commands.insertTable({
  rows: 3,
  cols: 3,
  withHeaderRow: true,
})

// Add a new row below
editor.commands.addTableRowBelow()

// Add a new column after
editor.commands.addTableColumnAfter()

// Select and merge cells
editor.commands.selectTableCell()
editor.commands.mergeTableCells()

// Move row up
editor.commands.moveTableRow({ direction: 'up' })

// Delete a column
editor.commands.deleteTableColumn()

Keyboard Shortcuts

Default keyboard shortcuts for table navigation:
  • Tab: Move to next cell
  • Shift+Tab: Move to previous cell
  • Arrow Keys: Navigate between cells
  • Enter: Create new row (when in last cell)
  • Backspace: Delete cell content or merge with previous

Advanced Features

Column Resizing

Tables support interactive column resizing by dragging column borders.

Drop Indicator

The extension includes visual feedback when dragging content over tables:
import { defineTableDropIndicator } from '@prosekit/extensions'

Cell Selection

Supports selecting multiple cells for batch operations like merging or deleting.
  • Use with defineDoc() and defineParagraph() for complete document structure
  • Combine with text formatting extensions for rich cell content
  • Works with defineImage() to embed images in table cells