Skip to Content
CommandsCommands: Tables

Commands: Tables

Commands for creating and editing tables: rows, columns, cells, layout, sorting and borders.

import { insertTable, insertRowBefore, setBorders } from "@stesura/core/commands";

Creating Tables

insertTable

Insert a table sized to the section’s content width, with the cursor in the first cell. Refused inside code blocks, inside another table, and wherever the schema cannot host a table (footnote/endnote bodies).

insertTable({ rows: number, cols: number, borders?: Borders | null // omit for default visible borders; null for borderless }): Command

createTableNode

Build a table Node (not a command) for programmatic builders. Returns null when the schema lacks the table nodes.

createTableNode(state: EditorState, options: CreateTableOptions): Node | null type CreateTableOptions = { rows: number; cols: number; borders?: Borders | null; maxWidth?: number; // px to size the columns against; default: the section's content width // per-cell paragraph attrs and/or inline content cellParagraph?: (row: number, col: number) => { attrs?: Record<string, unknown>; content?: Node | Fragment | null } | undefined; };

Column Operations

insertColumnBefore / insertColumnAfter

Insert a column left / right of the selection, rescaling the existing columns so the table keeps its overall width. Refused when no column has a width to rescale.

insertColumnBefore: Command insertColumnAfter: Command

deleteColumn

Delete the selected columns and redistribute their width across the remaining ones. Refused when every column is selected. While track changes is enabled, the widths are not redistributed.

deleteColumn: Command

distributeColWidths

Set every selected column to width px. Omit width to give them their average width (needs 2+ columns). Floored at 25px.

distributeColWidths(width?: number): Command

Row Operations

insertRowBefore / insertRowAfter

Insert as many rows as the selection spans, above / below it. New cells copy the adjacent selected row’s cell attrs, including colspans, with empty content; above the first row they are plain cells. Rowspans crossing the insert point grow to cover the new rows.

insertRowBefore(updateSelection?: boolean): Command insertRowAfter(updateSelection?: boolean): Command

insertRow

The TransactionFn factory behind both commands, for custom insertions. It inserts rect.bottom - rect.top rows at row index row. copyRow picks the row whose cell attrs are copied: "bottom" the row at row, "top" the row above it, null for plain cells.

insertRow( rect: TableRect, row: number, copyRow: "bottom" | "top" | null, updateSelection?: boolean ): TransactionFn

deleteRow

Delete the selected rows. When the selection spans every row, delete the whole table instead. Deleting rows with vertically merged cells is not tracked (skipTrackChanges). deleteRowTr (in @stesura/core/commands/internal) is the transaction-level variant, without the whole-table case.

deleteRow: Command

setRowHeight

Set the height attr on every row covered by the selection, capped at the section’s page height. Pass null, or a value below the 30px minimum, to clear it. Refused when every row already has that height.

setRowHeight(height: number | null): Command

Cells

mergeCells

Merge the selected cells into one. Only available when the selection’s outline forms a rectangle. The merge is not tracked (skipTrackChanges). mergeCellsTr in @stesura/core/commands/internal is the transaction-level variant and does not set skipTrackChanges.

mergeCells: Command

splitCell

Split a merged cell (rowspan or colspan > 1) back into single cells of its own type. The split is not tracked (skipTrackChanges). splitCellWithTypeTr(getCellType) in @stesura/core/commands/internal takes a custom cell-type resolver and does not set skipTrackChanges.

splitCell: Command

setCellAlignment

Align the selected cells’ content. The vertical half sets the cells’ verticalAlign; the horizontal half sets the text alignment of the blocks inside them.

setCellAlignment(alignment: `${"top" | "middle" | "bottom"}-${"start" | "center" | "end"}`): Command // setCellAlignment("top-start")

setCellAttr

Set attribute name on the selected cells. A dry run returns false when the cell already has value, unless returnTrueOnSameValue is set.

setCellAttr(name: string, value: unknown, returnTrueOnSameValue?: boolean): Command

Table Layout

setTableAlignment

Align the table within the section’s content width. Refused when the table already has that alignment.

setTableAlignment(alignment: "start" | "center" | "end"): Command

setTableSpacing

Merge spacing into the table’s space before/after; sides you leave out keep their value. Requires the whole table to be selected, as do the two commands below.

setTableSpacing(spacing: { before?: number; after?: number }): Command

setTableSpacingBeforeAfter

Set the spacing on one side.

setTableSpacingBeforeAfter({ position: "before" | "after", value: number }): Command

incrementTableSpacing

Add value to the spacing on one side, floored at 0.

incrementTableSpacing({ position: "before" | "after", value: number }): Command

Selection & Deletion

selectEntireTable

Select every cell of the table containing the selection, as a CellSelection. selectEntireTableAtPos(tablePos) targets the table at a known position.

selectEntireTable: Command selectEntireTableAtPos(tablePos: number): Command

deleteTable

Delete the table and put an empty paragraph in its place. deleteTableIfSelected runs only when the whole table is selected, so Delete inside a cell edits the cell instead.

deleteTable: Command deleteTableIfSelected: Command

Sorting

sortTableRows

Reorder all rows by one column’s text, compared as text, number or date according to orderBy. Empty or unparsable values sort last. Without options, it uses the table’s stored sort options, then { colIndex: 0, descending: false, orderBy: "text" }. It is refused, with a toast, when the table has any vertically merged cell or colIndex is out of range. It returns false when the rows are already sorted.

sortTableRows(options?: { colIndex: number; descending: boolean; orderBy: "text" | "number" | "date"; }): Command

setTableSortOptions

Store the sort options on the table (its sortable attr), so sortTableRows() can re-run later with the same settings.

setTableSortOptions(options: SortOptions): Command

Advanced

splitTable

Split the table in two at the cursor’s row, which becomes the first row of the second table. Refused on the first row and when a rowspan crosses that row.

splitTable: Command

Borders

setBorders applies borders to whatever the selection targets. It tries a selected horizontal rule, then a whole selected table, then cells, then styled blocks, and the first that applies wins.

import { setBorders } from "@stesura/core/commands"; setBorders(borders?: Borders): Command

setBordersTr(borders) in @stesura/core/commands/internal is the transaction-level variant.

Each side takes a BorderOptions:

type BorderOptions = { style: BorderStyle; // "single" | "dashed" | "dotted" | "double" | "groove" // | "ridge" | "inset" | "outset" | "none" color?: string; size?: number; space?: number; }; type Borders = { top?: BorderOptions; bottom?: BorderOptions; left?: BorderOptions; right?: BorderOptions; between?: BorderOptions; // blocks only insideHorizontal?: BorderOptions; // tables only insideVertical?: BorderOptions; // tables only };
// Horizontal rules on the selected cells, no verticals setBorders({ top: { style: "single", size: 1, color: "#000" }, bottom: { style: "single", size: 1, color: "#000" }, left: { style: "none" }, right: { style: "none" }, });

There is no "solid" style; the single-line style is "single". Use { style: "none" } to remove a side. A per-side null is only accepted on cell borders (CellBorders).

toggleOutline

Toggle the editor-wide outline overlay: dashed guides drawn where a block has no real border. Meta-only, so the doc is untouched.

toggleOutline: Command

insertHorizontalRule

Insert a horizontal_rule node at the selection.

insertHorizontalRule: Command

Next Steps

Last updated on