orcasvn-react-diagrams 0.2.11 → 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.
Files changed (55) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +15 -7
  3. package/ai/api-contract.json +90 -1
  4. package/ai/invariants.json +6 -2
  5. package/ai/manifest.json +1 -1
  6. package/dist/cjs/examples.js +916 -331
  7. package/dist/cjs/index.js +406 -97
  8. package/dist/cjs/types/api/createDiagramEditor.d.ts +3 -1
  9. package/dist/cjs/types/api/types.d.ts +64 -0
  10. package/dist/cjs/types/displaybox/demos/LinkPortCreationDemoTab.d.ts +3 -0
  11. package/dist/cjs/types/displaybox/demos/deletionEventsDemo.d.ts +2 -0
  12. package/dist/cjs/types/displaybox/demos/focusElementDemo.d.ts +4 -0
  13. package/dist/cjs/types/displaybox/demos/linkLabelsDemo.d.ts +4 -0
  14. package/dist/cjs/types/displaybox/types.d.ts +3 -0
  15. package/dist/cjs/types/displaybox/useDemoEditor.d.ts +3 -2
  16. package/dist/cjs/types/engine/DiagramEngine.d.ts +11 -1
  17. package/dist/cjs/types/engine/TextLayoutService.d.ts +1 -0
  18. package/dist/cjs/types/examples/index.d.ts +1 -1
  19. package/dist/cjs/types/renderer/konva/KonvaInteraction.d.ts +10 -1
  20. package/dist/esm/examples.js +916 -331
  21. package/dist/esm/examples.js.map +1 -1
  22. package/dist/esm/index.js +406 -97
  23. package/dist/esm/index.js.map +1 -1
  24. package/dist/esm/types/api/createDiagramEditor.d.ts +3 -1
  25. package/dist/esm/types/api/types.d.ts +64 -0
  26. package/dist/esm/types/displaybox/demos/LinkPortCreationDemoTab.d.ts +3 -0
  27. package/dist/esm/types/displaybox/demos/deletionEventsDemo.d.ts +2 -0
  28. package/dist/esm/types/displaybox/demos/focusElementDemo.d.ts +4 -0
  29. package/dist/esm/types/displaybox/demos/linkLabelsDemo.d.ts +4 -0
  30. package/dist/esm/types/displaybox/types.d.ts +3 -0
  31. package/dist/esm/types/displaybox/useDemoEditor.d.ts +3 -2
  32. package/dist/esm/types/engine/DiagramEngine.d.ts +11 -1
  33. package/dist/esm/types/engine/TextLayoutService.d.ts +1 -0
  34. package/dist/esm/types/examples/index.d.ts +1 -1
  35. package/dist/esm/types/renderer/konva/KonvaInteraction.d.ts +10 -1
  36. package/dist/examples.d.ts +55 -1
  37. package/dist/index.d.ts +67 -1
  38. package/docs/API_CONTRACT.md +88 -1
  39. package/docs/ARCHITECTURE.md +9 -7
  40. package/docs/CAPABILITIES.md +5 -0
  41. package/docs/COMMANDS_EVENTS.md +16 -6
  42. package/docs/DOCUMENTATION_WORKFLOW.md +5 -1
  43. package/docs/INTEGRATION_PLAYBOOK.md +8 -0
  44. package/docs/PORTING_CHECKLIST.md +4 -1
  45. package/docs/STATE_INVARIANTS.md +3 -0
  46. package/package.json +1 -1
  47. package/src/displaybox/demos/DeletionEventsDemoTab.tsx +167 -9
  48. package/src/displaybox/demos/LinkPortCreationDemoTab.tsx +98 -0
  49. package/src/displaybox/demos/deletionEventsDemo.ts +2 -2
  50. package/src/displaybox/demos/focusElementDemo.ts +91 -0
  51. package/src/displaybox/demos/index.tsx +124 -221
  52. package/src/displaybox/demos/linkLabelsDemo.ts +164 -0
  53. package/src/displaybox/demos/linkPortCreationDemo.ts +7 -7
  54. package/src/displaybox/types.ts +21 -11
  55. package/src/examples/index.ts +1 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,33 @@
2
2
 
3
3
  All notable changes to this project are documented in this file.
4
4
 
5
+ ## [0.2.13] - 2026-07-07
6
+
7
+ ### Added
8
+ - Host-callable `focusElement(elementId, options?)` editor helper for centering one target element and optionally applying an explicit zoom.
9
+ - Observational `elementDoubleClick` event for element-body double click / double tap without replacing ordinary click selection or text-edit precedence.
10
+ - Cancellable `elementDeleting`, `portDeleting`, `linkDeleting`, and `textDeleting` lifecycle events that fire before direct, selection-driven, or cascade removals commit.
11
+
12
+ ### Changed
13
+ - Delete requests now evaluate the full cascade plan before mutation commit, so a veto from any dependent `...Deleting` handler aborts that root delete request while unrelated selected roots can still continue deleting.
14
+ - `focusElement(...)` resolves nested and hidden elements by explicit id, preserves the current zoom by default, and uses the same viewport patch path as `setViewport(...)`.
15
+
16
+ ### Docs
17
+ - Updated release highlights, architecture/API/event docs, integration guidance, and machine-readable contract/invariant metadata for `v0.2.13`.
18
+
19
+ ## [0.2.12] - 2026-06-26
20
+
21
+ ### Added
22
+ - Optional `onCreateLinkTargetPort(context)` editor config callback for customizing the auto-created destination port when a link completes onto an element body.
23
+ - Supported link labels through ordinary link-owned `TextData` (`ownerId = link.id`) without introducing a separate `LinkData.label` field.
24
+
25
+ ### Changed
26
+ - Link-to-element placeholder preview, pointer-drop commit, and programmatic `completeLinkToElement(...)` now share the same target-port draft resolution and normalization flow before `elementLinkConnecting` runs.
27
+ - Link-owned text now behaves as an explicit public label contract: midpoint-relative positioning is preserved across drag, reroute, export-fit bounds, and link-removal cascade deletion.
28
+
29
+ ### Docs
30
+ - Updated release highlights, API/integration docs, state invariants, and machine-readable contract metadata for `v0.2.12`.
31
+
5
32
  ## [0.2.11] - 2026-06-20
6
33
 
7
34
  ### Added
package/README.md CHANGED
@@ -30,13 +30,21 @@ editor.addElement({
30
30
  });
31
31
  ```
32
32
 
33
- ## Release Highlights (v0.2.11)
34
-
35
- - Includes all completed `v0.2.1` through `v0.2.10` work, plus `v0.2.11` updates.
36
- - `v0.2.11` link color pool load-time fill:
37
- - `linkColorPoolPolicy.assignOnLoadWhenMissingStroke = true` backfills loaded links whose `style.stroke` is missing, `null`, or blank after trimming
38
- - explicit non-empty loaded `style.stroke` values are preserved exactly as loaded
39
- - the fill uses normalized custom `colors` when provided, otherwise the built-in 20-color pool
33
+ ## Release Highlights (v0.2.13)
34
+
35
+ - Includes all completed `v0.2.1` through `v0.2.12` work, plus `v0.2.13` updates.
36
+ - `v0.2.13` delete lifecycle guards:
37
+ - subscribe to `elementDeleting`, `portDeleting`, `linkDeleting`, or `textDeleting` to inspect a delete request before it commits
38
+ - each guard receives `trigger`, `root`, `cancel()`, and `cancelled` so hosts can veto direct, selection, or cascade removals
39
+ - a veto aborts the current root delete request without preventing unrelated selected roots from continuing
40
+ - `v0.2.13` viewport navigation helper:
41
+ - `focusElement(elementId, options?)` centers one target element by id
42
+ - current zoom is preserved by default, or hosts may pass `zoom`
43
+ - nested and hidden elements still resolve through the same world-position logic as the rest of the editor
44
+ - `v0.2.13` element double click event:
45
+ - subscribe to `elementDoubleClick` to observe double click / double tap on element bodies
46
+ - ordinary click selection still works as before
47
+ - text double click continues to prioritize built-in text editing
40
48
 
41
49
  ## API Docs
42
50
 
@@ -28,6 +28,7 @@
28
28
  "elementShapeHoverControls": "ElementShapeHoverControls",
29
29
  "onElementShapeHoverControlInteraction": "(event: ElementShapeHoverControlInteractionEvent) => void",
30
30
  "onElementShapeHoverControlActivated": "(event: ElementShapeHoverControlActivationEvent) => void",
31
+ "onCreateLinkTargetPort": "(context: LinkTargetPortCreationContext) => Partial<LinkTargetPortDraft> | void",
31
32
  "onChange": "(event: EngineChangeEvent) => void",
32
33
  "onSelection": "(event: EngineSelectionEvent) => void",
33
34
  "linkRouteRefreshPolicy": "LinkRouteRefreshPolicy",
@@ -138,6 +139,11 @@
138
139
  "defaults": {
139
140
  "routing": "auto",
140
141
  "textIds": []
142
+ },
143
+ "ownershipSemantics": {
144
+ "linkLabels": "Represent link labels as TextData with ownerId = link.id",
145
+ "linkTextIds": "LinkData.textIds is the owner-side index only",
146
+ "dedicatedLabelField": "No LinkData.label or LinkData.labels field"
141
147
  }
142
148
  },
143
149
  "textData": {
@@ -158,6 +164,12 @@
158
164
  ],
159
165
  "defaults": {
160
166
  "ownerId": null
167
+ },
168
+ "ownershipSemantics": {
169
+ "elementOwnedPosition": "owner-relative local position",
170
+ "portOwnedPosition": "owner-relative local position",
171
+ "linkOwnedPosition": "local offset from the owning link midpoint",
172
+ "missingOwner": "falls back to standalone world-position text"
161
173
  }
162
174
  },
163
175
  "elementLayoutDefaults": {
@@ -202,7 +214,8 @@
202
214
  "overflow": "'clip' | 'ellipsis-end' | 'ellipsis-middle' | 'ellipsis-start'",
203
215
  "padding": "number",
204
216
  "maxLines": "number",
205
- "fixedSize": "Size"
217
+ "fixedSize": "Size",
218
+ "linkOwnedDefault": "link-owned text does not implicitly default to owner-width or owner-box bounds"
206
219
  },
207
220
  "textInteractionPolicy": {
208
221
  "movable": "boolean",
@@ -262,6 +275,42 @@
262
275
  "assignOnLoadWhenMissingStroke": "boolean",
263
276
  "defaultPoolSize": 20
264
277
  },
278
+ "linkTargetPortCreation": {
279
+ "phase": "'preview' | 'commit'",
280
+ "draft": "Omit<PortData, 'id' | 'elementId'>",
281
+ "context": {
282
+ "phase": "LinkTargetPortCreationPhase",
283
+ "pointer": "Point",
284
+ "sourcePortId": "string",
285
+ "sourceElementId": "string",
286
+ "targetElementId": "string",
287
+ "sourcePort": "PortData",
288
+ "targetElement": "ElementData",
289
+ "defaultPort": "LinkTargetPortDraft"
290
+ },
291
+ "result": "Partial<LinkTargetPortDraft> | void",
292
+ "behavior": [
293
+ "runs only for link-to-element completion, not port-to-port linking or direct addPortToElement",
294
+ "preview and commit both invoke the callback before final target-port normalization against the target element",
295
+ "elementLinkConnecting remains the only cancellation surface"
296
+ ]
297
+ },
298
+ "linkLabelOwnership": {
299
+ "creation": "Create a link label with addText({ ownerId: linkId, ... })",
300
+ "storage": "Persist TextData.position as midpoint-relative local offset for link-owned text",
301
+ "rerouteBehavior": "Keep the stored local offset and recompute world position from the latest link midpoint",
302
+ "events": [
303
+ "textUpdated",
304
+ "textDeleted"
305
+ ]
306
+ },
307
+ "focusElementOptions": {
308
+ "zoom": "number",
309
+ "behavior": [
310
+ "omitted zoom preserves the current viewport zoom",
311
+ "provided zoom is clamped to the same normalized fit-zoom bounds"
312
+ ]
313
+ },
265
314
  "viewportFitOptions": {
266
315
  "padding": "number",
267
316
  "minZoom": "number",
@@ -281,6 +330,40 @@
281
330
  "beforeGridTemplate": "number[]",
282
331
  "afterGridTemplate": "number[]"
283
332
  },
333
+ "elementDoubleClickEvent": {
334
+ "elementId": "string",
335
+ "pointer": "EnginePointerInfo",
336
+ "isMulti": "boolean"
337
+ },
338
+ "deletionLifecycle": {
339
+ "trigger": "'direct' | 'selection' | 'cascade'",
340
+ "root": {
341
+ "entity": "'element' | 'port' | 'link' | 'text'",
342
+ "id": "string"
343
+ },
344
+ "sharedFields": [
345
+ "trigger",
346
+ "root",
347
+ "cancel",
348
+ "cancelled"
349
+ ],
350
+ "elementDeleting": {
351
+ "elementId": "string"
352
+ },
353
+ "portDeleting": {
354
+ "portId": "string",
355
+ "elementId": "string"
356
+ },
357
+ "linkDeleting": {
358
+ "linkId": "string",
359
+ "sourcePortId": "string",
360
+ "targetPortId": "string"
361
+ },
362
+ "textDeleting": {
363
+ "textId": "string",
364
+ "ownerId": "string | null"
365
+ }
366
+ },
284
367
  "diagramImageExportOptions": {
285
368
  "mimeType": "string",
286
369
  "quality": "number",
@@ -332,6 +415,7 @@
332
415
  "completeLinkToElement",
333
416
  "cancelLink",
334
417
  "zoomToFitElements",
418
+ "focusElement",
335
419
  "exportImage",
336
420
  "resize",
337
421
  "setElementShapeHoverControls",
@@ -350,13 +434,18 @@
350
434
  "portMoved": "PortMovedEvent",
351
435
  "portSelected": "PortSelectedEvent",
352
436
  "elementClick": "ElementPointerEvent",
437
+ "elementDoubleClick": "ElementDoubleClickEvent",
353
438
  "elementDragged": "ElementDropEvent",
354
439
  "elementMoved": "ElementMovedEvent",
355
440
  "elementResized": "ElementResizedEvent",
356
441
  "gridLayoutChanged": "GridLayoutChangedEvent",
442
+ "elementDeleting": "ElementDeletingEvent",
357
443
  "elementDeleted": "ElementDeletedEvent",
444
+ "portDeleting": "PortDeletingEvent",
358
445
  "portDeleted": "PortDeletedEvent",
446
+ "linkDeleting": "LinkDeletingEvent",
359
447
  "linkDeleted": "LinkDeletedEvent",
448
+ "textDeleting": "TextDeletingEvent",
360
449
  "textDeleted": "TextDeletedEvent",
361
450
  "textUpdated": "TextUpdatedEvent",
362
451
  "elementSelected": "ElementSelectedEvent",
@@ -28,10 +28,12 @@
28
28
  "link": [
29
29
  "link visible-state requires both endpoint ports to remain visible",
30
30
  "manual routing preserves interior bend points on endpoint updates",
31
- "auto routing normalizes first/last points to source/target port world positions"
31
+ "auto routing normalizes first/last points to source/target port world positions",
32
+ "deleting a link removes any link-owned text"
32
33
  ],
33
34
  "text": [
34
35
  "owner-bound text stores owner-relative position",
36
+ "link-owned text stores position as an offset from the owning link midpoint",
35
37
  "owned text visible-state follows its resolved owner visibility",
36
38
  "orphan owner references are tolerated as standalone world text",
37
39
  "displayContent/displayOffset/displayClipSize may be derived from text layout rules"
@@ -41,7 +43,9 @@
41
43
  "mutations emit change with patches and full state snapshot",
42
44
  "setSelection/toggleSelection normalize away hidden element bodies, direct-owned hidden artifacts, and selectable=false element ids before emitting selection",
43
45
  "setSelection emits selection plus derived selected entity events",
44
- "setViewport emits viewport patch without immediate render"
46
+ "setViewport emits viewport patch without immediate render",
47
+ "delete mutators emit cancellable elementDeleting/portDeleting/linkDeleting/textDeleting before commit and matching deleted events after successful removal",
48
+ "deleteSelection can skip a vetoed selected root while continuing unrelated selected roots"
45
49
  ],
46
50
  "verificationTests": [
47
51
  "src/models/__tests__/DiagramModel.test.ts",
package/ai/manifest.json CHANGED
@@ -30,5 +30,5 @@
30
30
  "analysis/White paper/Overview.md",
31
31
  "analysis/White paper/Requirements-Functional.md"
32
32
  ],
33
- "updatedAt": "2026-06-20"
33
+ "updatedAt": "2026-07-07"
34
34
  }