An EditModeHandler exposing getMode() and setMode().
At any moment the application is in exactly one interaction mode, or none (idle). The bus holds a
single EditMode ({ key, description?, args?, cursor?, cancel?, done?, onModeChange? }),
and every part of the app reads from and writes to that one value.
It exists so unrelated features can coordinate without depending on one another. A feature announces that its interaction has started by publishing a mode, and clears it when finished; other features react to the change. The bus is the decoupling layer between them.
Typical publishers (set a mode while their interaction is active):
key: 'edit', exposing the live editor handle (IEditable) via
EditMode.args.editable. The fine-grained enter-vs-edit distinction lives on that
handle's session, not on the bus key (the status-bar label is carried in
EditMode.description, refreshed by the publisher when it flips);key: 'copy' / 'cut';key: 'fill' / 'drag…', with a EditMode.cursor;Typical consumers (read the active mode):
Publishing a mode replaces the previous one and invokes its EditMode.onModeChange, so a mode can clean up when it is superseded (for instance, starting an edit supersedes a copy marquee, which then clears the clipboard).
The bus is a singleton — one instance per application, reachable from anywhere without
prop-threading. It is backed by singletonHook, so a SingletonHooksContainer must be mounted in
the tree.
const editMode = useEditMode();
// Publish a mode while an interaction is active, then clear it when done.
editMode.setMode({ key: 'fill', description: 'Drag to fill', cursor: 'crosshair' });
editMode.setMode(null);
// React to the active mode.
const mode = editMode.getMode();
const isEditing = mode?.key === 'edit';
Access the application's edit-mode bus — the single, app-wide signal describing the interaction currently in effect.