Skip to Content
CommandsCommands: Sections & Track Changes

Commands: Sections & Track Changes

Page layout commands (sections, page breaks, line numbers, headers and footers) from core, and the track-changes commands from @stesura/track-changes.

// section, page-break and header/footer commands ship in core import { addSection, removeSection, setSectionFormat } from "@stesura/core/commands"; // track-changes commands ship in the track-changes feature pack import { enableTrackChanges, disableTrackChanges, toggleTrackChanges, toggleTrackChangesVisibility, resolveTrackChanges, resolveAllTrackChanges, selectTrackChanges, } from "@stesura/track-changes";

Track changes also requires transactionModifier={trackChangesTransactionModifier} on StesuraEditor so transactions flow through the diff layer:

import { trackChangesTransactionModifier } from "@stesura/track-changes"; <StesuraEditor /* ... */ transactionModifier={trackChangesTransactionModifier} />

Sections

addSection

Split the current section after the top-level block holding the cursor. The blocks after it move into a new section that inherits the current one’s page setup and header/footer, and the cursor moves into the new section.

addSection(): Command

removeSection / removeSectionAt

Remove the section containing the selection, appending its content to the previous section. Refused, with a toast, on the first section. removeSectionAt takes the section node’s position instead of reading the selection.

removeSection: Command removeSectionAt(sectionPos: number): Command

setSectionFormat

Set the current section’s orientation, page size and/or margins in one step. A page size whose aspect contradicts the orientation is transposed to match it, and an orientation change without a size swaps the page’s width and height. Refused when nothing changes.

setSectionFormat(options: SectionOptions): Command type SectionOptions = { orientation?: "portrait" | "landscape"; pageSize?: { width: number; height: number }; margin?: { // merged over the current margins top?: number; bottom?: number; left?: number; right?: number; layout?: "narrow" | "moderate" | "wide" | "custom"; }; header?: boolean; // ignored by this command footer?: boolean; // ignored by this command };

There is no section background colour. The canvas behind the pages is set with setDocBgColor(color) (the docBgColor doc attr).

setOrientation

Switch the current section between portrait and landscape, swapping page width and height. Refused when already in that orientation.

setOrientation(orientation: "portrait" | "landscape"): Command

insertPageBreak

Insert a hard page break at the cursor (Word’s Ctrl+Enter). The paragraph is split around the break and the cursor lands after it; at the end of a block, the split leaves an empty paragraph for the cursor. Refused inside tables and outside section content.

insertPageBreak: Command

insertPageNumber

Insert a page-number field at the cursor. Refused inside code blocks.

insertPageNumber({ pageType: "currentPage" | "totalPages" }): Command

insertPageOfPage

Insert a “1 of 12” pair of page-number fields. middleText is the bare separator word (default "of"); a space is added on each side.

insertPageOfPage(middleText?: string): Command

Line Numbers

setLineNumbers

Merge attributes into the section’s line numbering (starting from the defaults when it is off), clamped to bounds.

setLineNumbers(attrs: Partial<{ countBy: number; // show only every Nth number (default 1) distance: number; // gutter gap in px (default 10) restart: "continuous" | "newPage" | "newSection"; // default "continuous" start: number; // first line's number, 1-based (default 1) }>): Command

toggleLineNumbers

Turn the section’s line numbering on (with the defaults) or off.

toggleLineNumbers(): Command

toggleSuppressLineNumbers

Toggle suppressLineNumbers on every suppressible block in the selection. Suppressed lines are skipped by the counter (Word semantics), not merely hidden. Pass suppress to force a value.

toggleSuppressLineNumbers(suppress?: boolean): Command

lineNumbersSuppressed

State reader, not a command: true when every suppressible block in the selection is suppressed.

lineNumbersSuppressed(state: EditorState): boolean

Headers & Footers

focusHeaderFooter

Select the content of the current section’s header or footer and set the headerFooterSyncPluginKey meta { openHeaderId, openFooterId }. It does not open the header/footer panel (nothing reads that meta), and on the main editor headerFooterGuardPlugin moves the selection back into the body. To open the panel, see Header & Footer.

focusHeaderFooter(focusOn: "header" | "footer"): Command

openHeader / openFooter

Set the headerFooterSyncPluginKey meta { openHeaderId: nodeId } / { openFooterId: nodeId }. Nothing reads it, so the panel does not open.

openHeader(nodeId: string): Command openFooter(nodeId: string): Command

setHeaderFooterDistance

Set the section’s headerFromTop / footerFromBottom (px). Pass sectionId when dispatching on the main editor while a header/footer sub-editor holds focus. Refused when nothing changes.

setHeaderFooterDistance(options: { headerFromTop?: number; footerFromBottom?: number; }, sectionId?: string): Command

insertHeaderFooterContent / deleteHeaderFooterContent

Add or remove a header_footer_content variant on both the section’s header and footer. Inserting adds one empty paragraph wherever the variant is missing. Deleting the "default" variant is refused. insertHeaderFooterContentTr(tr, state, sectionId, variant) in @stesura/core/commands/internal is the composable form.

type HeaderFooterVariant = "default" | "first" | "even"; insertHeaderFooterContent(sectionId: string, variant: HeaderFooterVariant): Command deleteHeaderFooterContent(sectionId: string, variant: HeaderFooterVariant): Command

insertPageNumberPreset

Insert a page number into a section’s header (top) or footer (bottom) as a Word-style preset: a borderless 1×3 table with left-, centre- and right-aligned columns. Creates the variant if needed, all in one transaction. Dispatch it on the main editor, not a header/footer sub-editor.

insertPageNumberPreset({ sectionId: string, variant?: HeaderFooterVariant, // default "default" position: { vertical: "top" | "bottom"; horizontal: "left" | "center" | "right" }, pageType?: "currentPage" | "totalPages" // default "currentPage" }): Command

fixHeadersFooters

Repair header/footer structure: resolve null and duplicate variants, mirror each variant on both header and footer (always including "default"), and give every content node at least one paragraph. Refused when nothing needs fixing.

fixHeadersFooters: Command

Which variants a section displays (different first page, odd/even) follows from which header_footer_content nodes exist, so insertHeaderFooterContent / deleteHeaderFooterContent toggle them — see Header & Footer.

Borders

Border commands (setBorders, toggleOutline, insertHorizontalRule) are documented on the tables page. They also apply to styled blocks and horizontal rules.

Track Changes

enableTrackChanges / disableTrackChanges / toggleTrackChanges

Turn track-changes recording on or off. The optional show argument also sets visibility at the same time. Omitted, turning tracking on also turns visibility on, and turning it off leaves visibility as it is. In review mode, disableTrackChanges and toggleTrackChanges return false.

enableTrackChanges(show?: boolean): Command disableTrackChanges(show?: boolean): Command toggleTrackChanges(show?: boolean): Command

toggleTrackChangesVisibility

Flip whether pending suggestions are displayed. Tracking itself is untouched — edits keep being recorded while the markup is hidden.

toggleTrackChangesVisibility: Command

selectTrackChanges

Move the selection to cover the tracked change with the given id — inline marks and block-level suggestions (a deleted row, a pending attribute change) alike.

selectTrackChanges(selectionId: string): Command

resolveTrackChanges

Accept or reject the suggestion under the cursor (or covering the selection). With an empty selection it resolves the whole same-user, same-burst change; a drawn selection resolves every suggestion it touches, in full. moveToNext jumps to the next suggestion afterwards.

Dry runs (toolbar probes) answer false on a document with no pending changes, so Accept/Reject buttons disable themselves when there is nothing to review — the same applies to resolveAllTrackChanges and disableTrackChanges, which return false rather than dispatching when they would change nothing.

resolveTrackChanges(action: "approve" | "reject", moveToNext?: boolean): Command

resolveAllTrackChanges

Accept or reject every suggestion in the document at once.

resolveAllTrackChanges(action: "approve" | "reject"): Command

Track Changes Marks

Tracked inline edits are stored as marks from @stesura/core/schema:

  • insertion: pending inserted text, rendered as <ins>.
  • deletion: pending deleted text, kept in the document and rendered as <del>.
  • modification: a pending inline mark change. type is "addMark" (newValue holds the added mark’s JSON) or "removeMark" (previousValue holds the removed one).

Each mark carries id, date, userId and userName. Block-level changes live on node attributes instead: trackChanges (block insertion or deletion) and trackChangesModification (attribute changes).

Next Steps

Last updated on