Skip to main content

API

ApollonEditor is the only class you construct. It mounts its own React tree into the DOM node you hand it and exposes an imperative API — your host code never touches React.

import { ApollonEditor, UMLDiagramType } from "@tumaet/apollon"
import "@tumaet/apollon/style.css"

const editor = new ApollonEditor(container, {
type: UMLDiagramType.ClassDiagram,
})

For internals (node/edge components, etc.), read dist/index.d.ts.

React hosts do not construct ApollonEditor directly — they render the <Apollon> component instead. The imperative class documented below remains the API for non-React hosts and for advanced control.

<Apollon> React component​

For React hosts, <Apollon> wraps ApollonEditor and owns its lifecycle: it constructs the editor on mount and destroys it on unmount. Import it from the package's main entry, @tumaet/apollon — see React for the full integration story (hooks, provider, ref, controlled-model overlay).

import { Apollon } from "@tumaet/apollon"
import "@tumaet/apollon/style.css"
;<Apollon style={{ height: 600 }} />

ApollonProps​

Container, lifecycle, and two layers of editor options.

Container. className, style (needs an explicit non-zero height), and children rendered inside the editor's context provider. Omitting children renders the default palette, zoom, and minimap; passing children makes the chrome composition explicit, so include <ApollonDefaultControls /> when custom children should keep the default controls.

Theming. theme (a --apollon-* token object, typically from createApollonTheme(...)) and dataTheme ("light" | "dark") are spread onto the mount node's style / data-theme on every render, so they are reactive in the React wrapper. See Theming.

Initial-only options — snapshotted at mount, ignored if they change afterwards. Re-key the component to apply them to a new editor.

PropTypeEffect
defaultModelUMLModelInitial diagram.
defaultTypeUMLDiagramTypeInitial diagram type when no defaultModel is supplied.
defaultModeApollonModeInitial mode — Modelling, Assessment, or Exporting.
defaultViewApollonViewInitial view.
availableViewsApollonView[]Views the user may switch between at runtime.
enablePopupsbooleanEnable inline edit/property popovers.
collaborationEnabledbooleanOpt into Yjs real-time sync; wire the transport from onMount.
collaborationApollonCollaborationOptionsFine-grained collaboration config (user identity + per-feature presence/cursor/follow toggles). Superset of collaborationEnabled.
debugbooleanDebug overlays/logging.

Reactive options — applied via the matching setter when the prop changes; no rebuild. Passing undefined for any reactive prop leaves the live value untouched (no reset). Re-key the component to fully reset.

PropTypeMaps to
readonlybooleaneditor.setReadonly(value)
viewApollonVieweditor.view = value
modeApollonModeeditor.setMode(value)
scrollLockbooleaneditor.setScrollLock(value)
keyboardShortcutsbooleaneditor.setKeyboardShortcuts(value)
labelsPartial<ApollonLabels>editor.setLabels(value)
tagsboolean | TagOptionseditor.setTags(value)
previewModebooleaneditor.setPreviewMode(value)
modelUMLModeleditor.model = value — controlled overlay

Lifecycle.

PropTypePurpose
onMount(editor) => void | (() => void)Fires once after mount. The optional returned function runs as cleanup before destroy.
refRef<ApollonEditor | null>Receives the editor after mount; nulled on unmount.

Hooks​

HookReturnsPurpose
useApollonEditor()ApollonEditor | nullThe editor for the nearest <Apollon> / <ApollonProvider>.
useApollonEditorOrThrow()ApollonEditorSame, but throws if no editor is mounted.
useApollonSubscription<T>(subscribe, getSnapshot)T | undefinedSubscribe to any editor.subscribeTo* channel with one call.
<ApollonProvider editor={...}>—Supply an externally-owned editor to descendants via context.

Constructor​

new ApollonEditor(element: HTMLElement, options?: ApollonOptions)

element must be an HTMLElement — the constructor throws Error("Element is required to initialize Apollon") otherwise. The element must have an explicit height; see Quickstart and Troubleshooting.

ApollonOptions​

Every field is optional.

OptionTypeDefaultEffect
typeUMLDiagramTypemodel.type or ClassDiagramDiagram type for a fresh canvas. Ignored when model is supplied and carries its own type.
modeApollonModeModellingModelling, Exporting, or Assessment. Drives which UI affordances render.
viewApollonViewModellingModelling, Exporting, or Highlight. Initial view.
availableViewsApollonView[][Modelling]Views the user may switch between. If supplied, the editor merges Modelling, the array, and the configured view. If omitted and view is Highlight, defaults to [Modelling, Highlight].
readonlybooleanfalseLocks the canvas. Can also be toggled at runtime with setReadonly.
enablePopupsbooleantrueEnables the inline edit/property popovers.
modelUMLModelempty diagramInitial diagram. Use importDiagram first if the JSON may be a v2/v3 model.
localeLocaleenLegacy no-op; use labels to localize editor strings.
labelsPartial<ApollonLabels>EnglishOverrides any subset of the editor UI strings exposed in ApollonLabels; can be updated at runtime with setLabels.
tagsboolean | TagOptionsfalseEnables + configures element-tag authoring (off by default). See Element tags; can be updated at runtime with setTags.
controlsOverlayControlInput[]default chromeBuilt-in and custom controls to register initially. Omit for defaults, pass [] for a bare canvas, or pass descriptors from paletteControl(), zoomControl(), miniMapControl(), defaultControls(), or custom controls. See Overlay controls.
debugbooleanfalseEnables debug overlays/logging.
collaborationEnabledbooleanfalseOpt into Yjs real-time sync. See Collaboration. Disables the local undo manager.
scrollLockbooleanfalsePrevents the canvas from capturing page scroll.
collaborationApollonCollaborationOptions—Fine-grained collaboration config — user identity plus per-feature showPresence / showCursors / showSelectionHighlights / showFollow toggles. A superset of collaborationEnabled; setting enabled (or a user) here also turns sync on. See Collaboration.
theme--apollon-* token map—--apollon-* CSS custom properties applied to the mount element. Build one with createApollonTheme. Unset tokens fall back to the built-in light/dark values. See Theming.
dataTheme"light" | "dark"inheritedSets data-theme on the mount element. Omit to inherit whatever an ancestor declares (or the light default). See Theming.

Lifecycle​

MemberReturnsPurpose
new ApollonEditor(element, options?)—Mount the editor's React tree into element.
destroy()voidUnmount, drop all subscriptions, stop sync, and destroy the Yjs doc. Always call before re-mounting on the same container.

State​

Model​

MemberTypePurpose
model (getter)UMLModelSnapshot of the current diagram as plain JSON.
model (setter)UMLModelReplace the entire diagram. Pass importDiagram(json) if the JSON may be v2/v3.
getDiagramMetadata(){ diagramTitle, diagramType }Title and type without serializing the whole model.
updateDiagramTitle(name)voidRename the diagram.
diagramType (setter)UMLDiagramTypeSwitch diagram type. Clears all nodes, edges, and assessments.

View and read-only state​

MemberTypePurpose
view (getter / setter)ApollonViewRead or set the active view.
setReadonly(readonly)(boolean) => voidToggle read-only at runtime. Clears selection and any open popover when locking.
setPreviewMode(active)(boolean) => voidOverlay a snapshot on the canvas without writing to the Yjs doc. Used for version-history previews.
toggleInteractiveElementsMode(forceEnabled?)(boolean?) => voidToggle (or force) the Highlight view for marking interactive elements.
setMode(mode)(ApollonMode) => voidSwitch between Modelling, Assessment, and Exporting at runtime.
setScrollLock(locked)(boolean) => voidToggle whether the canvas captures page scroll.
setLabels(labels)(Partial<ApollonLabels>) => voidReplace localized editor strings by merging a partial dictionary over the English defaults.
setTags(options?)(boolean | TagOptions) => voidEnable + configure element-tag authoring (off by default) — true for free-form, an object for a fixed vocabulary. See Element tags.
setElementTags(id, tags)(string, string[]) => voidReplace one element's tags programmatically (a node or a class attribute/method); [] clears them.
fitView(options?)({ padding?, duration?, respectInsets? }) => voidFit the diagram in view, capped at maxZoom: 1.0. Respects reserved overlay control insets by default; pass respectInsets: false to ignore them. duration defaults to 200 ms.

Canvas geometry​

MemberReturnsPurpose
getNodes()Node[]Live React Flow nodes ([] before init).
getEdges()Edge[]Live React Flow edges ([] before init).
getViewport(){ x, y, zoom } | nullCurrent viewport, or null before init.
screenToFlowPosition(position)XYPosition | nullConvert screen coordinates to canvas coordinates.
flowToScreenPosition(position)XYPosition | nullConvert canvas coordinates to screen coordinates.
getSelectedElements()string[]IDs of the currently selected elements.

Canvas overlays / controls​

Inject floating chrome (toolbars, banners, rails) into the editor's measured, inset-aware layout. See Overlay controls for regions, the <ApollonControl> React component, and the "make room" model.

MemberTypePurpose
addControl(control)(OverlayControlInput) => () => voidRegister a floating control; returns a disposer. Throws on a bad region / empty id.
updateControl(id, patch)(string, Partial<OverlayControlInput>) => voidPatch a control's options/renderer (no-op if absent; id is immutable).
removeControl(id)(string) => voidUnregister a control by id (no-op if absent); the imperative hide for a built-in.
hasControl(id)(string) => booleanWhether a control with this id is registered.
getControl(id)(string) => OverlayControlSnapshot | undefinedRead a registered control's current options (undefined if absent).
getRegionElement(region)(OverlayRegion) => HTMLElementStable pointer-transparent node to createPortal host chrome into (keeps host React context).
releaseRegionElement(region)(OverlayRegion) => voidRelease a region acquired via getRegionElement.

Assessment​

MemberTypePurpose
addOrUpdateAssessment(assessment)(Assessment) => voidAttach or update a score/feedback assessment on an element.
setElementHighlights(highlights)(Map<string, string> | Record<string, string> | null) => voidRing the given element ids (id → CSS color) — e.g. to flag elements missing feedback or carrying suggestions. Drawn as an outline, never a fill, so an element's own text and its assessment badge stay legible. Host-driven and ephemeral: never written to the model, serialized, or shared with collaborators. Each call replaces the previous set; pass null or an empty map to clear.
revealAssessment(id, options?)(string | null, { reveal?: boolean }) => voidSelect one element, open its feedback popover, and pan the canvas to it at the current zoom. Lets a host's feedback list drive the canvas — click an entry, the diagram answers where it applies. null clears the selection and closes the popover; { reveal: false } skips the pan. The popover only opens in assessment mode.
getElementHighlights()() => Record<string, string>The current highlight map (element id → CSS color).
getElementIdsByTag(tag)(string) => string[]Ids of every element carrying the host-defined tag — a node, or one of its members (class attribute, method, SFC action row). Exact and case-sensitive apart from surrounding whitespace; [] for an unknown or blank tag. Pair with setElementHighlights to color a group — see Element tags.
getInteractiveForSerialization()InteractiveElements | undefinedInteractive-element flags for inclusion in a saved model.

Subscriptions​

Every subscribeTo… method returns a numeric subscription id. Pass it to unsubscribe(id) to detach. destroy() drops all subscriptions automatically.

Unless noted otherwise, subscribeTo* channels are coarse: they re-fire on any state-store change and the callback receives the current value of the named field. subscribeToSelectionChange is the only channel with a built-in prev/next equality check.

MethodCallback signature
subscribeToModelChange(cb)(model: UMLModel) => void
subscribeToDiagramNameChange(cb)(title: string) => void
subscribeToSelectionChange(cb)(selectedElementIds: string[]) => void
subscribeToAssessmentSelection(cb)(selectedElementIds: string[]) => void
subscribeToAwarenessChanges(cb)(states: Map<number, CollaborationState>) => void
subscribeToCollaboratorChanges(cb)(collaborators: CollaboratorInfo[]) => void
unsubscribe(subscriptionId)(number) => void
const id = editor.subscribeToModelChange((model) => persist(model))
// later
editor.unsubscribe(id)

Collaboration​

These members are only meaningful with collaborationEnabled: true. See Collaboration for the full wiring.

MemberTypePurpose
sendBroadcastMessage(sendFn)((base64: string) => void) => voidRegister the callback the editor uses to emit Yjs frames.
receiveBroadcastedMessage(base64Data)(string) => voidFeed a received Yjs frame back into the editor.
broadcastFullState()() => voidPush the entire local Yjs doc to peers — call on every (re)connect.
setLocalAwarenessUser(user)(CollaborationUser) => voidSet the local user's identity for awareness.
setLocalAwarenessCursor(cursor)(CollaborationCursor | null) => voidPublish the local cursor position.
setLocalAwarenessSelectedElement(id)(string | null) => voidPublish the local selection.
setLocalAwarenessState(state)(Partial<CollaborationState>) => voidSet arbitrary local awareness state.
getLocalAwarenessClientId()() => numberThe local Yjs awareness client id.
getCollaborators()() => CollaboratorInfo[]The current collaborator roster.
ApollonEditor.generateInitialSyncMessage()() => string (static)Base64 handshake frame to request an initial sync.
ApollonEditor.generateInitialAwarenessSyncMessage()() => string (static)Base64 handshake frame to request an awareness sync.

Export​

MemberReturnsPurpose
exportAsSVG(options?)Promise<SVG>Render the current model to SVG.
ApollonEditor.exportModelAsSvg(model, options?)Promise<SVG>Static. Render an arbitrary model to SVG with no mounted editor.

SVG is { svg: string, clip: { x, y, width, height } }. See Export for ExportOptions and the PNG/PDF pipeline, or the Conversion API to convert models to SVG/PNG/PDF over HTTP via the standalone server.

Keyboard shortcuts​

Mod is Ctrl on Windows/Linux and Cmd on macOS; combos marked view work on read-only diagrams too. Nothing fires while the user is typing in a field or while a dialog or menu is open. Shortcuts belong to the editor that has focus: click or tap the canvas to activate it, then move focus outside the editor to return every shortcut to the surrounding page. Pointer-acquired canvas focus is released when the pointer leaves, so browser zoom remains available around an embedded editor. Keyboard users keep ownership until they move focus normally.

ComboAction
Mod+A / EscSelect all / clear selection (view)
Delete / BackspaceDelete selection
Mod+C / Mod+X / Mod+VCopy (view) / cut / paste
Mod+DDuplicate the selection beside itself
Arrow keysNudge selection
Mod+Z, Mod+Shift+Z/Mod+YUndo, redo
Mod+= / Mod+-Zoom in / out (view)
Mod+0Reset zoom to 100% (view)
Mod+Shift+1 / Mod+Shift+2Zoom to fit / zoom to selection (view)

Figma and Excalidraw put the last two on Shift+1/Shift+2, but a shortcut whose keys produce a printable character fails WCAG 2.1.4 unless it can be turned off, remapped, or scoped to focus.

Pass keyboardShortcuts: false to keep the editor's hands off every key above when the host binds them itself. Multiple editors need no special coordination: only the focused editor answers.

APOLLON_SHORTCUTS is the list the editor runs, so a host can render a sheet that tracks it, or check it before binding a key of its own. Each entry's first combo is the primary one — a sheet should render only that; the rest are aliases (Mod+Y redo, layout variants of Mod+=). Entries flagged canvasHandled are handled directly by React Flow on a focused canvas element, not by the editor-root dispatcher. shortcutKeyName turns a combo into the key it names, so a sheet renders "1" rather than the Digit1 code that combo matches on.

matchesShortcutCombo, isTypingTarget and isInsideOverlay are the primitives that handler matches and stands down with, exported so a host's own keys behave like the editor's:

import {
isInsideOverlay,
isTypingTarget,
matchesShortcutCombo,
type ApollonShortcutCombo,
} from "@tumaet/apollon"

const rename: ApollonShortcutCombo = { key: "r", mod: true }

document.addEventListener("keydown", (event) => {
if (event.isComposing || isTypingTarget(event) || isInsideOverlay(event)) {
return
}
if (!matchesShortcutCombo(event, rename)) return
event.preventDefault()
})

A combo matching on key follows what the user's layout prints and is compared case-insensitively; use code for digits, whose character moves between layouts and under Shift.

Diagram types​

Enum literals (the strings on the wire and in UMLModel.type) on the left; human-facing labels used elsewhere on the right.

Enum literalLabel
"ClassDiagram"Class
"ObjectDiagram"Object
"ActivityDiagram"Activity
"UseCaseDiagram"Use Case
"CommunicationDiagram"Communication
"ComponentDiagram"Component
"DeploymentDiagram"Deployment
"PetriNet"Petri Net
"ReachabilityGraph"Reachability Graph
"SyntaxTree"Syntax Tree
"Flowchart"Flowchart
"BPMN"BPMN
"Sfc"SFC

Enums​

EnumMembers
ApollonModeModelling, Exporting, Assessment
ApollonViewModelling, Exporting, Highlight
Localeen, de

See Collaboration for the Yjs hooks and Export for SVG/PNG/PDF/JSON details.