@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
@@ -0,0 +1,642 @@
1
+ import { computeRelationshipsView } from '@likec4/core'
2
+ import type {
3
+ DiagramEdge,
4
+ DiagramNode,
5
+ DiagramView,
6
+ EdgeId,
7
+ ElementKind,
8
+ Fqn,
9
+ IconUrl,
10
+ NodeId,
11
+ Point,
12
+ ViewId,
13
+ } from '@likec4/core/types'
14
+ import { useMemo } from 'react'
15
+
16
+ import dagre, { type EdgeConfig, type GraphLabel } from '@dagrejs/dagre'
17
+ import {
18
+ DefaultMap,
19
+ invariant,
20
+ isAncestor,
21
+ isDescendantOf,
22
+ nonNullable,
23
+ sortParentsFirst,
24
+ toArray,
25
+ } from '@likec4/core'
26
+ import type { ElementModel, RelationshipModel } from '@likec4/core/model'
27
+ import {
28
+ concat,
29
+ filter,
30
+ find,
31
+ forEachObj,
32
+ groupBy,
33
+ hasAtLeast,
34
+ map,
35
+ mapToObj,
36
+ only,
37
+ pipe,
38
+ prop,
39
+ reduce,
40
+ sortBy,
41
+ tap,
42
+ } from 'remeda'
43
+ import { useLikeC4Model } from '../../likec4model/useLikeC4Model'
44
+ import type { RelationshipsBrowserTypes } from './_types'
45
+
46
+ /**
47
+ * All constants related to the layout
48
+ */
49
+ const Sizes = {
50
+ dagre: {
51
+ ranksep: 60,
52
+ nodesep: 35,
53
+ edgesep: 25,
54
+ } satisfies GraphLabel,
55
+ edgeLabel: {
56
+ width: 120,
57
+ height: 10,
58
+ minlen: 1,
59
+ weight: 1,
60
+ } satisfies EdgeConfig,
61
+
62
+ emptyNodeOffset: 120,
63
+
64
+ nodeWidth: 330,
65
+ nodeHeight: 180,
66
+
67
+ // Spacer between elements in a compound node
68
+ // 0 means no spacer
69
+ spacerHeight: 0,
70
+
71
+ compound: {
72
+ labelHeight: 2,
73
+ paddingTop: 50,
74
+ paddingBottom: 32,
75
+ },
76
+ }
77
+ type NodeData = {
78
+ column: RelationshipsBrowserTypes.Column
79
+ portId: string
80
+ element: ElementModel | null
81
+ isCompound: boolean
82
+ inPorts: string[]
83
+ outPorts: string[]
84
+ }
85
+ function createGraph() {
86
+ const g = new dagre.graphlib.Graph<NodeData>({
87
+ directed: true,
88
+ compound: true,
89
+ multigraph: true,
90
+ })
91
+ g.setGraph({
92
+ ...Sizes.dagre,
93
+ rankdir: 'LR',
94
+ })
95
+ g.setDefaultEdgeLabel(() => ({ ...Sizes.edgeLabel }))
96
+ g.setDefaultNodeLabel(() => ({}))
97
+
98
+ // columns.reduce((prev, column) => {
99
+ // const c = graphColumn(column)
100
+ // g.setNode(c.id, {})
101
+ // g.setNode(c.anchor, { width: 40, height: 2 })
102
+ // g.setParent(c.anchor, c.id)
103
+ // if (prev) {
104
+ // g.setEdge(prev, c.anchor, {
105
+ // width: 0
106
+ // })
107
+ // }
108
+ // return c.anchor
109
+ // }, null as string | null)
110
+
111
+ return g
112
+ }
113
+ type G = ReturnType<typeof createGraph>
114
+
115
+ const PortSuffix = '-port'
116
+
117
+ function treeFromElements(elements: Iterable<ElementModel>) {
118
+ const sorted = sortParentsFirst([...elements]) as ReadonlyArray<ElementModel>
119
+ const root = new Set(sorted)
120
+ const map = new Map(sorted.map(e => [e.id, e]))
121
+ const parents = new DefaultMap<ElementModel, ElementModel | null>(() => null)
122
+ const children = sorted.reduce((acc, parent, index, all) => {
123
+ acc.set(
124
+ parent,
125
+ all
126
+ .slice(index + 1)
127
+ .filter(isDescendantOf(parent))
128
+ .map(e => {
129
+ root.delete(e)
130
+ return e
131
+ })
132
+ .reduce((acc, el) => {
133
+ if (!acc.some(isAncestor(el))) {
134
+ acc.push(el)
135
+ parents.set(el, parent)
136
+ }
137
+ return acc
138
+ }, [] as ElementModel[]),
139
+ )
140
+ return acc
141
+ }, new DefaultMap<ElementModel, ElementModel[]>(() => []))
142
+
143
+ return {
144
+ sorted,
145
+ byId: (id: string) => nonNullable(map.get(id as Fqn), `Element not found by id: ${id}`),
146
+ root: root as ReadonlySet<ElementModel>,
147
+ parent: (el: ElementModel) => parents.get(el),
148
+ children: (el: ElementModel): ReadonlyArray<ElementModel> => children.get(el),
149
+ }
150
+ }
151
+
152
+ function createNodes(
153
+ column: RelationshipsBrowserTypes.Column,
154
+ elements: ReadonlySet<ElementModel>,
155
+ g: G,
156
+ ) {
157
+ const graphNodes = new DefaultMap<Fqn, { id: string; portId: string }>(key => ({
158
+ id: `${column}-${key}`,
159
+ portId: `${column}-${key}`,
160
+ }))
161
+ const tree = treeFromElements(elements)
162
+ for (const element of tree.sorted) {
163
+ const isCompound = tree.children(element).length > 0
164
+ const fqn = element.id
165
+ const id = `${column}-${fqn}`
166
+ const portId = isCompound ? `${id}${PortSuffix}` : id
167
+ graphNodes.set(fqn, {
168
+ id,
169
+ portId,
170
+ })
171
+ g.setNode(id, {
172
+ column,
173
+ element,
174
+ isCompound,
175
+ portId,
176
+ inPorts: [],
177
+ outPorts: [],
178
+ width: Sizes.nodeWidth,
179
+ height: Sizes.nodeHeight,
180
+ })
181
+
182
+ if (isCompound) {
183
+ g.setNode(portId, {
184
+ element,
185
+ portId,
186
+ isCompound,
187
+ inPorts: [],
188
+ outPorts: [],
189
+ width: Sizes.nodeWidth - Sizes.dagre.ranksep,
190
+ height: Sizes.compound.labelHeight,
191
+ })
192
+ g.setParent(portId, id)
193
+ // g.node(id).padding = 60
194
+ }
195
+
196
+ const parent = tree.parent(element)
197
+ if (parent) {
198
+ g.setParent(id, `${column}-${parent.id}`)
199
+ }
200
+ }
201
+ return {
202
+ ...tree,
203
+ byId: (id: string) => {
204
+ const element = tree.byId(id)
205
+ const graph = graphNodes.get(element.id)
206
+ return {
207
+ element,
208
+ graph,
209
+ }
210
+ },
211
+ graphNodes,
212
+ }
213
+ }
214
+
215
+ /**
216
+ * Apply dagre layout to the graph
217
+ * And return a function to get node bounds for xyflow
218
+ */
219
+ function applyDagreLayout(g: G) {
220
+ dagre.layout(g, {
221
+ // disableOptimalOrderHeuristic: true,
222
+ })
223
+ return (nodeId: string) => {
224
+ const node = g.node(nodeId)
225
+ const { x, y, width, height } = node
226
+ return {
227
+ position: {
228
+ x: x - Math.round(width / 2),
229
+ y: y - Math.round(height / 2),
230
+ },
231
+ width,
232
+ height,
233
+ }
234
+ }
235
+ }
236
+
237
+ export type RelationshipsViewData = {
238
+ incomers: ReadonlySet<ElementModel>
239
+ incoming: ReadonlySet<RelationshipModel>
240
+ subjects: ReadonlySet<ElementModel>
241
+ outgoing: ReadonlySet<RelationshipModel>
242
+ outgoers: ReadonlySet<ElementModel>
243
+ }
244
+
245
+ export type LayoutRelationshipsViewResult = {
246
+ nodes: LayoutRelationshipsViewResult.Node[]
247
+ edges: LayoutRelationshipsViewResult.Edge[]
248
+ bounds: DiagramView['bounds']
249
+ }
250
+
251
+ export namespace LayoutRelationshipsViewResult {
252
+ export const Empty = '@empty' as ElementKind
253
+
254
+ export type Node = DiagramNode & {
255
+ column: RelationshipsBrowserTypes.Column
256
+ ports: RelationshipsBrowserTypes.Ports
257
+ }
258
+ export type Edge = DiagramEdge & {
259
+ // column: RelationshipsBrowserTypes.Column
260
+ }
261
+ }
262
+
263
+ export function layoutRelationshipsView(data: RelationshipsViewData): LayoutRelationshipsViewResult {
264
+ const g = createGraph()
265
+
266
+ const incomers = createNodes('incomers', data.incomers, g),
267
+ subjects = createNodes('subjects', data.subjects, g),
268
+ outgoers = createNodes('outgoers', data.outgoers, g)
269
+
270
+ const edges = [] as Array<{
271
+ name: string
272
+ source: string // node id
273
+ target: string // node id
274
+ relations: RelationshipModel[]
275
+ }>
276
+
277
+ pipe(
278
+ concat(
279
+ pipe(
280
+ toArray(data.incoming),
281
+ map(r => ({
282
+ id: r.source.id,
283
+ source: incomers.byId(r.source.id).graph,
284
+ target: subjects.byId(r.target.id).graph,
285
+ relation: r,
286
+ })),
287
+ // Sort by source
288
+ sortParentsFirst,
289
+ ),
290
+ pipe(
291
+ toArray(data.outgoing),
292
+ map(r => ({
293
+ id: r.target.id,
294
+ source: subjects.byId(r.source.id).graph,
295
+ target: outgoers.byId(r.target.id).graph,
296
+ relation: r,
297
+ })),
298
+ // Sort by target
299
+ sortParentsFirst,
300
+ ),
301
+ ),
302
+ map(r => ({
303
+ ...r,
304
+ expr: `${r.source.id}->${r.target.id}`,
305
+ })),
306
+ // Group if same source and target
307
+ groupBy(prop('expr')),
308
+ forEachObj((grouped) => {
309
+ const source = grouped[0].source
310
+ const target = grouped[0].target
311
+ const name = grouped[0].expr
312
+
313
+ g.node(source.id).outPorts.push(target.id)
314
+ g.node(target.id).inPorts.push(source.id)
315
+
316
+ g.setEdge(source.portId, target.portId, {
317
+ ...Sizes.edgeLabel,
318
+ }, name)
319
+ edges.push({
320
+ name,
321
+ source: source.id,
322
+ target: target.id,
323
+ relations: map(grouped, prop('relation')),
324
+ })
325
+ }),
326
+ )
327
+
328
+ // Grow nodes with more than 2 ports
329
+ for (const subjectNode of subjects.graphNodes.values()) {
330
+ const nodeId = subjectNode.id
331
+ const node = g.node(nodeId)
332
+ if (node.isCompound) {
333
+ continue
334
+ }
335
+ const edgeCount = Math.max(g.inEdges(nodeId)?.length ?? 0, g.outEdges(nodeId)?.length ?? 0)
336
+ if (edgeCount > 2) {
337
+ node.height = node.height + (edgeCount - 3) * 14
338
+ }
339
+ }
340
+
341
+ const nodeIds = [
342
+ ...incomers.graphNodes.values(),
343
+ ...subjects.graphNodes.values(),
344
+ ...outgoers.graphNodes.values(),
345
+ ]
346
+
347
+ if (incomers.graphNodes.size == 0) {
348
+ const id = 'incomers-empty'
349
+ g.setNode(id, {
350
+ column: 'incomers',
351
+ element: null,
352
+ isCompound: false,
353
+ portId: id,
354
+ inPorts: [],
355
+ outPorts: [],
356
+ width: Sizes.nodeWidth,
357
+ height: Sizes.nodeHeight,
358
+ })
359
+ for (const subjectNode of subjects.graphNodes.values()) {
360
+ g.setEdge(id, subjectNode.portId)
361
+ }
362
+ nodeIds.push({
363
+ id,
364
+ portId: id,
365
+ })
366
+ }
367
+ if (outgoers.graphNodes.size == 0) {
368
+ const id = 'outgoers-empty'
369
+ g.setNode(id, {
370
+ column: 'outgoers',
371
+ element: null,
372
+ isCompound: false,
373
+ portId: id,
374
+ inPorts: [],
375
+ outPorts: [],
376
+ width: Sizes.nodeWidth,
377
+ height: Sizes.nodeHeight,
378
+ })
379
+ for (const subjectNode of subjects.graphNodes.values()) {
380
+ g.setEdge(subjectNode.portId, id)
381
+ }
382
+ nodeIds.push({
383
+ id,
384
+ portId: id,
385
+ })
386
+ }
387
+
388
+ const dagreBounds = applyDagreLayout(g)
389
+
390
+ // Calculate bounds for all nodes except compounds
391
+ // We shrink compounds to fit their children
392
+ const _calculatedNodeBounds = pipe(
393
+ nodeIds,
394
+ // Compound nodes have different portId
395
+ filter(n => n.id === n.portId),
396
+ mapToObj(n => [n.id, dagreBounds(n.id)]),
397
+ )
398
+
399
+ function nodeBounds(nodeId: string): ReturnType<typeof dagreBounds> {
400
+ return _calculatedNodeBounds[nodeId] ??= pipe(
401
+ g.children(nodeId) as string[] | undefined ?? [],
402
+ filter(id => !id.endsWith(PortSuffix)),
403
+ map(id => nodeBounds(id)),
404
+ tap(bounds => {
405
+ invariant(bounds.length > 0, `Node ${nodeId} has no nested nodes`)
406
+ }),
407
+ reduce((acc, bounds) => {
408
+ return {
409
+ minY: Math.min(acc.minY, bounds.position.y),
410
+ maxY: Math.max(acc.maxY, bounds.position.y + bounds.height),
411
+ }
412
+ }, { minY: Infinity, maxY: -Infinity }),
413
+ ({ minY, maxY }) => {
414
+ const {
415
+ position: { x },
416
+ width,
417
+ } = dagreBounds(nodeId)
418
+ minY = minY - Sizes.compound.paddingTop
419
+ maxY = maxY + Sizes.compound.paddingBottom
420
+
421
+ return {
422
+ position: {
423
+ x,
424
+ y: minY,
425
+ },
426
+ width,
427
+ height: maxY - minY,
428
+ }
429
+ },
430
+ )
431
+ }
432
+
433
+ function nodeLevel(nodeId: string): number {
434
+ const parent = g.parent(nodeId)
435
+ if (parent) {
436
+ return nodeLevel(parent) + 1
437
+ }
438
+ return 0
439
+ }
440
+ function nodeDepth(nodeId: string): number {
441
+ const children = g.children(nodeId) as string[] | undefined ?? []
442
+ if (children.length === 0) {
443
+ return 0
444
+ }
445
+ return 1 + Math.max(...children.map(nodeDepth))
446
+ }
447
+
448
+ // Sort ports in subject vertically
449
+ const sortedPorts = (ports: string[]) => {
450
+ if (ports.length < 2) {
451
+ return ports
452
+ }
453
+ return pipe(
454
+ ports,
455
+ map(port => {
456
+ return {
457
+ port,
458
+ topY: nodeBounds(port).position.y,
459
+ }
460
+ }),
461
+ sortBy(prop('topY')),
462
+ map(prop('port')),
463
+ )
464
+ }
465
+
466
+ // In case we got negative positions
467
+ let minX = 0
468
+ let minY = 0
469
+
470
+ const [subject] = [...subjects.root]
471
+ invariant(subject, 'Subjects should not be empty')
472
+ let subjectBounds = nodeBounds(subjects.graphNodes.get(subject.id).id)
473
+ // let subjectBounds = rest.reduce((bounds, el) => {
474
+ // const elBounds = nodeBounds(subjects.graphNodes.get(el.id).id)
475
+ // return {
476
+ // position: {
477
+ // x: Math.min(bounds.position.x, elBounds.position.x),
478
+ // y: Math.min(bounds.position.y, elBounds.position.y),
479
+ // },
480
+ // width: Math.max(bounds.width, elBounds.width),
481
+ // height: Math.max(bounds.height, elBounds.height),
482
+ // }
483
+ // }, nodeBounds(subjects.graphNodes.get(subject.id).id))
484
+
485
+ const nodes = nodeIds.map(({ id }): LayoutRelationshipsViewResult.Node => {
486
+ const { element, inPorts, outPorts, column } = g.node(id)
487
+ let { position, width, height } = nodeBounds(id)
488
+
489
+ if (!element) {
490
+ height = Math.min(subjectBounds.height, 300)
491
+ position.y = subjectBounds.position.y + subjectBounds.height / 2 - height / 2
492
+ if (column === 'incomers') {
493
+ width = subjectBounds.position.x - Sizes.emptyNodeOffset - position.x
494
+ } else {
495
+ const rightX = position.x + width!
496
+ position.x = subjectBounds.position.x + subjectBounds.width + Sizes.emptyNodeOffset
497
+ width = rightX - position.x
498
+ }
499
+ return {
500
+ id: id as NodeId,
501
+ parent: null,
502
+ position: [position.x, position.y],
503
+ title: 'empty node',
504
+ description: null,
505
+ technology: null,
506
+ tags: null,
507
+ links: null,
508
+ color: 'muted',
509
+ shape: 'rectangle',
510
+ style: {
511
+ border: 'dashed',
512
+ opacity: 50,
513
+ },
514
+ kind: LayoutRelationshipsViewResult.Empty,
515
+ level: 0,
516
+ labelBBox: {
517
+ x: position.x,
518
+ y: position.y,
519
+ width: width,
520
+ height: height,
521
+ },
522
+ inEdges: [],
523
+ outEdges: [],
524
+ children: [],
525
+ width,
526
+ height,
527
+ column,
528
+ ports: {
529
+ in: [],
530
+ out: [],
531
+ },
532
+ }
533
+ }
534
+ const parentId = g.parent(id)
535
+
536
+ const children = (g.children(id) as NodeId[] | undefined ?? []).filter(c => !c.endsWith(PortSuffix))
537
+
538
+ minX = Math.min(minX, position.x)
539
+ minY = Math.min(minY, position.y)
540
+
541
+ const navigateTo = element.defaultView?.id ?? null
542
+
543
+ return {
544
+ id: id as NodeId,
545
+ parent: parentId as NodeId ?? null,
546
+ position: [position.x, position.y],
547
+ title: element.title,
548
+ description: element.description,
549
+ technology: element.technology,
550
+ tags: null,
551
+ links: null,
552
+ color: element.color,
553
+ shape: element.shape,
554
+ icon: element.icon ?? 'none' as IconUrl,
555
+ modelRef: element.id,
556
+ kind: element.kind,
557
+ level: nodeLevel(id),
558
+ labelBBox: {
559
+ x: position.x,
560
+ y: position.y,
561
+ width: width,
562
+ height: height,
563
+ },
564
+ style: {
565
+ ...element.$element.style,
566
+ },
567
+ navigateTo,
568
+ inEdges: [],
569
+ outEdges: [],
570
+ ...(children.length > 0 && { depth: nodeDepth(id) }),
571
+ children,
572
+ width,
573
+ height,
574
+ column,
575
+ ports: {
576
+ in: sortedPorts(inPorts),
577
+ out: sortedPorts(outPorts),
578
+ },
579
+ }
580
+ })
581
+
582
+ return {
583
+ bounds: {
584
+ x: minX,
585
+ y: minY,
586
+ width: g.graph().width ?? 100,
587
+ height: g.graph().height ?? 100,
588
+ },
589
+ nodes,
590
+ edges: g.edges().reduce((acc, e) => {
591
+ const edge = g.edge(e)
592
+ const ename = e.name
593
+ if (!ename) {
594
+ return acc
595
+ }
596
+ const { name, source, target, relations } = find(edges, e => e.name === ename)!
597
+ const onlyRelation = only(relations)
598
+ const label = onlyRelation?.title ?? 'untitled'
599
+ const isMultiple = relations.length > 1
600
+ const points = edge.points.map(p => [p.x, p.y] as Point)
601
+ if (!hasAtLeast(points, 1)) {
602
+ return acc
603
+ }
604
+ const navigateTo = onlyRelation?.navigateTo?.id ?? null
605
+ // edge.points
606
+ // const edge = g.edge(name)
607
+ acc.push({
608
+ id: name as EdgeId,
609
+ source: source as NodeId,
610
+ target: target as NodeId,
611
+ label: isMultiple ? `${relations.length} relationships` : label,
612
+ relations: relations.map(r => r.id),
613
+ parent: null,
614
+ points,
615
+ ...(navigateTo && { navigateTo }),
616
+ head: 'normal',
617
+ tail: 'none',
618
+ line: onlyRelation?.$relationship.line ?? 'dashed',
619
+ })
620
+ return acc
621
+ }, [] as LayoutRelationshipsViewResult.Edge[]),
622
+ }
623
+ }
624
+
625
+ export function useRelationshipsView(fqn: Fqn) {
626
+ const model = useLikeC4Model(true)
627
+ return useMemo(() => {
628
+ return {
629
+ id: `relationships-${fqn}` as ViewId,
630
+ title: `Relationships of ${fqn}`,
631
+ description: null,
632
+ autoLayout: {
633
+ direction: 'LR',
634
+ },
635
+ tags: null,
636
+ links: null,
637
+ hash: 'empty',
638
+ customColorDefinitions: {},
639
+ ...layoutRelationshipsView(computeRelationshipsView(fqn, model)),
640
+ }
641
+ }, [model, fqn, computeRelationshipsView])
642
+ }