Skip to Content
API Referenceeditor-react

@stesura/editor-react

The editor shell: the StesuraEditor component, the mount hooks that produce its state, and the hooks the editor UI is built from.

Entry pointContents
.StesuraEditor, FlowEditor, EditorLoadingState, mount hooks, state and toolbar-state hooks, providers, node views, floating menus, sub-editor building blocks, and the public types.
/toolbarToolbar components, kept off the root so the default toolbar lazy-loads: see Customizing the Toolbar.
/dropuseEditorDrop (needs react-dnd).

Guides: Getting Started for mounting, Customizing the Editor for the toolbar, menu and extension APIs.

Mount hooks

Mount hooks read currentUser from StesuraUserProvider and throw outside it.

useLocalEditor(args?)

In-memory editor state, no backend. Returns { editorState, dispatch, pluginFactory, schema }, the same shape as the collab mount hooks, so backends are interchangeable.

ArgTypeDefaultPurpose
editorIdstring"default"Editor id. Must match StesuraEditor’s field. Also registers the dispatch for getEditorDispatchById.
schemaSchemastesuraSchema()Read once at mount.
initialContentContent | Node | Fragment | JSONContentempty docRead once at mount. HTML strings are parsed with the DOM, so browser only.
configurationConfigPluginPropsForwarded to core’s configPlugin.
pluginOptionsStesuraPluginsOptionsToggles forwarded to stesuraPlugins.
extraPlugins({ editorId, parentEditorId? }) => Plugin[]Feature-pack plugins. Called for the main editor and for each sub-editor.
transactionModifierTransactionModifierFnRuns on every dispatch (e.g. trackChangesTransactionModifier). The latest value is used.

The main state’s plugins are built once. Later changes to configuration, pluginOptions or extraPlugins only reach sub-editors created afterwards.

On mount the hook also dispatches one normalizing transaction that heals out-of-range attributes and runs the derived passes (numbering, cross-references).

useEditorCore(args)

The base hook behind every mount backend (useLocalEditor, useCollabEditor, useLocalCollabEditor). Takes editorId, schema, configuration, pluginOptions, extraPlugins and transactionModifier, as above, and returns:

FieldPurpose
schemaThe schema, resolved once per mount.
pluginFactoryStable PluginCallback.
dispatch(tr) => void. Pass it to the editor’s dispatchTransaction.
dispatchBuild(build: (state) => Transaction | null | undefined) => void. Runs build inside the state updater, against the state the transaction is applied to. build must be pure: StrictMode calls it twice.
applyRemote(updater: (state) => EditorState) => void. Applies a state change that didn’t come through the view, such as received collab commits, and flushes it synchronously. Skips the mode gate, guard and modifier.
setStateRefAssign your backend’s setState to setStateRef.current in a layout effect.

Every dispatch drops local document changes in "view" mode, runs the attr-bounds guard, then calls transactionModifier(state, tr, currentUser, forceTrackChanges). forceTrackChanges is true for local transactions in "review" mode. dispatch and dispatchBuild are stable; the latest currentUser and transactionModifier are read per dispatch.

The view flushes its own dispatches synchronously (react-prosemirror), so view.state never lags the backend’s state. Anything that changes the state from async code (a promise, timer or socket callback) must flush too, or a keystroke typed before that update renders is dropped as mismatched. Use applyRemote, or getEditorDispatchById, which flushes for you.

useStesuraPluginFactory(args)

Just the plugin factory, for hosts that own their EditorState. Takes { schema, configuration?, pluginOptions?, extraPlugins? } and returns a permanently stable PluginCallback that builds the core plugins plus extraPlugins. Inputs are read on each call.

StesuraEditor props

Type: StesuraEditorProps from @stesura/editor-react.

PropTypeDefaultPurpose
state (required)EditorState | nullnull while the mount initialises; the toolbar and a skeleton render meanwhile.
dispatchTransaction (required)(tr) => voidThe mount hook’s dispatch. If it throws, the edit is dropped and an error toast shown.
schema (required)SchemaMust match the schema state was created with.
pluginFactory (required)PluginCallbackBuilds plugin sets for sub-editors. Read once at mount; pass the mount hook’s.
fieldstring"default"Editor id. Must match the mount hook’s editorId (dev warns on a mismatch). Read once: to switch documents, remount with a key.
transactionModifierTransactionModifierFnModifier for sub-editors (headers/footers, notes), read once at mount. The main editor’s modifier goes to the mount hook, so pass the same one to both.
mode"edit" | "review" | "view""edit""review": every local edit becomes a tracked suggestion, whatever the user’s toggle; throws if the track-changes plugin is not mounted. "view": read-only; local document changes are dropped at dispatch, remote collab changes still apply. See Editor modes.
editablebooleantrueDeprecated. editable={false} maps to mode="view". mode wins when both are set.
toolbarReactNode | falsebuilt-inA custom toolbar, or false for none. The built-in toolbar is lazy-loaded, so replacing it skips its chunk.
printModebooleanfalseChrome-less render for PDF/print capture: no toolbar, panels, zoom or scroll area. Also on when the state’s printMount config is set.
layout"page" | "flow""page""flow": one full-width block flow, no pages. Also on when the state’s layout config is "flow", which must be set too. Read once. See Flow Layout.
onFileUpload(file, type, contentType?) => Promise<string | undefined>Uploads a file and resolves to the URL to embed. Used by upload blocks and for images in imported DOCX files. contentType is sniffed from the file’s magic bytes: store with it, not with file.type, which the client controls. See File & Image Uploads.
onContentFocus(editorId, event) => voidFires when a document surface (main or sub-editor) receives focus.
nodeViewsNodeViewsNode views by node type name. Override built-in and extension views. Must be a stable reference.
uiExtensionsStesuraUIExtension[]Feature-pack UI: panels, toolbar groups, menus, node views. Must be a stable reference.
defaultLeftPanelsPartial<Record<LeftPanelDefaultAction, false>>Built-in left panels to remove, e.g. { toc: false }. Opening a removed panel’s action shows the “Error in panels” fallback.
defaultRightPanelsPartial<Record<RightPanelDefaultAction, false>>Built-in right panels to remove: "format paragraph", "style sheet", "toc settings", "accessibility".
contextMenuDefaultsPartial<Record<ContextMenuKey, false>>Built-in context menus to remove, e.g. { table: false }. See Customizing the Menus.
floatingMenuDefaultsPartial<Record<DefaultFloatingMenuKeys, false>>Built-in floating menus to remove: textFormat, link, slash, math.
slashMenuDefaultsPartial<Record<SlashMenuBuiltInKey, false>>Built-in slash-menu items to remove, e.g. { table: false }.
textMenuDefaultsPartial<Record<TextMenuKey, false>>Built-in text-format popup buttons to remove, e.g. { formatPainter: false }.
TabsReactNodeTab bar above the document.
messagesEditorMessage[]Message bars attached under the ribbon, like Word’s (id, variant: info/success/warning/error, title, message, actions, onDismiss). Stable reference.
userPreferencesPartial<UserPreferences>Preference defaults, applied once on first mount. Keys already in localStorage are kept.
localeSupportedLocale"en"UI locale. Other locales load as separate chunks.
iconSetIconSetFluentIcon geometry; classicIcons from @stesura/icons/classic for the classic set.

EditorLoadingState renders the editor’s loading skeleton and is safe to import statically, e.g. as the loading fallback of a dynamic() import. Pass it the same toolbar value as the editor: with the default toolbar it also prefetches the toolbar chunk.

StesuraUserProvider

Required above StesuraEditor and the mount hooks. useStesuraUser() reads it. useCurrentUser() returns only currentUser, and undefined outside the provider instead of throwing.

PropTypePurpose
currentUser{ id, name?, avatar?, color? }Author of comments and tracked changes, collab presence identity.
resolveUsers({ userIds }) => Promise<{ name, avatar? }[]>Resolves ids to display data. Results are index-aligned with userIds.
resolveMentionSuggestions({ text }) => Promise<string[]>User ids matching an @ mention query. Without it the mention dropdown never opens.

Panel controls

Programmatic open/close for the three panel areas that uiExtensions populate:

import { useLeftPanelControls } from "@stesura/editor-react"; const { isLeftPanelOpen, leftPanelAction, openLeftPanel, closeLeftPanel, toggleLeftPanel, setLeftPanelAction } = useLeftPanelControls();
HookReturns
useLeftPanelControls(){ isLeftPanelOpen, leftPanelAction, openLeftPanel(action), closeLeftPanel(), toggleLeftPanel(action), setLeftPanelAction(action) }
useRightPanelControls()The same with RightPanel names, where openRightPanel(action, meta?) and closeRightPanel({ skipGuard? }), plus the unsaved-changes guard: guard, setGuard(fn), resetGuard(), checkGuard, pendingAction, executePendingAction(), cancelPendingAction().
useBottomPanelControls()The same with BottomPanel names.

action is the key a panel registered under (leftPanels[].action, …). Toggling with a different action switches panels instead of closing.

Each hook is also split in two: use…PanelActions() returns only the actions, is stable and doesn’t subscribe (use it when you only open or close), and use…PanelState() returns only the state. Panel state is shared by every editor on the page.

A right-panel guard is () => boolean. When it returns false, the open, close, toggle or action change is stored as pendingAction instead; executePendingAction() replays it once the user confirms.

User preferences

Global, persisted to localStorage and shared by every editor on the page. Keys are those of UserPreferences (@stesura/core/types): showOutline, showRuler, zoomLevel, trackChanges, showComments, displayUnits, proofReadEnabled, …

HookPurpose
useUserPreferenceValue(key)Subscribes to one preference.
useSetUserPreference(key)Stable setter, no subscription. Takes a value or an updater function.
useUserPreference(key)[value, setter].
useShowOutline()Whether table outlines render in the surrounding editor: the showOutline preference, forced on in header/footer editors, always off in print mode.

Search navigation

Lets a search match inside a hidden region (footnote and endnote bodies, headers and footers, comments) open the panel or sub-editor that displays it.

ExportPurpose
usePublishSearchNavigation()Returns a publisher. Call it with the editor state right after a find/replace command moved the selection to a match, or with null when search closes.
useSearchNavigationTarget()The current SearchNavigationTarget ({ region, from, to, nav }) or null. from/to are main-document positions; nav increments on every navigation.
useSearchRegionListener(config)Drives a panel from navigation. config is { match(region), onEnter(key, target), onLeave() }: match returns a stable key for regions the panel owns, else null. onEnter fires on every navigation inside the region, so it must be idempotent. Mount it next to the panel it drives.

i18n

HookPurpose
useT()Translation map for the active locale. Re-renders on locale change.
useLocale()Active locale code.
useApplyLocale(locale)Loads and applies a locale for the whole page, falling back to English if loading fails. StesuraEditor already calls it with its locale prop.

Setup and utility hooks

useLocalEditor, useEditorCore, useStesuraPluginFactory, useT, useLocale, useApplyLocale, useDirection, useEditorStateSelectorEq, useIsCompactLayout, useReportNodeResize, useAutomaticColorPickerLabels, usePdfPreviewCapability, usePdfPreviewConfig, preserveNodeViewKey, toastText. Types: UseLocalEditorArgs, UseEditorCoreArgs.

/drop subpath

Drops from external react-dnd sources onto the canvas. A separate entry point so react-dnd stays out of bundles that don’t use it. The editor does not render a DndProvider; put one above it.

ExportPurpose
useEditorDrop({ view, field, accept, onDropCallback, canDropCallback? })Returns the drop ref to attach. accept lists react-dnd item types. onDropCallback({ view, pos, pointerPos, item, field }) returns { dropped: true } when it handled the drop. pos is the pointer position moved to the nearest body edge when it sits between section parts or between sections, so a block inserted there can never split a section; pointerPos is the raw position. Where there is no target (a hidden header or footer), canDrop is false and react-dnd shows no-drop. onDropCallback isn’t called in a read-only view or after a nested target handled the drop. canDropCallback takes the same argument; omitted means every drop is valid.
dropPositionFromMonitor(view, monitor)Document position under the drag pointer, or null. 0 is a valid position.

Sub-editors

Building blocks for nested editors (header/footer, footnote and endnote panels). A sub-editor mirrors one region of the main document in both directions and builds its own plugin instances from your pluginFactory. The built-in panels use it; you only need it for a custom panel over a document region. Exports: useSubEditor, useSubEditorSchema, useSubEditorPlugins, useSubEditorNodeViews, useSyncSearchMatch, SubEditorRegister, FocusOnOpen, FocusOnRequest.

Also on the root barrel

  • Toolbar state hooks (useRunTbCommand, probes, selectors, bound-editor hooks): Customizing the Toolbar.
  • Floating-menu hooks and components: Customizing the Menus.
  • Node-view helpers (useStesuraNodeView, useNodeViewSlots, stesuraNodeViews): Node Views.
  • Mode hooks (useSetEditorMode, useEditorStoreValue): Editor modes.
  • Per-editor registries for multi-editor hosts: useEditorStateById, useEditorViewById, useCurrentRootEditorId, useHeaderFooterEditing.
  • getEditorDispatchById(id): the mounted editor’s dispatchBuild, or null. For dispatching outside event handlers, including async code: getEditorDispatchById("default")?.((state) => state.tr.insertText("Hi")). The update is flushed synchronously, so don’t call it during render or from a React effect.
  • SearchBar, ProseMirrorDoc, and the layout pieces (EditorResizableLayout, EditorLeftPanel, EditorRightPanel, PanelLayout) for custom shells.

Editor state

Inside an editor (EditorProvider) the hooks read that editor; the ById variants take an id. Render on the debounced state; read the immediate state (the getters) in handlers and commands.

useDebouncedEditorState

Debounced state of the surrounding editor (EditorProvider).

Parameters:
This function does not accept any parameters.
Returns:
EditorState | null

useGetEditorState

Returns a non-subscribing getter for the surrounding editor’s state.

Parameters:
This function does not accept any parameters.
Returns:
() => EditorState | null

useEditorDebouncedStateById

Debounced state of the editor with that id, or null; the by-id counterpart of useDebouncedEditorState.

Parameters:
NameTypeDefault
idstring
Returns:
EditorState | null

useGetEditorStateById

Non-subscribing counterpart of useEditorStateById.

Parameters:
This function does not accept any parameters.
Returns:
(id: string) => EditorState | null

Current main editor

For chrome outside any editor provider: these follow the current main editor (useCurrentRootEditorId).

useCurrentRootEditorState

Re-renders on every transaction; prefer useCurrentRootEditorDebouncedState for UI.

Parameters:
This function does not accept any parameters.
Returns:
EditorState | null

useCurrentRootEditorDebouncedState

Debounced state of the current main editor, for chrome rendered outside any editor provider.

Parameters:
This function does not accept any parameters.
Returns:
EditorState | null

useGetRootEditorState

Returns a non-subscribing getter for the current main editor’s state. For actions like docx export that must ignore a bound sub-editor.

Parameters:
This function does not accept any parameters.
Returns:
() => EditorState | null

useRootEditorEventCallback

Wraps callback into a stable event handler that runs against the current main editor’s view.

Parameters:
NameTypeDefault
callback(view: EditorView, ...args: T) => R
Returns:
(...args: T) => R | undefined

Editor views

useParentView

View of the surrounding editor; null for sub-editors, whose views aren’t exposed.

Parameters:
This function does not accept any parameters.
Returns:
EditorView | null

useGetParentView

Non-subscribing counterpart of useParentView.

Parameters:
This function does not accept any parameters.
Returns:
() => EditorView | null

useEditorViewsCallback

Wraps callback to run against the FIRST registered main editor view; it does not fan out despite the name. Meant for single-editor pages; with several editors use useGetEditorViewById.

Parameters:
NameTypeDefault
callback(view: EditorView, ...args: T) => R
Returns:
(...args: T) => R | undefined

Dispatch

The builder getEditorDispatchById and useEditorCore’s dispatchBuild take.

BuildTransactionFn

Builds a transaction from the authoritative state; return null/undefined to dispatch nothing.

Parameters:
NameTypeDefault
stateEditorState
Returns:
Transaction | null | undefined

Editor context

Read the editor a component renders in.

useEditorId

Id of the surrounding editor (EditorProvider): the main editor’s field, or a sub-editor’s own id. Throws outside a provider.

Parameters:
This function does not accept any parameters.
Returns:
string

useRootEditorId

Id of the main editor this component renders under, also from inside a sub-editor. Throws outside StesuraEditor.

Parameters:
This function does not accept any parameters.
Returns:
string

useOptionalRootEditorId

Root editor id, or undefined outside a provider, for callers whose work is optional.

Parameters:
This function does not accept any parameters.
Returns:
string | undefined

useEditorSetup

The mount’s schema, pluginFactory, transactionModifier and onFileUpload. Throws outside an editor; useSchemaHasNode is the safe check for a node.

Parameters:
This function does not accept any parameters.
Returns:
EditorSetupContextType

useSchemaHasNode

Whether the mount’s schema has the node, for UI that inserts it (see excludeNodes). Outside an editor, e.g. in a toolbar shared across editors, it asks the bound editor’s schema; true while no editor is bound.

Parameters:
NameTypeDefault
namestring
Returns:
boolean

useIsFlowLayout

Whether this is a layout: "flow" mount: no pages, one full-width block flow. Resolved by StesuraEditor from the layout config or prop. False outside a provider.

Parameters:
This function does not accept any parameters.
Returns:
boolean

useGlobalDOMAttributes

Global-attribute DOM renderers for the mount’s schema, keyed by node name, for custom node views that render global attributes themselves. Throws outside StesuraEditor.

Parameters:
This function does not accept any parameters.
Returns:
GlobalDOMAttributesMap

OnFileUploadCallback

Uploads a file and resolves to its public URL.

Parameters:
NameTypeDefault
fileFile
uploadType"document" | "image"
contentTypestring

Type sniffed from the file’s magic bytes. Store with this, not file.type, which the client controls.

Returns:
Promise<string | undefined>

Editor store

useSetEditorStore

Setter for one of an editor’s core stores (value or (prev) => next), resolving the editor like useEditorStoreValue.

Never subscribes and returns a stable setter: the fallback id is read at call time, since useCurrentRootEditorId() would re-render the caller and change the setter’s identity.

Parameters:
NameTypeDefault
atomKeyK
editorIdstring
Returns:
(value: AtomValue<FullEditorStores[K]> | ((prev: AtomValue<FullEditorStores[K]>) => AtomValue<FullEditorStores[K]>)) => void

Floating menus

Building blocks for menus mounted inside the editor. See Customizing the Menus.

useEditorFloatingMenu

Positions a floating menu on a virtual element derived from the selection (top-centre by default, or getPositionReference) and wires dismissal. Render the result through FloatingMenuShell.

Parameters:
NameTypeDefault
__0EditorFloatingMenuOptions
Returns:
{ refs: { reference: MutableRefObject<ReferenceType | null>; floating: MutableRefObject<HTMLElement | null>; setReference: (node: ReferenceType | null) => void; setFloating: (node: HTMLElement | null) => void; } & ExtendedRefs<...>; floatingStyles: CSSProperties; getFloatingProps: (userProps?: HTMLProps<...> | undef...

EditorFloatingMenuOptions

Options for useEditorFloatingMenu and FloatingMenuShell.

NameTypeDefault
onClose() => void
placementPlacement
offsetnumber
strategyStrategy
getPositionReferencePositionReferenceCallback
role"none" | "dialog" | "alertdialog" | "tooltip" | "menu" | "listbox" | "tree" | "grid"

ARIA role for the floating element. Use Floating UI supported roles, or “none” to skip useRole (e.g., for toolbar).

anchorElementHTMLElement | null

Anchors to this element instead of the selection while set.

FloatingMenuShell

Portaled container for a selection-anchored floating menu (see useEditorFloatingMenu).

Parameters:
NameTypeDefault
__0{ children: ReactNode; floatingMenuOptions: EditorFloatingMenuOptions; manageFocus?: boolean; initialFocus?: number | RefObject<HTMLElement>; } & Omit<...>
Returns:
ReactPortal

FloatingMenuToolbar

Roving-tabindex toolbar for floating menu buttons.

Parameters:
NameTypeDefault
__0{ children: ReactNode; orientation?: "horizontal" | "vertical"; } & Omit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">
Returns:
Element

useEditorIsDisabled

Whether the editor view is non-editable. Not state-subscribed on purpose: re-reading a near-constant flag per transaction would re-render every menu item per keystroke.

Parameters:
This function does not accept any parameters.
Returns:
boolean

useCloseAllMainEditorFloatingMenus

Closes the root editor’s menus when isOpen turns true. Use in the sub-editor’s panel, not inside the sub-editor.

Parameters:
NameTypeDefault
isOpenboolean
Returns:
void

Enabled flags for menu items, computed once per state. The toolbar uses defineToolbarProbes instead. useMatchOnNode and the selectors nodeMatcher builds return a NodeMatch: { node, pos }, or undefined.

defineMenuCanRun

Enabled-state bundle for a menu’s commands, dry-run once per state. Call at module scope. Command args must not affect the result (e.g. setTableAlignment("start")); otherwise build MenuCanRun by hand with memoizeByState + nodeMatcher.

Parameters:
NameTypeDefault
commandsT
Returns:
MenuCanRun<keyof T & string>

useMenuCanRun

Re-renders only when a flag flips. All-false while the view is non-editable.

Parameters:
NameTypeDefault
canRunMenuCanRun<K>
Returns:
Readonly<Record<K, boolean>>

Enabled-state bundle for a menu: select maps a state to per-command flags; allFalse is the disabled answer.

NameTypeDefault
select(state: EditorState | null) => Readonly<Record<K, boolean>>
allFalseReadonly<Record<K, boolean>>

nodeMatcher

The node at selection.from if of the given type, else the nearest ancestor of that type. Memoized per (type name, state).

Parameters:
NameTypeDefault
nodeTypeNamestring
Returns:
(state: EditorState | null) => NodeMatch

useMatchOnNode

nodeMatcher as a hook; re-renders only when the matched node or its position changes.

Parameters:
NameTypeDefault
nodeTypeNamestring
Returns:
NodeMatch

nodeMatchEq

Reference equality is enough: untouched PM nodes keep their identity across transactions.

Parameters:
NameTypeDefault
a{ node: Node; pos: number; }
b{ node: Node; pos: number; }
Returns:
boolean

Built-in context menus

The components behind each ContextMenuKey. A ContextMenuExtension that reuses a key replaces that menu, so render the built-in inside your element to extend it rather than replace it.

The paragraph, toc, callout, floatingBox and floatingObject menus don’t check where the click landed; the built-in slot gates them with appliesTo. Give a replacement that renders one of them its own appliesTo.

KeyComponent
baseBaseContextMenu
linkLinkContextMenu
imageImageContextMenu
tableTableContextMenu
codeBlockCodeBlockContextMenu
paragraphParagraphContextMenu
tocTocContextMenu
calloutCalloutContextMenu
floatingBoxFloatingBoxContextMenu
floatingObjectFloatingObjectContextMenu

Toolbar

On the /toolbar subpath. See Customizing the Toolbar.

ToolBar

Ribbon toolbar with tabs, density toggle and search bar. tabs replaces the default tabs; a tab’s focusKey auto-activates it when the key changes.

Parameters:
NameTypeDefault
propsToolbarProps
Returns:
ReactNode

InsertCalloutButton

Insert-tab dropdown: wraps the selected blocks in a callout of the picked kind.

Parameters:
NameTypeDefault
props{}
Returns:
ReactNode

InsertFloatingBoxButton

Insert tab: a text box at the caret, opened with the caret inside.

Parameters:
NameTypeDefault
props{}
Returns:
ReactNode

floatingBoxProbes

Enabled-state probes for the text box buttons.

NameTypeDefault
insertTbProbe
setAttrsTbProbe
setTextAnchorTbProbe
editTbProbe
unwrapTbProbe
removeTbProbe

floatingBoxSelectors

Selected text box state (id, placement, …) for the text box buttons.

NameTypeDefault
idTbSelector<string | null>

The selected box’s id, for the contextual tab and keyed drafts.

placementTbSelector<{ wrap: string | null; side: FloatSide; } | null>

wrap plus the side a floated box sits on.

widthTbSelector<number | null>
heightTbSelector<number | null>
heightRuleTbSelector<FloatingBoxHeightRule | null>
outlineColorTbSelector<string | null>
outlineWidthTbSelector<number | null>
fillTbSelector<string | null>
paddingTbSelector<FloatingBoxPadding | null>
verticalAlignTbSelector<FloatingBoxVerticalAlign | null>
labelTbSelector<string | null>

Layout and scrolling

BottomPanelWrapper

Wraps the canvas in a vertical split with the bottom panel (bottomPanels from props and extensions), for custom shells. Renders children alone when there are no bottom panels or on compact viewports.

Parameters:
NameTypeDefault
__0{ children: ReactNode; }
Returns:
Element

useStatusBarCollapsed

Whether the status bar is out of room and entries should show their compact form.

Parameters:
This function does not accept any parameters.
Returns:
boolean

scrollCaretIntoView

Scrolls the selection head into view with PM’s threshold/margin semantics, against the current layout. Instant, via adjustScrollTarget. Vertical only: pagination never moves content sideways.

Parameters:
NameTypeDefault
viewEditorView
viewportHTMLElement
tagScrollClaimTag
Returns:
void

scrollElementIntoMainViewport

Eases the main viewport so el’s top sits topOffsetPx (visual px) below its top. Unlike el.scrollIntoView({smooth}), it doesn’t scroll every scrollable ancestor and survives direct scrollTop writes. Falls back to native scrollIntoView when el has no main viewport. label names the tween in the scroll ledger.

Parameters:
NameTypeDefault
elHTMLElement
topOffsetPxnumber
durationMsnumber
labelstring
Returns:
void

Scroll ledger

Every scrollTop change of the main viewport is recorded with the writers that claimed it, so a jump nobody claimed can be traced. Each ScrollLedgerEntry lists its ScrollClaims (the writer’s ScrollClaimTag, with its ScrollReason, and the delta it moved), the residual nobody claimed and a ScrollVerdict: unexpected for an unclaimed move, suspicious for an anchor correction of more than half a screen with no edit above the anchor. The e2e suite fails on either.

getScrollLedger

The recorded scrolls of viewport, oldest first (the last 256).

Parameters:
NameTypeDefault
viewportHTMLElement
Returns:
ScrollLedgerEntry[]

clearScrollLedger

Parameters:
NameTypeDefault
viewportHTMLElement
Returns:
void

Drop

dropTargetFromMonitor

The drop position under the pointer, snapped like the editor’s own drops: a position between section parts or between sections moves to the body edge nearest the pointer, and one inside a hidden header, footer or note container is null. pointerPos is the raw position.

Parameters:
NameTypeDefault
viewEditorView
monitorPointerMonitor
Returns:
{ pos: number; pointerPos: number; } | null
Last updated on