@likec4/diagram 1.19.2 → 1.20.0

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 +25 -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 -7
  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 +126 -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 -17
  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
@@ -0,0 +1,946 @@
1
+ import {
2
+ type BBox,
3
+ type DiagramView,
4
+ type EdgeId,
5
+ type Fqn,
6
+ type NodeId,
7
+ type RelationId,
8
+ type StepEdgeId,
9
+ type ViewChange,
10
+ type ViewId,
11
+ type XYPoint,
12
+ DiagramNode,
13
+ getBBoxCenter,
14
+ getParallelStepsPrefix,
15
+ invariant,
16
+ nonexhaustive,
17
+ nonNullable,
18
+ } from '@likec4/core'
19
+ import {
20
+ type ReactFlowInstance,
21
+ applyEdgeChanges,
22
+ applyNodeChanges,
23
+ getViewportForBounds,
24
+ useStoreApi,
25
+ } from '@xyflow/react'
26
+ import { type EdgeChange, type NodeChange, type Rect, type Viewport, nodeToRect } from '@xyflow/system'
27
+ import { clamp, first, hasAtLeast, prop } from 'remeda'
28
+ import {
29
+ type ActorRefFromLogic,
30
+ type SnapshotFrom,
31
+ and,
32
+ assertEvent,
33
+ assign,
34
+ cancel,
35
+ enqueueActions,
36
+ or,
37
+ raise,
38
+ sendTo,
39
+ setup,
40
+ spawnChild,
41
+ stopChild,
42
+ } from 'xstate'
43
+ import { MinZoom } from '../../base/const'
44
+ import type { EnabledFeatures } from '../../context'
45
+ import { AllDisabled } from '../../context/DiagramFeatures'
46
+ import type { OpenSourceParams } from '../../LikeC4Diagram.props'
47
+ import { relationshipDetailsActor } from '../../overlays/relationship-details/actor'
48
+ import { relationshipsBrowserActor } from '../../overlays/relationships-browser/actor'
49
+ import type { Types } from '../types'
50
+ import { createLayoutConstraints } from '../useLayoutConstraints'
51
+ import { type AlignmentMode, getAligner, toNodeRect } from './aligners'
52
+ import {
53
+ focusNodesEdges,
54
+ lastClickedNode,
55
+ mergeXYNodesEdges,
56
+ navigateBack,
57
+ navigateForward,
58
+ resetEdgeControlPoints,
59
+ unfocusNodesEdges,
60
+ updateActiveWalkthrough,
61
+ updateEdgeData,
62
+ updateNavigationHistory,
63
+ updateNodeData,
64
+ } from './assign'
65
+ import { type HotKeyEvent, hotkeyActor } from './hotkeyActor'
66
+ import { syncManualLayoutActor } from './syncManualLayoutActor'
67
+ import { focusedBounds } from './utils'
68
+
69
+ type XYStoreApi = ReturnType<typeof useStoreApi<Types.Node, Types.Edge>>
70
+
71
+ export interface NavigationHistory {
72
+ history: ReadonlyArray<{
73
+ viewId: ViewId
74
+ fromNode: NodeId | null
75
+ viewport: Viewport
76
+ }>
77
+ currentIndex: number
78
+ }
79
+
80
+ export interface Input {
81
+ view: DiagramView
82
+ xynodes: Types.Node[]
83
+ xyedges: Types.Edge[]
84
+ xystore: XYStoreApi
85
+ zoomable: boolean
86
+ pannable: boolean
87
+ fitViewPadding: number
88
+ }
89
+
90
+ export interface DiagramContext extends Input {
91
+ features: EnabledFeatures
92
+ initialized: boolean
93
+ viewport: Viewport
94
+ viewportChangedManually: boolean
95
+ lastOnNavigate: null | {
96
+ fromView: ViewId
97
+ toView: ViewId
98
+ fromNode: NodeId | null
99
+ }
100
+ navigationHistory: NavigationHistory
101
+ lastClickedNode: null | {
102
+ id: NodeId
103
+ clicks: number
104
+ timestamp: number
105
+ }
106
+ focusedNode: NodeId | null
107
+ activeElementDetails: null | {
108
+ fqn: Fqn
109
+ fromNode: NodeId | null
110
+ // internal xyflow node rect
111
+ nodeRect?: Rect | null
112
+ // in screen coordinates
113
+ nodeRectScreen?: Rect | null
114
+ }
115
+ viewportBeforeFocus: null | Viewport
116
+ xyflow: ReactFlowInstance<Types.Node, Types.Edge> | null
117
+ syncLayoutActorRef: ActorRefFromLogic<typeof syncManualLayoutActor>
118
+
119
+ // If Dynamic View
120
+ activeWalkthrough: null | {
121
+ stepId: StepEdgeId
122
+ parallelPrefix: string | null
123
+ }
124
+ }
125
+
126
+ export namespace DiagramContext {
127
+ export function findDiagramNode(ctx: DiagramContext, xynodeId: string) {
128
+ return ctx.view.nodes.find(n => n.id === xynodeId) ?? null
129
+ }
130
+
131
+ export function findDiagramEdge(ctx: DiagramContext, xyedgeId: string) {
132
+ return ctx.view.edges.find(e => e.id === xyedgeId) ?? null
133
+ }
134
+ }
135
+
136
+ export type Events =
137
+ | HotKeyEvent
138
+ | { type: 'xyflow.init'; instance: ReactFlowInstance<Types.Node, Types.Edge> }
139
+ | { type: 'xyflow.applyNodeChages'; changes: NodeChange<Types.Node>[] }
140
+ | { type: 'xyflow.applyEdgeChages'; changes: EdgeChange<Types.Edge>[] }
141
+ | { type: 'xyflow.viewportMoved'; viewport: Viewport; manually: boolean }
142
+ | { type: 'xyflow.nodeClick'; node: Types.Node }
143
+ | { type: 'xyflow.edgeClick'; edge: Types.Edge }
144
+ | { type: 'xyflow.paneClick' }
145
+ | { type: 'xyflow.paneDblClick' }
146
+ | { type: 'xyflow.resized' }
147
+ | { type: 'update.nodeData'; nodeId: NodeId; data: Partial<Types.NodeData> }
148
+ | { type: 'update.edgeData'; edgeId: EdgeId; data: Partial<Types.Edge['data']> }
149
+ | { type: 'update.view'; view: DiagramView; xynodes: Types.Node[]; xyedges: Types.Edge[] }
150
+ | { type: 'update.inputs'; inputs: Partial<Omit<Input, 'view'>> }
151
+ | { type: 'update.features'; features: EnabledFeatures }
152
+ | { type: 'fitDiagram'; duration?: number; bounds?: BBox }
153
+ | ({ type: 'open.source' } & OpenSourceParams)
154
+ | { type: 'open.elementDetails'; fqn: Fqn; fromNode?: NodeId | undefined }
155
+ | { type: 'open.relationshipDetails'; edgeId: EdgeId }
156
+ | { type: 'open.relationshipsBrowser'; fqn: Fqn }
157
+ | { type: 'close.overlay' }
158
+ | { type: 'navigate.to'; viewId: ViewId; fromNode?: NodeId | undefined }
159
+ | { type: 'navigate.back' }
160
+ | { type: 'navigate.forward' }
161
+ | { type: 'layout.align'; mode: AlignmentMode }
162
+ | { type: 'layout.resetEdgeControlPoints' }
163
+ | { type: 'saveManualLayout.schedule' }
164
+ | { type: 'saveManualLayout.cancel' }
165
+ | { type: 'focus.node'; nodeId: NodeId }
166
+ | { type: 'walkthrough.start'; stepId?: StepEdgeId }
167
+ | { type: 'walkthrough.step'; direction: 'next' | 'previous' }
168
+ | { type: 'walkthrough.end' }
169
+
170
+ export type ActionArg = { context: DiagramContext; event: Events }
171
+
172
+ // TODO: naming convention for actors
173
+ export const diagramMachine = setup({
174
+ types: {
175
+ context: {} as DiagramContext,
176
+ input: {} as Input,
177
+ children: {} as {
178
+ hotkey: 'hotkeyActor'
179
+ syncLayout: 'syncManualLayoutActor'
180
+ relationshipDetails: 'relationshipDetailsActor'
181
+ relationshipsBrowser: 'relationshipsBrowserActor'
182
+ },
183
+ events: {} as Events,
184
+ },
185
+ actors: {
186
+ hotkeyActor,
187
+ syncManualLayoutActor,
188
+ relationshipsBrowserActor,
189
+ relationshipDetailsActor,
190
+ },
191
+ guards: {
192
+ 'enabled: FitView': ({ context }) => context.features.enableFitView,
193
+ 'enabled: FocusMode': ({ context }) => context.features.enableFocusMode,
194
+ 'enabled: Readonly': ({ context }) => context.features.enableReadOnly,
195
+ 'not readonly': ({ context }) => !context.features.enableReadOnly,
196
+ 'is dynamic view': ({ context }) => context.view.__ === 'dynamic',
197
+ 'is another view': ({ context, event }) => {
198
+ assertEvent(event, ['update.view', 'navigate.to'])
199
+ if (event.type === 'update.view') {
200
+ return context.view.id !== event.view.id
201
+ }
202
+ if (event.type === 'navigate.to') {
203
+ return context.view.id !== event.viewId
204
+ }
205
+ nonexhaustive(event.type)
206
+ },
207
+ 'click: selected node ': ({ event }) => {
208
+ assertEvent(event, 'xyflow.nodeClick')
209
+ return event.node.selected === true
210
+ },
211
+ 'click: same node': ({ context, event }) => {
212
+ assertEvent(event, 'xyflow.nodeClick')
213
+ return context.lastClickedNode?.id === event.node.id
214
+ },
215
+ 'click: focused node': ({ context, event }) => {
216
+ assertEvent(event, 'xyflow.nodeClick')
217
+ return context.focusedNode === event.node.id
218
+ },
219
+ },
220
+ actions: {
221
+ 'trigger:NavigateTo': (_, _params: { viewId: ViewId }) => {
222
+ // navigate to view
223
+ },
224
+ 'trigger:OnChange': (_, _params: { change: ViewChange }) => {
225
+ // apply change
226
+ },
227
+ 'trigger:OpenSource': (_, _params: OpenSourceParams) => {
228
+ },
229
+
230
+ 'xyflow:fitDiagram': ({ context }, params?: { duration?: number; bounds?: BBox }) => {
231
+ const {
232
+ bounds = context.view.bounds,
233
+ duration = 450,
234
+ } = params ?? {}
235
+ const { width, height, panZoom, transform } = context.xystore.getState()
236
+
237
+ const maxZoom = Math.max(1, transform[2])
238
+ const viewport = getViewportForBounds(
239
+ bounds,
240
+ width,
241
+ height,
242
+ MinZoom,
243
+ maxZoom,
244
+ context.fitViewPadding,
245
+ )
246
+ viewport.x = Math.round(viewport.x)
247
+ viewport.y = Math.round(viewport.y)
248
+ panZoom?.setViewport(viewport, duration > 0 ? { duration } : undefined)
249
+ },
250
+
251
+ 'xyflow:setViewportCenter': ({ context }, params: { x: number; y: number }) => {
252
+ const { x, y } = params
253
+ invariant(context.xyflow, 'xyflow is not initialized')
254
+ const zoom = context.xyflow.getZoom()
255
+ context.xyflow.setCenter(Math.round(x), Math.round(y), { zoom })
256
+ },
257
+
258
+ 'xyflow:setViewport': ({ context }, params: { viewport: Viewport; duration?: number }) => {
259
+ const {
260
+ viewport,
261
+ duration = 350,
262
+ } = params
263
+ const { panZoom } = context.xystore.getState()
264
+ panZoom?.setViewport(viewport, duration > 0 ? { duration } : undefined)
265
+ },
266
+
267
+ 'xyflow:alignNodeFromToAfterNavigate': ({ context }, params: { fromNode: NodeId; toPosition: XYPoint }) => {
268
+ const xyflow = nonNullable(context.xyflow, 'xyflow is not initialized')
269
+ const elFrom = xyflow.getInternalNode(params.fromNode)
270
+ if (!elFrom) return
271
+ const fromPos = xyflow.flowToScreenPosition({
272
+ x: elFrom.internals.positionAbsolute.x, // + dimensions.width / 2,
273
+ y: elFrom.internals.positionAbsolute.y, // + dimensions.height / 2
274
+ }),
275
+ toPos = xyflow.flowToScreenPosition(params.toPosition),
276
+ diff = {
277
+ x: Math.round(fromPos.x - toPos.x),
278
+ y: Math.round(fromPos.y - toPos.y),
279
+ }
280
+ context.xystore.getState().panBy(diff)
281
+ },
282
+
283
+ 'layout.align': ({ context }, params: { mode: AlignmentMode }) => {
284
+ const { mode } = params
285
+ const { xystore } = context
286
+ const { nodeLookup, parentLookup } = xystore.getState()
287
+
288
+ const selectedNodes = new Set(nodeLookup.values().filter(n => n.selected).map(n => n.id))
289
+ const nodesToAlign = [...selectedNodes.difference(new Set(parentLookup.keys()))]
290
+
291
+ if (!hasAtLeast(nodesToAlign, 2)) {
292
+ console.warn('At least 2 nodes must be selected to align')
293
+ return
294
+ }
295
+ const constraints = createLayoutConstraints(xystore, nodesToAlign)
296
+
297
+ const aligner = getAligner(mode)
298
+
299
+ constraints.onMove(nodes => {
300
+ aligner.computeLayout(nodes.map(({ node }) => toNodeRect(node)))
301
+
302
+ nodes.forEach(({ rect, node }) => {
303
+ rect.positionAbsolute = {
304
+ ...rect.positionAbsolute,
305
+ ...aligner.applyPosition(toNodeRect(node)),
306
+ }
307
+ })
308
+ })
309
+ },
310
+ },
311
+ }).createMachine({
312
+ initial: 'initializing',
313
+ context: ({ input, self, spawn }) => ({
314
+ ...input,
315
+ features: { ...AllDisabled },
316
+ initialized: false,
317
+ viewportChangedManually: false,
318
+ lastOnNavigate: null,
319
+ lastClickedNode: null,
320
+ focusedNode: null,
321
+ activeElementDetails: null,
322
+ viewportBeforeFocus: null,
323
+ navigationHistory: {
324
+ currentIndex: 0,
325
+ history: [],
326
+ },
327
+ viewport: { x: 0, y: 0, zoom: 1 },
328
+ xyflow: null,
329
+ syncLayoutActorRef: spawn('syncManualLayoutActor', {
330
+ id: 'syncLayout',
331
+ input: { parent: self, viewId: input.view.id },
332
+ }),
333
+ activeWalkthrough: null,
334
+ }),
335
+ // entry: ({ spawn }) => spawn(layoutActor, { id: 'layout', input: { parent: self } }),
336
+ states: {
337
+ initializing: {
338
+ on: {
339
+ 'xyflow.init': {
340
+ actions: enqueueActions(({ enqueue, check }) => {
341
+ enqueue.assign({
342
+ initialized: true,
343
+ xyflow: ({ event }) => event.instance,
344
+ navigationHistory: ({ context, event }) => ({
345
+ currentIndex: 0,
346
+ history: [{
347
+ viewId: context.view.id,
348
+ fromNode: null,
349
+ viewport: { ...event.instance.getViewport() },
350
+ }],
351
+ }),
352
+ })
353
+ if (check('enabled: FitView')) {
354
+ enqueue({
355
+ type: 'xyflow:fitDiagram',
356
+ params: { duration: 0 },
357
+ })
358
+ }
359
+ }),
360
+ target: 'idle',
361
+ },
362
+ },
363
+ },
364
+ idle: {
365
+ id: 'idle',
366
+ on: {
367
+ 'xyflow.nodeClick': [
368
+ {
369
+ // TODO: xstate fails to infer the type of the guard
370
+ guard: and([
371
+ 'enabled: FocusMode' as const,
372
+ or([
373
+ 'click: same node' as const,
374
+ 'click: selected node ' as const,
375
+ ]),
376
+ ]) as any,
377
+ actions: [
378
+ assign({
379
+ lastClickedNode,
380
+ focusedNode: ({ event }) => event.node.id as NodeId,
381
+ }),
382
+ ],
383
+ target: 'focused',
384
+ },
385
+ {
386
+ actions: assign({
387
+ lastClickedNode,
388
+ }),
389
+ },
390
+ ],
391
+ 'xyflow.paneClick': {
392
+ actions: [
393
+ assign({
394
+ lastClickedNode: null,
395
+ }),
396
+ ],
397
+ },
398
+ 'xyflow.paneDblClick': {
399
+ actions: [
400
+ { type: 'xyflow:fitDiagram' },
401
+ { type: 'trigger:OpenSource', params: ({ context }) => ({ view: context.view.id }) },
402
+ ],
403
+ },
404
+ 'saveManualLayout.*': {
405
+ guard: 'not readonly',
406
+ actions: sendTo((c) => c.context.syncLayoutActorRef, ({ event }) => {
407
+ if (event.type === 'saveManualLayout.schedule') {
408
+ return { type: 'sync' }
409
+ }
410
+ if (event.type === 'saveManualLayout.cancel') {
411
+ return { type: 'cancel' }
412
+ }
413
+ nonexhaustive(event)
414
+ }),
415
+ },
416
+ 'focus.node': {
417
+ guard: 'enabled: FocusMode',
418
+ actions: assign({
419
+ focusedNode: ({ event }) => event.nodeId as NodeId,
420
+ }),
421
+ target: 'focused',
422
+ },
423
+ },
424
+ },
425
+ focused: {
426
+ entry: [
427
+ assign(s => ({
428
+ ...focusNodesEdges(s),
429
+ viewportBeforeFocus: { ...s.context.viewport },
430
+ })),
431
+ spawnChild('hotkeyActor', { id: 'hotkey' }),
432
+ {
433
+ type: 'xyflow:fitDiagram',
434
+ params: focusedBounds,
435
+ },
436
+ ],
437
+ on: {
438
+ 'xyflow.nodeClick': [
439
+ {
440
+ guard: 'click: focused node',
441
+ target: '#idle',
442
+ },
443
+ {
444
+ actions: [
445
+ assign({
446
+ lastClickedNode,
447
+ focusedNode: ({ event }) => event.node.id as NodeId,
448
+ }),
449
+ assign(focusNodesEdges),
450
+ {
451
+ type: 'xyflow:fitDiagram',
452
+ params: focusedBounds,
453
+ },
454
+ ],
455
+ },
456
+ ],
457
+ 'focus.node': {
458
+ actions: [
459
+ assign({
460
+ focusedNode: ({ event }) => event.nodeId,
461
+ }),
462
+ assign(focusNodesEdges),
463
+ {
464
+ type: 'xyflow:fitDiagram',
465
+ params: focusedBounds,
466
+ },
467
+ ],
468
+ },
469
+ 'key.esc': {
470
+ target: 'idle',
471
+ },
472
+ 'xyflow.paneClick': {
473
+ actions: assign({
474
+ lastClickedNode: null,
475
+ }),
476
+ target: 'idle',
477
+ },
478
+ 'saveManualLayout.*': {
479
+ guard: 'not readonly',
480
+ actions: sendTo(c => c.context.syncLayoutActorRef, ({ event }) => {
481
+ if (event.type === 'saveManualLayout.schedule') {
482
+ return { type: 'sync' }
483
+ }
484
+ if (event.type === 'saveManualLayout.cancel') {
485
+ return { type: 'cancel' }
486
+ }
487
+ nonexhaustive(event)
488
+ }),
489
+ },
490
+ },
491
+ exit: [
492
+ stopChild('hotkey'),
493
+ enqueueActions(({ enqueue, context }) => {
494
+ if (context.viewportBeforeFocus) {
495
+ enqueue({ type: 'xyflow:setViewport', params: { viewport: context.viewportBeforeFocus } })
496
+ } else {
497
+ enqueue({ type: 'xyflow:fitDiagram' })
498
+ }
499
+ enqueue.assign((s) => ({
500
+ ...unfocusNodesEdges(s),
501
+ viewportBeforeFocus: null,
502
+ focusedNode: null,
503
+ }))
504
+ }),
505
+ ],
506
+ },
507
+ overlay: {
508
+ entry: spawnChild('hotkeyActor', { id: 'hotkey' }),
509
+ initial: 'hole',
510
+ states: {
511
+ hole: {
512
+ target: '#idle',
513
+ },
514
+ elementDetails: {
515
+ guard: ({ context }: { context: DiagramContext }) => context.activeElementDetails !== null,
516
+ entry: assign({
517
+ activeElementDetails: ({ context }) => {
518
+ const fqn = context.activeElementDetails!.fqn
519
+ const fromNode = context.activeElementDetails!.fromNode
520
+ if (fromNode) {
521
+ const internalNode = nonNullable(
522
+ context.xystore.getState().nodeLookup.get(fromNode),
523
+ 'XY Internal Node not found',
524
+ )
525
+ const nodeRect = nodeToRect(internalNode)
526
+ const zoom = context.xyflow!.getZoom()
527
+
528
+ const nodeRectScreen = {
529
+ ...context.xyflow!.flowToScreenPosition(nodeRect),
530
+ width: nodeRect.width * zoom,
531
+ height: nodeRect.height * zoom,
532
+ }
533
+
534
+ return { fqn, fromNode, nodeRect, nodeRectScreen }
535
+ } else {
536
+ return { fqn, fromNode }
537
+ }
538
+ },
539
+ }),
540
+ on: {
541
+ // Catch event and do nothing
542
+ 'open.elementDetails': {
543
+ actions: assign({
544
+ activeElementDetails: ({ event, context }) => ({
545
+ ...context.activeElementDetails,
546
+ fqn: event.fqn,
547
+ fromNode: context.activeElementDetails?.fromNode ?? null,
548
+ }),
549
+ }),
550
+ },
551
+ 'close.overlay': {
552
+ target: '#idle',
553
+ },
554
+ 'key.esc': {
555
+ target: '#idle',
556
+ },
557
+ },
558
+ exit: assign({
559
+ activeElementDetails: null,
560
+ }),
561
+ },
562
+ relationshipsBrowser: {
563
+ invoke: {
564
+ id: 'relationshipsBrowser',
565
+ src: 'relationshipsBrowserActor',
566
+ input: ({ context, event }) => {
567
+ assertEvent(event, 'open.relationshipsBrowser')
568
+ return {
569
+ subject: event.fqn,
570
+ scope: context.view,
571
+ }
572
+ },
573
+ onDone: {
574
+ target: '#idle',
575
+ },
576
+ },
577
+ on: {
578
+ 'open.relationshipsBrowser': {
579
+ actions: sendTo('relationshipsBrowser', ({ event }) => ({
580
+ type: 'navigate.to',
581
+ subject: event.fqn,
582
+ })),
583
+ },
584
+ 'close.overlay': {
585
+ actions: sendTo('relationshipsBrowser', { type: 'close' }),
586
+ },
587
+ 'key.esc': {
588
+ actions: sendTo('relationshipsBrowser', { type: 'close' }),
589
+ },
590
+ },
591
+ },
592
+ relationshipDetails: {
593
+ invoke: {
594
+ id: 'relationshipDetails',
595
+ src: 'relationshipDetailsActor',
596
+ input: ({ event, context }) => {
597
+ assertEvent(event, 'open.relationshipDetails')
598
+ return {
599
+ edgeId: event.edgeId,
600
+ view: context.view,
601
+ }
602
+ },
603
+ onDone: {
604
+ target: '#idle',
605
+ },
606
+ },
607
+ on: {
608
+ 'close.overlay': {
609
+ actions: sendTo('relationshipDetails', { type: 'close' }),
610
+ },
611
+ 'key.esc': {
612
+ actions: sendTo('relationshipDetails', { type: 'close' }),
613
+ },
614
+ },
615
+ },
616
+ },
617
+ on: {
618
+ // We received another view, close overlay and process event again
619
+ 'update.view': {
620
+ guard: 'is another view',
621
+ actions: raise(({ event }) => event, { delay: 50 }),
622
+ target: '#idle',
623
+ },
624
+ },
625
+ exit: [
626
+ stopChild('hotkey'),
627
+ ],
628
+ },
629
+ // Navigating to another view (after `navigateTo` event)
630
+ navigating: {
631
+ initial: 'pending',
632
+ type: 'compound',
633
+ states: {
634
+ pending: {
635
+ entry: enqueueActions(({ enqueue }) => {
636
+ enqueue.sendTo(c => c.context.syncLayoutActorRef, { type: 'stop' })
637
+ enqueue.stopChild('layout')
638
+ enqueue({
639
+ type: 'trigger:NavigateTo',
640
+ params: ({ context }) => ({
641
+ viewId: nonNullable(context.lastOnNavigate, 'Invalid state, lastOnNavigate is null').toView,
642
+ }),
643
+ })
644
+ }),
645
+ on: {
646
+ 'update.view': {
647
+ actions: enqueueActions(({ enqueue, context, event }) => {
648
+ const { fromNode, toNode } = findCorrespondingNode(context, event)
649
+ if (fromNode && toNode) {
650
+ enqueue({
651
+ type: 'xyflow:alignNodeFromToAfterNavigate',
652
+ params: {
653
+ fromNode: fromNode.id,
654
+ toPosition: {
655
+ x: toNode.position[0],
656
+ y: toNode.position[1],
657
+ },
658
+ },
659
+ })
660
+ } else {
661
+ enqueue({
662
+ type: 'xyflow:setViewportCenter',
663
+ params: getBBoxCenter(event.view.bounds),
664
+ })
665
+ }
666
+ enqueue.assign(updateNavigationHistory)
667
+ enqueue.assign(mergeXYNodesEdges)
668
+ enqueue.raise({ type: 'fitDiagram' }, { id: 'fitDiagram', delay: 75 })
669
+ }),
670
+ target: 'done',
671
+ },
672
+ },
673
+ },
674
+ done: {
675
+ type: 'final',
676
+ },
677
+ },
678
+ onDone: {
679
+ target: 'idle',
680
+ },
681
+ exit: assign({
682
+ syncLayoutActorRef: ({ self, context, spawn }) =>
683
+ spawn('syncManualLayoutActor', { id: 'syncLayout', input: { parent: self, viewId: context.view.id } }),
684
+ lastOnNavigate: null,
685
+ }),
686
+ },
687
+ walkthrough: {
688
+ entry: [
689
+ spawnChild('hotkeyActor', { id: 'hotkey' }),
690
+ assign({
691
+ viewportBeforeFocus: ({ context }) => context.viewport,
692
+ activeWalkthrough: ({ context, event }) => {
693
+ assertEvent(event, 'walkthrough.start')
694
+ const stepId = event.stepId ?? first(context.xyedges)!.id as StepEdgeId
695
+ return {
696
+ stepId,
697
+ parallelPrefix: getParallelStepsPrefix(stepId),
698
+ }
699
+ },
700
+ }),
701
+ assign(updateActiveWalkthrough),
702
+ {
703
+ type: 'xyflow:fitDiagram',
704
+ params: focusedBounds,
705
+ },
706
+ ],
707
+ on: {
708
+ 'key.esc': {
709
+ target: 'idle',
710
+ },
711
+ 'key.arrow.left': {
712
+ actions: raise({ type: 'walkthrough.step', direction: 'previous' }),
713
+ },
714
+ 'key.arrow.right': {
715
+ actions: raise({ type: 'walkthrough.step', direction: 'next' }),
716
+ },
717
+ 'walkthrough.step': {
718
+ actions: enqueueActions(({ enqueue, context, event }) => {
719
+ const { stepId } = context.activeWalkthrough!
720
+ const stepIndex = context.xyedges.findIndex(e => e.id === stepId)
721
+ const nextStepIndex = clamp(event.direction === 'next' ? stepIndex + 1 : stepIndex - 1, {
722
+ min: 0,
723
+ max: context.xyedges.length - 1,
724
+ })
725
+ if (nextStepIndex === stepIndex) {
726
+ return
727
+ }
728
+ const nextStepId = context.xyedges[nextStepIndex]!.id as StepEdgeId
729
+ enqueue.assign({
730
+ activeWalkthrough: {
731
+ stepId: nextStepId,
732
+ parallelPrefix: getParallelStepsPrefix(nextStepId),
733
+ },
734
+ })
735
+ enqueue.assign(updateActiveWalkthrough)
736
+ enqueue({
737
+ type: 'xyflow:fitDiagram',
738
+ params: focusedBounds,
739
+ })
740
+ }),
741
+ },
742
+ 'walkthrough.end': {
743
+ target: 'idle',
744
+ },
745
+ // We received another view, close overlay and process event again
746
+ 'update.view': {
747
+ guard: 'is another view',
748
+ actions: raise(({ event }) => event, { delay: 50 }),
749
+ target: 'idle',
750
+ },
751
+ },
752
+ exit: enqueueActions(({ enqueue, context }) => {
753
+ enqueue.stopChild('hotkey')
754
+ if (context.viewportBeforeFocus) {
755
+ enqueue({ type: 'xyflow:setViewport', params: { viewport: context.viewportBeforeFocus } })
756
+ } else {
757
+ enqueue({ type: 'xyflow:fitDiagram' })
758
+ }
759
+ enqueue.assign((s) => ({
760
+ activeWalkthrough: null,
761
+ ...unfocusNodesEdges(s),
762
+ viewportBeforeFocus: null,
763
+ }))
764
+ }),
765
+ },
766
+ },
767
+ on: {
768
+ 'xyflow.applyNodeChages': {
769
+ actions: assign({
770
+ xynodes: ({ context, event }) => applyNodeChanges(event.changes, context.xynodes),
771
+ }),
772
+ },
773
+ 'xyflow.applyEdgeChages': {
774
+ actions: assign({
775
+ xyedges: ({ context, event }) => applyEdgeChanges(event.changes, context.xyedges),
776
+ }),
777
+ },
778
+ 'xyflow.viewportMoved': {
779
+ actions: assign({
780
+ viewportChangedManually: (({ event }) => event.manually),
781
+ viewport: (({ event }) => event.viewport),
782
+ }),
783
+ },
784
+ 'fitDiagram': {
785
+ guard: 'enabled: FitView',
786
+ actions: {
787
+ type: 'xyflow:fitDiagram',
788
+ params: prop('event'),
789
+ },
790
+ },
791
+ 'navigate.to': {
792
+ guard: 'is another view',
793
+ actions: [
794
+ assign({
795
+ lastOnNavigate: ({ context, event }) => ({
796
+ fromView: context.view.id,
797
+ toView: event.viewId,
798
+ fromNode: event.fromNode ?? null,
799
+ }),
800
+ }),
801
+ ],
802
+ target: '.navigating',
803
+ },
804
+ 'navigate.back': {
805
+ guard: ({ context }: ActionArg) => context.navigationHistory.currentIndex > 0,
806
+ actions: assign(navigateBack),
807
+ target: '.navigating',
808
+ },
809
+ 'navigate.forward': {
810
+ guard: ({ context }: ActionArg) =>
811
+ context.navigationHistory.currentIndex < context.navigationHistory.history.length - 1,
812
+ actions: assign(navigateForward),
813
+ target: '.navigating',
814
+ },
815
+ 'update.view': {
816
+ actions: [
817
+ assign(updateNavigationHistory),
818
+ enqueueActions(({ enqueue, event, check, context }) => {
819
+ const isAnotherView = check('is another view')
820
+ if (isAnotherView) {
821
+ const viewId = event.view.id
822
+ enqueue.sendTo(c => c.context.syncLayoutActorRef, { type: 'stop' })
823
+ enqueue.stopChild('layout')
824
+ enqueue.assign({
825
+ focusedNode: null,
826
+ syncLayoutActorRef: ({ self, spawn }) =>
827
+ spawn('syncManualLayoutActor', { id: 'syncLayout', input: { parent: self, viewId } }),
828
+ })
829
+ const { fromNode, toNode } = findCorrespondingNode(context, event)
830
+ if (fromNode && toNode) {
831
+ enqueue({
832
+ type: 'xyflow:alignNodeFromToAfterNavigate',
833
+ params: {
834
+ fromNode: fromNode.id,
835
+ toPosition: {
836
+ x: toNode.position[0],
837
+ y: toNode.position[1],
838
+ },
839
+ },
840
+ })
841
+ } else {
842
+ enqueue({
843
+ type: 'xyflow:setViewportCenter',
844
+ params: getBBoxCenter(event.view.bounds),
845
+ })
846
+ }
847
+ } else {
848
+ enqueue.sendTo(c => c.context.syncLayoutActorRef, { type: 'synced' })
849
+ }
850
+ if (isAnotherView || !context.viewportChangedManually) {
851
+ enqueue.raise({ type: 'fitDiagram' }, { id: 'fitDiagram', delay: 90 })
852
+ }
853
+ enqueue.assign(mergeXYNodesEdges)
854
+ enqueue.assign({
855
+ lastOnNavigate: null,
856
+ })
857
+ }),
858
+ ],
859
+ },
860
+ 'update.inputs': {
861
+ actions: assign(({ event }) => ({ ...event.inputs })),
862
+ },
863
+ 'update.features': {
864
+ actions: assign({
865
+ features: ({ event }) => event.features,
866
+ }),
867
+ },
868
+ 'update.nodeData': {
869
+ actions: assign(updateNodeData),
870
+ },
871
+ 'update.edgeData': {
872
+ actions: assign(updateEdgeData),
873
+ },
874
+ 'layout.align': {
875
+ guard: 'not readonly',
876
+ actions: [
877
+ { type: 'layout.align', params: ({ event }) => ({ mode: event.mode }) },
878
+ raise({ type: 'saveManualLayout.schedule' }),
879
+ ],
880
+ },
881
+ 'layout.resetEdgeControlPoints': {
882
+ guard: 'not readonly',
883
+ actions: [
884
+ assign(resetEdgeControlPoints),
885
+ raise({ type: 'saveManualLayout.schedule' }),
886
+ ],
887
+ },
888
+ 'xyflow.resized': {
889
+ guard: ({ context }: { context: DiagramContext }) =>
890
+ context.features.enableFitView && !context.viewportChangedManually,
891
+ actions: [
892
+ cancel('fitDiagram'),
893
+ raise({ type: 'fitDiagram' }, { id: 'fitDiagram', delay: 200 }),
894
+ ],
895
+ },
896
+ 'open.elementDetails': {
897
+ actions: assign({
898
+ activeElementDetails: ({ event, context }) => ({
899
+ fqn: event.fqn,
900
+ fromNode: event.fromNode ?? context.lastClickedNode?.id ?? null,
901
+ fromNodeScreenPosition: null,
902
+ }),
903
+ }),
904
+ target: '.overlay.elementDetails',
905
+ },
906
+ 'open.relationshipDetails': {
907
+ target: '.overlay.relationshipDetails',
908
+ },
909
+ 'open.relationshipsBrowser': {
910
+ target: '.overlay.relationshipsBrowser',
911
+ },
912
+ 'open.source': {
913
+ actions: {
914
+ type: 'trigger:OpenSource',
915
+ params: prop('event'),
916
+ },
917
+ },
918
+ 'walkthrough.start': {
919
+ guard: 'is dynamic view',
920
+ target: '.walkthrough',
921
+ },
922
+ },
923
+ exit: [
924
+ stopChild('layout'),
925
+ stopChild('hotkey'),
926
+ assign({
927
+ xyflow: null,
928
+ xystore: null as any,
929
+ initialized: false,
930
+ syncLayoutActorRef: null as any,
931
+ }),
932
+ ],
933
+ })
934
+
935
+ const nodeRef = (node: DiagramNode) => DiagramNode.modelRef(node) ?? DiagramNode.deploymentRef(node)
936
+ function findCorrespondingNode(context: DiagramContext, event: { view: DiagramView }) {
937
+ const fromNodeId = context.lastOnNavigate?.fromNode
938
+ const fromNode = fromNodeId && context.view.nodes.find(n => n.id === fromNodeId)
939
+ const fromRef = fromNode && nodeRef(fromNode)
940
+ const toNode = fromRef && event.view.nodes.find(n => nodeRef(n) === fromRef)
941
+ return { fromNode, toNode }
942
+ }
943
+
944
+ export type Machine = typeof diagramMachine
945
+ export type MachineSnapshot = SnapshotFrom<Machine>
946
+ export type LikeC4ViewActorRef = ActorRefFromLogic<Machine>