@likec4/diagram 1.19.2 → 1.20.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 (581) hide show
  1. package/dist/LikeC4Diagram.css.d.ts +0 -1
  2. package/dist/LikeC4Diagram.css.js +1 -5
  3. package/dist/LikeC4Diagram.d.ts +1 -4
  4. package/dist/LikeC4Diagram.js +102 -147
  5. package/dist/LikeC4Diagram.props.d.ts +10 -16
  6. package/dist/LikeC4Search.js +7 -15
  7. package/dist/StaticLikeC4Diagram.d.ts +1 -1
  8. package/dist/base/Background.d.ts +7 -0
  9. package/dist/{xyflow/XYFlowBackground.js → base/Background.js} +5 -6
  10. package/dist/base/BaseXYFlow.d.ts +14 -0
  11. package/dist/base/BaseXYFlow.js +146 -0
  12. package/dist/base/example/RelationshipsBrowser.d.ts +6 -0
  13. package/dist/base/example/_types.d.ts +20 -0
  14. package/dist/base/example/custom.d.ts +71 -0
  15. package/dist/base/example/useViewToNodesEdges.d.ts +6 -0
  16. package/dist/base/index.d.ts +2 -0
  17. package/dist/base/primitives/NodeHandles.d.ts +4 -0
  18. package/dist/base/primitives/NodeHandles.js +14 -0
  19. package/dist/base/primitives/compound/CompoundActionButton.css.d.ts +3 -0
  20. package/dist/base/primitives/compound/CompoundActionButton.css.js +9 -0
  21. package/dist/base/primitives/compound/CompoundActionButton.d.ts +7 -0
  22. package/dist/base/primitives/compound/CompoundActionButton.js +48 -0
  23. package/dist/base/primitives/compound/CompoundDetailsButton.css.d.ts +3 -0
  24. package/dist/base/primitives/compound/CompoundDetailsButton.css.js +9 -0
  25. package/dist/base/primitives/compound/CompoundDetailsButton.d.ts +7 -0
  26. package/dist/base/primitives/compound/CompoundDetailsButton.js +50 -0
  27. package/dist/base/primitives/compound/CompoundNodeContainer.css.d.ts +9 -0
  28. package/dist/base/primitives/compound/CompoundNodeContainer.css.js +17 -0
  29. package/dist/base/primitives/compound/CompoundNodeContainer.d.ts +26 -0
  30. package/dist/base/primitives/compound/CompoundNodeContainer.js +86 -0
  31. package/dist/base/primitives/compound/CompoundTitle.css.d.ts +2 -0
  32. package/dist/base/primitives/compound/CompoundTitle.css.js +7 -0
  33. package/dist/base/primitives/compound/CompoundTitle.d.ts +6 -0
  34. package/dist/base/primitives/compound/CompoundTitle.js +20 -0
  35. package/dist/base/primitives/customEdge.d.ts +41 -0
  36. package/dist/base/primitives/customEdge.js +13 -0
  37. package/dist/base/primitives/customNode.d.ts +7 -0
  38. package/dist/base/primitives/customNode.js +10 -0
  39. package/dist/base/primitives/edge/EdgeActionButton.d.ts +7 -0
  40. package/dist/base/primitives/edge/EdgeActionButton.js +24 -0
  41. package/dist/base/primitives/edge/EdgeContainer.d.ts +10 -0
  42. package/dist/base/primitives/edge/EdgeContainer.js +35 -0
  43. package/dist/{xyflow/edges/edges.css.d.ts → base/primitives/edge/EdgeLabel.css.d.ts} +5 -9
  44. package/dist/base/primitives/edge/EdgeLabel.css.js +25 -0
  45. package/dist/base/primitives/edge/EdgeLabel.d.ts +51 -0
  46. package/dist/base/primitives/edge/EdgeLabel.js +90 -0
  47. package/dist/{xyflow → base/primitives/edge}/EdgeMarkers.d.ts +2 -0
  48. package/dist/{xyflow → base/primitives/edge}/EdgeMarkers.js +29 -1
  49. package/dist/base/primitives/edge/EdgePath.d.ts +44 -0
  50. package/dist/base/primitives/edge/EdgePath.js +77 -0
  51. package/dist/base/primitives/edge/edge.css.d.ts +6 -0
  52. package/dist/base/primitives/edge/edge.css.js +14 -0
  53. package/dist/base/primitives/element/ElementActionButtons.css.d.ts +3 -0
  54. package/dist/base/primitives/element/ElementActionButtons.css.js +9 -0
  55. package/dist/base/primitives/element/ElementActionButtons.d.ts +13 -0
  56. package/dist/base/primitives/element/ElementActionButtons.js +62 -0
  57. package/dist/base/primitives/element/ElementDetailsButton.css.d.ts +3 -0
  58. package/dist/base/primitives/element/ElementDetailsButton.css.js +9 -0
  59. package/dist/base/primitives/element/ElementDetailsButton.d.ts +7 -0
  60. package/dist/base/primitives/element/ElementDetailsButton.js +54 -0
  61. package/dist/base/primitives/element/ElementNodeContainer.css.d.ts +3 -0
  62. package/dist/base/primitives/element/ElementNodeContainer.css.js +7 -0
  63. package/dist/base/primitives/element/ElementNodeContainer.d.ts +26 -0
  64. package/dist/base/primitives/element/ElementNodeContainer.js +60 -0
  65. package/dist/base/primitives/element/ElementShape.css.d.ts +6 -0
  66. package/dist/base/primitives/element/ElementShape.css.js +14 -0
  67. package/dist/base/primitives/element/ElementShape.d.ts +28 -0
  68. package/dist/{xyflow/nodes/element/ElementShapeSvg.js → base/primitives/element/ElementShape.js} +23 -7
  69. package/dist/base/primitives/element/ElementTitle.css.d.ts +8 -0
  70. package/dist/base/primitives/element/ElementTitle.css.js +19 -0
  71. package/dist/base/primitives/element/ElementTitle.d.ts +10 -0
  72. package/dist/base/primitives/element/ElementTitle.js +66 -0
  73. package/dist/base/primitives/index.d.ts +17 -0
  74. package/dist/base/types.d.ts +90 -0
  75. package/dist/base/types.js +54 -0
  76. package/dist/base/updateEdges.d.ts +3 -0
  77. package/dist/base/updateEdges.js +31 -0
  78. package/dist/base/updateNodes.d.ts +3 -0
  79. package/dist/base/updateNodes.js +36 -0
  80. package/dist/base/xyflowMachine.d.ts +212 -0
  81. package/dist/context/DiagramEventHandlers.d.ts +10 -0
  82. package/dist/context/DiagramEventHandlers.js +49 -0
  83. package/dist/context/DiagramFeatures.d.ts +31 -0
  84. package/dist/context/DiagramFeatures.js +140 -0
  85. package/dist/{ui → context}/FramerMotionConfig.js +2 -4
  86. package/dist/context/IconRenderer.d.ts +11 -0
  87. package/dist/{xyflow/nodes/shared/ElementIcon.js → context/IconRenderer.js} +14 -14
  88. package/dist/context/RootContainer.d.ts +9 -0
  89. package/dist/context/RootContainer.js +20 -0
  90. package/dist/context/index.d.ts +7 -0
  91. package/dist/globals.css.js +0 -86
  92. package/dist/hooks/index.d.ts +7 -5
  93. package/dist/hooks/useCurrentViewId.d.ts +2 -0
  94. package/dist/hooks/useCurrentViewId.js +8 -0
  95. package/dist/hooks/useDiagram.d.ts +10725 -0
  96. package/dist/hooks/useDiagram.js +119 -0
  97. package/dist/hooks/useDiagramActor.d.ts +5 -0
  98. package/dist/hooks/useDiagramActor.js +21 -0
  99. package/dist/hooks/useDiagramContext.d.ts +3 -0
  100. package/dist/hooks/useDiagramContext.js +10 -0
  101. package/dist/hooks/useMantinePortalProps.js +2 -2
  102. package/dist/hooks/useXYFlow.d.ts +195 -37
  103. package/dist/hooks/useXYFlow.js +4 -6
  104. package/dist/index.d.ts +3 -2
  105. package/dist/index.js +5 -6
  106. package/dist/likec4diagram/DiagramActor.d.ts +7 -0
  107. package/dist/likec4diagram/DiagramActor.js +71 -0
  108. package/dist/likec4diagram/DiagramUI.d.ts +2 -0
  109. package/dist/likec4diagram/DiagramUI.js +22 -0
  110. package/dist/likec4diagram/XYFlow.d.ts +6 -0
  111. package/dist/likec4diagram/XYFlow.js +122 -0
  112. package/dist/likec4diagram/custom/edges/NotePopover.css.d.ts +2 -0
  113. package/dist/likec4diagram/custom/edges/NotePopover.css.js +7 -0
  114. package/dist/likec4diagram/custom/edges/NotePopover.d.ts +4 -0
  115. package/dist/likec4diagram/custom/edges/NotePopover.js +101 -0
  116. package/dist/likec4diagram/custom/edges/RelationshipEdge.d.ts +55 -0
  117. package/dist/likec4diagram/custom/edges/RelationshipEdge.js +307 -0
  118. package/dist/{xyflow → likec4diagram/custom}/edges/RelationshipsDropdownMenu.css.js +4 -4
  119. package/dist/{xyflow → likec4diagram/custom}/edges/RelationshipsDropdownMenu.d.ts +5 -5
  120. package/dist/{xyflow → likec4diagram/custom}/edges/RelationshipsDropdownMenu.js +51 -53
  121. package/dist/likec4diagram/custom/edges/edges.css.d.ts +2 -0
  122. package/dist/likec4diagram/custom/edges/edges.css.js +7 -0
  123. package/dist/likec4diagram/custom/edges/utils.d.ts +22 -0
  124. package/dist/likec4diagram/custom/edges/utils.js +24 -0
  125. package/dist/likec4diagram/custom/index.d.ts +57 -0
  126. package/dist/likec4diagram/custom/index.js +7 -0
  127. package/dist/likec4diagram/custom/nodes/CompoundActions.d.ts +5 -0
  128. package/dist/likec4diagram/custom/nodes/CompoundActions.js +25 -0
  129. package/dist/likec4diagram/custom/nodes/ElementActions.d.ts +7 -0
  130. package/dist/likec4diagram/custom/nodes/ElementActions.js +69 -0
  131. package/dist/likec4diagram/custom/nodes/nodeTypes.d.ts +10 -0
  132. package/dist/likec4diagram/custom/nodes/nodeTypes.js +94 -0
  133. package/dist/likec4diagram/custom/nodes/toolbar/ColorButton.d.ts +21 -0
  134. package/dist/likec4diagram/custom/nodes/toolbar/ColorButton.js +159 -0
  135. package/dist/likec4diagram/custom/nodes/toolbar/CompoundToolbar.d.ts +7 -0
  136. package/dist/likec4diagram/custom/nodes/toolbar/CompoundToolbar.js +128 -0
  137. package/dist/likec4diagram/custom/nodes/toolbar/ElementToolbar.d.ts +7 -0
  138. package/dist/likec4diagram/custom/nodes/toolbar/ElementToolbar.js +149 -0
  139. package/dist/likec4diagram/custom/nodes/toolbar/Toolbar.d.ts +8 -0
  140. package/dist/likec4diagram/custom/nodes/toolbar/Toolbar.js +66 -0
  141. package/dist/likec4diagram/custom/nodes/toolbar/_shared.d.ts +40 -0
  142. package/dist/likec4diagram/custom/nodes/toolbar/_shared.js +131 -0
  143. package/dist/likec4diagram/custom/nodes/toolbar/styles.css.d.ts +1 -0
  144. package/dist/likec4diagram/custom/nodes/toolbar/styles.css.js +5 -0
  145. package/dist/likec4diagram/state/actorContext.d.ts +50849 -0
  146. package/dist/likec4diagram/state/actorContext.js +12 -0
  147. package/dist/{state → likec4diagram/state}/aligners.d.ts +4 -1
  148. package/dist/{state → likec4diagram/state}/aligners.js +31 -5
  149. package/dist/likec4diagram/state/assign.d.ts +18 -0
  150. package/dist/likec4diagram/state/assign.js +343 -0
  151. package/dist/likec4diagram/state/hotkeyActor.d.ts +5 -0
  152. package/dist/likec4diagram/state/hotkeyActor.js +18 -0
  153. package/dist/likec4diagram/state/inspector.d.ts +5 -0
  154. package/dist/likec4diagram/state/machine.d.ts +10751 -0
  155. package/dist/likec4diagram/state/machine.js +783 -0
  156. package/dist/likec4diagram/state/syncManualLayoutActor.d.ts +113 -0
  157. package/dist/likec4diagram/state/syncManualLayoutActor.js +178 -0
  158. package/dist/likec4diagram/state/utils.d.ts +8 -0
  159. package/dist/likec4diagram/state/utils.js +48 -0
  160. package/dist/likec4diagram/types.d.ts +74 -0
  161. package/dist/{ui/top-left → likec4diagram/ui/controls}/ChangeAutoLayoutButton.js +11 -10
  162. package/dist/likec4diagram/ui/controls/Controls.d.ts +2 -0
  163. package/dist/likec4diagram/ui/controls/Controls.js +102 -0
  164. package/dist/likec4diagram/ui/controls/LayoutDriftNotification.d.ts +2 -0
  165. package/dist/likec4diagram/ui/controls/LayoutDriftNotification.js +43 -0
  166. package/dist/{ui/top-left → likec4diagram/ui/controls}/ManualLayoutToolsButton.js +11 -11
  167. package/dist/likec4diagram/ui/controls/NavigationButtons.d.ts +1 -0
  168. package/dist/likec4diagram/ui/controls/NavigationButtons.js +92 -0
  169. package/dist/{ui/top-left → likec4diagram/ui/controls}/_shared.js +2 -1
  170. package/dist/{ui/top-left → likec4diagram/ui/controls}/styles.css.d.ts +1 -1
  171. package/dist/likec4diagram/ui/controls/styles.css.js +17 -0
  172. package/dist/likec4diagram/ui/diagram-title/DiagramTitlePanel.css.js +11 -0
  173. package/dist/likec4diagram/ui/diagram-title/DiagramTitlePanel.d.ts +1 -0
  174. package/dist/{ui → likec4diagram/ui/diagram-title}/DiagramTitlePanel.js +3 -3
  175. package/dist/likec4diagram/ui/diagram-title/Link.d.ts +4 -0
  176. package/dist/likec4diagram/ui/index.d.ts +2 -0
  177. package/dist/likec4diagram/ui/notation/NotationPanel.css.js +13 -0
  178. package/dist/likec4diagram/ui/notation/NotationPanel.d.ts +2 -0
  179. package/dist/{ui → likec4diagram/ui}/notation/NotationPanel.js +23 -31
  180. package/dist/{ui → likec4diagram/ui/walkthrough}/DynamicViewWalkthrough.css.js +4 -4
  181. package/dist/{ui → likec4diagram/ui/walkthrough}/DynamicViewWalkthrough.js +19 -44
  182. package/dist/{xyflow → likec4diagram}/useLayoutConstraints.d.ts +11 -6
  183. package/dist/{xyflow → likec4diagram}/useLayoutConstraints.js +17 -12
  184. package/dist/likec4diagram/useViewToNodesEdges.d.ts +11 -0
  185. package/dist/likec4diagram/useViewToNodesEdges.js +245 -0
  186. package/dist/likec4model/index.d.ts +1 -1
  187. package/dist/likec4model/useLikeC4Model.d.ts +1 -11
  188. package/dist/likec4model/useLikeC4Model.js +1 -39
  189. package/dist/overlays/Overlays.js +61 -105
  190. package/dist/overlays/element-details/ElementDetailsCard.js +111 -116
  191. package/dist/overlays/element-details/TabPanelDeployments.js +4 -7
  192. package/dist/overlays/element-details/TabPanelRelationships.css.js +0 -2
  193. package/dist/overlays/element-details/TabPanelRelationships.d.ts +1 -1
  194. package/dist/overlays/element-details/TabPanelRelationships.js +35 -64
  195. package/dist/overlays/element-details/TabPanelStructure.d.ts +2 -2
  196. package/dist/overlays/element-details/TabPanelStructure.js +1 -1
  197. package/dist/overlays/overlay/Overlay.css.d.ts +2 -0
  198. package/dist/overlays/overlay/Overlay.css.js +93 -0
  199. package/dist/overlays/overlay/Overlay.d.ts +8 -0
  200. package/dist/overlays/overlay/Overlay.js +86 -0
  201. package/dist/overlays/relationship-details/RelationshipDetails.d.ts +5 -0
  202. package/dist/overlays/relationship-details/RelationshipDetails.js +189 -0
  203. package/dist/overlays/{edge-details → relationship-details}/SelectEdge.css.d.ts +1 -0
  204. package/dist/overlays/relationship-details/SelectEdge.css.js +17 -0
  205. package/dist/overlays/{edge-details → relationship-details}/SelectEdge.d.ts +1 -1
  206. package/dist/overlays/{edge-details → relationship-details}/SelectEdge.js +8 -8
  207. package/dist/overlays/relationship-details/_types.d.ts +36 -0
  208. package/dist/overlays/relationship-details/actor.d.ts +41 -0
  209. package/dist/overlays/relationship-details/actor.js +113 -0
  210. package/dist/overlays/relationship-details/custom/ElementActions.d.ts +5 -0
  211. package/dist/overlays/relationship-details/custom/ElementActions.js +33 -0
  212. package/dist/overlays/relationship-details/custom/edgeTypes.d.ts +49 -0
  213. package/dist/overlays/relationship-details/custom/edgeTypes.js +51 -0
  214. package/dist/overlays/relationship-details/custom/index.d.ts +2 -0
  215. package/dist/overlays/relationship-details/custom/nodeTypes.d.ts +39 -0
  216. package/dist/overlays/relationship-details/custom/nodeTypes.js +89 -0
  217. package/dist/overlays/relationship-details/custom/styles.css.d.ts +1 -0
  218. package/dist/overlays/relationship-details/hooks.d.ts +59 -0
  219. package/dist/overlays/relationship-details/hooks.js +46 -0
  220. package/dist/overlays/{edge-details/use-layouted-edge-details.d.ts → relationship-details/useLayoutedDetails.d.ts} +4 -6
  221. package/dist/overlays/{edge-details/use-layouted-edge-details.js → relationship-details/useLayoutedDetails.js} +68 -64
  222. package/dist/overlays/relationships-browser/-useRelationshipsView.d.ts +39 -0
  223. package/dist/overlays/relationships-browser/-useRelationshipsView.js +488 -0
  224. package/dist/overlays/relationships-browser/RelationshipsBrowser.d.ts +5 -0
  225. package/dist/overlays/relationships-browser/RelationshipsBrowser.js +209 -0
  226. package/dist/overlays/{relationships-of → relationships-browser}/SelectElement.css.d.ts +1 -0
  227. package/dist/overlays/relationships-browser/SelectElement.css.js +9 -0
  228. package/dist/overlays/relationships-browser/SelectElement.d.ts +7 -0
  229. package/dist/overlays/{relationships-of → relationships-browser}/SelectElement.js +11 -8
  230. package/dist/overlays/relationships-browser/_types.d.ts +40 -0
  231. package/dist/overlays/relationships-browser/actor.d.ts +66 -0
  232. package/dist/overlays/relationships-browser/actor.js +159 -0
  233. package/dist/overlays/relationships-browser/custom/ElementActions.d.ts +5 -0
  234. package/dist/overlays/relationships-browser/custom/ElementActions.js +43 -0
  235. package/dist/overlays/relationships-browser/custom/EmptyNode.d.ts +5 -0
  236. package/dist/overlays/{relationships-of/xyflow → relationships-browser/custom}/EmptyNode.js +1 -3
  237. package/dist/overlays/relationships-browser/custom/edgeTypes.d.ts +46 -0
  238. package/dist/overlays/relationships-browser/custom/edgeTypes.js +51 -0
  239. package/dist/overlays/relationships-browser/custom/index.d.ts +2 -0
  240. package/dist/overlays/relationships-browser/custom/nodeTypes.d.ts +45 -0
  241. package/dist/overlays/relationships-browser/custom/nodeTypes.js +93 -0
  242. package/dist/overlays/relationships-browser/custom/styles.css.d.ts +1 -0
  243. package/dist/overlays/relationships-browser/custom/styles.css.js +5 -0
  244. package/dist/overlays/relationships-browser/hooks.d.ts +62 -0
  245. package/dist/overlays/relationships-browser/hooks.js +46 -0
  246. package/dist/overlays/relationships-browser/useViewToNodesEdges.d.ts +10 -0
  247. package/dist/overlays/relationships-browser/useViewToNodesEdges.js +160 -0
  248. package/dist/style.css +1 -1
  249. package/dist/utils/index.d.ts +4 -0
  250. package/dist/{xyflow/utils.d.ts → utils/xyflow.d.ts} +4 -4
  251. package/dist/{xyflow/utils.js → utils/xyflow.js} +14 -20
  252. package/package.json +23 -20
  253. package/src/LikeC4Diagram.css.ts +21 -15
  254. package/src/LikeC4Diagram.props.ts +14 -21
  255. package/src/LikeC4Diagram.tsx +105 -150
  256. package/src/LikeC4Search.tsx +21 -28
  257. package/src/StaticLikeC4Diagram.tsx +0 -1
  258. package/src/{xyflow/XYFlowBackground.tsx → base/Background.tsx} +8 -8
  259. package/src/base/BaseXYFlow.tsx +200 -0
  260. package/src/{xyflow → base}/const.ts +1 -1
  261. package/src/base/example/RelationshipsBrowser.tsx +62 -0
  262. package/src/base/example/_types.ts +71 -0
  263. package/src/base/example/custom.tsx +58 -0
  264. package/src/base/example/useViewToNodesEdges.ts +193 -0
  265. package/src/base/index.ts +10 -0
  266. package/src/base/primitives/NodeHandles.tsx +18 -0
  267. package/src/base/primitives/compound/CompoundActionButton.css.ts +55 -0
  268. package/src/base/primitives/compound/CompoundActionButton.tsx +52 -0
  269. package/src/base/primitives/compound/CompoundDetailsButton.css.ts +56 -0
  270. package/src/base/primitives/compound/CompoundDetailsButton.tsx +54 -0
  271. package/src/base/primitives/compound/CompoundNodeContainer.css.ts +161 -0
  272. package/src/base/primitives/compound/CompoundNodeContainer.tsx +95 -0
  273. package/src/base/primitives/compound/CompoundTitle.css.ts +43 -0
  274. package/src/base/primitives/compound/CompoundTitle.tsx +29 -0
  275. package/src/base/primitives/customEdge.ts +32 -0
  276. package/src/base/primitives/customNode.ts +21 -0
  277. package/src/base/primitives/edge/EdgeActionButton.tsx +27 -0
  278. package/src/base/primitives/edge/EdgeContainer.tsx +48 -0
  279. package/src/base/primitives/edge/EdgeLabel.css.ts +196 -0
  280. package/src/base/primitives/edge/EdgeLabel.tsx +136 -0
  281. package/src/{xyflow → base/primitives/edge}/EdgeMarkers.tsx +29 -1
  282. package/src/base/primitives/edge/EdgePath.tsx +89 -0
  283. package/src/base/primitives/edge/edge.css.ts +122 -0
  284. package/src/base/primitives/element/ElementActionButtons.css.ts +48 -0
  285. package/src/base/primitives/element/ElementActionButtons.tsx +73 -0
  286. package/src/base/primitives/element/ElementDetailsButton.css.ts +54 -0
  287. package/src/base/primitives/element/ElementDetailsButton.tsx +59 -0
  288. package/src/base/primitives/element/ElementNodeContainer.css.ts +47 -0
  289. package/src/base/primitives/element/ElementNodeContainer.tsx +72 -0
  290. package/src/base/primitives/element/ElementShape.css.ts +134 -0
  291. package/src/{xyflow/nodes/element/ElementShapeSvg.tsx → base/primitives/element/ElementShape.tsx} +64 -19
  292. package/src/base/primitives/element/ElementTitle.css.ts +156 -0
  293. package/src/base/primitives/element/ElementTitle.tsx +76 -0
  294. package/src/base/primitives/index.ts +17 -0
  295. package/src/base/types.ts +169 -0
  296. package/src/base/updateEdges.ts +40 -0
  297. package/src/base/updateNodes.ts +46 -0
  298. package/src/base/xyflowMachine.ts +75 -0
  299. package/src/context/DiagramEventHandlers.tsx +53 -0
  300. package/src/context/DiagramFeatures.tsx +162 -0
  301. package/src/{ui → context}/FramerMotionConfig.tsx +2 -6
  302. package/src/context/IconRenderer.tsx +45 -0
  303. package/src/context/RootContainer.tsx +31 -0
  304. package/src/context/index.ts +14 -0
  305. package/src/globals.css.ts +32 -32
  306. package/src/hooks/index.ts +7 -5
  307. package/src/hooks/useCurrentViewId.ts +8 -0
  308. package/src/hooks/useDiagram.ts +129 -0
  309. package/src/hooks/useDiagramActor.ts +25 -0
  310. package/src/hooks/useDiagramContext.ts +11 -0
  311. package/src/hooks/useMantinePortalProps.ts +2 -2
  312. package/src/hooks/useXYFlow.ts +12 -38
  313. package/src/index.ts +3 -7
  314. package/src/likec4diagram/DiagramActor.tsx +79 -0
  315. package/src/likec4diagram/DiagramUI.tsx +28 -0
  316. package/src/likec4diagram/XYFlow.tsx +137 -0
  317. package/src/likec4diagram/custom/edges/NotePopover.css.ts +27 -0
  318. package/src/likec4diagram/custom/edges/NotePopover.tsx +96 -0
  319. package/src/likec4diagram/custom/edges/RelationshipEdge.tsx +355 -0
  320. package/src/{xyflow → likec4diagram/custom}/edges/RelationshipsDropdownMenu.css.ts +7 -7
  321. package/src/{xyflow → likec4diagram/custom}/edges/RelationshipsDropdownMenu.tsx +91 -70
  322. package/src/likec4diagram/custom/edges/edges.css.ts +39 -0
  323. package/src/likec4diagram/custom/edges/utils.ts +125 -0
  324. package/src/likec4diagram/custom/index.tsx +8 -0
  325. package/src/likec4diagram/custom/nodes/CompoundActions.tsx +27 -0
  326. package/src/likec4diagram/custom/nodes/ElementActions.tsx +74 -0
  327. package/src/likec4diagram/custom/nodes/nodeTypes.tsx +107 -0
  328. package/src/likec4diagram/custom/nodes/toolbar/ColorButton.tsx +175 -0
  329. package/src/likec4diagram/custom/nodes/toolbar/CompoundToolbar.tsx +122 -0
  330. package/src/likec4diagram/custom/nodes/toolbar/ElementToolbar.tsx +140 -0
  331. package/src/likec4diagram/custom/nodes/toolbar/Toolbar.tsx +77 -0
  332. package/src/likec4diagram/custom/nodes/toolbar/_shared.tsx +143 -0
  333. package/src/likec4diagram/custom/nodes/toolbar/styles.css.ts +9 -0
  334. package/src/likec4diagram/state/actorContext.ts +8 -0
  335. package/src/{state → likec4diagram/state}/aligners.ts +67 -40
  336. package/src/likec4diagram/state/assign.ts +384 -0
  337. package/src/likec4diagram/state/hotkeyActor.ts +20 -0
  338. package/src/likec4diagram/state/inspector.ts +23 -0
  339. package/src/likec4diagram/state/machine.ts +946 -0
  340. package/src/likec4diagram/state/syncManualLayoutActor.ts +219 -0
  341. package/src/likec4diagram/state/utils.ts +52 -0
  342. package/src/likec4diagram/types.ts +144 -0
  343. package/src/{ui/top-left → likec4diagram/ui/controls}/ChangeAutoLayoutButton.tsx +32 -28
  344. package/src/likec4diagram/ui/controls/Controls.tsx +107 -0
  345. package/src/likec4diagram/ui/controls/LayoutDriftNotification.tsx +46 -0
  346. package/src/{ui/top-left → likec4diagram/ui/controls}/ManualLayoutToolsButton.tsx +16 -16
  347. package/src/likec4diagram/ui/controls/NavigationButtons.tsx +83 -0
  348. package/src/{ui/top-left → likec4diagram/ui/controls}/_shared.ts +4 -3
  349. package/src/{ui/top-left → likec4diagram/ui/controls}/styles.css.ts +17 -17
  350. package/src/{ui → likec4diagram/ui/diagram-title}/DiagramTitlePanel.css.ts +11 -11
  351. package/src/{ui → likec4diagram/ui/diagram-title}/DiagramTitlePanel.tsx +6 -5
  352. package/src/likec4diagram/ui/diagram-title/Link.tsx +40 -0
  353. package/src/likec4diagram/ui/index.ts +2 -0
  354. package/src/{ui → likec4diagram/ui}/notation/NotationPanel.css.ts +18 -18
  355. package/src/{ui → likec4diagram/ui}/notation/NotationPanel.tsx +44 -44
  356. package/src/{ui → likec4diagram/ui/walkthrough}/DynamicViewWalkthrough.css.ts +16 -16
  357. package/src/{ui → likec4diagram/ui/walkthrough}/DynamicViewWalkthrough.tsx +29 -49
  358. package/src/{xyflow → likec4diagram}/useLayoutConstraints.ts +54 -43
  359. package/src/likec4diagram/useViewToNodesEdges.ts +297 -0
  360. package/src/likec4model/index.ts +0 -6
  361. package/src/likec4model/useLikeC4Model.ts +1 -43
  362. package/src/overlays/Overlays.tsx +201 -147
  363. package/src/overlays/element-details/ElementDetailsCard.css.ts +58 -58
  364. package/src/overlays/element-details/ElementDetailsCard.tsx +143 -128
  365. package/src/overlays/element-details/TabPanelDeployments.css.ts +14 -14
  366. package/src/overlays/element-details/TabPanelDeployments.tsx +22 -22
  367. package/src/overlays/element-details/TabPanelRelationships.css.ts +19 -19
  368. package/src/overlays/element-details/TabPanelRelationships.tsx +45 -28
  369. package/src/overlays/element-details/TabPanelStructure.css.ts +7 -7
  370. package/src/overlays/element-details/TabPanelStructure.tsx +11 -11
  371. package/src/overlays/overlay/Overlay.css.ts +73 -0
  372. package/src/overlays/overlay/Overlay.tsx +99 -0
  373. package/src/overlays/relationship-details/RelationshipDetails.tsx +234 -0
  374. package/src/overlays/{edge-details → relationship-details}/SelectEdge.css.ts +20 -13
  375. package/src/overlays/{edge-details → relationship-details}/SelectEdge.tsx +14 -14
  376. package/src/overlays/relationship-details/_types.ts +73 -0
  377. package/src/overlays/relationship-details/actor.ts +162 -0
  378. package/src/overlays/relationship-details/custom/ElementActions.tsx +45 -0
  379. package/src/overlays/relationship-details/custom/edgeTypes.tsx +49 -0
  380. package/src/overlays/relationship-details/custom/index.tsx +2 -0
  381. package/src/overlays/relationship-details/custom/nodeTypes.tsx +108 -0
  382. package/src/overlays/relationship-details/custom/styles.css.ts +13 -0
  383. package/src/overlays/relationship-details/hooks.ts +48 -0
  384. package/src/overlays/{edge-details/use-layouted-edge-details.ts → relationship-details/useLayoutedDetails.ts} +128 -114
  385. package/src/overlays/relationships-browser/-useRelationshipsView.ts +642 -0
  386. package/src/overlays/relationships-browser/RelationshipsBrowser.tsx +247 -0
  387. package/src/overlays/{relationships-of → relationships-browser}/SelectElement.css.ts +12 -5
  388. package/src/overlays/{relationships-of → relationships-browser}/SelectElement.tsx +19 -18
  389. package/src/overlays/relationships-browser/_types.ts +89 -0
  390. package/src/overlays/relationships-browser/actor.ts +224 -0
  391. package/src/overlays/relationships-browser/custom/ElementActions.tsx +44 -0
  392. package/src/overlays/relationships-browser/custom/EmptyNode.tsx +18 -0
  393. package/src/overlays/relationships-browser/custom/edgeTypes.tsx +49 -0
  394. package/src/overlays/relationships-browser/custom/index.tsx +2 -0
  395. package/src/overlays/relationships-browser/custom/nodeTypes.tsx +109 -0
  396. package/src/overlays/relationships-browser/custom/styles.css.ts +13 -0
  397. package/src/overlays/relationships-browser/hooks.ts +48 -0
  398. package/src/overlays/relationships-browser/useViewToNodesEdges.ts +209 -0
  399. package/src/utils/index.ts +15 -0
  400. package/src/{xyflow/utils.ts → utils/xyflow.ts} +22 -8
  401. package/dist/_virtual/_commonjsHelpers.js +0 -6
  402. package/dist/controls/Text.d.ts +0 -2
  403. package/dist/controls/Text.js +0 -7
  404. package/dist/controls/action-button-bar/ActionButtonBar.css.d.ts +0 -1
  405. package/dist/controls/action-button-bar/ActionButtonBar.css.js +0 -5
  406. package/dist/controls/action-button-bar/ActionButtonBar.d.ts +0 -9
  407. package/dist/controls/action-button-bar/ActionButtonBar.js +0 -100
  408. package/dist/controls/action-button-bar/useActionButtonBarCtx.d.ts +0 -10
  409. package/dist/controls/action-button-bar/useActionButtonBarCtx.js +0 -9
  410. package/dist/controls/action-buttons/ActionButton.css.d.ts +0 -1
  411. package/dist/controls/action-buttons/ActionButton.css.js +0 -5
  412. package/dist/controls/action-buttons/ActionButton.d.ts +0 -9
  413. package/dist/controls/action-buttons/ActionButton.js +0 -66
  414. package/dist/controls/action-buttons/ActionButtons.d.ts +0 -12
  415. package/dist/controls/action-buttons/ActionButtons.js +0 -99
  416. package/dist/hooks/useDiagramState.d.ts +0 -6
  417. package/dist/hooks/useDiagramState.js +0 -27
  418. package/dist/overlays/OverlayContext.d.ts +0 -10
  419. package/dist/overlays/OverlayContext.js +0 -9
  420. package/dist/overlays/Overlays.css.d.ts +0 -3
  421. package/dist/overlays/Overlays.css.js +0 -7
  422. package/dist/overlays/edge-details/EdgeDetailsXYFlow.d.ts +0 -5
  423. package/dist/overlays/edge-details/EdgeDetailsXYFlow.js +0 -185
  424. package/dist/overlays/edge-details/SelectEdge.css.js +0 -17
  425. package/dist/overlays/edge-details/_types.d.ts +0 -14
  426. package/dist/overlays/edge-details/xyflow/CompoundNode.d.ts +0 -5
  427. package/dist/overlays/edge-details/xyflow/CompoundNode.js +0 -76
  428. package/dist/overlays/edge-details/xyflow/ElementNode.d.ts +0 -5
  429. package/dist/overlays/edge-details/xyflow/ElementNode.js +0 -159
  430. package/dist/overlays/edge-details/xyflow/RelationshipEdge.d.ts +0 -3
  431. package/dist/overlays/edge-details/xyflow/RelationshipEdge.js +0 -84
  432. package/dist/overlays/edge-details/xyflow/styles.css.d.ts +0 -9
  433. package/dist/overlays/edge-details/xyflow/styles.css.js +0 -21
  434. package/dist/overlays/index.d.ts +0 -1
  435. package/dist/overlays/relationships-of/RelationshipsOverlay.d.ts +0 -5
  436. package/dist/overlays/relationships-of/RelationshipsOverlay.js +0 -193
  437. package/dist/overlays/relationships-of/RelationshipsXYFlow.d.ts +0 -19
  438. package/dist/overlays/relationships-of/RelationshipsXYFlow.js +0 -290
  439. package/dist/overlays/relationships-of/SelectElement.css.js +0 -7
  440. package/dist/overlays/relationships-of/SelectElement.d.ts +0 -7
  441. package/dist/overlays/relationships-of/_types.d.ts +0 -28
  442. package/dist/overlays/relationships-of/use-layouted-relationships.d.ts +0 -22
  443. package/dist/overlays/relationships-of/use-layouted-relationships.js +0 -496
  444. package/dist/overlays/relationships-of/xyflow/CompoundNode.d.ts +0 -6
  445. package/dist/overlays/relationships-of/xyflow/CompoundNode.js +0 -120
  446. package/dist/overlays/relationships-of/xyflow/ElementNode.d.ts +0 -6
  447. package/dist/overlays/relationships-of/xyflow/ElementNode.js +0 -194
  448. package/dist/overlays/relationships-of/xyflow/EmptyNode.d.ts +0 -5
  449. package/dist/overlays/relationships-of/xyflow/RelationshipEdge.d.ts +0 -3
  450. package/dist/overlays/relationships-of/xyflow/RelationshipEdge.js +0 -123
  451. package/dist/overlays/relationships-of/xyflow/styles.css.d.ts +0 -14
  452. package/dist/overlays/relationships-of/xyflow/styles.css.js +0 -24
  453. package/dist/overlays/shared/xyflow/RelationshipEdge.css.d.ts +0 -4
  454. package/dist/overlays/shared/xyflow/RelationshipEdge.css.js +0 -12
  455. package/dist/overlays/shared/xyflow/_types.d.ts +0 -77
  456. package/dist/state/DiagramContext.d.ts +0 -1609
  457. package/dist/state/DiagramContext.js +0 -101
  458. package/dist/state/diagram-to-xyflow.d.ts +0 -11
  459. package/dist/state/diagram-to-xyflow.js +0 -113
  460. package/dist/state/diagramStore.d.ts +0 -1705
  461. package/dist/state/diagramStore.js +0 -808
  462. package/dist/state/diagramStore.layout.d.ts +0 -4
  463. package/dist/state/diagramStore.layout.js +0 -56
  464. package/dist/ui/DiagramTitlePanel.css.js +0 -11
  465. package/dist/ui/DiagramTitlePanel.d.ts +0 -1
  466. package/dist/ui/notation/NotationPanel.css.js +0 -16
  467. package/dist/ui/notation/NotationPanel.d.ts +0 -1
  468. package/dist/ui/top-left/TopLeftPanel.d.ts +0 -4
  469. package/dist/ui/top-left/TopLeftPanel.js +0 -211
  470. package/dist/ui/top-left/styles.css.js +0 -17
  471. package/dist/xyflow/FitviewOnDiagramChange.d.ts +0 -4
  472. package/dist/xyflow/FitviewOnDiagramChange.js +0 -72
  473. package/dist/xyflow/SelectEdgesOnNodeFocus.d.ts +0 -1
  474. package/dist/xyflow/SelectEdgesOnNodeFocus.js +0 -96
  475. package/dist/xyflow/XYFlow.d.ts +0 -8
  476. package/dist/xyflow/XYFlow.js +0 -145
  477. package/dist/xyflow/XYFlowBackground.d.ts +0 -10
  478. package/dist/xyflow/XYFlowInner.d.ts +0 -8
  479. package/dist/xyflow/XYFlowInner.js +0 -41
  480. package/dist/xyflow/edges/EdgeLabel.d.ts +0 -7
  481. package/dist/xyflow/edges/EdgeLabel.js +0 -160
  482. package/dist/xyflow/edges/RelationshipEdge.d.ts +0 -6
  483. package/dist/xyflow/edges/RelationshipEdge.js +0 -443
  484. package/dist/xyflow/edges/edges.css.js +0 -37
  485. package/dist/xyflow/edges/utils.d.ts +0 -16
  486. package/dist/xyflow/edges/utils.js +0 -24
  487. package/dist/xyflow/nodes/AnimateVariants.d.ts +0 -1313
  488. package/dist/xyflow/nodes/AnimateVariants.js +0 -123
  489. package/dist/xyflow/nodes/Node.css.d.ts +0 -3
  490. package/dist/xyflow/nodes/Node.css.js +0 -9
  491. package/dist/xyflow/nodes/compound/CompoundNode.css.d.ts +0 -14
  492. package/dist/xyflow/nodes/compound/CompoundNode.css.js +0 -27
  493. package/dist/xyflow/nodes/compound/CompoundNode.d.ts +0 -6
  494. package/dist/xyflow/nodes/compound/CompoundNode.js +0 -216
  495. package/dist/xyflow/nodes/compound/index.d.ts +0 -1
  496. package/dist/xyflow/nodes/element/ElementLink.css.d.ts +0 -3
  497. package/dist/xyflow/nodes/element/ElementLink.d.ts +0 -6
  498. package/dist/xyflow/nodes/element/ElementNode.d.ts +0 -6
  499. package/dist/xyflow/nodes/element/ElementNode.js +0 -190
  500. package/dist/xyflow/nodes/element/ElementShapeSvg.d.ts +0 -17
  501. package/dist/xyflow/nodes/element/element.css.d.ts +0 -18
  502. package/dist/xyflow/nodes/element/element.css.js +0 -31
  503. package/dist/xyflow/nodes/element/index.d.ts +0 -1
  504. package/dist/xyflow/nodes/shared/ElementIcon.d.ts +0 -8
  505. package/dist/xyflow/nodes/shared/Toolbar.d.ts +0 -9
  506. package/dist/xyflow/nodes/shared/Toolbar.js +0 -436
  507. package/dist/xyflow/types.d.ts +0 -36
  508. package/dist/xyflow/useXYFlowEvents.d.ts +0 -160
  509. package/dist/xyflow/useXYFlowEvents.js +0 -275
  510. package/src/controls/Text.ts +0 -5
  511. package/src/controls/action-button-bar/ActionButtonBar.css.ts +0 -13
  512. package/src/controls/action-button-bar/ActionButtonBar.tsx +0 -138
  513. package/src/controls/action-button-bar/useActionButtonBarCtx.ts +0 -13
  514. package/src/controls/action-buttons/ActionButton.css.ts +0 -29
  515. package/src/controls/action-buttons/ActionButton.tsx +0 -66
  516. package/src/controls/action-buttons/ActionButtons.tsx +0 -138
  517. package/src/hooks/useDiagramState.ts +0 -36
  518. package/src/overlays/OverlayContext.tsx +0 -11
  519. package/src/overlays/Overlays.css.ts +0 -136
  520. package/src/overlays/edge-details/EdgeDetailsXYFlow.tsx +0 -255
  521. package/src/overlays/edge-details/_types.ts +0 -18
  522. package/src/overlays/edge-details/xyflow/CompoundNode.tsx +0 -72
  523. package/src/overlays/edge-details/xyflow/ElementNode.tsx +0 -152
  524. package/src/overlays/edge-details/xyflow/RelationshipEdge.tsx +0 -85
  525. package/src/overlays/edge-details/xyflow/styles.css.ts +0 -144
  526. package/src/overlays/index.tsx +0 -1
  527. package/src/overlays/relationships-of/RelationshipsOverlay.tsx +0 -185
  528. package/src/overlays/relationships-of/RelationshipsXYFlow.tsx +0 -378
  529. package/src/overlays/relationships-of/_types.ts +0 -40
  530. package/src/overlays/relationships-of/use-layouted-relationships.ts +0 -699
  531. package/src/overlays/relationships-of/xyflow/CompoundNode.tsx +0 -124
  532. package/src/overlays/relationships-of/xyflow/ElementNode.tsx +0 -194
  533. package/src/overlays/relationships-of/xyflow/EmptyNode.tsx +0 -19
  534. package/src/overlays/relationships-of/xyflow/RelationshipEdge.tsx +0 -127
  535. package/src/overlays/relationships-of/xyflow/styles.css.ts +0 -214
  536. package/src/overlays/shared/xyflow/RelationshipEdge.css.ts +0 -60
  537. package/src/overlays/shared/xyflow/_types.ts +0 -87
  538. package/src/state/DiagramContext.tsx +0 -107
  539. package/src/state/diagram-to-xyflow.ts +0 -150
  540. package/src/state/diagramStore.layout.ts +0 -66
  541. package/src/state/diagramStore.ts +0 -1099
  542. package/src/ui/top-left/TopLeftPanel.tsx +0 -220
  543. package/src/xyflow/FitviewOnDiagramChange.tsx +0 -83
  544. package/src/xyflow/SelectEdgesOnNodeFocus.tsx +0 -106
  545. package/src/xyflow/XYFlow.tsx +0 -179
  546. package/src/xyflow/XYFlowInner.tsx +0 -48
  547. package/src/xyflow/edges/EdgeLabel.tsx +0 -193
  548. package/src/xyflow/edges/RelationshipEdge.tsx +0 -547
  549. package/src/xyflow/edges/edges.css.ts +0 -288
  550. package/src/xyflow/edges/utils.ts +0 -153
  551. package/src/xyflow/nodes/AnimateVariants.ts +0 -143
  552. package/src/xyflow/nodes/Node.css.ts +0 -44
  553. package/src/xyflow/nodes/compound/CompoundNode.css.ts +0 -258
  554. package/src/xyflow/nodes/compound/CompoundNode.tsx +0 -227
  555. package/src/xyflow/nodes/compound/index.ts +0 -1
  556. package/src/xyflow/nodes/element/ElementLink.css.ts +0 -67
  557. package/src/xyflow/nodes/element/ElementLink.tsx +0 -97
  558. package/src/xyflow/nodes/element/ElementNode.tsx +0 -209
  559. package/src/xyflow/nodes/element/element.css.ts +0 -369
  560. package/src/xyflow/nodes/element/index.ts +0 -1
  561. package/src/xyflow/nodes/shared/ElementIcon.tsx +0 -43
  562. package/src/xyflow/nodes/shared/Toolbar.tsx +0 -496
  563. package/src/xyflow/types.ts +0 -57
  564. package/src/xyflow/useXYFlowEvents.ts +0 -315
  565. /package/dist/{xyflow → base}/const.d.ts +0 -0
  566. /package/dist/{xyflow → base}/const.js +0 -0
  567. /package/dist/{ui → context}/EnsureMantine.d.ts +0 -0
  568. /package/dist/{ui → context}/EnsureMantine.js +0 -0
  569. /package/dist/{ui → context}/FramerMotionConfig.d.ts +0 -0
  570. /package/dist/{xyflow → likec4diagram/custom}/edges/RelationshipsDropdownMenu.css.d.ts +0 -0
  571. /package/dist/{ui/top-left → likec4diagram/ui/controls}/ChangeAutoLayoutButton.d.ts +0 -0
  572. /package/dist/{ui/top-left → likec4diagram/ui/controls}/ManualLayoutToolsButton.d.ts +0 -0
  573. /package/dist/{ui/top-left → likec4diagram/ui/controls}/_shared.d.ts +0 -0
  574. /package/dist/{ui → likec4diagram/ui/diagram-title}/DiagramTitlePanel.css.d.ts +0 -0
  575. /package/dist/{ui → likec4diagram/ui/diagram-title}/Link.js +0 -0
  576. /package/dist/{ui → likec4diagram/ui}/notation/NotationPanel.css.d.ts +0 -0
  577. /package/dist/{ui → likec4diagram/ui}/notation/index.d.ts +0 -0
  578. /package/dist/{ui → likec4diagram/ui/walkthrough}/DynamicViewWalkthrough.css.d.ts +0 -0
  579. /package/dist/{ui → likec4diagram/ui/walkthrough}/DynamicViewWalkthrough.d.ts +0 -0
  580. /package/src/{ui → context}/EnsureMantine.tsx +0 -0
  581. /package/src/{ui → likec4diagram/ui}/notation/index.ts +0 -0
@@ -1,9 +1,11 @@
1
- import { invariant, type NonEmptyArray } from '@likec4/core'
2
- import type { Rect, XYPosition } from '@xyflow/react'
1
+ import { type NonEmptyArray, invariant, nonexhaustive } from '@likec4/core'
2
+ import type { InternalNode, Rect, XYPosition } from '@xyflow/react'
3
+ import { getNodeDimensions } from '@xyflow/system'
3
4
  import { map, pick, pipe, reduce, sortBy } from 'remeda'
4
5
 
5
6
  export type GridAlignmentMode = 'Column' | 'Row'
6
7
  export type LinearAlignmentMode = 'Left' | 'Center' | 'Right' | 'Top' | 'Middle' | 'Bottom'
8
+ export type AlignmentMode = LinearAlignmentMode | GridAlignmentMode
7
9
 
8
10
  export abstract class Aligner {
9
11
  abstract computeLayout(nodes: NodeRect[]): void
@@ -15,7 +17,7 @@ export class LinearAligner extends Aligner {
15
17
  constructor(
16
18
  private getEdgePosition: (nodes: NodeRect[]) => number,
17
19
  private computePosition: (alignTo: number, node: NodeRect) => number,
18
- private propertyToEdit: keyof XYPosition
20
+ private propertyToEdit: keyof XYPosition,
19
21
  ) {
20
22
  super()
21
23
  }
@@ -26,7 +28,7 @@ export class LinearAligner extends Aligner {
26
28
 
27
29
  override applyPosition(node: NodeRect): Partial<XYPosition> {
28
30
  return {
29
- [this.propertyToEdit]: this.computePosition(this.alignTo!, node)
31
+ [this.propertyToEdit]: this.computePosition(this.alignTo!, node),
30
32
  }
31
33
  }
32
34
  }
@@ -73,13 +75,13 @@ export class GridAligner extends Aligner {
73
75
  primaryAxisDimension: 'width',
74
76
  secondaryAxisDimension: 'height',
75
77
  primaryAxisCoord: 'x',
76
- secondaryAxisCoord: 'y'
78
+ secondaryAxisCoord: 'y',
77
79
  }
78
80
  : {
79
81
  primaryAxisDimension: 'height',
80
82
  secondaryAxisDimension: 'width',
81
83
  primaryAxisCoord: 'y',
82
- secondaryAxisCoord: 'x'
84
+ secondaryAxisCoord: 'x',
83
85
  }
84
86
  }
85
87
 
@@ -91,7 +93,7 @@ export class GridAligner extends Aligner {
91
93
  // Sort by primary axis
92
94
  const sortedNodeRects = pipe(
93
95
  nodes,
94
- sortBy(r => r[this.primaryAxisCoord])
96
+ sortBy(r => r[this.primaryAxisCoord]),
95
97
  )
96
98
 
97
99
  const layoutRect = this.getLayoutRect(sortedNodeRects)
@@ -111,7 +113,7 @@ export class GridAligner extends Aligner {
111
113
  x,
112
114
  y,
113
115
  width: right - x,
114
- height: bottom - y
116
+ height: bottom - y,
115
117
  }
116
118
  }
117
119
 
@@ -127,14 +129,14 @@ export class GridAligner extends Aligner {
127
129
  layer.occupiedSpace += node[this.secondaryAxisDimension]
128
130
  layerEnd = Math.max(
129
131
  node[this.primaryAxisCoord] + node[this.primaryAxisDimension],
130
- layerEnd
132
+ layerEnd,
131
133
  )
132
134
  } else {
133
135
  layer = {
134
136
  primaryAxisSize: node[this.primaryAxisDimension],
135
137
  nodes: [node],
136
138
  occupiedSpace: node[this.secondaryAxisDimension],
137
- layout: null
139
+ layout: null,
138
140
  }
139
141
  layers.push(layer)
140
142
  layerEnd = node[this.primaryAxisCoord] + node[this.primaryAxisDimension]
@@ -142,9 +144,7 @@ export class GridAligner extends Aligner {
142
144
  }
143
145
  }
144
146
 
145
- layers.forEach(l =>
146
- l.nodes.sort((a, b) => a[this.secondaryAxisCoord] - b[this.secondaryAxisCoord])
147
- )
147
+ layers.forEach(l => l.nodes.sort((a, b) => a[this.secondaryAxisCoord] - b[this.secondaryAxisCoord]))
148
148
 
149
149
  return layers as NonEmptyArray<Layer>
150
150
  }
@@ -161,19 +161,19 @@ export class GridAligner extends Aligner {
161
161
  const baseLayerIndex = layers.reduce(
162
162
  (widestLayerIndex, layer, i) =>
163
163
  layers[widestLayerIndex]!.occupiedSpace < layer.occupiedSpace ? i : widestLayerIndex,
164
- 0
164
+ 0,
165
165
  )
166
166
  const baseLayer = layers[baseLayerIndex]!
167
167
  const baseLayerPosition = layers.slice(0, baseLayerIndex).reduce(
168
168
  (a, layer) => a + layer.primaryAxisSize + rowMargin,
169
- layoutRect[this.primaryAxisCoord]
169
+ layoutRect[this.primaryAxisCoord],
170
170
  )
171
171
  const baseLayerLayout = this.buildLayerLayout(
172
172
  baseLayer,
173
173
  layoutRect,
174
174
  baseLayerPosition,
175
175
  nodeMap,
176
- null
176
+ null,
177
177
  )
178
178
  baseLayer.layout = baseLayerLayout
179
179
  layout.push(...baseLayerLayout.nodePositions)
@@ -211,17 +211,17 @@ export class GridAligner extends Aligner {
211
211
  layoutRect: Rect,
212
212
  placeNextLayerAt: number,
213
213
  nodeMap: Map<string, NodeRect>,
214
- refLayer: Layer | null
214
+ refLayer: Layer | null,
215
215
  ): Layout {
216
216
  let bestLayerLayout = this.scoreLayout(
217
217
  this.spaceAround(layer, layoutRect, placeNextLayerAt),
218
- nodeMap
218
+ nodeMap,
219
219
  )
220
220
 
221
221
  if (layer.nodes.length != 1) {
222
222
  const currentlayerLayout = this.scoreLayout(
223
223
  this.spaceBetween(layer, layoutRect, placeNextLayerAt),
224
- nodeMap
224
+ nodeMap,
225
225
  )
226
226
  bestLayerLayout = currentlayerLayout[0] < bestLayerLayout[0] ? currentlayerLayout : bestLayerLayout
227
227
  }
@@ -229,7 +229,7 @@ export class GridAligner extends Aligner {
229
229
  if (refLayer && refLayer.nodes.length - 1 >= layer.nodes.length) {
230
230
  const currentlayerLayout = this.scoreLayout(
231
231
  this.placeInGaps(layer, placeNextLayerAt, refLayer),
232
- nodeMap
232
+ nodeMap,
233
233
  )
234
234
  bestLayerLayout = currentlayerLayout[0] < bestLayerLayout[0] ? currentlayerLayout : bestLayerLayout
235
235
  }
@@ -237,7 +237,7 @@ export class GridAligner extends Aligner {
237
237
  if (refLayer && refLayer.nodes.length >= layer.nodes.length) {
238
238
  const currentlayerLayout = this.scoreLayout(
239
239
  this.placeInCells(layer, placeNextLayerAt, refLayer),
240
- nodeMap
240
+ nodeMap,
241
241
  )
242
242
  bestLayerLayout = currentlayerLayout[0] < bestLayerLayout[0] ? currentlayerLayout : bestLayerLayout
243
243
  }
@@ -248,7 +248,7 @@ export class GridAligner extends Aligner {
248
248
  private spaceBetween(
249
249
  layer: Layer,
250
250
  layoutRect: Rect,
251
- placeNextLayerAt: number
251
+ placeNextLayerAt: number,
252
252
  ): Layout {
253
253
  const freeSpace = layoutRect[this.secondaryAxisDimension] - layer.occupiedSpace
254
254
  const margin = freeSpace / (layer.nodes.length - 1)
@@ -260,7 +260,7 @@ export class GridAligner extends Aligner {
260
260
  for (let node of layer.nodes) {
261
261
  result.set(node.id, {
262
262
  [this.secondaryAxisCoord]: placeNextNodeAt,
263
- [this.primaryAxisCoord]: placeNextLayerAt
263
+ [this.primaryAxisCoord]: placeNextLayerAt,
264
264
  } as XYPosition)
265
265
  placeNextNodeAt += node[this.secondaryAxisDimension] + margin
266
266
  i++
@@ -272,7 +272,7 @@ export class GridAligner extends Aligner {
272
272
  private spaceAround(
273
273
  layer: Layer,
274
274
  layoutRect: Rect,
275
- placeNextLayerAt: number
275
+ placeNextLayerAt: number,
276
276
  ): Layout {
277
277
  const freeSpace = layoutRect[this.secondaryAxisDimension] - layer.occupiedSpace
278
278
  const margin = freeSpace / (layer.nodes.length + 1)
@@ -283,7 +283,7 @@ export class GridAligner extends Aligner {
283
283
  for (let node of sortBy(layer.nodes, n => n[this.secondaryAxisCoord])) {
284
284
  result.set(node.id, {
285
285
  [this.secondaryAxisCoord]: placeNextNodeAt,
286
- [this.primaryAxisCoord]: placeNextLayerAt
286
+ [this.primaryAxisCoord]: placeNextLayerAt,
287
287
  } as XYPosition)
288
288
  placeNextNodeAt += node[this.secondaryAxisDimension] + margin
289
289
  }
@@ -294,7 +294,7 @@ export class GridAligner extends Aligner {
294
294
  private placeInGaps(
295
295
  layer: Layer,
296
296
  placeNextLayerAt: number,
297
- refLayer: Layer
297
+ refLayer: Layer,
298
298
  ): Layout {
299
299
  const result = new Map<string, XYPosition>()
300
300
 
@@ -322,7 +322,7 @@ export class GridAligner extends Aligner {
322
322
 
323
323
  result.set(node.id, {
324
324
  [this.secondaryAxisCoord]: node[this.secondaryAxisCoord] + bestOffset,
325
- [this.primaryAxisCoord]: placeNextLayerAt
325
+ [this.primaryAxisCoord]: placeNextLayerAt,
326
326
  } as XYPosition)
327
327
  }
328
328
 
@@ -332,7 +332,7 @@ export class GridAligner extends Aligner {
332
332
  private placeInCells(
333
333
  layer: Layer,
334
334
  placeNextLayerAt: number,
335
- refLayer: Layer
335
+ refLayer: Layer,
336
336
  ): Layout {
337
337
  const result = new Map<string, XYPosition>()
338
338
 
@@ -361,7 +361,7 @@ export class GridAligner extends Aligner {
361
361
 
362
362
  result.set(node.id, {
363
363
  [this.secondaryAxisCoord]: node[this.secondaryAxisCoord] + bestOffset,
364
- [this.primaryAxisCoord]: placeNextLayerAt
364
+ [this.primaryAxisCoord]: placeNextLayerAt,
365
365
  } as XYPosition)
366
366
  }
367
367
 
@@ -370,7 +370,7 @@ export class GridAligner extends Aligner {
370
370
 
371
371
  private scoreLayout(
372
372
  layout: Layout,
373
- originalRects: Map<string, NodeRect>
373
+ originalRects: Map<string, NodeRect>,
374
374
  ): [number, Layout] {
375
375
  return [
376
376
  pipe(
@@ -383,9 +383,9 @@ export class GridAligner extends Aligner {
383
383
  map(([original, suggested]) =>
384
384
  Math.abs(original![this.secondaryAxisCoord] - suggested![this.secondaryAxisCoord])
385
385
  ),
386
- reduce((a, b) => a + b, 0)
386
+ reduce((a, b) => a + b, 0),
387
387
  ),
388
- layout
388
+ layout,
389
389
  ]
390
390
  }
391
391
 
@@ -404,7 +404,7 @@ export class GridAligner extends Aligner {
404
404
  result.push(
405
405
  (currentNodePosition[this.secondaryAxisCoord]
406
406
  + previousNodePosition[this.secondaryAxisCoord]
407
- + previousNode[this.secondaryAxisDimension]) / 2
407
+ + previousNode[this.secondaryAxisDimension]) / 2,
408
408
  )
409
409
  }
410
410
 
@@ -423,7 +423,7 @@ export class GridAligner extends Aligner {
423
423
 
424
424
  result.push(
425
425
  nodePosition[this.secondaryAxisCoord]
426
- + node[this.secondaryAxisDimension] / 2
426
+ + node[this.secondaryAxisDimension] / 2,
427
427
  )
428
428
  }
429
429
 
@@ -437,37 +437,64 @@ export function getLinearAligner(mode: LinearAlignmentMode): Aligner {
437
437
  return new LinearAligner(
438
438
  nodes => Math.min(...nodes.map(n => n.x)),
439
439
  (alignTo, _) => Math.floor(alignTo),
440
- 'x'
440
+ 'x',
441
441
  )
442
442
  case 'Top':
443
443
  return new LinearAligner(
444
444
  nodes => Math.min(...nodes.map(n => n.y)),
445
445
  (alignTo, _) => Math.floor(alignTo),
446
- 'y'
446
+ 'y',
447
447
  )
448
448
  case 'Right':
449
449
  return new LinearAligner(
450
450
  nodes => Math.max(...nodes.map(n => n.x + n.width)),
451
451
  (alignTo, node) => Math.floor(alignTo - node.width!),
452
- 'x'
452
+ 'x',
453
453
  )
454
454
  case 'Bottom':
455
455
  return new LinearAligner(
456
456
  nodes => Math.max(...nodes.map(n => n.y + n.height)),
457
457
  (alignTo, node) => Math.floor(alignTo - node.height!),
458
- 'y'
458
+ 'y',
459
459
  )
460
460
  case 'Center':
461
461
  return new LinearAligner(
462
462
  nodes => Math.min(...nodes.map(n => n.x + n.width / 2)),
463
463
  (alignTo, node) => Math.floor(alignTo - node.width / 2),
464
- 'x'
464
+ 'x',
465
465
  )
466
466
  case 'Middle':
467
467
  return new LinearAligner(
468
468
  nodes => Math.min(...nodes.map(n => n.y + n.height / 2)),
469
469
  (alignTo, node) => Math.floor(alignTo - node.height / 2),
470
- 'y'
470
+ 'y',
471
471
  )
472
472
  }
473
473
  }
474
+
475
+ export function toNodeRect(node: InternalNode): NodeRect {
476
+ const { width, height } = getNodeDimensions(node)
477
+ return {
478
+ ...node.internals.positionAbsolute,
479
+ id: node.id,
480
+ width,
481
+ height,
482
+ }
483
+ }
484
+
485
+ export function getAligner(mode: AlignmentMode): Aligner {
486
+ switch (mode) {
487
+ case 'Left':
488
+ case 'Right':
489
+ case 'Top':
490
+ case 'Bottom':
491
+ case 'Center':
492
+ case 'Middle':
493
+ return getLinearAligner(mode)
494
+ case 'Column':
495
+ case 'Row':
496
+ return new GridAligner(mode)
497
+ default:
498
+ nonexhaustive(mode)
499
+ }
500
+ }
@@ -0,0 +1,384 @@
1
+ import { type NodeId, type XYPoint, invariant, nonNullable } from '@likec4/core'
2
+ import { getNodeDimensions } from '@xyflow/system'
3
+ import { deepEqual as eq } from 'fast-equals'
4
+ import { isEmpty, mergeDeep, omit } from 'remeda'
5
+ import { assertEvent } from 'xstate'
6
+ import { Base } from '../../base'
7
+ import { type Vector, vector, VectorImpl } from '../../utils/vector'
8
+ import type { Types } from '../types'
9
+ import type { ActionArg, DiagramContext } from './machine'
10
+
11
+ export function lastClickedNode(
12
+ params: { context: DiagramContext; event: { node: Types.Node } },
13
+ ): DiagramContext['lastClickedNode'] {
14
+ const { lastClickedNode } = params.context
15
+ if (!lastClickedNode || lastClickedNode.id !== params.event.node.id) {
16
+ return {
17
+ id: params.event.node.id as NodeId,
18
+ clicks: 1,
19
+ timestamp: Date.now(),
20
+ }
21
+ }
22
+ return {
23
+ id: lastClickedNode.id,
24
+ clicks: lastClickedNode.clicks + 1,
25
+ timestamp: Date.now(),
26
+ }
27
+ }
28
+
29
+ export function mergeXYNodesEdges({ context, event }: ActionArg): Partial<DiagramContext> {
30
+ assertEvent(event, 'update.view')
31
+ const nextView = event.view
32
+ const isSameView = context.view.id === nextView.id
33
+
34
+ const currentNodes = context.xynodes
35
+ const xynodes = event.xynodes.map((update) => {
36
+ const existing = currentNodes.find(n => n.id === update.id)
37
+ if (existing) {
38
+ const { width: existingWidth, height: existingHeight } = getNodeDimensions(existing)
39
+ if (
40
+ eq(existing.type, update.type)
41
+ && eq(existingWidth, update.initialWidth)
42
+ && eq(existingHeight, update.initialHeight)
43
+ && eq(existing.hidden ?? false, update.hidden ?? false)
44
+ && eq(existing.position, update.position)
45
+ && eq(existing.data, update.data)
46
+ && eq(existing.parentId ?? null, update.parentId ?? null)
47
+ ) {
48
+ return existing
49
+ }
50
+ return {
51
+ ...omit(existing, ['measured', 'parentId']),
52
+ ...update,
53
+ // Force dimensions from update
54
+ width: update.initialWidth,
55
+ height: update.initialHeight,
56
+ data: {
57
+ ...existing.data,
58
+ ...update.data,
59
+ },
60
+ } as Types.Node
61
+ }
62
+ return update
63
+ })
64
+ // Merge with existing edges, but only if the view is the same
65
+ // and the edges have no layout drift
66
+ let xyedges = event.xyedges
67
+ if (isSameView && !nextView.hasLayoutDrift) {
68
+ const currentEdges = context.xyedges
69
+ xyedges = event.xyedges.map((update): Types.Edge => {
70
+ const existing = currentEdges.find(n => n.id === update.id)
71
+ if (existing) {
72
+ if (
73
+ eq(existing.hidden ?? false, update.hidden ?? false)
74
+ && eq(existing.data, update.data)
75
+ ) {
76
+ return existing
77
+ }
78
+ return {
79
+ ...existing,
80
+ ...update,
81
+ data: {
82
+ ...existing.data,
83
+ ...update.data,
84
+ },
85
+ }
86
+ }
87
+ return update
88
+ })
89
+ }
90
+
91
+ if (!isSameView) {
92
+ for (const node of xynodes) {
93
+ node.data = {
94
+ ...node.data,
95
+ dimmed: false,
96
+ hovered: false,
97
+ }
98
+ }
99
+ for (const edge of xyedges) {
100
+ edge.data = {
101
+ ...edge.data,
102
+ dimmed: false,
103
+ hovered: false,
104
+ active: false,
105
+ }
106
+ }
107
+ }
108
+
109
+ return {
110
+ xynodes,
111
+ xyedges,
112
+ view: nextView,
113
+ }
114
+ }
115
+
116
+ export function focusNodesEdges(params: ActionArg): Partial<DiagramContext> {
117
+ const { xynodes: _xynodes, xyedges: _xyedges, focusedNode } = params.context
118
+ if (!focusedNode) {
119
+ return {}
120
+ }
121
+ const focused = new Set([focusedNode as string])
122
+ const xyedges = _xyedges.map((edge) => {
123
+ if (edge.source === focusedNode || edge.target === focusedNode) {
124
+ focused.add(edge.source)
125
+ focused.add(edge.target)
126
+ return Base.setData(edge, {
127
+ dimmed: false,
128
+ active: true,
129
+ })
130
+ }
131
+ return Base.setData(edge, {
132
+ dimmed: true,
133
+ active: false,
134
+ })
135
+ })
136
+
137
+ return {
138
+ xynodes: _xynodes.map(n => Base.setDimmed(n, !focused.has(n.id))),
139
+ xyedges,
140
+ }
141
+ }
142
+
143
+ export function unfocusNodesEdges({ context }: ActionArg): Partial<DiagramContext> {
144
+ const { xynodes, xyedges } = context
145
+ return {
146
+ xynodes: xynodes.map(Base.setDimmed(false)),
147
+ xyedges: xyedges.map(Base.setData({
148
+ dimmed: false,
149
+ active: false,
150
+ })),
151
+ }
152
+ }
153
+
154
+ export function updateNavigationHistory({ context, event }: ActionArg): Partial<DiagramContext> {
155
+ assertEvent(event, 'update.view')
156
+ let {
157
+ view,
158
+ navigationHistory: {
159
+ currentIndex,
160
+ history,
161
+ },
162
+ lastOnNavigate,
163
+ viewport,
164
+ } = context
165
+ const stepCurrent = nonNullable(history[currentIndex])
166
+ if (stepCurrent.viewId !== event.view.id) {
167
+ // Navigation by browser back/forward ?
168
+ if (!lastOnNavigate) {
169
+ const stepBack = currentIndex > 0 ? nonNullable(history[currentIndex - 1]) : null
170
+ if (stepBack && stepBack.viewId === event.view.id) {
171
+ return {
172
+ navigationHistory: {
173
+ currentIndex: currentIndex - 1,
174
+ history,
175
+ },
176
+ lastOnNavigate: {
177
+ fromView: stepCurrent.viewId,
178
+ toView: stepBack.viewId,
179
+ fromNode: stepCurrent.fromNode,
180
+ },
181
+ }
182
+ }
183
+ const stepForward = currentIndex < history.length - 1 ? nonNullable(history[currentIndex + 1]) : null
184
+ if (stepForward && stepForward.viewId === event.view.id) {
185
+ return {
186
+ navigationHistory: {
187
+ currentIndex: currentIndex + 1,
188
+ history,
189
+ },
190
+ lastOnNavigate: {
191
+ fromView: stepCurrent.viewId,
192
+ toView: stepForward.viewId,
193
+ fromNode: stepForward.fromNode,
194
+ },
195
+ }
196
+ }
197
+ }
198
+
199
+ history = [
200
+ ...history.slice(0, currentIndex + 1),
201
+ {
202
+ viewId: event.view.id,
203
+ fromNode: lastOnNavigate?.fromNode ?? null,
204
+ viewport: { ...viewport },
205
+ },
206
+ ]
207
+ currentIndex = history.length - 1
208
+ return {
209
+ navigationHistory: {
210
+ currentIndex,
211
+ history,
212
+ },
213
+ }
214
+ }
215
+ return {}
216
+ }
217
+
218
+ export function navigateBack({ context }: ActionArg): Partial<DiagramContext> {
219
+ const {
220
+ navigationHistory: {
221
+ currentIndex,
222
+ history,
223
+ },
224
+ } = context
225
+ invariant(currentIndex > 0, 'Cannot navigate back')
226
+ const stepCurrent = history[currentIndex]!
227
+ const stepBack = history[currentIndex - 1]!
228
+ return {
229
+ navigationHistory: {
230
+ currentIndex: currentIndex - 1,
231
+ history,
232
+ },
233
+ lastOnNavigate: {
234
+ fromView: stepCurrent.viewId,
235
+ toView: stepBack.viewId,
236
+ fromNode: stepCurrent.fromNode,
237
+ },
238
+ }
239
+ }
240
+
241
+ export function navigateForward({ context }: ActionArg): Partial<DiagramContext> {
242
+ const {
243
+ navigationHistory: {
244
+ currentIndex,
245
+ history,
246
+ },
247
+ } = context
248
+ invariant(currentIndex < history.length - 1, 'Cannot navigate forward')
249
+ const stepCurrent = history[currentIndex]!
250
+ const stepForward = history[currentIndex + 1]!
251
+ return {
252
+ navigationHistory: {
253
+ currentIndex: currentIndex + 1,
254
+ history,
255
+ },
256
+ lastOnNavigate: {
257
+ fromView: stepCurrent.viewId,
258
+ toView: stepForward.viewId,
259
+ fromNode: stepForward.fromNode,
260
+ },
261
+ }
262
+ }
263
+
264
+ export function updateNodeData({ context, event }: ActionArg): Partial<DiagramContext> {
265
+ assertEvent(event, 'update.nodeData')
266
+ const xynodes = context.xynodes.map((node): Types.Node =>
267
+ node.id !== event.nodeId ? node : (({
268
+ ...node,
269
+ data: mergeDeep(node.data as any, event.data as any),
270
+ }) as Types.Node)
271
+ )
272
+ return { xynodes }
273
+ }
274
+
275
+ export function updateEdgeData({ context, event }: ActionArg): Partial<DiagramContext> {
276
+ assertEvent(event, 'update.edgeData')
277
+ const xyedges = context.xyedges.map((edge): Types.Edge =>
278
+ edge.id !== event.edgeId ? edge : (({
279
+ ...edge,
280
+ data: mergeDeep(edge.data as any, event.data as any),
281
+ }) as Types.Edge)
282
+ )
283
+ return { xyedges }
284
+ }
285
+
286
+ export function resetEdgeControlPoints({ context }: ActionArg): Partial<DiagramContext> {
287
+ const { xynodes } = context
288
+
289
+ function getNodeCenter(node: Types.Node, nodes: Types.Node[]) {
290
+ const dimensions = vector({ x: node.width || 0, y: node.height || 0 })
291
+ let position = vector(node.position)
292
+ .add(dimensions.mul(0.5))
293
+
294
+ let currentNode = node
295
+ do {
296
+ const parent = currentNode.parentId && nodes.find(x => x.id == currentNode.parentId)
297
+
298
+ if (!parent) {
299
+ break
300
+ }
301
+
302
+ currentNode = parent
303
+ position = position.add(parent.position)
304
+ } while (true)
305
+
306
+ return position
307
+ }
308
+
309
+ function getControlPointForEdge(edge: Types.Edge): XYPoint[] {
310
+ const source = xynodes.find(x => x.id == edge.source)
311
+ const target = xynodes.find(x => x.id == edge.target)
312
+ if (!source || !target) {
313
+ return []
314
+ }
315
+
316
+ const sourceCenter = getNodeCenter(source, xynodes)
317
+ const targetCenter = getNodeCenter(target, xynodes)
318
+
319
+ if (!sourceCenter || !targetCenter) {
320
+ return []
321
+ }
322
+
323
+ // Edge is a loop
324
+ if (source == target) {
325
+ const loopSize = 80
326
+ const centerOfTopBoundary = new VectorImpl(0, source.height || 0)
327
+ .mul(-0.5)
328
+ .add(sourceCenter)
329
+
330
+ return [
331
+ centerOfTopBoundary.add(new VectorImpl(-loopSize / 2.5, -loopSize)),
332
+ centerOfTopBoundary.add(new VectorImpl(loopSize / 2.5, -loopSize)),
333
+ ]
334
+ }
335
+
336
+ const sourceToTargetVector = targetCenter.sub(sourceCenter)
337
+ const sourceBorderPoint = getBorderPointOnVector(source, sourceCenter, sourceToTargetVector)
338
+ const targetBorderPoint = getBorderPointOnVector(target, targetCenter, sourceToTargetVector.mul(-1))
339
+
340
+ return [sourceBorderPoint.add(targetBorderPoint.sub(sourceBorderPoint).mul(0.3))]
341
+ }
342
+
343
+ function getBorderPointOnVector(node: Types.Node, nodeCenter: Vector, v: Vector) {
344
+ const xScale = (node.width || 0) / 2 / v.x
345
+ const yScale = (node.height || 0) / 2 / v.y
346
+
347
+ const scale = Math.min(Math.abs(xScale), Math.abs(yScale))
348
+
349
+ return vector(v).mul(scale).add(nodeCenter)
350
+ }
351
+
352
+ return {
353
+ xyedges: context.xyedges.map(edge => {
354
+ if (!edge.data.controlPoints || isEmpty(edge.data.controlPoints)) {
355
+ return edge
356
+ }
357
+ return ({
358
+ ...edge,
359
+ data: {
360
+ ...edge.data,
361
+ controlPoints: getControlPointForEdge(edge),
362
+ },
363
+ })
364
+ }),
365
+ }
366
+ }
367
+
368
+ export function updateActiveWalkthrough({ context }: ActionArg): Partial<DiagramContext> {
369
+ const { stepId, parallelPrefix } = nonNullable(context.activeWalkthrough, 'activeWalkthrough is null')
370
+ const step = nonNullable(context.xyedges.find(x => x.id === stepId))
371
+ return {
372
+ xyedges: context.xyedges.map(edge => {
373
+ const active = stepId === edge.id || (!!parallelPrefix && edge.id.startsWith(parallelPrefix))
374
+ return Base.setData(edge, {
375
+ active,
376
+ dimmed: !active,
377
+ })
378
+ }),
379
+ xynodes: context.xynodes.map(node => {
380
+ const active = step.source === node.id || step.target === node.id
381
+ return Base.setDimmed(node, !active)
382
+ }),
383
+ }
384
+ }