@orbat-mapper/tactical-draw 0.2.0-alpha.21 → 0.2.0-alpha.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -0
- package/dist/index.d.mts +97 -1
- package/dist/index.mjs +649 -113
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -87,6 +87,22 @@ if (session && "canCommit" in session) {
|
|
|
87
87
|
}
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
+
Live edit and transform sessions expose a session-local `history`. Completed
|
|
91
|
+
gestures and authored programmatic mutations are undoable without settling the
|
|
92
|
+
session; pointer-move preview frames are not history steps:
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
const active = td.activeSession;
|
|
96
|
+
const history =
|
|
97
|
+
(active && "history" in active ? active.history : null) ?? td.activeTransformSession?.history;
|
|
98
|
+
if (history) history.undo();
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`history.subscribe(...)` reports `canUndo`, `canRedo`, and optional operation
|
|
102
|
+
labels. Committing folds only the selected working state into the host document
|
|
103
|
+
as one operation. Changing a transform session's members with `setGraphics()`
|
|
104
|
+
establishes a new local baseline and clears both stacks.
|
|
105
|
+
|
|
90
106
|
## Bring your own engine
|
|
91
107
|
|
|
92
108
|
Implement `MapAdapter` (or extend `BaseMapAdapter`) against your map engine
|
package/dist/index.d.mts
CHANGED
|
@@ -12,6 +12,11 @@ interface PointerEventInfo {
|
|
|
12
12
|
* mouse paths populate it; touch leaves it `undefined`.
|
|
13
13
|
*/
|
|
14
14
|
altKey?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Whether Shift was held for this pointer event. Rotation gestures use the
|
|
17
|
+
* live value to constrain transform-box angles to 15-degree increments.
|
|
18
|
+
*/
|
|
19
|
+
shiftKey?: boolean;
|
|
15
20
|
/** Engine-native event, for drivers that need to call preventDefault etc. */
|
|
16
21
|
native?: unknown;
|
|
17
22
|
}
|
|
@@ -672,6 +677,22 @@ type EditMode = "reshape" | "transform" | "labeldrag" | "delete";
|
|
|
672
677
|
*/
|
|
673
678
|
type SettleReason = "close" | "error" | TacticalDrawAbortReason;
|
|
674
679
|
//#endregion
|
|
680
|
+
//#region src/tactical-draw/session-history.d.ts
|
|
681
|
+
type SessionChangeSource = "gesture" | "undo" | "redo" | "programmatic";
|
|
682
|
+
interface SessionHistoryState {
|
|
683
|
+
readonly canUndo: boolean;
|
|
684
|
+
readonly canRedo: boolean;
|
|
685
|
+
readonly undoLabel?: string;
|
|
686
|
+
readonly redoLabel?: string;
|
|
687
|
+
}
|
|
688
|
+
interface SessionHistory {
|
|
689
|
+
/** Current availability and optional labels. Each session retains at most 100 completed steps. */
|
|
690
|
+
readonly state: SessionHistoryState;
|
|
691
|
+
undo(): boolean;
|
|
692
|
+
redo(): boolean;
|
|
693
|
+
subscribe(listener: (state: SessionHistoryState) => void): () => void;
|
|
694
|
+
}
|
|
695
|
+
//#endregion
|
|
675
696
|
//#region src/tactical-draw/edit-session.d.ts
|
|
676
697
|
/**
|
|
677
698
|
* Surface delivered via `td.edit(measure, opts).onSession` and synchronously
|
|
@@ -683,6 +704,8 @@ type SettleReason = "close" | "error" | TacticalDrawAbortReason;
|
|
|
683
704
|
* asynchronously).
|
|
684
705
|
*/
|
|
685
706
|
interface EditSession {
|
|
707
|
+
/** Undo/redo for completed mutations within this live session. */
|
|
708
|
+
readonly history: SessionHistory;
|
|
686
709
|
/** Immutable edit-start input. */
|
|
687
710
|
readonly graphic: ControlMeasure;
|
|
688
711
|
/** Live complete working graphic. Copy on read. */
|
|
@@ -820,6 +843,8 @@ interface EditSession {
|
|
|
820
843
|
* observe partial state. See PRD #40 user-stories 23–24.
|
|
821
844
|
*/
|
|
822
845
|
interface EditChangeEvent {
|
|
846
|
+
/** How this working-copy transition was initiated. */
|
|
847
|
+
readonly source: SessionChangeSource;
|
|
823
848
|
/** Working state after the completed gesture. */
|
|
824
849
|
readonly graphic: GraphicSnapshot<ControlMeasure>;
|
|
825
850
|
/** State immediately before this gesture. */
|
|
@@ -840,6 +865,7 @@ interface EditChangeEvent {
|
|
|
840
865
|
//#endregion
|
|
841
866
|
//#region src/tactical-draw/graphic-edit-session.d.ts
|
|
842
867
|
interface GraphicEditChangeEvent<G extends Graphic = Graphic> {
|
|
868
|
+
readonly source: SessionChangeSource;
|
|
843
869
|
readonly graphic: GraphicSnapshot<G>;
|
|
844
870
|
readonly previous: GraphicSnapshot<G>;
|
|
845
871
|
readonly session: GraphicEditSession<G>;
|
|
@@ -849,6 +875,7 @@ interface GraphicEditChangeEvent<G extends Graphic = Graphic> {
|
|
|
849
875
|
}
|
|
850
876
|
/** Common selection/editing contract shared by control measures and point symbols. */
|
|
851
877
|
interface GraphicEditSession<G extends Graphic = Graphic> {
|
|
878
|
+
readonly history: SessionHistory;
|
|
852
879
|
/** Immutable edit-start input. */
|
|
853
880
|
readonly graphic: G;
|
|
854
881
|
/** Live working graphic. Copy on read. */
|
|
@@ -885,6 +912,8 @@ interface GraphicEditSession<G extends Graphic = Graphic> {
|
|
|
885
912
|
* delivers, asynchronously).
|
|
886
913
|
*/
|
|
887
914
|
interface TransformSession {
|
|
915
|
+
/** Undo/redo for completed gestures within the current membership baseline. */
|
|
916
|
+
readonly history: SessionHistory;
|
|
888
917
|
/**
|
|
889
918
|
* Live view of the current members' join-time input graphics — a fresh array
|
|
890
919
|
* on each read, in current membership order. Grows/shrinks as [[setGraphics]]
|
|
@@ -926,6 +955,11 @@ interface TransformSession {
|
|
|
926
955
|
* current box angle. Session-scoped state (`sizeAnchor`, box angle,
|
|
927
956
|
* non-geometry dirty) is unchanged.
|
|
928
957
|
*
|
|
958
|
+
* Calling this establishes a new session-history baseline: both undo and
|
|
959
|
+
* redo are cleared after retained members carry their working state
|
|
960
|
+
* forward. Membership changes and already-emitted exit snapshots are not
|
|
961
|
+
* undoable within the live session.
|
|
962
|
+
*
|
|
929
963
|
* **Return value** — the committed exit snapshots of the members removed *by
|
|
930
964
|
* this call*, built exactly like [[close]]'s snapshots (pixel size baked to
|
|
931
965
|
* ground unless `sizeAnchor` is `"screen"`, then cloned and rendered); an
|
|
@@ -1036,6 +1070,8 @@ interface TransformSession {
|
|
|
1036
1070
|
* `EditChangeEvent` for the identical emission contract this mirrors.
|
|
1037
1071
|
*/
|
|
1038
1072
|
interface TransformChangeEvent {
|
|
1073
|
+
/** How this working-copy transition was initiated. */
|
|
1074
|
+
readonly source: SessionChangeSource;
|
|
1039
1075
|
/** Working state after the completed gesture, index-aligned with `session.graphics` as of this emission. */
|
|
1040
1076
|
readonly graphics: GraphicSnapshot<ControlMeasure>[];
|
|
1041
1077
|
/** State immediately before this gesture, index-aligned with `session.graphics` as of this emission. */
|
|
@@ -1058,6 +1094,7 @@ interface TransformChangeEvent {
|
|
|
1058
1094
|
//#endregion
|
|
1059
1095
|
//#region src/tactical-draw/graphic-transform-session.d.ts
|
|
1060
1096
|
interface GraphicTransformChangeEvent {
|
|
1097
|
+
readonly source: SessionChangeSource;
|
|
1061
1098
|
readonly graphics: GraphicSnapshot[];
|
|
1062
1099
|
readonly previous: GraphicSnapshot[];
|
|
1063
1100
|
readonly session: GraphicTransformSession;
|
|
@@ -1066,6 +1103,7 @@ interface GraphicTransformChangeEvent {
|
|
|
1066
1103
|
abort(): void;
|
|
1067
1104
|
}
|
|
1068
1105
|
interface GraphicTransformSession {
|
|
1106
|
+
readonly history: SessionHistory;
|
|
1069
1107
|
readonly graphics: readonly Graphic[];
|
|
1070
1108
|
readonly workingGraphics: readonly Graphic[];
|
|
1071
1109
|
readonly dirty: boolean;
|
|
@@ -1146,6 +1184,55 @@ interface DrawSession {
|
|
|
1146
1184
|
onSettled(handler: (reason: SettleReason) => void): () => void;
|
|
1147
1185
|
}
|
|
1148
1186
|
//#endregion
|
|
1187
|
+
//#region src/tactical-draw/snapping.d.ts
|
|
1188
|
+
type SnapInteraction = "draw" | "reshape" | "translate" | "label-drag";
|
|
1189
|
+
interface SnapCandidateRequest {
|
|
1190
|
+
coordinate: Position;
|
|
1191
|
+
pixel: PixelCoordinate;
|
|
1192
|
+
interaction: SnapInteraction;
|
|
1193
|
+
graphicId?: string;
|
|
1194
|
+
controlPointIndex?: number;
|
|
1195
|
+
originalEvent?: unknown;
|
|
1196
|
+
}
|
|
1197
|
+
interface SnapCandidate {
|
|
1198
|
+
id: string;
|
|
1199
|
+
coordinate: Position;
|
|
1200
|
+
kind: string;
|
|
1201
|
+
graphicId?: string;
|
|
1202
|
+
controlPointIndex?: number;
|
|
1203
|
+
priority?: number;
|
|
1204
|
+
}
|
|
1205
|
+
type SnapCandidateProvider = (request: SnapCandidateRequest) => readonly SnapCandidate[];
|
|
1206
|
+
interface SnapResult {
|
|
1207
|
+
coordinate: Position;
|
|
1208
|
+
pixel: PixelCoordinate;
|
|
1209
|
+
candidate: SnapCandidate;
|
|
1210
|
+
distancePixels: number;
|
|
1211
|
+
}
|
|
1212
|
+
interface GraphicGeometrySnappingOptions {
|
|
1213
|
+
/** Snap to the nearest point along generated linework and polygon boundaries. Default `true`. */
|
|
1214
|
+
edges?: boolean;
|
|
1215
|
+
/** Snap to generated geometry vertices. Default `false`. */
|
|
1216
|
+
vertices?: boolean;
|
|
1217
|
+
}
|
|
1218
|
+
interface SnappingOptions {
|
|
1219
|
+
enabled?: boolean;
|
|
1220
|
+
tolerancePixels?: number;
|
|
1221
|
+
sources?: {
|
|
1222
|
+
graphics?: boolean;
|
|
1223
|
+
/**
|
|
1224
|
+
* Snap to generated control-measure geometry. `true` enables edges with
|
|
1225
|
+
* vertices disabled; pass an object to select either candidate type.
|
|
1226
|
+
* Text/label point features and the active graphic are excluded.
|
|
1227
|
+
*/
|
|
1228
|
+
graphicGeometry?: boolean | GraphicGeometrySnappingOptions;
|
|
1229
|
+
external?: SnapCandidateProvider;
|
|
1230
|
+
};
|
|
1231
|
+
bypass?: (originalEvent: unknown) => boolean;
|
|
1232
|
+
/** Called for each resolution attempt; `null` clears a host-rendered indicator. */
|
|
1233
|
+
onSnap?: (result: SnapResult | null) => void;
|
|
1234
|
+
}
|
|
1235
|
+
//#endregion
|
|
1149
1236
|
//#region src/tactical-draw/point-symbol-draw-controller.d.ts
|
|
1150
1237
|
type DrawPointSymbolDraft = Pick<PointSymbol, "kind" | "sidc"> & Partial<Omit<PointSymbol, "kind" | "sidc">>;
|
|
1151
1238
|
//#endregion
|
|
@@ -1196,6 +1283,8 @@ interface TacticalDrawOptions {
|
|
|
1196
1283
|
* the draw API itself are deferred (PRD #40 user-story-5 note).
|
|
1197
1284
|
*/
|
|
1198
1285
|
generateId?: () => string;
|
|
1286
|
+
/** Optional engine-level snapping for draw and edit interactions. */
|
|
1287
|
+
snapping?: SnappingOptions;
|
|
1199
1288
|
}
|
|
1200
1289
|
interface EditOptions {
|
|
1201
1290
|
signal?: AbortSignal;
|
|
@@ -1344,6 +1433,8 @@ declare class TacticalDraw {
|
|
|
1344
1433
|
private readonly defaultInteractionStyle;
|
|
1345
1434
|
private readonly generateId;
|
|
1346
1435
|
private readonly pointSymbols;
|
|
1436
|
+
private snappingOptions;
|
|
1437
|
+
private readonly resolveSnap;
|
|
1347
1438
|
private destroyed;
|
|
1348
1439
|
private hasRendered;
|
|
1349
1440
|
private readonly activeInteraction;
|
|
@@ -1394,7 +1485,12 @@ declare class TacticalDraw {
|
|
|
1394
1485
|
* surrounding collection state.
|
|
1395
1486
|
*/
|
|
1396
1487
|
private lastRenderedMeasures;
|
|
1488
|
+
private snapGeometryFeatures;
|
|
1397
1489
|
constructor(adapter: MapAdapter, options?: TacticalDrawOptions);
|
|
1490
|
+
/** Replace snapping configuration without recreating the map adapter or façade. */
|
|
1491
|
+
setSnappingOptions(options?: SnappingOptions): void;
|
|
1492
|
+
/** Clear transient host affordances when snapping or its interaction ends. */
|
|
1493
|
+
private clearSnapResult;
|
|
1398
1494
|
/**
|
|
1399
1495
|
* Render `measures` into features and write them to the graphics layer.
|
|
1400
1496
|
* Routes every measure through [[renderMeasureForAdapter]] so pixel sizing is
|
|
@@ -1782,4 +1878,4 @@ declare function nearestWorldCopyLng(lng: number, refLng: number): number;
|
|
|
1782
1878
|
/** `nearestWorldCopyLng` applied to a lon/lat position. */
|
|
1783
1879
|
declare function nearestWorldCopyPosition(position: Position, refLng: number): Position;
|
|
1784
1880
|
//#endregion
|
|
1785
|
-
export { BaseMapAdapter, type CombinedAbort, DEFAULT_LABEL_SIZE_PIXELS, DEFAULT_TEXT_SIZE_MAX_PIXELS, DEFAULT_TEXT_SIZE_MIN_PIXELS, type DrawMeasureDraft, type DrawOptions, type DrawPointSymbolDraft, type DrawSession, type EditChangeEvent, type EditManyOptions, type EditMode, type EditOptions, type EditPointerDriver, type EditSession, type FeatureOps, type Graphic, type GraphicEditChangeEvent, type GraphicEditSession, type GraphicRender, type GraphicSnapshot, type GraphicTransformChangeEvent, type GraphicTransformSession, type GuideStyle, type HandleStyle, type IconResource, type InteractionHit, type InteractionStyle, type LayerId, type MapAdapter, type MapCursor, type MapEvent, type MapEventHandler, type NativeEventEntry, type PickEvent, type PickHandler, type PickOptions, type PixelCoordinate, type PointSymbol, type PointSymbolAnchor, type PointSymbolCapability, PointSymbolCapabilityRequiredError, type PointSymbolColors, type PointSymbolFootprint, type PointSymbolGraphicModifiers, type PointSymbolRender, type PointSymbolSize, type PointSymbolStyle, type PointerCallback, PointerCallbackHub, type PointerEventInfo, type SettleReason, type SizeAnchor, type StyleOptions, TOUCH_HIT_TOLERANCE_PX, TacticalDraw, TacticalDrawAbortError, type TacticalDrawAbortReason, TacticalDrawDestroyedError, type TacticalDrawLayerOptions, type TacticalDrawOptions, type TextStyleOptions, type ToPixel, type TransformBox, type TransformChangeEvent, type TransformSession, bindAbortable, clonePointSymbol, coerceHandleStyle, combineWithHostSignal, getSizeAnchor, hitTestFeature, hitTestIconFeature, ignoreAbort, isPointSymbol, isTacticalDrawAbortError, nearestWorldCopyLng, nearestWorldCopyPosition, pickHitTolerance, pointSymbolFootprint, resolveGroundTextSizePixels, tryControlMeasureIdFromFeature };
|
|
1881
|
+
export { BaseMapAdapter, type CombinedAbort, DEFAULT_LABEL_SIZE_PIXELS, DEFAULT_TEXT_SIZE_MAX_PIXELS, DEFAULT_TEXT_SIZE_MIN_PIXELS, type DrawMeasureDraft, type DrawOptions, type DrawPointSymbolDraft, type DrawSession, type EditChangeEvent, type EditManyOptions, type EditMode, type EditOptions, type EditPointerDriver, type EditSession, type FeatureOps, type Graphic, type GraphicEditChangeEvent, type GraphicEditSession, type GraphicGeometrySnappingOptions, type GraphicRender, type GraphicSnapshot, type GraphicTransformChangeEvent, type GraphicTransformSession, type GuideStyle, type HandleStyle, type IconResource, type InteractionHit, type InteractionStyle, type LayerId, type MapAdapter, type MapCursor, type MapEvent, type MapEventHandler, type NativeEventEntry, type PickEvent, type PickHandler, type PickOptions, type PixelCoordinate, type PointSymbol, type PointSymbolAnchor, type PointSymbolCapability, PointSymbolCapabilityRequiredError, type PointSymbolColors, type PointSymbolFootprint, type PointSymbolGraphicModifiers, type PointSymbolRender, type PointSymbolSize, type PointSymbolStyle, type PointerCallback, PointerCallbackHub, type PointerEventInfo, type SessionChangeSource, type SessionHistory, type SessionHistoryState, type SettleReason, type SizeAnchor, type SnapCandidate, type SnapCandidateProvider, type SnapCandidateRequest, type SnapInteraction, type SnapResult, type SnappingOptions, type StyleOptions, TOUCH_HIT_TOLERANCE_PX, TacticalDraw, TacticalDrawAbortError, type TacticalDrawAbortReason, TacticalDrawDestroyedError, type TacticalDrawLayerOptions, type TacticalDrawOptions, type TextStyleOptions, type ToPixel, type TransformBox, type TransformChangeEvent, type TransformSession, bindAbortable, clonePointSymbol, coerceHandleStyle, combineWithHostSignal, getSizeAnchor, hitTestFeature, hitTestIconFeature, ignoreAbort, isPointSymbol, isTacticalDrawAbortError, nearestWorldCopyLng, nearestWorldCopyPosition, pickHitTolerance, pointSymbolFootprint, resolveGroundTextSizePixels, tryControlMeasureIdFromFeature };
|