@likec4/diagram 1.27.0 → 1.27.1

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 (57) hide show
  1. package/bundle/index.js +327 -281
  2. package/dist/LikeC4Diagram.js +2 -8
  3. package/dist/base/primitives/compound/CompoundNodeContainer.js +1 -1
  4. package/dist/base/primitives/edge/EdgeLabel.css.js +1 -4
  5. package/dist/base/primitives/edge/EdgeLabelContainer.js +1 -1
  6. package/dist/base/primitives/edge/EdgePath.js +0 -3
  7. package/dist/base/primitives/edge/edge.css.js +2 -0
  8. package/dist/base/primitives/element/ElementNodeContainer.css.js +1 -0
  9. package/dist/base/primitives/element/ElementShape.css.js +1 -12
  10. package/dist/base/primitives/element/ElementTitle.css.js +3 -2
  11. package/dist/base/types.js +2 -2
  12. package/dist/components/Link.js +1 -1
  13. package/dist/hooks/useDiagram.d.ts +320 -490
  14. package/dist/likec4diagram/DiagramXYFlow.js +10 -9
  15. package/dist/likec4diagram/custom/edges/RelationshipEdge.js +30 -41
  16. package/dist/likec4diagram/custom/nodes/toolbar/Toolbar.js +1 -1
  17. package/dist/likec4diagram/custom/nodes/toolbar/styles.css.js +6 -1
  18. package/dist/likec4diagram/ui/controls/LayoutDriftNotification.js +13 -5
  19. package/dist/likec4diagram/useLayoutConstraints.d.ts +11 -10
  20. package/dist/likec4diagram/useLayoutConstraints.js +64 -61
  21. package/dist/overlays/Overlays.js +2 -2
  22. package/dist/overlays/overlay/Overlay.css.js +31 -12
  23. package/dist/overlays/overlay/Overlay.js +30 -27
  24. package/dist/overlays/relationship-details/useLayoutedDetails.js +1 -1
  25. package/dist/overlays/relationships-browser/SelectElement.js +4 -4
  26. package/dist/state/DiagramActorProvider.d.ts +4 -2
  27. package/dist/state/DiagramActorProvider.js +30 -37
  28. package/dist/state/assign.js +2 -2
  29. package/dist/state/diagram-machine.d.ts +450 -608
  30. package/dist/state/diagram-machine.js +87 -57
  31. package/dist/styles.css.js +1 -1
  32. package/package.json +5 -5
  33. package/src/LikeC4Diagram.tsx +1 -7
  34. package/src/base/primitives/compound/CompoundNodeContainer.tsx +1 -1
  35. package/src/base/primitives/edge/EdgeLabel.css.ts +1 -4
  36. package/src/base/primitives/edge/EdgeLabelContainer.tsx +1 -1
  37. package/src/base/primitives/edge/EdgePath.tsx +0 -3
  38. package/src/base/primitives/edge/edge.css.ts +2 -0
  39. package/src/base/primitives/element/ElementNodeContainer.css.ts +1 -0
  40. package/src/base/primitives/element/ElementShape.css.ts +1 -12
  41. package/src/base/primitives/element/ElementTitle.css.ts +3 -2
  42. package/src/base/types.ts +2 -7
  43. package/src/components/Link.tsx +3 -1
  44. package/src/likec4diagram/DiagramXYFlow.tsx +11 -9
  45. package/src/likec4diagram/custom/edges/RelationshipEdge.tsx +39 -48
  46. package/src/likec4diagram/custom/nodes/toolbar/Toolbar.tsx +2 -2
  47. package/src/likec4diagram/custom/nodes/toolbar/styles.css.ts +5 -0
  48. package/src/likec4diagram/ui/controls/LayoutDriftNotification.tsx +8 -4
  49. package/src/likec4diagram/useLayoutConstraints.ts +84 -89
  50. package/src/overlays/Overlays.tsx +2 -2
  51. package/src/overlays/overlay/Overlay.css.ts +30 -12
  52. package/src/overlays/overlay/Overlay.tsx +35 -29
  53. package/src/overlays/relationship-details/useLayoutedDetails.ts +1 -1
  54. package/src/overlays/relationships-browser/SelectElement.tsx +5 -5
  55. package/src/state/DiagramActorProvider.tsx +40 -50
  56. package/src/state/assign.ts +2 -2
  57. package/src/state/diagram-machine.ts +100 -69
@@ -28,6 +28,7 @@ const diagramMachine = setup({
28
28
  overlaysActorLogic
29
29
  },
30
30
  guards: {
31
+ "isReady": ({ context }) => context.initialized.xydata && context.initialized.xyflow,
31
32
  "enabled: FitView": ({ context }) => context.features.enableFitView,
32
33
  "enabled: FocusMode": ({ context }) => context.features.enableFocusMode,
33
34
  "enabled: Readonly": ({ context }) => context.features.enableReadOnly,
@@ -160,15 +161,18 @@ const diagramMachine = setup({
160
161
  }
161
162
  const constraints = createLayoutConstraints(xystore, nodesToAlign);
162
163
  const aligner = getAligner(mode);
163
- constraints.onMove((nodes) => {
164
- aligner.computeLayout(nodes.map(({ node }) => toNodeRect(node)));
165
- nodes.forEach(({ rect, node }) => {
166
- rect.positionAbsolute = {
167
- ...rect.positionAbsolute,
168
- ...aligner.applyPosition(toNodeRect(node))
169
- };
170
- });
171
- });
164
+ const nodes = nodesToAlign.map((id) => ({
165
+ node: nonNullable(nodeLookup.get(id)),
166
+ rect: nonNullable(constraints.rects.get(id))
167
+ }));
168
+ aligner.computeLayout(nodes.map(({ node }) => toNodeRect(node)));
169
+ for (const { rect, node } of nodes) {
170
+ rect.positionAbsolute = {
171
+ ...rect.positionAbsolute,
172
+ ...aligner.applyPosition(toNodeRect(node))
173
+ };
174
+ }
175
+ constraints.updateXYFlowNodes();
172
176
  },
173
177
  "updateFeatures": enqueueActions(({ enqueue, system, event }) => {
174
178
  assertEvent(event, "update.features");
@@ -195,6 +199,12 @@ const diagramMachine = setup({
195
199
  type: "close.all"
196
200
  }
197
201
  ),
202
+ "startSyncLayout": assign(({ context, spawn, self }) => ({
203
+ syncLayoutActorRef: spawn("syncManualLayoutActorLogic", {
204
+ id: "syncLayout",
205
+ input: { parent: self, viewId: context.view.id }
206
+ })
207
+ })),
198
208
  "stopSyncLayout": enqueueActions(({ context, enqueue }) => {
199
209
  enqueue.sendTo(context.syncLayoutActorRef, { type: "stop" });
200
210
  enqueue.stopChild(context.syncLayoutActorRef);
@@ -247,11 +257,16 @@ const diagramMachine = setup({
247
257
  initial: "initializing",
248
258
  context: ({ input, self, spawn }) => ({
249
259
  ...input,
260
+ xyedges: [],
261
+ xynodes: [],
250
262
  features: { ...AllDisabled },
251
263
  toggledFeatures: DiagramToggledFeaturesPersistence.read() ?? {
252
264
  enableReadOnly: true
253
265
  },
254
- initialized: false,
266
+ initialized: {
267
+ xydata: false,
268
+ xyflow: false
269
+ },
255
270
  viewportChangedManually: false,
256
271
  lastOnNavigate: null,
257
272
  lastClickedNode: null,
@@ -264,10 +279,7 @@ const diagramMachine = setup({
264
279
  },
265
280
  viewport: { x: 0, y: 0, zoom: 1 },
266
281
  xyflow: null,
267
- syncLayoutActorRef: spawn("syncManualLayoutActorLogic", {
268
- id: "syncLayout",
269
- input: { parent: self, viewId: input.view.id }
270
- }),
282
+ syncLayoutActorRef: null,
271
283
  activeWalkthrough: null
272
284
  }),
273
285
  // entry: ({ spawn }) => spawn(layoutActor, { id: 'layout', input: { parent: self } }),
@@ -275,32 +287,54 @@ const diagramMachine = setup({
275
287
  initializing: {
276
288
  on: {
277
289
  "xyflow.init": {
278
- actions: [
279
- assign(({ context, event }) => ({
280
- initialized: true,
281
- xyflow: event.instance,
282
- navigationHistory: {
283
- currentIndex: 0,
284
- history: [{
285
- viewId: context.view.id,
286
- fromNode: null,
287
- viewport: { ...event.instance.getViewport() }
288
- }]
289
- }
290
- })),
291
- enqueueActions(({ enqueue, check }) => {
292
- if (check("enabled: FitView")) {
293
- enqueue({
294
- type: "xyflow:fitDiagram",
295
- params: { duration: 0 }
296
- });
297
- }
298
- })
299
- ],
300
- target: "ready"
290
+ actions: assign(({ context, event }) => ({
291
+ initialized: {
292
+ ...context.initialized,
293
+ xyflow: true
294
+ },
295
+ xyflow: event.instance
296
+ })),
297
+ target: "isReady"
298
+ },
299
+ "update.view": {
300
+ actions: assign(({ context, event, spawn, self }) => ({
301
+ initialized: {
302
+ ...context.initialized,
303
+ xydata: true
304
+ },
305
+ view: event.view,
306
+ xynodes: event.xynodes,
307
+ xyedges: event.xyedges
308
+ })),
309
+ target: "isReady"
301
310
  }
302
311
  }
303
312
  },
313
+ "isReady": {
314
+ always: [{
315
+ guard: "isReady",
316
+ actions: [
317
+ {
318
+ type: "xyflow:fitDiagram",
319
+ params: { duration: 0 }
320
+ },
321
+ "startSyncLayout",
322
+ assign(({ context }) => ({
323
+ navigationHistory: {
324
+ currentIndex: 0,
325
+ history: [{
326
+ viewId: context.view.id,
327
+ fromNode: null,
328
+ viewport: { ...context.xyflow.getViewport() }
329
+ }]
330
+ }
331
+ }))
332
+ ],
333
+ target: "ready"
334
+ }, {
335
+ target: "initializing"
336
+ }]
337
+ },
304
338
  ready: {
305
339
  initial: "idle",
306
340
  on: {
@@ -658,14 +692,6 @@ const diagramMachine = setup({
658
692
  })
659
693
  }
660
694
  ],
661
- exit: assign({
662
- syncLayoutActorRef: ({ self, context, spawn }) => spawn("syncManualLayoutActorLogic", {
663
- id: "syncLayout",
664
- systemId: "syncLayout",
665
- input: { parent: self, viewId: context.view.id }
666
- })
667
- // lastOnNavigate: null,
668
- }),
669
695
  on: {
670
696
  "update.view": {
671
697
  actions: enqueueActions(({ enqueue, context, event }) => {
@@ -690,10 +716,11 @@ const diagramMachine = setup({
690
716
  enqueue.raise({ type: "fitDiagram", duration: 200 }, { id: "fitDiagram", delay: 25 });
691
717
  }
692
718
  enqueue.assign(updateNavigationHistory);
693
- enqueue.assign(mergeXYNodesEdges);
694
719
  enqueue.assign({
720
+ ...mergeXYNodesEdges({ context, event }),
695
721
  lastOnNavigate: null
696
722
  });
723
+ enqueue("startSyncLayout");
697
724
  }),
698
725
  target: "#idle"
699
726
  }
@@ -736,15 +763,10 @@ const diagramMachine = setup({
736
763
  enqueueActions(({ enqueue, event, check, context }) => {
737
764
  const isAnotherView = check("is another view");
738
765
  if (isAnotherView) {
739
- const viewId = event.view.id;
740
766
  enqueue("closeAllOverlays");
741
767
  enqueue("stopSyncLayout");
742
768
  enqueue.assign({
743
- focusedNode: null,
744
- syncLayoutActorRef: ({ self, spawn }) => spawn("syncManualLayoutActorLogic", {
745
- id: "syncLayout",
746
- input: { parent: self, viewId }
747
- })
769
+ focusedNode: null
748
770
  });
749
771
  const { fromNode, toNode } = findCorrespondingNode(context, event);
750
772
  if (fromNode && toNode) {
@@ -766,16 +788,19 @@ const diagramMachine = setup({
766
788
  });
767
789
  enqueue.raise({ type: "fitDiagram", duration: 200 }, { id: "fitDiagram", delay: 25 });
768
790
  }
791
+ }
792
+ enqueue.assign({
793
+ ...mergeXYNodesEdges({ context, event }),
794
+ lastOnNavigate: null
795
+ });
796
+ if (isAnotherView) {
797
+ enqueue("startSyncLayout");
769
798
  } else {
770
799
  enqueue.sendTo((c) => c.context.syncLayoutActorRef, { type: "synced" });
771
800
  if (!context.viewportChangedManually) {
772
801
  enqueue.raise({ type: "fitDiagram" }, { id: "fitDiagram", delay: 50 });
773
802
  }
774
803
  }
775
- enqueue.assign(mergeXYNodesEdges);
776
- enqueue.assign({
777
- lastOnNavigate: null
778
- });
779
804
  })
780
805
  ]
781
806
  },
@@ -793,7 +818,12 @@ const diagramMachine = setup({
793
818
  assign({
794
819
  xyflow: null,
795
820
  xystore: null,
796
- initialized: false,
821
+ xyedges: [],
822
+ xynodes: [],
823
+ initialized: {
824
+ xydata: false,
825
+ xyflow: false
826
+ },
797
827
  syncLayoutActorRef: null
798
828
  })
799
829
  ]