orcasvn-react-diagrams 0.2.12 → 0.2.13
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/CHANGELOG.md +14 -0
- package/README.md +15 -11
- package/ai/api-contract.json +47 -0
- package/ai/invariants.json +6 -2
- package/ai/manifest.json +1 -1
- package/dist/cjs/examples.js +427 -48
- package/dist/cjs/index.js +226 -36
- package/dist/cjs/types/api/createDiagramEditor.d.ts +2 -1
- package/dist/cjs/types/api/types.d.ts +50 -0
- package/dist/cjs/types/displaybox/demos/deletionEventsDemo.d.ts +2 -0
- package/dist/cjs/types/displaybox/demos/focusElementDemo.d.ts +4 -0
- package/dist/cjs/types/engine/DiagramEngine.d.ts +9 -0
- package/dist/esm/examples.js +427 -48
- package/dist/esm/examples.js.map +1 -1
- package/dist/esm/index.js +226 -36
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/api/createDiagramEditor.d.ts +2 -1
- package/dist/esm/types/api/types.d.ts +50 -0
- package/dist/esm/types/displaybox/demos/deletionEventsDemo.d.ts +2 -0
- package/dist/esm/types/displaybox/demos/focusElementDemo.d.ts +4 -0
- package/dist/esm/types/engine/DiagramEngine.d.ts +9 -0
- package/dist/examples.d.ts +51 -0
- package/dist/index.d.ts +52 -1
- package/docs/API_CONTRACT.md +48 -1
- package/docs/ARCHITECTURE.md +9 -7
- package/docs/CAPABILITIES.md +3 -0
- package/docs/COMMANDS_EVENTS.md +15 -6
- package/docs/DOCUMENTATION_WORKFLOW.md +3 -1
- package/docs/INTEGRATION_PLAYBOOK.md +4 -0
- package/docs/PORTING_CHECKLIST.md +4 -1
- package/package.json +1 -1
- package/src/displaybox/demos/DeletionEventsDemoTab.tsx +167 -9
- package/src/displaybox/demos/deletionEventsDemo.ts +2 -2
- package/src/displaybox/demos/focusElementDemo.ts +91 -0
- package/src/displaybox/demos/index.tsx +2 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DiagramEngineHandle, Point, DiagramState, ElementShapeHoverControlActivationEvent, ElementShapeHoverControlInteractionEvent, ElementShapeHoverControls, EngineChangeEvent, EngineSelectionEvent, LinkTargetPortCreationHandler, LinkColorPoolPolicy, LinkRouteRefreshPolicy, ViewportFitOptions } from './types';
|
|
1
|
+
import { DiagramEngineHandle, Point, DiagramState, ElementShapeHoverControlActivationEvent, ElementShapeHoverControlInteractionEvent, ElementShapeHoverControls, EngineChangeEvent, EngineSelectionEvent, LinkTargetPortCreationHandler, LinkColorPoolPolicy, LinkRouteRefreshPolicy, FocusElementOptions, ViewportFitOptions } from './types';
|
|
2
2
|
import { type BuiltInShapeKind } from '../shapes';
|
|
3
3
|
export type SimpleShape = {
|
|
4
4
|
id: string;
|
|
@@ -41,6 +41,7 @@ export type DiagramEditorHandle = DiagramEngineHandle & {
|
|
|
41
41
|
completeLinkToElement: (targetElementId: string, pointer: Point) => void;
|
|
42
42
|
cancelLink: () => void;
|
|
43
43
|
zoomToFitElements: (options?: ViewportFitOptions) => void;
|
|
44
|
+
focusElement: (elementId: string, options?: FocusElementOptions) => void;
|
|
44
45
|
exportImage: (options?: DiagramImageExportOptions) => string;
|
|
45
46
|
resize: (width: number, height: number) => void;
|
|
46
47
|
setElementShapeHoverControls: (controls?: ElementShapeHoverControls) => void;
|
|
@@ -24,6 +24,9 @@ export type ViewportFitOptions = {
|
|
|
24
24
|
minZoom?: number;
|
|
25
25
|
maxZoom?: number;
|
|
26
26
|
};
|
|
27
|
+
export type FocusElementOptions = {
|
|
28
|
+
zoom?: number;
|
|
29
|
+
};
|
|
27
30
|
export type MoveConstraint = 'free' | 'inside' | 'border';
|
|
28
31
|
export type TextInteractionPolicy = {
|
|
29
32
|
movable?: boolean;
|
|
@@ -394,6 +397,11 @@ export type ElementPointerEvent = {
|
|
|
394
397
|
pointer: EnginePointerInfo;
|
|
395
398
|
isMulti: boolean;
|
|
396
399
|
};
|
|
400
|
+
export type ElementDoubleClickEvent = {
|
|
401
|
+
elementId: string;
|
|
402
|
+
pointer: EnginePointerInfo;
|
|
403
|
+
isMulti: boolean;
|
|
404
|
+
};
|
|
397
405
|
export type ElementMovedEvent = {
|
|
398
406
|
elementId: string;
|
|
399
407
|
oldWorld: Point;
|
|
@@ -418,18 +426,55 @@ export type GridLayoutChangedEvent = {
|
|
|
418
426
|
beforeGridTemplate?: ElementLayoutGridRowTemplate[];
|
|
419
427
|
afterGridTemplate: ElementLayoutGridRowTemplate[];
|
|
420
428
|
};
|
|
429
|
+
export type DeletionTrigger = 'direct' | 'selection' | 'cascade';
|
|
430
|
+
export type DeletionRootRef = {
|
|
431
|
+
entity: 'element' | 'port' | 'link' | 'text';
|
|
432
|
+
id: string;
|
|
433
|
+
};
|
|
434
|
+
export type ElementDeletingEvent = {
|
|
435
|
+
elementId: string;
|
|
436
|
+
trigger: DeletionTrigger;
|
|
437
|
+
root: DeletionRootRef;
|
|
438
|
+
cancel: () => void;
|
|
439
|
+
cancelled: boolean;
|
|
440
|
+
};
|
|
421
441
|
export type ElementDeletedEvent = {
|
|
422
442
|
elementId: string;
|
|
423
443
|
};
|
|
444
|
+
export type PortDeletingEvent = {
|
|
445
|
+
portId: string;
|
|
446
|
+
elementId: string;
|
|
447
|
+
trigger: DeletionTrigger;
|
|
448
|
+
root: DeletionRootRef;
|
|
449
|
+
cancel: () => void;
|
|
450
|
+
cancelled: boolean;
|
|
451
|
+
};
|
|
424
452
|
export type PortDeletedEvent = {
|
|
425
453
|
portId: string;
|
|
426
454
|
elementId: string;
|
|
427
455
|
};
|
|
456
|
+
export type LinkDeletingEvent = {
|
|
457
|
+
linkId: string;
|
|
458
|
+
sourcePortId: string;
|
|
459
|
+
targetPortId: string;
|
|
460
|
+
trigger: DeletionTrigger;
|
|
461
|
+
root: DeletionRootRef;
|
|
462
|
+
cancel: () => void;
|
|
463
|
+
cancelled: boolean;
|
|
464
|
+
};
|
|
428
465
|
export type LinkDeletedEvent = {
|
|
429
466
|
linkId: string;
|
|
430
467
|
sourcePortId: string;
|
|
431
468
|
targetPortId: string;
|
|
432
469
|
};
|
|
470
|
+
export type TextDeletingEvent = {
|
|
471
|
+
textId: string;
|
|
472
|
+
ownerId?: string | null;
|
|
473
|
+
trigger: DeletionTrigger;
|
|
474
|
+
root: DeletionRootRef;
|
|
475
|
+
cancel: () => void;
|
|
476
|
+
cancelled: boolean;
|
|
477
|
+
};
|
|
433
478
|
export type TextDeletedEvent = {
|
|
434
479
|
textId: string;
|
|
435
480
|
ownerId?: string | null;
|
|
@@ -483,13 +528,18 @@ export type EngineEventMap = {
|
|
|
483
528
|
portMoved: PortMovedEvent;
|
|
484
529
|
portSelected: PortSelectedEvent;
|
|
485
530
|
elementClick: ElementPointerEvent;
|
|
531
|
+
elementDoubleClick: ElementDoubleClickEvent;
|
|
486
532
|
elementDragged: ElementDropEvent;
|
|
487
533
|
elementMoved: ElementMovedEvent;
|
|
488
534
|
elementResized: ElementResizedEvent;
|
|
489
535
|
gridLayoutChanged: GridLayoutChangedEvent;
|
|
536
|
+
elementDeleting: ElementDeletingEvent;
|
|
490
537
|
elementDeleted: ElementDeletedEvent;
|
|
538
|
+
portDeleting: PortDeletingEvent;
|
|
491
539
|
portDeleted: PortDeletedEvent;
|
|
540
|
+
linkDeleting: LinkDeletingEvent;
|
|
492
541
|
linkDeleted: LinkDeletedEvent;
|
|
542
|
+
textDeleting: TextDeletingEvent;
|
|
493
543
|
textDeleted: TextDeletedEvent;
|
|
494
544
|
textUpdated: TextUpdatedEvent;
|
|
495
545
|
elementSelected: ElementSelectedEvent;
|
|
@@ -120,6 +120,7 @@ export default class DiagramEngine {
|
|
|
120
120
|
emitPortMouseDown(event: PortMouseEvent): void;
|
|
121
121
|
emitPortMouseUp(event: PortMouseEvent): void;
|
|
122
122
|
emitElementClick(elementId: string, pointer: EnginePointerInfo, isMulti: boolean): void;
|
|
123
|
+
emitElementDoubleClick(elementId: string, pointer: EnginePointerInfo, isMulti: boolean): void;
|
|
123
124
|
emitElementLinkStarted(event: {
|
|
124
125
|
sourcePortId: string;
|
|
125
126
|
sourceElementId: string;
|
|
@@ -172,6 +173,14 @@ export default class DiagramEngine {
|
|
|
172
173
|
private refreshLinksForRenderCycle;
|
|
173
174
|
private normalizePortsForHostPolicies;
|
|
174
175
|
private computeRemovalDiff;
|
|
176
|
+
private resolveDeletionRoot;
|
|
177
|
+
private applyRemovalCommand;
|
|
178
|
+
private planRemoval;
|
|
179
|
+
private emitDeletionLifecycleEvents;
|
|
180
|
+
private emitElementDeleting;
|
|
181
|
+
private emitPortDeleting;
|
|
182
|
+
private emitLinkDeleting;
|
|
183
|
+
private emitTextDeleting;
|
|
175
184
|
private emitEntityDeletionEvents;
|
|
176
185
|
}
|
|
177
186
|
export declare const createDiagramEngine: (config: DiagramEngineConfig) => DiagramEngineHandle;
|
package/dist/examples.d.ts
CHANGED
|
@@ -26,6 +26,9 @@ type ViewportFitOptions = {
|
|
|
26
26
|
minZoom?: number;
|
|
27
27
|
maxZoom?: number;
|
|
28
28
|
};
|
|
29
|
+
type FocusElementOptions = {
|
|
30
|
+
zoom?: number;
|
|
31
|
+
};
|
|
29
32
|
type MoveConstraint = 'free' | 'inside' | 'border';
|
|
30
33
|
type TextInteractionPolicy = {
|
|
31
34
|
movable?: boolean;
|
|
@@ -353,6 +356,11 @@ type ElementPointerEvent = {
|
|
|
353
356
|
pointer: EnginePointerInfo;
|
|
354
357
|
isMulti: boolean;
|
|
355
358
|
};
|
|
359
|
+
type ElementDoubleClickEvent = {
|
|
360
|
+
elementId: string;
|
|
361
|
+
pointer: EnginePointerInfo;
|
|
362
|
+
isMulti: boolean;
|
|
363
|
+
};
|
|
356
364
|
type ElementMovedEvent = {
|
|
357
365
|
elementId: string;
|
|
358
366
|
oldWorld: Point;
|
|
@@ -377,18 +385,55 @@ type GridLayoutChangedEvent = {
|
|
|
377
385
|
beforeGridTemplate?: ElementLayoutGridRowTemplate[];
|
|
378
386
|
afterGridTemplate: ElementLayoutGridRowTemplate[];
|
|
379
387
|
};
|
|
388
|
+
type DeletionTrigger = 'direct' | 'selection' | 'cascade';
|
|
389
|
+
type DeletionRootRef = {
|
|
390
|
+
entity: 'element' | 'port' | 'link' | 'text';
|
|
391
|
+
id: string;
|
|
392
|
+
};
|
|
393
|
+
type ElementDeletingEvent = {
|
|
394
|
+
elementId: string;
|
|
395
|
+
trigger: DeletionTrigger;
|
|
396
|
+
root: DeletionRootRef;
|
|
397
|
+
cancel: () => void;
|
|
398
|
+
cancelled: boolean;
|
|
399
|
+
};
|
|
380
400
|
type ElementDeletedEvent = {
|
|
381
401
|
elementId: string;
|
|
382
402
|
};
|
|
403
|
+
type PortDeletingEvent = {
|
|
404
|
+
portId: string;
|
|
405
|
+
elementId: string;
|
|
406
|
+
trigger: DeletionTrigger;
|
|
407
|
+
root: DeletionRootRef;
|
|
408
|
+
cancel: () => void;
|
|
409
|
+
cancelled: boolean;
|
|
410
|
+
};
|
|
383
411
|
type PortDeletedEvent = {
|
|
384
412
|
portId: string;
|
|
385
413
|
elementId: string;
|
|
386
414
|
};
|
|
415
|
+
type LinkDeletingEvent = {
|
|
416
|
+
linkId: string;
|
|
417
|
+
sourcePortId: string;
|
|
418
|
+
targetPortId: string;
|
|
419
|
+
trigger: DeletionTrigger;
|
|
420
|
+
root: DeletionRootRef;
|
|
421
|
+
cancel: () => void;
|
|
422
|
+
cancelled: boolean;
|
|
423
|
+
};
|
|
387
424
|
type LinkDeletedEvent = {
|
|
388
425
|
linkId: string;
|
|
389
426
|
sourcePortId: string;
|
|
390
427
|
targetPortId: string;
|
|
391
428
|
};
|
|
429
|
+
type TextDeletingEvent = {
|
|
430
|
+
textId: string;
|
|
431
|
+
ownerId?: string | null;
|
|
432
|
+
trigger: DeletionTrigger;
|
|
433
|
+
root: DeletionRootRef;
|
|
434
|
+
cancel: () => void;
|
|
435
|
+
cancelled: boolean;
|
|
436
|
+
};
|
|
392
437
|
type TextDeletedEvent = {
|
|
393
438
|
textId: string;
|
|
394
439
|
ownerId?: string | null;
|
|
@@ -442,13 +487,18 @@ type EngineEventMap = {
|
|
|
442
487
|
portMoved: PortMovedEvent;
|
|
443
488
|
portSelected: PortSelectedEvent;
|
|
444
489
|
elementClick: ElementPointerEvent;
|
|
490
|
+
elementDoubleClick: ElementDoubleClickEvent;
|
|
445
491
|
elementDragged: ElementDropEvent;
|
|
446
492
|
elementMoved: ElementMovedEvent;
|
|
447
493
|
elementResized: ElementResizedEvent;
|
|
448
494
|
gridLayoutChanged: GridLayoutChangedEvent;
|
|
495
|
+
elementDeleting: ElementDeletingEvent;
|
|
449
496
|
elementDeleted: ElementDeletedEvent;
|
|
497
|
+
portDeleting: PortDeletingEvent;
|
|
450
498
|
portDeleted: PortDeletedEvent;
|
|
499
|
+
linkDeleting: LinkDeletingEvent;
|
|
451
500
|
linkDeleted: LinkDeletedEvent;
|
|
501
|
+
textDeleting: TextDeletingEvent;
|
|
452
502
|
textDeleted: TextDeletedEvent;
|
|
453
503
|
textUpdated: TextUpdatedEvent;
|
|
454
504
|
elementSelected: ElementSelectedEvent;
|
|
@@ -569,6 +619,7 @@ type DiagramEditorHandle = DiagramEngineHandle & {
|
|
|
569
619
|
completeLinkToElement: (targetElementId: string, pointer: Point) => void;
|
|
570
620
|
cancelLink: () => void;
|
|
571
621
|
zoomToFitElements: (options?: ViewportFitOptions) => void;
|
|
622
|
+
focusElement: (elementId: string, options?: FocusElementOptions) => void;
|
|
572
623
|
exportImage: (options?: DiagramImageExportOptions) => string;
|
|
573
624
|
resize: (width: number, height: number) => void;
|
|
574
625
|
setElementShapeHoverControls: (controls?: ElementShapeHoverControls) => void;
|
package/dist/index.d.ts
CHANGED
|
@@ -24,6 +24,9 @@ type ViewportFitOptions = {
|
|
|
24
24
|
minZoom?: number;
|
|
25
25
|
maxZoom?: number;
|
|
26
26
|
};
|
|
27
|
+
type FocusElementOptions = {
|
|
28
|
+
zoom?: number;
|
|
29
|
+
};
|
|
27
30
|
type MoveConstraint = 'free' | 'inside' | 'border';
|
|
28
31
|
type TextInteractionPolicy = {
|
|
29
32
|
movable?: boolean;
|
|
@@ -394,6 +397,11 @@ type ElementPointerEvent = {
|
|
|
394
397
|
pointer: EnginePointerInfo;
|
|
395
398
|
isMulti: boolean;
|
|
396
399
|
};
|
|
400
|
+
type ElementDoubleClickEvent = {
|
|
401
|
+
elementId: string;
|
|
402
|
+
pointer: EnginePointerInfo;
|
|
403
|
+
isMulti: boolean;
|
|
404
|
+
};
|
|
397
405
|
type ElementMovedEvent = {
|
|
398
406
|
elementId: string;
|
|
399
407
|
oldWorld: Point;
|
|
@@ -418,18 +426,55 @@ type GridLayoutChangedEvent = {
|
|
|
418
426
|
beforeGridTemplate?: ElementLayoutGridRowTemplate[];
|
|
419
427
|
afterGridTemplate: ElementLayoutGridRowTemplate[];
|
|
420
428
|
};
|
|
429
|
+
type DeletionTrigger = 'direct' | 'selection' | 'cascade';
|
|
430
|
+
type DeletionRootRef = {
|
|
431
|
+
entity: 'element' | 'port' | 'link' | 'text';
|
|
432
|
+
id: string;
|
|
433
|
+
};
|
|
434
|
+
type ElementDeletingEvent = {
|
|
435
|
+
elementId: string;
|
|
436
|
+
trigger: DeletionTrigger;
|
|
437
|
+
root: DeletionRootRef;
|
|
438
|
+
cancel: () => void;
|
|
439
|
+
cancelled: boolean;
|
|
440
|
+
};
|
|
421
441
|
type ElementDeletedEvent = {
|
|
422
442
|
elementId: string;
|
|
423
443
|
};
|
|
444
|
+
type PortDeletingEvent = {
|
|
445
|
+
portId: string;
|
|
446
|
+
elementId: string;
|
|
447
|
+
trigger: DeletionTrigger;
|
|
448
|
+
root: DeletionRootRef;
|
|
449
|
+
cancel: () => void;
|
|
450
|
+
cancelled: boolean;
|
|
451
|
+
};
|
|
424
452
|
type PortDeletedEvent = {
|
|
425
453
|
portId: string;
|
|
426
454
|
elementId: string;
|
|
427
455
|
};
|
|
456
|
+
type LinkDeletingEvent = {
|
|
457
|
+
linkId: string;
|
|
458
|
+
sourcePortId: string;
|
|
459
|
+
targetPortId: string;
|
|
460
|
+
trigger: DeletionTrigger;
|
|
461
|
+
root: DeletionRootRef;
|
|
462
|
+
cancel: () => void;
|
|
463
|
+
cancelled: boolean;
|
|
464
|
+
};
|
|
428
465
|
type LinkDeletedEvent = {
|
|
429
466
|
linkId: string;
|
|
430
467
|
sourcePortId: string;
|
|
431
468
|
targetPortId: string;
|
|
432
469
|
};
|
|
470
|
+
type TextDeletingEvent = {
|
|
471
|
+
textId: string;
|
|
472
|
+
ownerId?: string | null;
|
|
473
|
+
trigger: DeletionTrigger;
|
|
474
|
+
root: DeletionRootRef;
|
|
475
|
+
cancel: () => void;
|
|
476
|
+
cancelled: boolean;
|
|
477
|
+
};
|
|
433
478
|
type TextDeletedEvent = {
|
|
434
479
|
textId: string;
|
|
435
480
|
ownerId?: string | null;
|
|
@@ -483,13 +528,18 @@ type EngineEventMap = {
|
|
|
483
528
|
portMoved: PortMovedEvent;
|
|
484
529
|
portSelected: PortSelectedEvent;
|
|
485
530
|
elementClick: ElementPointerEvent;
|
|
531
|
+
elementDoubleClick: ElementDoubleClickEvent;
|
|
486
532
|
elementDragged: ElementDropEvent;
|
|
487
533
|
elementMoved: ElementMovedEvent;
|
|
488
534
|
elementResized: ElementResizedEvent;
|
|
489
535
|
gridLayoutChanged: GridLayoutChangedEvent;
|
|
536
|
+
elementDeleting: ElementDeletingEvent;
|
|
490
537
|
elementDeleted: ElementDeletedEvent;
|
|
538
|
+
portDeleting: PortDeletingEvent;
|
|
491
539
|
portDeleted: PortDeletedEvent;
|
|
540
|
+
linkDeleting: LinkDeletingEvent;
|
|
492
541
|
linkDeleted: LinkDeletedEvent;
|
|
542
|
+
textDeleting: TextDeletingEvent;
|
|
493
543
|
textDeleted: TextDeletedEvent;
|
|
494
544
|
textUpdated: TextUpdatedEvent;
|
|
495
545
|
elementSelected: ElementSelectedEvent;
|
|
@@ -857,6 +907,7 @@ type DiagramEditorHandle = DiagramEngineHandle & {
|
|
|
857
907
|
completeLinkToElement: (targetElementId: string, pointer: Point) => void;
|
|
858
908
|
cancelLink: () => void;
|
|
859
909
|
zoomToFitElements: (options?: ViewportFitOptions) => void;
|
|
910
|
+
focusElement: (elementId: string, options?: FocusElementOptions) => void;
|
|
860
911
|
exportImage: (options?: DiagramImageExportOptions) => string;
|
|
861
912
|
resize: (width: number, height: number) => void;
|
|
862
913
|
setElementShapeHoverControls: (controls?: ElementShapeHoverControls) => void;
|
|
@@ -864,4 +915,4 @@ type DiagramEditorHandle = DiagramEngineHandle & {
|
|
|
864
915
|
};
|
|
865
916
|
declare const createDiagramEditor: (config: DiagramEditorConfig) => DiagramEditorHandle;
|
|
866
917
|
|
|
867
|
-
export { type AnchorReference, type BorderSide$1 as BorderSide, type ClientRectLike, type DiagramContainer, type DiagramEditorConfig, type DiagramEditorHandle, type DiagramEngineHandle, type DiagramImageExportOptions, type DiagramPatch, type DiagramState, type EdgeHoverControl, type ElementChildInteractionPolicy, type ElementData, type ElementDeletedEvent, type ElementDropEvent, type ElementLayout, type ElementLayoutAlign, type ElementLayoutAutoResizeMode, type ElementLayoutChildFitCrossAxis, type ElementLayoutChildFitMainAxis, type ElementLayoutGridRowTemplate, type ElementLayoutLabelReservedSpace, type ElementLayoutLabelReservedSpaceMode, type ElementLayoutLabelReservedSpacePlacement, type ElementLayoutMode, type ElementLinkConnectingEvent, type ElementLinkEndedEvent, type ElementLinkStartedEvent, type ElementMovedEvent, type ElementPointerEvent, type ElementPortMovementPolicy, type ElementResizedEvent, type ElementSelectedEvent, type ElementShapeControlDragEvent, type ElementShapeControlEventType, type ElementShapeHoverControlActivationEvent, type ElementShapeHoverControlInteractionEvent, type ElementShapeHoverControls, EllipseMidPoint, type EngineChangeEvent, type EngineConfigEvent, type EngineEventMap, type EnginePointerInfo, type EngineSelectionEvent, type GridLayoutChangedEvent, type GridLayoutChangedReason, type GridRowSnapshot, type HostAnchorPreset, type HoverControlIcon, type LinkColorPoolPolicy, type LinkData, type LinkDeletedEvent, type LinkRouteRefreshMode, type LinkRouteRefreshPolicy, type LinkRoutingMode, type LinkTargetPortCreationContext, type LinkTargetPortCreationHandler, type LinkTargetPortCreationPhase, type LinkTargetPortCreationResult, type LinkTargetPortDraft, type MoveConstraint, type OverlayShapeConfig, type OverlayShapeHandle, type PaperClickEvent, type Point, type PortAnchor, type PortAnchorConstraint, type PortBorderTransformContext, type PortBorderTransformResult, type PortData, type PortDeletedEvent, type PortLinkAttachMode, type PortMouseEvent, type PortMovedEvent, type PortPositionLimits, type PortSelectedEvent, type PositionAxisLimit, type Rect, type RerouteLinksOptions, type ResolvePortAnchorsOptions, type ShapeControlDefinition, type ShapeControlTargetKind, type ShapeControlVisibilityTrigger, type ShapeDrawContext, type ShapeEdgeTarget, type ShapeEllipseMidPointTarget, type ShapeHoverGeometry, type ShapeVertexTarget, type SimpleShape, type Size, type TextData, type TextDeletedEvent, type TextInteractionPolicy, type TextLayout, type TextLayoutBoundsMode, type TextLayoutOverflowMode, type TextLayoutWrapMode, type TextSelectedEvent, type TextUpdatedEvent, type VertexHoverControl, type ViewportFitOptions, createDiagramEditor, createDiagramEngine };
|
|
918
|
+
export { type AnchorReference, type BorderSide$1 as BorderSide, type ClientRectLike, type DeletionRootRef, type DeletionTrigger, type DiagramContainer, type DiagramEditorConfig, type DiagramEditorHandle, type DiagramEngineHandle, type DiagramImageExportOptions, type DiagramPatch, type DiagramState, type EdgeHoverControl, type ElementChildInteractionPolicy, type ElementData, type ElementDeletedEvent, type ElementDeletingEvent, type ElementDoubleClickEvent, type ElementDropEvent, type ElementLayout, type ElementLayoutAlign, type ElementLayoutAutoResizeMode, type ElementLayoutChildFitCrossAxis, type ElementLayoutChildFitMainAxis, type ElementLayoutGridRowTemplate, type ElementLayoutLabelReservedSpace, type ElementLayoutLabelReservedSpaceMode, type ElementLayoutLabelReservedSpacePlacement, type ElementLayoutMode, type ElementLinkConnectingEvent, type ElementLinkEndedEvent, type ElementLinkStartedEvent, type ElementMovedEvent, type ElementPointerEvent, type ElementPortMovementPolicy, type ElementResizedEvent, type ElementSelectedEvent, type ElementShapeControlDragEvent, type ElementShapeControlEventType, type ElementShapeHoverControlActivationEvent, type ElementShapeHoverControlInteractionEvent, type ElementShapeHoverControls, EllipseMidPoint, type EngineChangeEvent, type EngineConfigEvent, type EngineEventMap, type EnginePointerInfo, type EngineSelectionEvent, type FocusElementOptions, type GridLayoutChangedEvent, type GridLayoutChangedReason, type GridRowSnapshot, type HostAnchorPreset, type HoverControlIcon, type LinkColorPoolPolicy, type LinkData, type LinkDeletedEvent, type LinkDeletingEvent, type LinkRouteRefreshMode, type LinkRouteRefreshPolicy, type LinkRoutingMode, type LinkTargetPortCreationContext, type LinkTargetPortCreationHandler, type LinkTargetPortCreationPhase, type LinkTargetPortCreationResult, type LinkTargetPortDraft, type MoveConstraint, type OverlayShapeConfig, type OverlayShapeHandle, type PaperClickEvent, type Point, type PortAnchor, type PortAnchorConstraint, type PortBorderTransformContext, type PortBorderTransformResult, type PortData, type PortDeletedEvent, type PortDeletingEvent, type PortLinkAttachMode, type PortMouseEvent, type PortMovedEvent, type PortPositionLimits, type PortSelectedEvent, type PositionAxisLimit, type Rect, type RerouteLinksOptions, type ResolvePortAnchorsOptions, type ShapeControlDefinition, type ShapeControlTargetKind, type ShapeControlVisibilityTrigger, type ShapeDrawContext, type ShapeEdgeTarget, type ShapeEllipseMidPointTarget, type ShapeHoverGeometry, type ShapeVertexTarget, type SimpleShape, type Size, type TextData, type TextDeletedEvent, type TextDeletingEvent, type TextInteractionPolicy, type TextLayout, type TextLayoutBoundsMode, type TextLayoutOverflowMode, type TextLayoutWrapMode, type TextSelectedEvent, type TextUpdatedEvent, type VertexHoverControl, type ViewportFitOptions, createDiagramEditor, createDiagramEngine };
|
package/docs/API_CONTRACT.md
CHANGED
|
@@ -105,6 +105,12 @@ Defaults:
|
|
|
105
105
|
- non-finite values fall back to defaults
|
|
106
106
|
- `minZoom`/`maxZoom` are clamped to positive values and normalized into ascending order
|
|
107
107
|
|
|
108
|
+
### `FocusElementOptions`
|
|
109
|
+
- Optional `zoom?: number`
|
|
110
|
+
- Semantics:
|
|
111
|
+
- omitted `zoom` preserves the current viewport zoom
|
|
112
|
+
- provided `zoom` is clamped to the same normalized min/max range used by viewport fit helpers
|
|
113
|
+
|
|
108
114
|
### `TextInteractionPolicy`
|
|
109
115
|
- Optional `movable?: boolean` (default behavior: `true`)
|
|
110
116
|
- Optional `editable?: boolean` (default behavior: `true`)
|
|
@@ -197,6 +203,36 @@ Defaults:
|
|
|
197
203
|
- `beforeRows` / `afterRows`: arrays of `{ childIds: string[] }` snapshots describing derived row membership before and after the topology change
|
|
198
204
|
- Emitted only when enabled grid-child width resizing causes a real row-topology change
|
|
199
205
|
|
|
206
|
+
### `ElementDoubleClickEvent`
|
|
207
|
+
- Required: `elementId`, `pointer`, `isMulti`
|
|
208
|
+
- Emitted for eligible element-body double click / double tap
|
|
209
|
+
- Observational only; does not cancel or replace the normal click-selection flow
|
|
210
|
+
|
|
211
|
+
### `DeletionTrigger`
|
|
212
|
+
- `'direct' | 'selection' | 'cascade'`
|
|
213
|
+
|
|
214
|
+
### `DeletionRootRef`
|
|
215
|
+
- Required: `entity`, `id`
|
|
216
|
+
- `entity`: `'element' | 'port' | 'link' | 'text'`
|
|
217
|
+
- `id` is the original requested delete root for the active delete pass
|
|
218
|
+
|
|
219
|
+
### `ElementDeletingEvent`
|
|
220
|
+
- Required: `elementId`, `trigger`, `root`, `cancel`, `cancelled`
|
|
221
|
+
- Emitted before an element deletion commits, including descendant element cascades
|
|
222
|
+
|
|
223
|
+
### `PortDeletingEvent`
|
|
224
|
+
- Required: `portId`, `elementId`, `trigger`, `root`, `cancel`, `cancelled`
|
|
225
|
+
- Emitted before a port deletion commits, including cascades caused by parent element removal
|
|
226
|
+
|
|
227
|
+
### `LinkDeletingEvent`
|
|
228
|
+
- Required: `linkId`, `sourcePortId`, `targetPortId`, `trigger`, `root`, `cancel`, `cancelled`
|
|
229
|
+
- Emitted before a link deletion commits, including cascades caused by element or port removal
|
|
230
|
+
|
|
231
|
+
### `TextDeletingEvent`
|
|
232
|
+
- Required: `textId`, `trigger`, `root`, `cancel`, `cancelled`
|
|
233
|
+
- Optional: `ownerId?: string | null`
|
|
234
|
+
- Emitted before a text deletion commits, including cascades caused by owner deletion
|
|
235
|
+
|
|
200
236
|
### `TextData`
|
|
201
237
|
- Required: `id`, `content`, `position`
|
|
202
238
|
- Optional: `size`, `style`, `ownerId`, `layout`, `interaction`, `displayContent`, `displayOffset`, `displayClipSize`
|
|
@@ -251,6 +287,7 @@ Defaults:
|
|
|
251
287
|
- `completeLinkToElement(targetElementId, pointer)`
|
|
252
288
|
- `cancelLink()`
|
|
253
289
|
- `zoomToFitElements(options?)`
|
|
290
|
+
- `focusElement(elementId, options?)`
|
|
254
291
|
- `exportImage(options?)`
|
|
255
292
|
- `resize(width, height)`
|
|
256
293
|
- `setElementShapeHoverControls(controls?)`
|
|
@@ -290,13 +327,18 @@ Defaults:
|
|
|
290
327
|
- `portMoved: PortMovedEvent`
|
|
291
328
|
- `portSelected: PortSelectedEvent`
|
|
292
329
|
- `elementClick: ElementPointerEvent`
|
|
330
|
+
- `elementDoubleClick: ElementDoubleClickEvent`
|
|
293
331
|
- `elementDragged: ElementDropEvent`
|
|
294
332
|
- `elementMoved: ElementMovedEvent`
|
|
295
333
|
- `elementResized: ElementResizedEvent`
|
|
296
334
|
- `gridLayoutChanged: GridLayoutChangedEvent`
|
|
335
|
+
- `elementDeleting: ElementDeletingEvent`
|
|
297
336
|
- `elementDeleted: ElementDeletedEvent`
|
|
337
|
+
- `portDeleting: PortDeletingEvent`
|
|
298
338
|
- `portDeleted: PortDeletedEvent`
|
|
339
|
+
- `linkDeleting: LinkDeletingEvent`
|
|
299
340
|
- `linkDeleted: LinkDeletedEvent`
|
|
341
|
+
- `textDeleting: TextDeletingEvent`
|
|
300
342
|
- `textDeleted: TextDeletedEvent`
|
|
301
343
|
- `textUpdated: TextUpdatedEvent`
|
|
302
344
|
- `elementSelected: ElementSelectedEvent`
|
|
@@ -312,8 +354,11 @@ Defaults:
|
|
|
312
354
|
- `zoomToFitElements` computes bounds from `elements[]` only, ignores ports/links/texts for fit expansion, and no-ops when no elements exist.
|
|
313
355
|
- `zoomToFitElements` ignores hidden elements when computing fit bounds.
|
|
314
356
|
- `zoomToFitElements` applies its result through `setViewport`, so hosts observe the standard viewport patch/change path.
|
|
357
|
+
- `focusElement(elementId, options?)` centers the target element bounds in the current editor viewport and preserves the current zoom unless `options.zoom` is provided.
|
|
358
|
+
- `focusElement(...)` no-ops when the target id does not resolve to an element world position.
|
|
315
359
|
- `exportImage({ fitToContent })` derives crop bounds from visible scene entities only.
|
|
316
360
|
- Built-in empty-paper panning now starts from plain primary-button drag and no longer requires `panKey`; marquee selection uses `Shift + primary drag`.
|
|
361
|
+
- `elementDoubleClick` is observational; normal click selection still runs, and text double click keeps built-in text-edit precedence instead of also emitting `elementDoubleClick`.
|
|
317
362
|
- `clientToWorld` uses: `world = (client - containerRect - pan) / zoom`, with zoom fallback to `1` when zoom is `0`.
|
|
318
363
|
- `rerouteLinks(ids)` skips manual links unless `options.includeManual === true`.
|
|
319
364
|
- `linkRouteRefreshPolicy.mode` defaults to `'mutation-only'`; `'redraw-two-endpoint-change'` enables redraw-cycle reroute checks for links whose two endpoints changed.
|
|
@@ -326,6 +371,8 @@ Defaults:
|
|
|
326
371
|
- Link labels use the existing text lifecycle and event surface: `addText(...)`, `moveTextTo(...)`, `updateText(...)`, `removeText(...)`, `textUpdated`, and `textDeleted`.
|
|
327
372
|
- Link-owned text defaults to unconstrained layout unless `TextLayout.boundsMode` is explicitly set; element-only owner-width defaults do not apply to link labels.
|
|
328
373
|
- `gridLayoutChanged` is additive and does not replace standard `change` / `elementResized` flows.
|
|
374
|
+
- Deletion mutators emit cancellable `elementDeleting` / `portDeleting` / `linkDeleting` / `textDeleting` before commit and matching `...Deleted` events after successful removal.
|
|
375
|
+
- Canceling any dependent `...Deleting` event aborts the current root deletion request; `deleteSelection()` still continues evaluating unrelated selected roots.
|
|
329
376
|
- `ElementData.visible = false` hides only the element body from built-in renderer sync, hit testing, marquee selection, persisted selection, and fit/export helpers.
|
|
330
377
|
- Descendant element visibility is not suppressed by hidden ancestors; direct-owned parent ports/texts still follow the hidden parent, and links remain visible whenever both endpoint ports are visible.
|
|
331
378
|
- `ElementData.selectable = false` blocks built-in element-body selection while still allowing visible owned ports to participate in their normal interaction flows.
|
|
@@ -334,7 +381,7 @@ Defaults:
|
|
|
334
381
|
- `TextData.interaction.movable = false` blocks built-in drag only; selection still works and programmatic movement remains allowed.
|
|
335
382
|
- `TextData.interaction.editable = false` blocks built-in textarea editing only; selection still works and programmatic text updates remain allowed.
|
|
336
383
|
- Text layout/overflow resolution updates `displayContent` and emits `textUpdated` when `updateText` is called.
|
|
337
|
-
-
|
|
384
|
+
- Successful cascade removal still emits the matching dependent `...Deleted` events for removed entities.
|
|
338
385
|
|
|
339
386
|
## Verification References
|
|
340
387
|
- `src/api/__tests__/createDiagramEditor.test.ts`
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
> Sections: [Module Boundaries](#module-boundaries) | [Runtime Flow](#runtime-flow) | [Integration Boundary](#integration-boundary) | [Key Sources](#key-sources)
|
|
4
4
|
|
|
5
5
|
## Module Boundaries
|
|
6
|
-
- `src/api/`: public entry points and
|
|
7
|
-
- `src/engine/`: command execution, event bus, selection, viewport, routing/snap integration.
|
|
6
|
+
- `src/api/`: public entry points, type contracts, and editor-only helpers such as `zoomToFitElements(...)` and `focusElement(...)`.
|
|
7
|
+
- `src/engine/`: command execution, event bus, selection, viewport, routing/snap integration, and delete-lifecycle orchestration.
|
|
8
8
|
- `src/engine/`: `DiagramEngine` orchestration plus extracted services (`TextLayoutService`, `AutoLayoutService`, `LinkRoutingService`, `MutationPipeline`).
|
|
9
9
|
- `src/models/`: in-memory state graph for elements/ports/links/texts.
|
|
10
10
|
- `src/renderer/`: renderer interface and shape registry contracts.
|
|
@@ -14,15 +14,17 @@
|
|
|
14
14
|
- `src/utils/`: geometry, patch helpers, guards, ids.
|
|
15
15
|
|
|
16
16
|
## Runtime Flow
|
|
17
|
-
1. Host calls API mutator.
|
|
18
|
-
2.
|
|
19
|
-
3. Engine
|
|
20
|
-
4.
|
|
21
|
-
5.
|
|
17
|
+
1. Host calls API mutator or editor helper.
|
|
18
|
+
2. Interaction or API helper resolves target intent and any required lifecycle hooks.
|
|
19
|
+
3. Engine executes command(s) against model or applies viewport state updates.
|
|
20
|
+
4. Engine emits patches + latest state via `change`.
|
|
21
|
+
5. Scheduler requests render.
|
|
22
|
+
6. Renderer syncs model to view nodes.
|
|
22
23
|
|
|
23
24
|
## Integration Boundary
|
|
24
25
|
- Engine core does not require Konva if you use `createDiagramEngine` with a custom `Renderer`.
|
|
25
26
|
- `createDiagramEditor` wires Konva stage, hit testing, and interaction defaults.
|
|
27
|
+
- The Konva-backed editor surface also owns editor-only navigation helpers such as `focusElement(...)`.
|
|
26
28
|
|
|
27
29
|
## Key Sources
|
|
28
30
|
- `src/api/createDiagramEditor.ts`
|
package/docs/CAPABILITIES.md
CHANGED
|
@@ -18,7 +18,10 @@
|
|
|
18
18
|
- Optional grid-child width topology editing with `gridLayoutChanged` host events.
|
|
19
19
|
- Parent-owned direct-child drag suppression through `ElementData.childElementInteraction`.
|
|
20
20
|
- Element-level visibility/selectability policy through `ElementData.visible` and `ElementData.selectable`, with element-body-only hiding, direct-owned port/text suppression, and visible descendants that keep their own links/rendering behavior.
|
|
21
|
+
- Host-callable viewport focus through `focusElement(elementId, options?)`.
|
|
21
22
|
- Element shape hover controls with edge/vertex/midpoint targets and interaction callbacks.
|
|
23
|
+
- Observational `elementDoubleClick` event for element-body double click / double tap.
|
|
24
|
+
- Cancellable delete lifecycle events (`elementDeleting`, `portDeleting`, `linkDeleting`, `textDeleting`) before direct, selection, and cascade removals commit.
|
|
22
25
|
- Link labels through link-owned `TextData`, including midpoint-relative attachment that follows reroute and endpoint movement.
|
|
23
26
|
- Optional host callback for shaping auto-created destination ports during link-to-element preview and commit.
|
|
24
27
|
- Optional random link color assignment from configurable pools during link creation, plus opt-in load-time fill for links missing `style.stroke`.
|
package/docs/COMMANDS_EVENTS.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
- Engine mutators route through command factories in `src/engine/EngineCommands.ts`.
|
|
7
7
|
- Each command applies model mutation and returns one or more patches.
|
|
8
8
|
- `emitChange` publishes `{ patches, state }` on `change`.
|
|
9
|
-
- Editor helpers such as `zoomToFitElements(options?)` compose existing
|
|
9
|
+
- Editor helpers such as `zoomToFitElements(options?)` and `focusElement(elementId, options?)` compose existing viewport updates rather than introducing separate patch types.
|
|
10
10
|
|
|
11
11
|
## Patch Entities
|
|
12
12
|
- `element`
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
## Mutation To Events Mapping
|
|
21
21
|
- `add/move/resize/remove element`
|
|
22
22
|
- Always `change`
|
|
23
|
-
- Plus `elementMoved`, `elementResized`, or `elementDeleted` when applicable
|
|
23
|
+
- Plus `elementMoved`, `elementResized`, `elementDeleting`, or `elementDeleted` when applicable
|
|
24
24
|
- `resize element` with enabled grid-child width topology editing
|
|
25
25
|
- Standard `change`
|
|
26
26
|
- Standard `elementResized` when size changes
|
|
@@ -28,22 +28,26 @@
|
|
|
28
28
|
- `add/move/remove port`
|
|
29
29
|
- Always `change`
|
|
30
30
|
- Plus `portMoved` on effective movement
|
|
31
|
-
- Plus `portDeleted` on removal (including cascade removal)
|
|
31
|
+
- Plus `portDeleting` before removal and `portDeleted` on successful removal (including cascade removal)
|
|
32
32
|
- `add/update/remove link`
|
|
33
33
|
- Always `change`
|
|
34
|
-
- Plus `linkDeleted` on removal (including cascade removal)
|
|
34
|
+
- Plus `linkDeleting` before removal and `linkDeleted` on successful removal (including cascade removal)
|
|
35
35
|
- `add/update/move/remove text`
|
|
36
36
|
- Always `change`
|
|
37
37
|
- Plus `textUpdated` when `updateText` resolves display layout
|
|
38
|
-
- Plus `textDeleted` on removal (including cascade removal)
|
|
38
|
+
- Plus `textDeleting` before removal and `textDeleted` on successful removal (including cascade removal)
|
|
39
39
|
- `setSelection/toggleSelection/deleteSelection`
|
|
40
40
|
- `selection` plus derived selected entity events
|
|
41
|
+
- `deleteSelection` evaluates each selected root independently, so a vetoed root can be skipped while unrelated roots still delete
|
|
41
42
|
- hidden element bodies, direct-owned hidden artifacts, and `selectable:false` element IDs are filtered out before selection persists/emits
|
|
42
43
|
- `setViewport`
|
|
43
44
|
- `change` with viewport patch (`render: false`)
|
|
44
45
|
- `zoomToFitElements`
|
|
45
46
|
- delegates to `setViewport` when at least one visible element exists
|
|
46
47
|
- emits the same viewport `change` patch path
|
|
48
|
+
- `focusElement`
|
|
49
|
+
- delegates to `setViewport` when the target element resolves
|
|
50
|
+
- preserves the current zoom unless `options.zoom` is supplied
|
|
47
51
|
- `setRouting/setSnapping/registerShape`
|
|
48
52
|
- `config` events
|
|
49
53
|
|
|
@@ -53,6 +57,8 @@
|
|
|
53
57
|
- legacy `element-drop`
|
|
54
58
|
- `elementDragged`
|
|
55
59
|
- Click paper: `paperClick`
|
|
60
|
+
- Double click/tap element body:
|
|
61
|
+
- `elementDoubleClick`
|
|
56
62
|
- Linking:
|
|
57
63
|
- `elementLinkStarted`
|
|
58
64
|
- optional `onCreateLinkTargetPort(...)` preview/commit shaping for link-to-element completion
|
|
@@ -60,13 +66,16 @@
|
|
|
60
66
|
- `elementLinkEnded`
|
|
61
67
|
|
|
62
68
|
## Preconditions
|
|
63
|
-
- Events are emitted only after engine state transition logic.
|
|
69
|
+
- Events are emitted only after engine state transition logic resolves a valid action.
|
|
70
|
+
- Cancellable `...Deleting` events emit before the corresponding mutation commits.
|
|
64
71
|
- Derived events require selected IDs to resolve to known entity types.
|
|
65
72
|
|
|
66
73
|
## Failure Modes
|
|
67
74
|
- Unknown IDs do not emit entity-specific movement/selection events.
|
|
68
75
|
- Canceled link creation emits `elementLinkEnded` with `cancelled=true` and no link creation.
|
|
76
|
+
- `focusElement(...)` emits no viewport change when the target element id does not resolve.
|
|
69
77
|
- Built-in element-body selection emits no persisted element selection when the target element is hidden or sets `selectable = false`.
|
|
78
|
+
- Text double click continues text editing precedence and does not also emit `elementDoubleClick`.
|
|
70
79
|
- Built-in drag on a direct child element emits no move/drop mutation when its parent sets `childElementInteraction.movable = false`.
|
|
71
80
|
- `textUpdated` emits only when target text exists; missing IDs remain no-op.
|
|
72
81
|
|
|
@@ -59,7 +59,7 @@ When resuming later:
|
|
|
59
59
|
5. Re-run packaging verification.
|
|
60
60
|
|
|
61
61
|
## 6. Current Status
|
|
62
|
-
- Last updated: 2026-
|
|
62
|
+
- Last updated: 2026-07-07
|
|
63
63
|
- Last completed step: 10
|
|
64
64
|
- Next step: 7 (optional additional fixture coverage for deeper nested/manual-route scenarios)
|
|
65
65
|
- Owner: Codex (with repository maintainers)
|
|
@@ -93,3 +93,5 @@ When resuming later:
|
|
|
93
93
|
- 2026-06-20: Ran release validations: `npm run typecheck`, `npm test -- --watchAll=false`, `npm run build`, `npm run rollup-build-lib`, and `npm pack --dry-run`.
|
|
94
94
|
- 2026-06-26: Completed release-doc pass for `v0.2.12`; refreshed release highlights, link-created target-port callback contract text, integration guidance, and machine-readable contract metadata.
|
|
95
95
|
- 2026-06-26: Ran release validations: `npm run typecheck`, `npm test -- --watchAll=false`, `npm run build`, `npm run rollup-build-lib`, and `npm pack --dry-run`.
|
|
96
|
+
- 2026-07-07: Completed release-doc pass for `v0.2.13`; refreshed release highlights, focus/navigation and delete-lifecycle API/event docs, and machine-readable contract metadata.
|
|
97
|
+
- 2026-07-07: Ran release validations: `npm run typecheck`, `npm test -- --watchAll=false`, `npm run build`, `npm run rollup-build-lib`, and `npm pack --dry-run`.
|
|
@@ -23,6 +23,8 @@ Embed this library into another diagram host while preserving deterministic stat
|
|
|
23
23
|
10. Set `linkColorPoolPolicy` when hosts want random link colors on creation and optional load-time backfill for loaded links whose `style.stroke` is missing or blank.
|
|
24
24
|
11. Create link labels with ordinary `TextData` by setting `ownerId` to the target link id; the stored `position` is midpoint-relative for link-owned text rather than a free world-space coordinate.
|
|
25
25
|
12. Set `onCreateLinkTargetPort` when hosts need to customize the auto-created destination port for link-to-element drops; keep using `elementLinkConnecting` when the host needs to cancel the drop entirely.
|
|
26
|
+
13. Use `focusElement(elementId, options?)` when the host needs to center one editor element in response to navigation, search, or external selection.
|
|
27
|
+
14. Subscribe to `elementDoubleClick` and cancellable `...Deleting` events when the host needs double-click intent or pre-delete confirmation/guard logic.
|
|
26
28
|
|
|
27
29
|
## Path B: Engine-Only Adapter
|
|
28
30
|
1. Implement `Renderer`:
|
|
@@ -42,9 +44,11 @@ Embed this library into another diagram host while preserving deterministic stat
|
|
|
42
44
|
- host edge label -> `TextData` with `ownerId = link.id`
|
|
43
45
|
- Event mapping:
|
|
44
46
|
- host click -> `setSelection` / `emitElementClick`-equivalent behavior
|
|
47
|
+
- host double click / double tap -> `elementDoubleClick`
|
|
45
48
|
- host drag end -> `emitElementDrop`-equivalent payload
|
|
46
49
|
- host link gesture -> `elementLinkStarted/Connecting/Ended` lifecycle
|
|
47
50
|
- optional host target-port shaping -> `onCreateLinkTargetPort(...)` for link-to-element preview/commit only
|
|
51
|
+
- host delete confirmation / veto surface -> cancellable `elementDeleting` / `portDeleting` / `linkDeleting` / `textDeleting`
|
|
48
52
|
|
|
49
53
|
## Behavioral Checklist Per Integration Step
|
|
50
54
|
- Preconditions
|
|
@@ -32,14 +32,17 @@
|
|
|
32
32
|
- Ensure host can emulate:
|
|
33
33
|
- `elementDrop` + legacy `element-drop`
|
|
34
34
|
- `paperClick`
|
|
35
|
+
- `elementDoubleClick`
|
|
35
36
|
- `elementLinkStarted/Connecting/Ended`
|
|
36
37
|
- `portMouseDown/portMouseUp`
|
|
37
|
-
-
|
|
38
|
+
- cancellable delete lifecycle events (`elementDeleting`, `portDeleting`, `linkDeleting`, `textDeleting`)
|
|
39
|
+
- post-delete and text lifecycle events (`elementDeleted`, `portDeleted`, `linkDeleted`, `textDeleted`, `textUpdated`)
|
|
38
40
|
|
|
39
41
|
## 6. Verify Cascading Deletes
|
|
40
42
|
- Deleting element should remove descendant ports, connected links, owned texts.
|
|
41
43
|
- Deleting port should remove connected links and owned texts.
|
|
42
44
|
- Deleting link should remove owned texts.
|
|
45
|
+
- A veto from any `...Deleting` handler should abort that root delete request before mutation commit.
|
|
43
46
|
|
|
44
47
|
## 7. Run Fixture-Based Validation
|
|
45
48
|
- Load fixtures from `fixtures/*.json`.
|