@likec4/diagram 1.58.0 → 1.59.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 (229) hide show
  1. package/dist/LikeC4Diagram.js +1 -1
  2. package/dist/LikeC4Diagram.props.d.ts +1 -1
  3. package/dist/LikeC4Styles.js +1 -1
  4. package/dist/LikeC4View.js +2 -2
  5. package/dist/ReactLikeC4.d.ts +1 -1
  6. package/dist/base/Base.d.ts +3 -2
  7. package/dist/base/Base.js +14 -26
  8. package/dist/base/BaseXYFlow.d.ts +2 -1
  9. package/dist/base/BaseXYFlow.js +63 -4
  10. package/dist/base/keyboardZoom.d.ts +3 -0
  11. package/dist/base/keyboardZoom.js +20 -0
  12. package/dist/base/updateEdges.js +7 -16
  13. package/dist/base/updateNodes.js +3 -9
  14. package/dist/base-primitives/compound/CompoundActionButton.d.ts +2 -1
  15. package/dist/base-primitives/compound/CompoundActionButton.js +5 -2
  16. package/dist/base-primitives/compound/CompoundDetailsButton.d.ts +2 -1
  17. package/dist/base-primitives/compound/CompoundDetailsButton.js +5 -2
  18. package/dist/base-primitives/compound/CompoundTitle.d.ts +7 -1
  19. package/dist/base-primitives/compound/CompoundTitle.js +2 -1
  20. package/dist/base-primitives/compound/actionbtns.css.d.ts +1 -1
  21. package/dist/base-primitives/edge/EdgeActionButton.d.ts +2 -1
  22. package/dist/base-primitives/edge/EdgeActionButton.js +2 -1
  23. package/dist/base-primitives/edge/EdgeContainer.d.ts +1 -1
  24. package/dist/base-primitives/edge/EdgeContainer.js +4 -2
  25. package/dist/base-primitives/edge/EdgeLabel.d.ts +2 -0
  26. package/dist/base-primitives/edge/EdgeLabel.js +2 -5
  27. package/dist/base-primitives/element/ElementActionButtons.d.ts +1 -0
  28. package/dist/base-primitives/element/ElementActionButtons.js +4 -1
  29. package/dist/base-primitives/element/ElementData.d.ts +3 -1
  30. package/dist/base-primitives/element/ElementData.js +2 -1
  31. package/dist/base-primitives/element/ElementDetailsButton.d.ts +2 -1
  32. package/dist/base-primitives/element/ElementDetailsButton.js +5 -2
  33. package/dist/base-primitives/element/ElementNodeContainer.js +1 -1
  34. package/dist/base-primitives/element/ElementShape.js +3 -0
  35. package/dist/components/ErrorFallback.js +3 -5
  36. package/dist/components/Link.js +6 -6
  37. package/dist/components/NavigationPanel.js +1 -1
  38. package/dist/components/SearchControl.css.js +11 -11
  39. package/dist/context/TagStylesContext.d.ts +3 -3
  40. package/dist/context/TagStylesContext.js +16 -16
  41. package/dist/custom/index.d.ts +1 -0
  42. package/dist/custom/index.js +3 -2
  43. package/dist/editor/actor/actions.js +1 -1
  44. package/dist/editor/actor/machine.d.ts +4 -6
  45. package/dist/editor/actor/setup.d.ts +16 -2
  46. package/dist/editor/actor/setup.js +5 -4
  47. package/dist/hooks/index.d.ts +1 -1
  48. package/dist/hooks/safeContext.d.ts +156 -3
  49. package/dist/hooks/safeContext.js +60 -12
  50. package/dist/hooks/useCurrentViewModel.js +1 -1
  51. package/dist/hooks/useDiagram.d.ts +8 -0
  52. package/dist/hooks/useDiagram.js +9 -2
  53. package/dist/hooks/useEditorActor.js +1 -1
  54. package/dist/hooks/useLikeC4ElementsTree.js +1 -1
  55. package/dist/hooks/useLikeC4Model.js +1 -1
  56. package/dist/hooks/useXYFlow.d.ts +1 -0
  57. package/dist/hooks/useXYFlow.js +5 -3
  58. package/dist/index.d.ts +1 -1
  59. package/dist/index.js +2 -2
  60. package/dist/likec4diagram/DiagramUI.js +19 -6
  61. package/dist/likec4diagram/DiagramXYFlow.js +39 -14
  62. package/dist/likec4diagram/convert-to-xyflow.d.ts +3 -5
  63. package/dist/likec4diagram/convert-to-xyflow.js +29 -10
  64. package/dist/likec4diagram/custom/edges/RelationshipEdge.js +13 -4
  65. package/dist/likec4diagram/custom/edges/SequenceStepEdge.js +11 -4
  66. package/dist/likec4diagram/custom/edges/edges.css.js +1 -1
  67. package/dist/likec4diagram/custom/index.d.ts +2 -1
  68. package/dist/likec4diagram/custom/index.js +5 -3
  69. package/dist/likec4diagram/custom/nodes/CompoundActions.js +1 -0
  70. package/dist/likec4diagram/custom/nodes/ElementActions.d.ts +2 -2
  71. package/dist/likec4diagram/custom/nodes/ElementActions.js +13 -3
  72. package/dist/likec4diagram/custom/nodes/NodeNotes.js +0 -4
  73. package/dist/likec4diagram/custom/nodes/SequenceActorNode.js +32 -19
  74. package/dist/likec4diagram/custom/nodes/SequenceSubFlow.d.ts +2 -0
  75. package/dist/likec4diagram/custom/nodes/SequenceSubFlow.js +234 -0
  76. package/dist/likec4diagram/custom/nodes/index.d.ts +1 -0
  77. package/dist/likec4diagram/custom/nodes/nodes.js +20 -5
  78. package/dist/likec4diagram/custom/nodes/toolbar/ColorButton.js +1 -1
  79. package/dist/likec4diagram/custom/nodes/toolbar/_shared.js +1 -1
  80. package/dist/likec4diagram/relationship-popover/RelationshipPopover.js +15 -14
  81. package/dist/likec4diagram/relationship-popover/components.d.ts +1 -1
  82. package/dist/likec4diagram/state/DiagramActorProvider.js +11 -20
  83. package/dist/likec4diagram/state/aligners.js +1 -1
  84. package/dist/likec4diagram/state/assign.d.ts +1 -1
  85. package/dist/likec4diagram/state/assign.js +1 -1
  86. package/dist/likec4diagram/state/createViewChange.js +1 -1
  87. package/dist/likec4diagram/state/diagram-api.d.ts +18 -10
  88. package/dist/likec4diagram/state/diagram-api.js +333 -229
  89. package/dist/likec4diagram/state/machine.actions.d.ts +1026 -332
  90. package/dist/likec4diagram/state/machine.actions.js +115 -44
  91. package/dist/likec4diagram/state/machine.actions.layout.d.ts +123 -51
  92. package/dist/likec4diagram/state/machine.actions.layout.js +40 -33
  93. package/dist/likec4diagram/state/machine.d.ts +154 -16
  94. package/dist/likec4diagram/state/machine.js +5 -41
  95. package/dist/likec4diagram/state/machine.setup.d.ts +84 -19
  96. package/dist/likec4diagram/state/machine.setup.js +65 -12
  97. package/dist/likec4diagram/state/machine.state.initializing.d.ts +59 -33
  98. package/dist/likec4diagram/state/machine.state.navigating.js +7 -3
  99. package/dist/likec4diagram/state/machine.state.ready.d.ts +1540 -476
  100. package/dist/likec4diagram/state/machine.state.ready.focused.d.ts +294 -53
  101. package/dist/likec4diagram/state/machine.state.ready.focused.js +3 -3
  102. package/dist/likec4diagram/state/machine.state.ready.idle.d.ts +264 -73
  103. package/dist/likec4diagram/state/machine.state.ready.idle.js +31 -6
  104. package/dist/likec4diagram/state/machine.state.ready.js +22 -16
  105. package/dist/likec4diagram/state/machine.state.ready.printing.d.ts +23 -9
  106. package/dist/likec4diagram/state/machine.state.ready.walkthrough.d.ts +288 -84
  107. package/dist/likec4diagram/state/machine.state.ready.walkthrough.js +135 -66
  108. package/dist/likec4diagram/state/types.d.ts +4 -2
  109. package/dist/likec4diagram/state/utils.d.ts +7 -0
  110. package/dist/likec4diagram/state/utils.js +36 -34
  111. package/dist/likec4diagram/types.d.ts +47 -3
  112. package/dist/likec4diagram/ui/FloatingSequenceActors.d.ts +6 -0
  113. package/dist/likec4diagram/ui/FloatingSequenceActors.js +155 -0
  114. package/dist/likec4diagram/ui/LayoutDriftFrame.js +2 -2
  115. package/dist/likec4diagram/ui/index.d.ts +2 -0
  116. package/dist/likec4diagram/ui/notation/NotationPanel.css.js +5 -5
  117. package/dist/likec4diagram/ui/sequence-outline/SequenceOutlinePanel.d.ts +2 -0
  118. package/dist/likec4diagram/ui/sequence-outline/SequenceOutlinePanel.js +540 -0
  119. package/dist/likec4diagram/ui/sequence-outline/state.d.ts +36 -0
  120. package/dist/likec4diagram/ui/sequence-outline/state.js +55 -0
  121. package/dist/likec4diagram/xyflow-diagram/diagram-view.d.ts +1 -1
  122. package/dist/likec4diagram/xyflow-diagram/diagram-view.js +112 -60
  123. package/dist/likec4diagram/xyflow-sequence/_types.d.ts +55 -5
  124. package/dist/likec4diagram/xyflow-sequence/const.d.ts +5 -5
  125. package/dist/likec4diagram/xyflow-sequence/const.js +4 -4
  126. package/dist/likec4diagram/xyflow-sequence/layouter.d.ts +30 -6
  127. package/dist/likec4diagram/xyflow-sequence/layouter.js +566 -0
  128. package/dist/likec4diagram/xyflow-sequence/{sequence-layout.d.ts → sequence-view-to-xy.d.ts} +8 -2
  129. package/dist/likec4diagram/xyflow-sequence/{sequence-layout.js → sequence-view-to-xy.js} +111 -14
  130. package/dist/likec4diagram/xyflow-sequence/sequence-view.d.ts +2 -7
  131. package/dist/likec4diagram/xyflow-sequence/sequence-view.js +144 -0
  132. package/dist/likec4diagram/xyflow-sequence/utils.d.ts +9 -1
  133. package/dist/likec4diagram/xyflow-sequence/utils.js +96 -0
  134. package/dist/navigationpanel/NavigationPanel.d.ts +5 -2
  135. package/dist/navigationpanel/NavigationPanel.js +58 -59
  136. package/dist/navigationpanel/NavigationPanelDropdown.js +45 -38
  137. package/dist/navigationpanel/_common.js +2 -2
  138. package/dist/navigationpanel/actor.actions.d.ts +19 -0
  139. package/dist/navigationpanel/actor.actions.js +45 -0
  140. package/dist/navigationpanel/actor.d.ts +34 -96
  141. package/dist/navigationpanel/actor.js +21 -84
  142. package/dist/navigationpanel/actor.setup.d.ts +98 -0
  143. package/dist/navigationpanel/actor.setup.js +31 -0
  144. package/dist/navigationpanel/comparepanel/DriftsSummary.js +4 -5
  145. package/dist/navigationpanel/controls/DetailsControls.js +7 -8
  146. package/dist/navigationpanel/dropdown/ProjectsMenu.js +1 -1
  147. package/dist/navigationpanel/editorpanel/styles.js +8 -8
  148. package/dist/navigationpanel/hooks.d.ts +20 -5
  149. package/dist/navigationpanel/hooks.js +4 -18
  150. package/dist/navigationpanel/styles.css.d.ts +1 -1
  151. package/dist/navigationpanel/walkthrough/ActiveWalkthroughControls.js +2 -2
  152. package/dist/navigationpanel/walkthrough/DynamicViewControls.d.ts +4 -4
  153. package/dist/navigationpanel/walkthrough/DynamicViewControls.js +23 -25
  154. package/dist/navigationpanel/walkthrough/WalkthroughPanel.js +5 -5
  155. package/dist/overlays/Overlays.d.ts +4 -2
  156. package/dist/overlays/Overlays.js +10 -10
  157. package/dist/overlays/element-details/ElementDetailsCard.css.js +17 -17
  158. package/dist/overlays/element-details/MetadataValue.js +15 -15
  159. package/dist/overlays/element-details/TabPanelDeployments.css.js +5 -5
  160. package/dist/overlays/element-details/TabPanelRelationships.css.js +11 -11
  161. package/dist/overlays/element-details/TabPanelRelationships.js +1 -1
  162. package/dist/overlays/element-details/TabPanelStructure.css.js +2 -2
  163. package/dist/overlays/element-details/TabPanelStructure.js +1 -1
  164. package/dist/overlays/element-details/actor.d.ts +2 -3
  165. package/dist/overlays/hooks.d.ts +28 -0
  166. package/dist/overlays/hooks.js +5 -0
  167. package/dist/overlays/overlay/Overlay.js +34 -25
  168. package/dist/overlays/overlaysActor.js +0 -1
  169. package/dist/overlays/relationship-details/custom/nodeTypes.js +1 -1
  170. package/dist/overlays/relationship-details/layout.js +1 -1
  171. package/dist/overlays/relationships-browser/SelectElement.css.js +2 -2
  172. package/dist/overlays/relationships-browser/actor.js +79 -78
  173. package/dist/overlays/relationships-browser/custom/nodeTypes.js +1 -1
  174. package/dist/overlays/relationships-browser/hooks.js +1 -1
  175. package/dist/overlays/relationships-browser/layout.js +2 -2
  176. package/dist/projects-overview/actor.js +4 -4
  177. package/dist/search/Search.js +1 -1
  178. package/dist/search/components/ElementsColumn.css.js +2 -2
  179. package/dist/search/components/ViewsColum.js +1 -1
  180. package/dist/search/components/_shared.css.d.ts +1 -1
  181. package/dist/search/components/_shared.css.js +23 -23
  182. package/dist/search/components/styles.css.js +4 -4
  183. package/dist/shadowroot/ShadowRoot.d.ts +1 -1
  184. package/dist/shadowroot/ShadowRoot.js +76 -28
  185. package/dist/styles2.js +1 -1
  186. package/dist/utils/defineActors.d.ts +21 -0
  187. package/dist/utils/defineActors.js +13 -0
  188. package/dist/utils/index.d.ts +1 -0
  189. package/dist/utils/index.js +5 -4
  190. package/dist/utils/readableText.d.ts +11 -0
  191. package/dist/utils/readableText.js +18 -0
  192. package/package.json +18 -30
  193. package/panda.buildinfo.json +270 -288
  194. package/styles-min.css +1 -1
  195. package/styles.css +1 -1
  196. package/adhoc-editor/package.json +0 -4
  197. package/dist/adhoc-editor/EditorPanel.d.ts +0 -1
  198. package/dist/adhoc-editor/EditorPanel.js +0 -106
  199. package/dist/adhoc-editor/ElementsTree.d.ts +0 -2
  200. package/dist/adhoc-editor/ElementsTree.js +0 -112
  201. package/dist/adhoc-editor/LikeC4AdHocViewEditor.d.ts +0 -4
  202. package/dist/adhoc-editor/LikeC4AdHocViewEditor.js +0 -83
  203. package/dist/adhoc-editor/components/Tree.d.ts +0 -48
  204. package/dist/adhoc-editor/components/Tree.js +0 -213
  205. package/dist/adhoc-editor/hooks.d.ts +0 -14
  206. package/dist/adhoc-editor/hooks.js +0 -34
  207. package/dist/adhoc-editor/index.d.ts +0 -2
  208. package/dist/adhoc-editor/index.js +0 -2
  209. package/dist/adhoc-editor/state/ActorProvider.d.ts +0 -5
  210. package/dist/adhoc-editor/state/ActorProvider.js +0 -37
  211. package/dist/adhoc-editor/state/actor.d.ts +0 -13
  212. package/dist/adhoc-editor/state/actor.editor.d.ts +0 -56
  213. package/dist/adhoc-editor/state/actor.editor.js +0 -167
  214. package/dist/adhoc-editor/state/actor.js +0 -14
  215. package/dist/adhoc-editor/state/actor.layouter.d.ts +0 -51
  216. package/dist/adhoc-editor/state/actor.layouter.js +0 -54
  217. package/dist/adhoc-editor/state/actor.types.d.ts +0 -63
  218. package/dist/adhoc-editor/state/actor.types.js +0 -25
  219. package/dist/adhoc-editor/state/panel.d.ts +0 -95
  220. package/dist/adhoc-editor/state/panel.js +0 -124
  221. package/dist/adhoc-editor/state/utils.d.ts +0 -17
  222. package/dist/adhoc-editor/state/utils.js +0 -25
  223. package/dist/adhoc-editor/useElementsTree.d.ts +0 -18
  224. package/dist/adhoc-editor/useElementsTree.js +0 -98
  225. package/dist/adhoc-editor/viewrules/ViewRulesPanel.d.ts +0 -6
  226. package/dist/context/ShadowRootContext.d.ts +0 -3
  227. package/dist/context/ShadowRootContext.js +0 -5
  228. package/dist/shadowroot/styles.d.ts +0 -13
  229. package/dist/shadowroot/styles.js +0 -60
@@ -1,30 +1,49 @@
1
1
  import "../../_virtual/_rolldown/runtime.js";
2
2
  import { SeqParallelAreaColor, SeqZIndex } from "./const.js";
3
+ import { calcSequenceLayout } from "./sequence-view.js";
4
+ import { entries, filter, first, identity, isArray, isEmptyish, isTruthy, map, pipe, piped } from "remeda";
3
5
  import { nonNullable } from "@likec4/core";
4
- //#region src/likec4diagram/xyflow-sequence/sequence-layout.ts
6
+ import { NodeId, dynamicViewFlow as dynamicViewFlow$1, hasProp as hasProp$1 } from "@likec4/core/types";
7
+ //#region src/likec4diagram/xyflow-sequence/sequence-view-to-xy.ts
8
+ var calcCollapsedFlows = piped(identity(), entries(), filter(([_, collapsed]) => collapsed), map(([flowId]) => flowId));
5
9
  /**
6
10
  * Converts a sequence layout to XY flow nodes and edges.
7
11
  * @param view The next dynamic view which contains the sequence layout.
8
12
  * @param currentViewId The ID of the current view (optional, used to exclude navigation to the current view)
9
13
  */
10
- function sequenceLayoutToXY(view, currentViewId) {
11
- const { actors, steps, compounds, parallelAreas, bounds } = view.sequenceLayout;
14
+ function sequenceLayoutToXY({ view, currentViewId, collapsedFlows }) {
15
+ const flow = hasProp$1(view, "flow") ? dynamicViewFlow$1(view) : void 0;
16
+ const layout = flow && !isEmptyish(collapsedFlows) ? calcSequenceLayout(view, flow, calcCollapsedFlows(collapsedFlows)) : view.sequenceLayout;
17
+ const ctx = {
18
+ view,
19
+ flow,
20
+ layout,
21
+ collapsedFlows,
22
+ subflowArea: (id) => layout.subflows.find((area) => area.id === id)
23
+ };
24
+ const { actors, steps, compounds, parallelAreas, subflows, bounds } = ctx.layout;
12
25
  const xynodes = [];
13
26
  const xyedges = [];
14
27
  const getNode = (id) => {
15
28
  return nonNullable(view.nodes.find((n) => n.id === id));
16
29
  };
17
30
  for (const compound of compounds) xynodes.push(toCompoundArea(compound, getNode(compound.origin), view));
18
- for (const parallelArea of parallelAreas) xynodes.push(toSeqParallelArea(parallelArea, view));
31
+ if (isArray(subflows) && hasProp$1(ctx, "flow")) xynodes.push(...createSubflowNodes(ctx));
32
+ else for (const parallelArea of parallelAreas) xynodes.push(toSeqParallelArea(parallelArea, view));
19
33
  for (const actor of actors) xynodes.push(toSeqActorNode(actor, getNode(actor.id), bounds, view));
34
+ let stepnum = 1;
20
35
  for (const step of steps) {
21
36
  const edge = view.edges.find((e) => e.id === step.id);
22
- if (!edge) throw new Error(`Edge ${step.id} not found`);
23
- xyedges.push(toSeqStepEdge(step, edge, currentViewId ?? view.id));
37
+ if (!edge) {
38
+ console.error(`Step Edge "${step.id}" not found`);
39
+ continue;
40
+ }
41
+ xyedges.push(toSeqStepEdge(step, edge, currentViewId ?? view.id, stepnum++, ctx));
24
42
  }
25
43
  return {
26
44
  xynodes,
27
- xyedges
45
+ xyedges,
46
+ layout
28
47
  };
29
48
  }
30
49
  /**
@@ -50,6 +69,7 @@ function toCompoundArea({ id, x, y, width, height, depth }, node, view) {
50
69
  viewLayoutDir: "LR",
51
70
  notes: void 0
52
71
  },
72
+ zIndex: SeqZIndex.compound,
53
73
  position: {
54
74
  x,
55
75
  y
@@ -89,7 +109,7 @@ function toSeqParallelArea({ parallelPrefix, x, y, width, height }, view) {
89
109
  viewLayoutDir: "LR",
90
110
  notes: void 0
91
111
  },
92
- zIndex: SeqZIndex.parallel,
112
+ zIndex: SeqZIndex.subflows,
93
113
  position: {
94
114
  x,
95
115
  y
@@ -135,7 +155,6 @@ function toSeqActorNode({ id, x, y, width, height, ports }, actor, bounds, view)
135
155
  viewLayoutDir: "LR"
136
156
  },
137
157
  deletable: false,
138
- selectable: true,
139
158
  zIndex: SeqZIndex.actor,
140
159
  position: {
141
160
  x,
@@ -147,7 +166,8 @@ function toSeqActorNode({ id, x, y, width, height, ports }, actor, bounds, view)
147
166
  initialHeight: height
148
167
  };
149
168
  }
150
- function toSeqStepEdge({ id, labelBBox, sourceHandle, targetHandle }, edge, currentViewId) {
169
+ function toSeqStepEdge({ id, labelBBox, sourceHandle, targetHandle, hidden }, edge, currentViewId, stepnum, { flow }) {
170
+ let parent = flow?.parent(id);
151
171
  return {
152
172
  id,
153
173
  type: "seq-step",
@@ -164,6 +184,7 @@ function toSeqStepEdge({ id, labelBBox, sourceHandle, targetHandle }, edge, curr
164
184
  width: labelBBox?.width ?? edge.labelBBox?.width ?? 32,
165
185
  height: labelBBox?.height ?? edge.labelBBox?.height ?? 32
166
186
  },
187
+ stepnum,
167
188
  labelXY: null,
168
189
  points: edge.points,
169
190
  color: edge.color,
@@ -172,18 +193,94 @@ function toSeqStepEdge({ id, labelBBox, sourceHandle, targetHandle }, edge, curr
172
193
  head: edge.head ?? "normal",
173
194
  tail: edge.tail ?? "none",
174
195
  astPath: edge.astPath,
175
- drifts: edge.drifts ?? null
196
+ drifts: edge.drifts ?? null,
197
+ parentFlow: parent ? {
198
+ id: parent.id,
199
+ type: parent._type
200
+ } : null
176
201
  },
177
202
  deletable: false,
178
- selectable: true,
179
203
  focusable: false,
180
- zIndex: 20,
181
- interactionWidth: 40,
204
+ hidden: hidden ?? false,
205
+ zIndex: SeqZIndex.step,
206
+ interactionWidth: 50,
182
207
  source: edge.source,
183
208
  sourceHandle,
184
209
  target: edge.target,
185
210
  targetHandle
186
211
  };
187
212
  }
213
+ function createSubflowNodes(ctx) {
214
+ const nodes = [];
215
+ let lastLeftNode = void 0;
216
+ ctx.flow.walk({ subflow: ({ subflow, previous, parent: _parent }) => {
217
+ const area = ctx.subflowArea(subflow.id);
218
+ if (!area) return false;
219
+ const node = createSubflowNode(area, subflow, ctx);
220
+ if (!previous) node.data.isFirst = true;
221
+ nodes.push(node);
222
+ return {
223
+ next: ctx.flow.subflows(subflow),
224
+ onLeave: ({ lastVisited }) => {
225
+ const nd = ctx.flow.guards.isSubFlow(lastVisited) && nodes.find((n) => n.data.flowId === lastVisited.id);
226
+ if (nd) nd.data.isLast = true;
227
+ lastLeftNode = node;
228
+ }
229
+ };
230
+ } });
231
+ if (lastLeftNode) lastLeftNode.data.isLast = true;
232
+ return nodes;
233
+ }
234
+ function createSubflowNode(area, subflow, ctx) {
235
+ const { x, y, width, height } = area;
236
+ const id = NodeId(subflow.id);
237
+ const level = ctx.flow.level(subflow.id);
238
+ const flowData = ctx.flow.guards.isAltOrTry(subflow) ? composeAltTryData(area, subflow, ctx) : { flowType: subflow._type };
239
+ return {
240
+ id,
241
+ type: "seq-subflow",
242
+ data: {
243
+ id,
244
+ flowId: subflow.id,
245
+ title: subflow.title ?? "",
246
+ technology: null,
247
+ color: SeqParallelAreaColor.default,
248
+ shape: "rectangle",
249
+ style: {},
250
+ tags: [],
251
+ x,
252
+ y,
253
+ level,
254
+ icon: null,
255
+ width,
256
+ height,
257
+ description: null,
258
+ viewId: ctx.view.id,
259
+ drifts: null,
260
+ notes: void 0,
261
+ collapsed: ctx.collapsedFlows[subflow.id] ?? false,
262
+ ...flowData
263
+ },
264
+ zIndex: SeqZIndex.subflows + level,
265
+ position: {
266
+ x,
267
+ y
268
+ },
269
+ draggable: false,
270
+ deletable: false,
271
+ focusable: false,
272
+ width,
273
+ initialWidth: width,
274
+ height,
275
+ initialHeight: height
276
+ };
277
+ }
278
+ function composeAltTryData(parent, subflow, { flow, subflowArea }) {
279
+ const firstBranch = pipe(flow.subflows(subflow), map(({ id }) => subflowArea(id)), filter(isTruthy), first());
280
+ return {
281
+ flowType: subflow._type,
282
+ headerHeight: firstBranch ? firstBranch.y - parent.y : 20
283
+ };
284
+ }
188
285
  //#endregion
189
286
  export { sequenceLayoutToXY };
@@ -1,7 +1,2 @@
1
- import { BBox, LayoutedDynamicView } from '@likec4/core/types';
2
- import { Types } from '../types';
3
- export declare function sequenceViewToXY(view: LayoutedDynamicView): {
4
- bounds: BBox;
5
- xynodes: Array<Types.SequenceActorNode | Types.SequenceParallelArea | Types.ViewGroupNode>;
6
- xyedges: Array<Types.SequenceStepEdge>;
7
- };
1
+ import { DynamicViewFlow, LayoutedDynamicView, StepPath } from '@likec4/core/types';
2
+ export declare function calcSequenceLayout(view: LayoutedDynamicView, flow: DynamicViewFlow, collapsedFlows?: StepPath[]): LayoutedDynamicView.Sequence.Layout;
@@ -0,0 +1,144 @@
1
+ import "../../_virtual/_rolldown/runtime.js";
2
+ import { buildCompounds } from "./utils.js";
3
+ import { SequenceViewLayouter } from "./layouter.js";
4
+ import { flat, groupByProp, hasAtLeast, map, mapValues, pipe, values } from "remeda";
5
+ import { DefaultMap, invariant, nonNullable } from "@likec4/core/utils";
6
+ import { parentFlow } from "@likec4/core/types";
7
+ //#region src/likec4diagram/xyflow-sequence/sequence-view.ts
8
+ function calcSequenceLayout(view, flow, collapsedFlows = []) {
9
+ const actorNodes = /* @__PURE__ */ new Set();
10
+ const getNode = (id) => nonNullable(view.nodes.find((n) => n.id === id));
11
+ const preparedSteps = [];
12
+ for (const edge of view.edges) {
13
+ const source = getNode(edge.source);
14
+ const target = getNode(edge.target);
15
+ if (source.children.length || target.children.length) {
16
+ console.error("Sequence view does not support nested actors");
17
+ continue;
18
+ }
19
+ actorNodes.add(source);
20
+ actorNodes.add(target);
21
+ preparedSteps.push({
22
+ edge,
23
+ source,
24
+ target
25
+ });
26
+ }
27
+ const actors = view.nodes.filter((n) => actorNodes.has(n));
28
+ invariant(hasAtLeast(actors, 1), "actors array must not be empty");
29
+ const actorPorts = new DefaultMap(() => []);
30
+ const steps = [];
31
+ let row = 0;
32
+ let prevStep;
33
+ for (const { edge, source, target } of preparedSteps) {
34
+ let sourceColumn = actors.indexOf(source);
35
+ let targetColumn = actors.indexOf(target);
36
+ const isSelfLoop = source === target;
37
+ const isBack = sourceColumn > targetColumn;
38
+ const parent = parentFlow(edge.id);
39
+ let isContinuing = false;
40
+ if (prevStep && prevStep.target == source && prevStep.parent === parent) isContinuing = prevStep.isSelfLoop !== isSelfLoop || prevStep.isBack === isBack;
41
+ if (!isContinuing && prevStep) row++;
42
+ const step = {
43
+ id: edge.id,
44
+ from: {
45
+ column: sourceColumn,
46
+ row
47
+ },
48
+ to: {
49
+ column: targetColumn,
50
+ row: isSelfLoop ? ++row : row
51
+ },
52
+ edge,
53
+ isSelfLoop,
54
+ isBack,
55
+ parent,
56
+ offset: isContinuing ? (prevStep?.offset ?? 0) + 22 : 0,
57
+ source,
58
+ target,
59
+ label: edge.labelBBox ? {
60
+ height: edge.labelBBox.height + 8 + (edge.navigateTo ? 20 : 0),
61
+ width: edge.labelBBox.width + 16,
62
+ text: edge.label
63
+ } : null
64
+ };
65
+ steps.push(step);
66
+ actorPorts.get(source).push({
67
+ step,
68
+ row,
69
+ type: "source",
70
+ position: isBack && !isSelfLoop ? "left" : "right"
71
+ });
72
+ actorPorts.get(target).push({
73
+ step,
74
+ row,
75
+ type: "target",
76
+ position: isBack || isSelfLoop ? "right" : "left"
77
+ });
78
+ prevStep = step;
79
+ }
80
+ const layout = new SequenceViewLayouter({
81
+ actors,
82
+ steps,
83
+ compounds: buildCompounds(actors, view.nodes),
84
+ flow,
85
+ collapsedFlows
86
+ });
87
+ const bounds = layout.getViewBounds();
88
+ const compounds = pipe(layout.getCompoundBoxes(), map(({ node, ...box }) => ({
89
+ ...box,
90
+ id: node.id,
91
+ origin: node.id
92
+ })), groupByProp("id"), mapValues((boxes, id) => {
93
+ if (hasAtLeast(boxes, 2)) return map(boxes, (box, i) => ({
94
+ ...box,
95
+ id: `${id}-${i + 1}`
96
+ }));
97
+ return boxes;
98
+ }), values(), flat());
99
+ return {
100
+ actors: actors.map((actor) => toSeqActor({
101
+ actor,
102
+ ports: actorPorts.get(actor),
103
+ layout
104
+ })),
105
+ compounds,
106
+ steps: map(steps, (s) => ({
107
+ id: s.id,
108
+ sourceHandle: s.id + "_source",
109
+ targetHandle: s.id + "_target",
110
+ ...s.label && { labelBBox: {
111
+ width: s.label.width,
112
+ height: s.label.height
113
+ } },
114
+ hidden: layout.isStepCollapsed(s)
115
+ })),
116
+ parallelAreas: [],
117
+ subflows: layout.getSubflowAreas(),
118
+ bounds
119
+ };
120
+ }
121
+ function toSeqActor({ actor, ports, layout }) {
122
+ const { x, y, width, height } = layout.getActorBox(actor);
123
+ return {
124
+ id: actor.id,
125
+ x,
126
+ y,
127
+ width,
128
+ height,
129
+ ports: ports.map((p) => {
130
+ const bbox = layout.getPortCenter(p.step, p.type);
131
+ return {
132
+ id: `${p.step.id}_${p.type}`,
133
+ cx: bbox.cx - x,
134
+ cy: bbox.cy - y,
135
+ height: bbox.height,
136
+ type: p.type,
137
+ position: p.position,
138
+ hidden: layout.isStepCollapsed(p.step)
139
+ };
140
+ })
141
+ };
142
+ }
143
+ //#endregion
144
+ export { calcSequenceLayout };
@@ -1,5 +1,13 @@
1
1
  import { DiagramNode } from '@likec4/core/types';
2
- import { Compound, ParallelRect, Step } from './_types';
2
+ import { Compound, ParallelRect, Rect, Spacing, Step } from './_types';
3
+ export type NormalizedSpacing = {
4
+ left: number;
5
+ right: number;
6
+ top: number;
7
+ bottom: number;
8
+ };
9
+ export declare function normalizeSpacing(padding?: Spacing | number): NormalizedSpacing;
10
+ export declare function rectFromSteps(steps: Array<Step>): Rect;
3
11
  /**
4
12
  * From steps find boxes that must be marked as parallel on the layout
5
13
  */
@@ -0,0 +1,96 @@
1
+ import "../../_virtual/_rolldown/runtime.js";
2
+ import "remeda";
3
+ import { Stack, invariant, isAncestor } from "@likec4/core/utils";
4
+ import "@likec4/core/types";
5
+ //#region src/likec4diagram/xyflow-sequence/utils.ts
6
+ var paddingFromNumber = (spacing) => ({
7
+ left: spacing,
8
+ right: spacing,
9
+ top: spacing,
10
+ bottom: spacing
11
+ });
12
+ function normalizeSpacing(padding = 16) {
13
+ if (typeof padding === "number") return paddingFromNumber(padding);
14
+ return {
15
+ left: padding?.left ?? padding?.x ?? 0,
16
+ right: padding?.right ?? padding?.x ?? 0,
17
+ top: padding?.top ?? padding?.y ?? 0,
18
+ bottom: padding?.bottom ?? padding?.y ?? 0
19
+ };
20
+ }
21
+ function rectFromSteps(steps) {
22
+ invariant(steps.length > 0);
23
+ return steps.reduce((acc, step) => {
24
+ const columns = [step.from.column, step.to.column];
25
+ const rows = [step.from.row, step.to.row];
26
+ acc.min.column = Math.min(acc.min.column, ...columns);
27
+ acc.min.row = Math.min(acc.min.row, ...rows);
28
+ acc.max.column = Math.max(acc.max.column, ...columns);
29
+ acc.max.row = Math.max(acc.max.row, ...rows);
30
+ return acc;
31
+ }, {
32
+ min: {
33
+ column: Infinity,
34
+ row: Infinity
35
+ },
36
+ max: {
37
+ column: -Infinity,
38
+ row: -Infinity
39
+ }
40
+ });
41
+ }
42
+ /**
43
+ * Builds a tree of compounds from actors and nodes.
44
+ * @param actors the actors in the sequence view
45
+ * @param nodes the nodes in likec4 diagram
46
+ * @returns an array of compounds where each compound is a node in the sequence view
47
+ * that is an ancestor of one of the actors
48
+ */
49
+ function buildCompounds(actors, nodes) {
50
+ if (actors.length === 0 || actors.length === nodes.length) return [];
51
+ const getNode = (id) => nodes.find((n) => n.id === id);
52
+ function parentsLookup(node) {
53
+ const parent = node.parent && getNode(node.parent);
54
+ if (parent) return [parent, ...parentsLookup(parent)];
55
+ return [];
56
+ }
57
+ const stack = new Stack();
58
+ const result = [];
59
+ actors.forEach((actor) => {
60
+ const parents = parentsLookup(actor);
61
+ if (parents.length === 0) {
62
+ stack.clear();
63
+ return;
64
+ }
65
+ let head;
66
+ let parent = parents[0];
67
+ while (head = stack.peek()?.node) {
68
+ if (!parent || head.id === parent.id) {
69
+ parents.length = 0;
70
+ break;
71
+ }
72
+ if (!isAncestor(head.id, parent.id)) {
73
+ stack.pop();
74
+ continue;
75
+ }
76
+ break;
77
+ }
78
+ while (head = parents.pop()) {
79
+ let compound = stack.peek();
80
+ if (compound && (isAncestor(head.id, compound.node.id) || head.id === compound.node.id)) continue;
81
+ const parentAsCompound = {
82
+ node: head,
83
+ from: actor,
84
+ to: actor,
85
+ nested: []
86
+ };
87
+ if (!compound) result.push(parentAsCompound);
88
+ else compound.nested.push(parentAsCompound);
89
+ stack.push(parentAsCompound);
90
+ }
91
+ stack.forEach((c) => c.to = actor);
92
+ });
93
+ return result;
94
+ }
95
+ //#endregion
96
+ export { buildCompounds, normalizeSpacing, rectFromSteps };
@@ -1,2 +1,5 @@
1
- import { MemoExoticComponent } from 'react';
2
- export declare const NavigationPanel: MemoExoticComponent<() => import("react").JSX.Element>;
1
+ import { NavigationPanelActorRef } from './actor';
2
+ import { NamedExoticComponent } from 'react';
3
+ export declare const NavigationPanel: NamedExoticComponent<{
4
+ actorRef: NavigationPanelActorRef;
5
+ }>;
@@ -1,10 +1,7 @@
1
1
  import "../_virtual/_rolldown/runtime.js";
2
- import { useDiagram } from "../hooks/safeContext.js";
3
- import { useDiagramContext } from "../hooks/useDiagram.js";
4
- import { useCurrentView } from "../hooks/useCurrentView.js";
2
+ import { selectDiagramContext, useDiagramSelector } from "../hooks/safeContext.js";
5
3
  import { useOptionalCurrentViewModel } from "../context/LikeC4ModelContext.js";
6
4
  import { useMantinePortalProps } from "../hooks/useMantinePortalProps.js";
7
- import { navigationPanelActorLogic } from "./actor.js";
8
5
  import { ComparePanel } from "./comparepanel/ComparePanel.js";
9
6
  import { EditorPanel } from "./editorpanel/EditorPanel.js";
10
7
  import { NavigationPanelActorContextProvider } from "./hooks.js";
@@ -13,28 +10,35 @@ import { NavigationPanelControls } from "./NavigationPanelControls.js";
13
10
  import { NavigationPanelDropdown } from "./NavigationPanelDropdown.js";
14
11
  import { WalkthroughPanel } from "./walkthrough/WalkthroughPanel.js";
15
12
  import { memo, useEffect } from "react";
16
- import { jsx, jsxs } from "react/jsx-runtime";
13
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
17
14
  import { Popover, PopoverTarget } from "@mantine/core";
18
15
  import { AnimatePresence, LayoutGroup } from "motion/react";
19
- import { useActorRef, useSelector } from "@xstate/react";
16
+ import { useSelector } from "@xstate/react";
20
17
  import { VStack } from "@likec4/styles/jsx";
18
+ import { hasProp, isDynamicView } from "@likec4/core/types";
21
19
  import { hstack } from "@likec4/styles/patterns";
22
20
  import * as m$1 from "motion/react-m";
23
21
  //#region src/navigationpanel/NavigationPanel.tsx
24
- var NavigationPanel = memo(() => {
25
- const diagram = useDiagram();
26
- const view = useCurrentView();
22
+ var select = selectDiagramContext((s) => {
23
+ const isActiveWalkthrough = !!s.activeWalkthrough;
24
+ if (isDynamicView(s.view) && isActiveWalkthrough) {
25
+ const isSequenceView = s.dynamicViewVariant === "sequence";
26
+ return {
27
+ view: s.view,
28
+ mode: isSequenceView && hasProp(s.view, "flow") ? "walkthrough-flow" : "walkthrough"
29
+ };
30
+ }
31
+ return {
32
+ view: s.view,
33
+ mode: "default"
34
+ };
35
+ });
36
+ var stateHasActiveTag = (state) => state.hasTag("active");
37
+ var NavigationPanel = memo(({ actorRef }) => {
38
+ const { view, mode } = useDiagramSelector(select);
27
39
  const viewModel = useOptionalCurrentViewModel();
28
- const actorRef = useActorRef(navigationPanelActorLogic, { input: {
29
- view,
30
- viewModel
31
- } });
32
- useEffect(() => {
33
- const subscription = actorRef.on("navigateTo", (event) => {
34
- diagram.navigateTo(event.viewId);
35
- });
36
- return () => subscription.unsubscribe();
37
- }, [actorRef, diagram]);
40
+ const opened = useSelector(actorRef, stateHasActiveTag);
41
+ const portalProps = useMantinePortalProps();
38
42
  useEffect(() => {
39
43
  actorRef.send({
40
44
  type: "update.inputs",
@@ -67,52 +71,47 @@ var NavigationPanel = memo(() => {
67
71
  },
68
72
  _print: { display: "none" }
69
73
  },
70
- children: /* @__PURE__ */ jsxs(NavigationPanelActorContextProvider, {
74
+ children: /* @__PURE__ */ jsx(NavigationPanelActorContextProvider, {
71
75
  value: actorRef,
72
- children: [
73
- /* @__PURE__ */ jsx(NavigationPanelImpl, { actor: actorRef }),
76
+ children: mode !== "walkthrough-flow" && /* @__PURE__ */ jsxs(Fragment$1, { children: [
77
+ /* @__PURE__ */ jsxs(Popover, {
78
+ offset: { mainAxis: 4 },
79
+ opened,
80
+ position: "bottom-start",
81
+ trapFocus: opened,
82
+ ...portalProps,
83
+ clickOutsideEvents: [
84
+ "pointerdown",
85
+ "mousedown",
86
+ "click"
87
+ ],
88
+ onDismiss: () => actorRef.send({ type: "dropdown.dismiss" }),
89
+ children: [/* @__PURE__ */ jsx(LayoutGroup, { children: /* @__PURE__ */ jsx(PopoverTarget, { children: /* @__PURE__ */ jsx(m$1.div, {
90
+ layout: true,
91
+ layoutDependency: mode,
92
+ className: hstack({
93
+ layerStyle: "likec4.panel",
94
+ position: "relative",
95
+ gap: "xs",
96
+ cursor: "pointer",
97
+ pointerEvents: "all",
98
+ width: "100%"
99
+ }),
100
+ onMouseLeave: () => actorRef.send({ type: "breadcrumbs.mouseLeave" }),
101
+ children: /* @__PURE__ */ jsx(AnimatePresence, {
102
+ propagate: true,
103
+ initial: false,
104
+ children: mode === "walkthrough" ? /* @__PURE__ */ jsx(ActiveWalkthroughControls, {}) : /* @__PURE__ */ jsx(NavigationPanelControls, {})
105
+ })
106
+ }) }) }), opened && /* @__PURE__ */ jsx(NavigationPanelDropdown, {})]
107
+ }),
74
108
  /* @__PURE__ */ jsx(ComparePanel, {}),
75
- /* @__PURE__ */ jsx(WalkthroughPanel, {}),
109
+ mode === "walkthrough" && /* @__PURE__ */ jsx(WalkthroughPanel, {}),
76
110
  /* @__PURE__ */ jsx(EditorPanel, {})
77
- ]
111
+ ] })
78
112
  })
79
113
  });
80
114
  });
81
115
  NavigationPanel.displayName = "NavigationPanel";
82
- var stateHasActiveTag = (state) => state.hasTag("active");
83
- var NavigationPanelImpl = ({ actor }) => {
84
- const opened = useSelector(actor, stateHasActiveTag);
85
- return /* @__PURE__ */ jsxs(Popover, {
86
- offset: { mainAxis: 4 },
87
- opened,
88
- position: "bottom-start",
89
- trapFocus: opened,
90
- ...useMantinePortalProps(),
91
- clickOutsideEvents: [
92
- "pointerdown",
93
- "mousedown",
94
- "click"
95
- ],
96
- onDismiss: () => actor.send({ type: "dropdown.dismiss" }),
97
- children: [/* @__PURE__ */ jsx(NavigationPanelPopoverTarget, { actor }), opened && /* @__PURE__ */ jsx(NavigationPanelDropdown, {})]
98
- });
99
- };
100
- var NavigationPanelPopoverTarget = ({ actor }) => {
101
- const isActiveWalkthrough = useDiagramContext((c) => c.activeWalkthrough !== null);
102
- return /* @__PURE__ */ jsx(LayoutGroup, { children: /* @__PURE__ */ jsx(PopoverTarget, { children: /* @__PURE__ */ jsx(m$1.div, {
103
- layout: true,
104
- layoutDependency: isActiveWalkthrough,
105
- className: hstack({
106
- layerStyle: "likec4.panel",
107
- position: "relative",
108
- gap: "xs",
109
- cursor: "pointer",
110
- pointerEvents: "all",
111
- width: "100%"
112
- }),
113
- onMouseLeave: () => actor.send({ type: "breadcrumbs.mouseLeave" }),
114
- children: /* @__PURE__ */ jsx(AnimatePresence, { children: isActiveWalkthrough ? /* @__PURE__ */ jsx(ActiveWalkthroughControls, {}) : /* @__PURE__ */ jsx(NavigationPanelControls, {}) })
115
- }) }) });
116
- };
117
116
  //#endregion
118
117
  export { NavigationPanel };