Recipes ​
Common host integrations, ready to adapt.
Variable-length draw with Done / Cancel buttons ​
Variable-length kinds need a UI to commit. Subscribe in onSession, read the live session from activeSession, and use facade-level cancel() for cancellation.
ts
import { ignoreAbort } from "@orbat-mapper/tactical-draw";
const pending = td.draw(
{ kind: "fortified-area" },
{
onSession(s) {
doneButton.disabled = !s.canCommit;
s.onChange(() => {
doneButton.disabled = !s.canCommit; // inside the kind's valid range?
});
},
},
);
doneButton.onclick = () => {
const session = td.activeSession;
if (session && "canCommit" in session) session.commit();
};
cancelButton.onclick = () => td.cancel();
void pending
.then(({ graphic }) => {
measures.push(graphic);
td.render(measures);
})
.catch(ignoreAbort);Validate edits and reject invalid changes ​
onChange fires once per completed gesture. Call event.reject() to roll back to the previous state, close() to accept and end, or abort() to cancel. Effects apply after all listeners run.
ts
await td.edit(measure, {
onSession(session) {
session.onChange((event) => {
if (!isInsideAllowedArea(event.graphic.graphic.controlPoints)) {
event.reject(); // bounce the gesture, keep editing
}
});
},
});Drive style & options from UI controls ​
During an edit, session.setStyle() and session.setOptions() shallow-merge into the live working copy, re-render the preview, mark the edit dirty, and emit onChange.
ts
import { ignoreAbort } from "@orbat-mapper/tactical-draw";
const pending = td.edit(measure);
strokeWidthInput.oninput = () => {
const session = td.activeSession;
if (session && "setStyle" in session) {
session.setStyle({ strokeWidth: Number(strokeWidthInput.value) });
}
};
smoothToggle.onchange = () => {
const session = td.activeSession;
if (session && "setOptions" in session) {
session.setOptions({ smooth: smoothToggle.checked });
}
};
cancelButton.onclick = () => td.cancel();
void pending
.then(({ graphic: next }) => {
const i = measures.findIndex((m) => m.id === next.id);
if (i !== -1) measures.splice(i, 1, next);
td.render(measures);
})
.catch(ignoreAbort);