Paper@beaket/paper

API Reference

<Paper> props

Import from @beaket/paper/react. All props are optional.

PropTypeNotes
defaultValuestringInitial markdown document. Not live — the editor is uncontrolled; replace the whole doc via ref.setValue().
onChange(value: string) => voidFull markdown on user edits only. Fired once after IME composition settles; setValue does not echo back. No internal debounce.
highlightsHighlightInput[]Highlight/annotation ranges. Live prop — re-resolved on change (deferred during IME).
activeHighlightIdstring | nullThe hovered/selected highlight id. Live prop for declarative visual sync.
onHighlightStatusChange(m: Map<string, AnchorStatus>) => voidRe-resolution status of highlights (mainly on load/delete).
onHighlightClick(id: string) => voidA highlight was clicked — e.g. open a comment panel.
onSelect(sel: SelectionInfo | null) => voidSelection report { text, anchor, rect }, null when empty. Draw a floating toolbar from rect.
onInsertImageImageResolverDecides the URL for a dropped/pasted image. Upload/storage is yours. Default: in-session blob: URL.
slashItemsSlashItemsConfigCustomize the / menu. Array = full replacement; (defaults) => items = derive from defaults (recommended).
triggersTriggerSpec[]Custom autocomplete triggers beyond / — @ mentions, [[ wikilinks. Each { trigger, minQueryLength?, onQuery, onSelect? }; onQuery(q) returns items (sync or Promise) that insert a markdown string, with data handed back to onSelect. Fixed at creation.
tokensTokenSpec[]Render pattern-matched markdown (e.g. an inserted [@Name](user:id)) as an atomic token — the caret steps over it, one Backspace deletes it whole. Each { pattern, render }; render(match) => { label, className? }. The markdown stays the source of truth (round-trips on copy); identity comes from the capture groups. Fixed at creation.
codeBlockRenderersRecord<string, CodeBlockRenderer>Render registered fenced code blocks as widgets — e.g. a mermaid fence as a diagram. Keyed by fence language; off-cursor shows the rendered output, on-cursor the raw source. The editor ships no renderer — you inject (code, el, ctx) => void | Promise<void> (throw/reject shows error text). Unregistered languages stay normal code blocks. Fixed at creation.
colorScheme"light" | "dark" | "system"Live prop. "system" (default) follows the OS prefers-color-scheme; "light"/"dark" force the scheme. Flips without recreating the editor, so the document is kept.
placeholderstringHint shown on an empty document; hides once there is text. Fixed at creation.
readOnlybooleanLive prop. Disables typing, IME, image/table ingest, and table cell editing; native selection and the copy buttons keep working. Flips without recreating the editor.
heightstringFixed editor height (any CSS length, e.g. "25rem") — scrolls internally past it. Omit for grow-with-content. Fixed at creation.
minHeightstringMinimum editable height (any CSS length) — grows with content; the editable surface fills it, so clicking anywhere places a cursor (no dead zone). Fixed at creation.
classNamestringClass on the editor container element.

Imperative handle (ref)

The ref exposes a PaperHandle:

MethodReturnsNotes
getValue()stringCurrent markdown document.
setValue(md)voidReplace the whole document. Deferred until an active IME composition settles. Does not fire onChange.
focus()voidFocus the editor.
getSelection(){ from, to, text } | nullCurrent selection in source coordinates; null when empty.
getView()EditorView | undefinedEscape hatch — the raw CodeMirror 6 EditorView. No cross-version guarantees. Returns undefined until the view has mounted, so a ref callback can guard with const v = h.getView(); if (!v) return;.

Core createEditor(parent, options)

The vanilla core takes the mount element and an EditorOptions object, returning a PaperEditor handle (below). These options are the editor's own surface; highlights, activeHighlightId, and className are React-wrapper additions, not core options:

OptionTypeNotes
docstringInitial markdown document. Empty if omitted. (The React wrapper exposes this as defaultValue.)
onChange(value: string) => voidSame contract as in the props table above.
onInsertImageImageResolverImage placement resolver.
slashItemsSlashItemsConfigSlash-menu customization.
triggersTriggerSpec[]Declarative @ / [[ autocomplete triggers (async onQuery; declarative insert). Same in core and React.
tokensTokenSpec[]Atomic token rendering — pattern-matched markdown rendered inline (link visual language by default) as atomic units the caret steps over (declarative render). Same in core and React.
codeBlockRenderersRecord<string, CodeBlockRenderer>Consumer-delegated code-block rendering — a registered fence (e.g. mermaid) renders as a widget off-cursor, raw source on-cursor. The editor ships no renderer; you inject one. Same in core and React.
colorScheme"light" | "dark" | "system"Light/dark scheme. Flip live (without recreating) via editor.setColorScheme(scheme).
placeholderstringHint shown on an empty document. Fixed at creation.
readOnlybooleanRead-only mode. Flip live via editor.setReadOnly(readOnly). Disables editing/ingest; copy + selection still work.
height / minHeightstringExplicit sizing (CSS lengths). height = fixed with internal scroll; minHeight = grow-with-content floor (the editable surface fills it). Same in core and React.
onSelect(sel: SelectionInfo | null) => voidSelection report.
onHighlightStatusChange / onHighlightClickcallbacksHighlight surface. The highlight list is set imperatively via editor.setHighlights(list).

The PaperEditor handle

Every method is IME-safe: a call made during a composition is held and applied once it settles.

MethodNotes
getValue()The full markdown document.
setValue(md)Replace the whole document. Does not echo through onChange.
focus()Focus the editor.
getSelection(){ from, to, text } in source coordinates, or null on an empty selection.
setHighlights(list)Replace the highlight list (HighlightInput[]).
setActiveHighlight(id)Set the active highlight id, or null.
setColorScheme(scheme)Flip light/dark/system without recreating the editor.
setReadOnly(readOnly)Flip read-only mode without recreating the editor.
getView()The underlying CodeMirror EditorView. Unsafe — no cross-version guarantees.
destroy()Tear the editor down. Do not call the handle afterwards.

Styling →