Skip to Content
CommandsCommands: Specialized

Commands: Specialized

Core commands for numbering, images, code blocks, the format painter, languages, style sheets, files and document attributes, plus the command sets that ship in the feature packs: comments (@stesura/comments), footnotes and cross-references (@stesura/references), and proofread (@stesura/proofread/commands).

import { toggleCounter, insertImageUpload, setLanguage } from "@stesura/core/commands"; import { insertPendingComment, insertComment } from "@stesura/comments"; import { insertFootnote, insertCrossReference, nextFootnote } from "@stesura/references"; import { toggleProofread, onProofreadReplace } from "@stesura/proofread/commands";

Footnotes & Endnotes

From @stesura/references.

insertFootnote

Insert a footnote anchor at the cursor, or at the end of a non-empty selection (which is kept, not replaced). Pass a ref to reuse an existing note, omit to mint a new one. onSuccess is called with the ref on dispatch only.

insertFootnote(footnoteRef?: string, onSuccess?: (ref: string) => void): Command

nextFootnote / previousFootnote

Navigate to the note following / preceding the cursor (wrapping).

nextFootnote(onSuccess?: (ref: string) => void): Command previousFootnote(onSuccess?: (ref: string) => void): Command

Navigate relative to a known note ref.

navigateFootnote(noteRef: string, direction: 1 | -1, onNavigate?: (ref: string) => void): Command

Endnotes have the exact same surface: insertEndnote, nextEndnote, previousEndnote, navigateEndnote. See References.

Numbering & Lists

Lists are reusable configs (listRef → levels) stored in the doc’s listConfigs attr; numbered blocks point at a config and a list instance (instanceId). See Numbering for the model.

toggleCounter

The list button (buttonType) or the format dropdown (levelFormat); pass exactly one. On a numbered block, pressing the same button again removes the numbering, the other button switches bullet ↔ number, and a format rewrites the level. On an unnumbered block it continues an adjacent matching list or starts a new one. On a range, it removes the numbering when every non-empty block is already numbered; otherwise it puts them all on one new instance.

toggleCounter(props?: { buttonType?: "number" | "bullet"; levelFormat?: LevelFormat; // { format, text, tabStop?, gender?, casing? } }): Command

adjustLevel

Move every numbered block in the selection one level deeper ("up") or shallower ("down"), or to an explicit level, which wins over direction. The level is clamped to the deepest level the list defines. "down" at level 1 removes the numbering. When a style-numbered paragraph’s target level is bound to a paragraph style, the change becomes a style switch (Word’s legal-template model).

adjustLevel({ direction?: "up" | "down"; level?: number }): Command

continueNumbering / restartNumbering

continueNumbering joins the selected instance to the nearest preceding item of the same list, so its counters carry on; it is refused when there is none. restartNumbering starts a fresh instance at the selected paragraph, and the rest of the list follows. Top-level items only.

continueNumbering: Command restartNumbering: Command

removeNumbering

Remove numbering from the numbered block at the selection, deleting its counter node.

removeNumbering: Command

setNumberingAttrs

Merge numbering attributes into every node of the selected list instance (same listRef + instanceId), not just the one under the cursor. To edit the level config itself, use updateNumbering.

setNumberingAttrs(attrs: Partial<NumberingAttrs>): Command

setFollowBy / setListTabStop

Set what follows the number, or the tab stop in px (null clears it), on the level config of the list at the selection. Writing the config rather than the node means the value carries into new instances and into DOCX export. A default or shared config is copied first, so only the selected instance changes.

setFollowBy(followBy: "tab" | "space" | "nothing"): Command setListTabStop(tabStop: number | null): Command

applyListRef

Apply an existing list config as direct numbering. With a collapsed selection it re-lists the caret block’s whole instance, or numbers an unnumbered block by joining an adjacent instance of the same list. With a range, every non-empty numberable block is numbered and keeps its own instance.

applyListRef(listRef: string): Command

updateNumbering

Save levels as a list config and move the listRef / instanceId instance onto it. An identical existing config is reused; a default or shared config is forked into a new listRef. Refused when the doc would not change.

updateNumbering({ listRef: string | undefined; levels: ILevelsOptions[]; instanceId: string | undefined; newListRef?: string; // precomputed target ref, for single-transaction composition }): Command

saveListConfigToDocAttrs / removeListConfig

Store or delete a list config in the doc’s listConfigs attr. The built-in default lists are seed values. Saving under a default ref stores a shadow that overrides the built-in for this document, while saving the built-in’s own values drops the shadow. Removing a default ref deletes the shadow and restores the built-in.

saveListConfigToDocAttrs(listRef: string, levels: ILevelsOptions[]): Command removeListConfig(listRef: string): Command

cleanupUnusedListRefs

Drop list configs that no node or style references, and default-ref shadows identical to the built-in.

cleanupUnusedListRefs: Command

Transaction Variants

From @stesura/core/commands/internal:

adjustLevelTr(props): TransactionFn applyListRefTr(listRef): TransactionFn cleanupUnusedListRefsTr: TransactionFn removeListConfigTr(reference): TransactionFn removeNumberingTr: TransactionFn saveListConfigToDocAttrsTr(listRef, levels): TransactionFn setNumberingAttrsTr(attrs): TransactionFn toggleCounterTr(props?): TransactionFn updateNumberingTr(props): TransactionFn

Images

insertImageUpload

Insert an upload placeholder that resolves into an image node once the upload completes. Refused inside code blocks and while an image is selected.

insertImageUpload: Command

resizeImage

Resize the selected image, block image or inline image_anchored.

resizeImage(size: { width: number; height: number }): Command

setImageAlignment

Align the selected image. On a floated (square/tight) anchored image, start/end set the float side; center and fullWidth apply to block images only.

setImageAlignment(align: "start" | "end" | "center" | "fullWidth"): Command

setImageToFullWidth

Scale the selected block image to the section’s content width, preserving its aspect ratio.

setImageToFullWidth(): Command

setImageWrap

Set the wrap mode, converting between the two image nodes when needed. "top-bottom" uses the block image node; every other mode uses the inline image_anchored node. Block → anchored moves the image into the adjacent textblock; anchored → block places it as the next block after its paragraph.

setImageWrap(wrap: "top-bottom" | "inline" | "square" | "tight" | "front" | "behind"): Command

setImageSide

Set which side a square/tight anchored image floats to.

setImageSide(side: "left" | "right"): Command

setImageAlt

Set an image’s alt text. The three states are exclusive: { alt: "…" } is meaningful, { decorative: true } is decorative (any alt is discarded), and { alt: null } is undeclared. Blank alt text counts as undeclared. Pass pos to target an image other than the selected one.

setImageAlt({ alt?: string | null; decorative?: boolean; pos?: number }): Command

resetAspectRatio

Resize the selected image back to its natural aspect ratio, keeping its width (or its height when the width is unknown).

resetAspectRatio(attrs: { aspectRatio: number | null; width?: number; height?: number }): Command

Code Blocks

insertCodeBlock

Insert an empty code block at the selection. Refused inside an existing one.

insertCodeBlock: Command

updateCodeBlockAttrs

Set one attribute on the code block at pos.

updateCodeBlockAttrs( attribute: "codeLanguage" | "theme" | "showLineNumbers", value: unknown, pos: number ): Command

splitCodeBlock

Split the code block after the caret’s line. Language, theme and line numbers carry over. Refused on the last line.

splitCodeBlock: Command

codeLanguage is the syntax-highlighting language, not to be confused with proofingLanguage, the block’s spell-check language set by setLanguage.

Comments

From @stesura/comments. See Comments for the full system.

insertPendingComment

Mark the current selection (or, when empty, the word at the caret) for a new comment. Triggers the comment composer UI.

insertPendingComment: Command;

insertComment

Anchor the pending comment with the created thread ID. Requires a non-empty pending selection.

insertComment(threadId: string | null): Command

insertPendingNodeComment / setNodeComment

Node-target counterparts: start a pending comment on a single node (image, table…), then attach the thread ID to it.

insertPendingNodeComment: Command setNodeComment(threadId: string | null): Command

closePendingComment

Cancel the pending comment without creating it.

closePendingComment: Command;

setSelectedThreadId

Select (or deselect with null) a thread, highlighting all its anchors.

setSelectedThreadId(threadId: string | null): Command

deleteCommentsWithThreadId

Delete all anchors for a thread — boundary anchors and node-comment entries. Skips header, footer and note subtrees; removeCommentAnchors covers the whole doc.

deleteCommentsWithThreadId(threadId: string | null): Command

removeCommentAnchors / healDanglingCommentAnchors

Lifecycle cleanup: remove anchors for a known set of thread IDs, or heal unbalanced/dangling anchors anywhere in the doc.

removeCommentAnchors(threadIds: ReadonlySet<string>): Command healDanglingCommentAnchors: Command

insertMention

Replace the “@query” text with a mention node plus a trailing space, in one transaction.

insertMention(match: MentionMatch, userId: string): Command

Cross-References

From @stesura/references.

insertCrossReference

Insert a reference to a heading or numbered item, replacing the selection.

insertCrossReference({ targetId: string, text: string, refTo: "default" | "fullContext" | "aboveBelow", separator: string | null // between levels of a fullContext reference }): Command

Table of Contents

insertTOC

Insert a toc node at the cursor. Refused inside tables.

insertTOC(): Command

Format Painter

enableFormatPainter

Arm the format painter with the formatting at the cursor: inline marks plus the textblock’s type and attrs. A source selection covering part of a single block captures the marks only. Refused in code blocks.

enableFormatPainter({ once: boolean }): Command // once: true → disarm after the first apply // once: false → stay armed until disableFormatPainter

applyFormatPainter

Paint the captured formatting onto the selection, or onto the word under a bare cursor, replacing existing marks except track-changes marks. Block type, numbering, indent, spacing, background, borders and style follow only when the target is a whole block, spans several blocks, or is a bare cursor. A partial selection inside one paragraph takes the character formatting only.

applyFormatPainter: Command

disableFormatPainter

Disarm the format painter and restore the default cursor.

disableFormatPainter: Command

Invisible Characters

toggleInvisibleCharacters / setInvisibleCharacters

Toggle, or set, the pilcrow / space / tab markers. Meta-only: the doc is untouched.

toggleInvisibleCharacters: Command setInvisibleCharacters(show: boolean): Command

Spell Check

Commands from @stesura/proofread/commands unless noted. See Proofread.

toggleProofread

Enable or disable spell checking. The flag is page-global: every editor on the page follows it.

toggleProofread: Command;

retryProofread

Re-check the whole document now, skipping the debounce and the failure backoff: the Retry button of the status bar and panel. Blocks with current cached results are not re-sent. Returns false when proofreading is off.

retryProofread: Command;

Language: three levels

A block’s language resolves as

paragraph.proofingLanguage ?? style.language ?? doc.language

This is Word’s chain (run ?? style ?? docDefaults). doc.language always answers, so resolution never fails. The middle level is a style field, not a command: set language on a style definition (Stylesheet panel, or submitStyleDefChange) and every block with that style follows it.

setDocLanguage

Set the document default, the level every unstamped, unstyled block follows, and the one written to docDefaults on DOCX export. Surfaced in the status bar’s language menu. Ships in core. Refused when unchanged.

setDocLanguage(language: string): Command // setDocLanguage("fr-FR")

setLanguage

Stamp proofingLanguage on the blocks in the selection, or pass null to drop the stamp and follow the style/document again. Ships in core (@stesura/core/commands), re-exported by the proofread pack.

setLanguage(language: string | null): Command // setLanguage("en-US") // setLanguage(null) // "follow document"

Both commands dispatch updateCounters, because spelled-out numbering formats (cardinalText, ordinalText) and cross-references render in the effective language. setLanguage does it only when a changed block is numbered or the doc holds a cross-reference.

getSelectionLanguage / getLanguageFromSelection

State readers from @stesura/core/helpers, not commands. They read the effective language at the selection. getSelectionLanguage also reports whether the selection states its language or inherits it, so the UI can show “French (inherited)”.

getSelectionLanguage(state: EditorState): { language: string | undefined; isExplicit: boolean } getLanguageFromSelection(state: EditorState): string | undefined

language is undefined only when the selection spans more than one language.

resolveLanguageAtPos

Also from @stesura/core/helpers. The same resolution for a single position, for code that has a pos rather than a selection.

resolveLanguageAtPos(state: EditorState, pos: number): string

onProofreadReplace

Replace the flagged text with a suggestion, keeping its non-track-changes marks, and select it. An empty value deletes the text. Takes the decoration it applies to — read it with getProofreadDecoInSelection(state) from @stesura/proofread/helpers.

onProofreadReplace(value: string, decor: ProofreadDecoration): Command

onProofreadIgnore

Ignore this one occurrence (applies the proofReadIgnore mark).

onProofreadIgnore(decor: Decoration): Command

onProofreadIgnoreAll

Ignore every whole-word, case-sensitive occurrence in the document.

onProofreadIgnoreAll(decor: Decoration): Command

onProofreadAddToDictionary

Add the flagged word to the user’s dictionary under the block’s language (primary subtag). Nothing is written to the document. Returns false unless the plugin was configured with createDictionary — see Proofread: user dictionary.

onProofreadAddToDictionary(decor: Decoration): Command

Style Sheets

See Style Sheets for the full model. Blocks reference their style through the styleId attr.

setStyleSheet

Apply a paragraph style to the paragraphs/headings in the selection, converting between paragraph and heading to match the style’s outline level. Refused for character styles, unknown ids and inside code blocks. deleteMarks: true always strips direct-formatting marks; "sameStyle" strips them only when every block in the range already has that style.

setStyleSheet(styleSheetId: string, deleteMarks?: true | "sameStyle"): Command // setStyleSheet("Normal") // setStyleSheet("Heading1")

replaceStyleDefIds

Re-point every paragraph/heading using one style at another (default "Normal"). Heading-ness follows the target style’s outline level. replaceStyleSheetIdsTr in @stesura/core/commands/internal is the transaction-level variant.

replaceStyleDefIds(prevStyleDefId: string | undefined, newStyleDefId?: string): Command

upsertStyleDefinition / createStyleDefinition / updateStyleDefinition

Write a style definition into the doc’s override map, which stores only the fields that differ from the default style sheet. Upserts deep-merge into the existing override; options.replace stores styleDef as the whole override instead. createStyleDefinition fails on an existing id and updateStyleDefinition on a missing one.

upsertStyleDefinition(styleId: string, styleDef: Partial<StyleDefinition>, options?: UpsertStyleDefinitionOptions): Command createStyleDefinition(styleId: string, styleDef: StyleDefinition): Command updateStyleDefinition(styleId: string, styleDef: Partial<StyleDefinition>): Command

submitStyleDefChange

Apply a style edit in one undoable transaction. A nullish currentStyleDefId creates the style. Equal ids replace the stored override, so omitted fields mean “cleared”. Different ids rename it, rewriting block refs and dependent styles’ basedOn/next. Renaming a default style is rejected.

submitStyleDefChange(currentStyleDefId: string | null | undefined, newStyleDefId: string, styleDef: StyleDefinition): Command

deleteStyleDefinition

Delete a custom style, re-pointing blocks and dependent styles at replaceWith (default "Normal"). Throws for a default style; those are reset, not deleted.

deleteStyleDefinition(styleDefId: string, replaceWith?: string): Command

setStyleNumberingBinding

Bind a paragraph style to a list level, or clear the binding with null. At most one style can hold a (listRef, level) slot, so any other style bound to it is reset.

setStyleNumberingBinding(styleId: string, numbering: StyleNumbering | null): Command

File Upload

insertFileUpload

Insert an upload placeholder that resolves into a file node. Refused inside code blocks and tables. With a file node selected, it inserts after it.

insertFileUpload: Command

File node commands

Position-based commands for the file node at pos:

setFileRotation(pos: number, rotation: number): Command // one of the four storable angles rotateFile(pos: number, delta: number): Command // quarter turn (90 or -90), wraps at 360 setFileDisplayPreview(pos: number, displayPreview: boolean): Command // preview vs card moveFileNode(pos: number, direction: -1 | 1): Command // one position among its siblings

applyFileNodeMove(tr, pos, direction) is the builder behind moveFileNode. It appends the move to tr and returns the node’s new position, or null when it cannot move.

Document Attributes

setDocAttr<K extends keyof DocAttrs>(attr: K, value: DocAttrs[K]): Command // refused when unchanged setDocBgColor(color: string): Command // canvas colour behind the pages (docBgColor) setDocDirection(dir: TextDirection): Command // default direction: paragraph.dir ?? section.dir ?? doc.dir

Next Steps

Last updated on