Readonly
Read-only (view) mode is a single engine-level flag that gates all editing while leaving pan, zoom, and selection alive. Toggle it with โฅR (actionToggleReadOnly) or programmatically:
import { Editor } from "@oh-just-another/state";
const editor = new Editor({ readOnly: true }); // start read-only
editor.setReadOnly(false); // flip at runtime (idempotent)
editor.toggleReadOnly();
const on = editor.readOnly;
What it gatesโ
- Pointer edits โ drags that would create, move, resize, rotate, erase, or draw all bail at press-down. Panning, zooming, and click-to-select still work.
- Actions โ the action registry disables every action not flagged
viewMode: true. Navigation-safe actions (select-all, copy, zoom, grid, mode switches to non-editing tools, and the read-only toggle itself) stay live; the toggle isviewMode-flagged so the keyboard can always leave view mode. - Mutating verbs โ engine verbs (
deleteSelected,paste,moveSelectionBy,groupSelected, z-order, โฆ) return early, so hosts don't have to guard each entry point.
The bundled toolbar and menus disable their editing buttons automatically (useReadOnly hook in @oh-just-another/react-ui).
From Reactโ
DiagramRoot in @oh-just-another/react-ui takes a readOnly prop (changing it after mount flips the live editor). The top-level Editor component has no dedicated prop yet โ reach the engine through the ref:
import { useRef } from "react";
import { Editor, type EditorAPI } from "@oh-just-another/editor";
function Host() {
const ref = useRef<EditorAPI>(null);
const freeze = () => ref.current?.editor?.setReadOnly(true);
return <Editor ref={ref} />;
}
Narrower alternativesโ
Lock individual elements or layers. A locked element is skipped by hit-testing for edits; isElementLocked reports the effective state (walking up the parent / layer chain).
import { isElementLocked } from "@oh-just-another/scene";
const frozen = isElementLocked(scene, element);
Hide the editing chrome. The React Editor component can drop the toolbar, menus, and panels for a presentation-style view:
<Editor hideToolbar hideMainMenu hideSelectionPanel hideContextMenu />