@likec4/diagram 1.18.0 → 1.19.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 (277) hide show
  1. package/LICENSE +1 -1
  2. package/dist/LikeC4CustomColors.d.ts +7 -0
  3. package/dist/LikeC4CustomColors.js +30 -0
  4. package/dist/LikeC4Diagram.css.d.ts +5 -0
  5. package/dist/LikeC4Diagram.css.js +13 -0
  6. package/dist/LikeC4Diagram.d.ts +6 -0
  7. package/dist/LikeC4Diagram.js +194 -0
  8. package/dist/LikeC4Diagram.props.d.ts +166 -0
  9. package/dist/LikeC4ModelProvider.d.ts +9 -0
  10. package/dist/LikeC4ModelProvider.js +12 -0
  11. package/dist/LikeC4Search.css.d.ts +1 -0
  12. package/dist/LikeC4Search.css.js +5 -0
  13. package/dist/LikeC4Search.d.ts +2 -0
  14. package/dist/LikeC4Search.js +96 -0
  15. package/dist/StaticLikeC4Diagram.d.ts +3 -0
  16. package/dist/StaticLikeC4Diagram.js +41 -0
  17. package/dist/_virtual/_commonjsHelpers.js +6 -0
  18. package/dist/controls/Text.d.ts +2 -0
  19. package/dist/controls/Text.js +7 -0
  20. package/dist/controls/action-button-bar/ActionButtonBar.css.d.ts +1 -0
  21. package/dist/controls/action-button-bar/ActionButtonBar.css.js +5 -0
  22. package/dist/controls/action-button-bar/ActionButtonBar.d.ts +9 -0
  23. package/dist/controls/action-button-bar/ActionButtonBar.js +100 -0
  24. package/dist/controls/action-button-bar/useActionButtonBarCtx.d.ts +10 -0
  25. package/dist/controls/action-button-bar/useActionButtonBarCtx.js +9 -0
  26. package/dist/controls/action-buttons/ActionButton.css.d.ts +1 -0
  27. package/dist/controls/action-buttons/ActionButton.css.js +5 -0
  28. package/dist/controls/action-buttons/ActionButton.d.ts +9 -0
  29. package/dist/controls/action-buttons/ActionButton.js +66 -0
  30. package/dist/controls/action-buttons/ActionButtons.d.ts +12 -0
  31. package/dist/controls/action-buttons/ActionButtons.js +99 -0
  32. package/dist/globals.css.d.ts +1 -0
  33. package/dist/globals.css.js +92 -0
  34. package/dist/hooks/index.d.ts +5 -0
  35. package/dist/hooks/useDiagramState.d.ts +6 -0
  36. package/dist/hooks/useDiagramState.js +27 -0
  37. package/dist/hooks/useMantinePortalProps.d.ts +9 -0
  38. package/dist/hooks/useMantinePortalProps.js +9 -0
  39. package/dist/hooks/useSetState.d.ts +2 -0
  40. package/dist/hooks/useSetState.js +19 -0
  41. package/dist/hooks/useUpdateEffect.d.ts +4 -0
  42. package/dist/hooks/useUpdateEffect.js +32 -0
  43. package/dist/hooks/useXYFlow.d.ts +270 -0
  44. package/dist/hooks/useXYFlow.js +20 -0
  45. package/dist/index.d.ts +11 -0
  46. package/dist/index.js +25 -0
  47. package/dist/likec4model/LikeC4ModelContext.d.ts +3 -0
  48. package/dist/likec4model/LikeC4ModelContext.js +5 -0
  49. package/dist/likec4model/index.d.ts +2 -0
  50. package/dist/likec4model/useLikeC4ElementsTree.d.ts +12 -0
  51. package/dist/likec4model/useLikeC4ElementsTree.js +25 -0
  52. package/dist/likec4model/useLikeC4Model.d.ts +20 -0
  53. package/dist/likec4model/useLikeC4Model.js +55 -0
  54. package/dist/overlays/OverlayContext.d.ts +10 -0
  55. package/dist/overlays/OverlayContext.js +9 -0
  56. package/dist/overlays/Overlays.css.d.ts +3 -0
  57. package/dist/overlays/Overlays.css.js +7 -0
  58. package/dist/overlays/Overlays.d.ts +2 -0
  59. package/dist/overlays/Overlays.js +137 -0
  60. package/dist/overlays/edge-details/EdgeDetailsXYFlow.d.ts +5 -0
  61. package/dist/overlays/edge-details/EdgeDetailsXYFlow.js +185 -0
  62. package/dist/overlays/edge-details/SelectEdge.css.d.ts +7 -0
  63. package/dist/overlays/edge-details/SelectEdge.css.js +17 -0
  64. package/dist/overlays/edge-details/SelectEdge.d.ts +5 -0
  65. package/dist/overlays/edge-details/SelectEdge.js +129 -0
  66. package/dist/overlays/edge-details/_types.d.ts +14 -0
  67. package/dist/overlays/edge-details/use-layouted-edge-details.d.ts +21 -0
  68. package/dist/overlays/edge-details/use-layouted-edge-details.js +270 -0
  69. package/dist/overlays/edge-details/xyflow/CompoundNode.d.ts +5 -0
  70. package/dist/overlays/edge-details/xyflow/CompoundNode.js +76 -0
  71. package/dist/overlays/edge-details/xyflow/ElementNode.d.ts +5 -0
  72. package/dist/overlays/edge-details/xyflow/ElementNode.js +159 -0
  73. package/dist/overlays/edge-details/xyflow/RelationshipEdge.d.ts +3 -0
  74. package/dist/overlays/edge-details/xyflow/RelationshipEdge.js +84 -0
  75. package/dist/overlays/edge-details/xyflow/styles.css.d.ts +9 -0
  76. package/dist/overlays/edge-details/xyflow/styles.css.js +21 -0
  77. package/dist/overlays/element-details/ElementDetailsCard.css.d.ts +16 -0
  78. package/dist/overlays/element-details/ElementDetailsCard.css.js +33 -0
  79. package/dist/overlays/element-details/ElementDetailsCard.d.ts +7 -0
  80. package/dist/overlays/element-details/ElementDetailsCard.js +484 -0
  81. package/dist/overlays/element-details/TabPanelDeployments.css.d.ts +4 -0
  82. package/dist/overlays/element-details/TabPanelDeployments.css.js +11 -0
  83. package/dist/overlays/element-details/TabPanelDeployments.d.ts +7 -0
  84. package/dist/overlays/element-details/TabPanelDeployments.js +173 -0
  85. package/dist/overlays/element-details/TabPanelRelationships.css.d.ts +5 -0
  86. package/dist/overlays/element-details/TabPanelRelationships.css.js +11 -0
  87. package/dist/overlays/element-details/TabPanelRelationships.d.ts +8 -0
  88. package/dist/overlays/element-details/TabPanelRelationships.js +157 -0
  89. package/dist/overlays/element-details/TabPanelStructure.css.d.ts +2 -0
  90. package/dist/overlays/element-details/TabPanelStructure.css.js +7 -0
  91. package/dist/overlays/element-details/TabPanelStructure.d.ts +25 -0
  92. package/dist/overlays/element-details/TabPanelStructure.js +91 -0
  93. package/dist/overlays/index.d.ts +1 -0
  94. package/dist/overlays/relationships-of/RelationshipsOverlay.d.ts +5 -0
  95. package/dist/overlays/relationships-of/RelationshipsOverlay.js +193 -0
  96. package/dist/overlays/relationships-of/RelationshipsXYFlow.d.ts +19 -0
  97. package/dist/overlays/relationships-of/RelationshipsXYFlow.js +290 -0
  98. package/dist/overlays/relationships-of/SelectElement.css.d.ts +2 -0
  99. package/dist/overlays/relationships-of/SelectElement.css.js +7 -0
  100. package/dist/overlays/relationships-of/SelectElement.d.ts +7 -0
  101. package/dist/overlays/relationships-of/SelectElement.js +126 -0
  102. package/dist/overlays/relationships-of/_types.d.ts +28 -0
  103. package/dist/overlays/relationships-of/use-layouted-relationships.d.ts +22 -0
  104. package/dist/overlays/relationships-of/use-layouted-relationships.js +496 -0
  105. package/dist/overlays/relationships-of/xyflow/CompoundNode.d.ts +6 -0
  106. package/dist/overlays/relationships-of/xyflow/CompoundNode.js +120 -0
  107. package/dist/overlays/relationships-of/xyflow/ElementNode.d.ts +6 -0
  108. package/dist/overlays/relationships-of/xyflow/ElementNode.js +194 -0
  109. package/dist/overlays/relationships-of/xyflow/EmptyNode.d.ts +5 -0
  110. package/dist/overlays/relationships-of/xyflow/EmptyNode.js +18 -0
  111. package/dist/overlays/relationships-of/xyflow/RelationshipEdge.d.ts +3 -0
  112. package/dist/overlays/relationships-of/xyflow/RelationshipEdge.js +123 -0
  113. package/dist/overlays/relationships-of/xyflow/styles.css.d.ts +14 -0
  114. package/dist/overlays/relationships-of/xyflow/styles.css.js +24 -0
  115. package/dist/overlays/shared/xyflow/RelationshipEdge.css.d.ts +4 -0
  116. package/dist/overlays/shared/xyflow/RelationshipEdge.css.js +12 -0
  117. package/dist/overlays/shared/xyflow/_types.d.ts +77 -0
  118. package/dist/state/DiagramContext.d.ts +1609 -0
  119. package/dist/state/DiagramContext.js +101 -0
  120. package/dist/state/aligners.d.ts +42 -0
  121. package/dist/state/aligners.js +349 -0
  122. package/dist/state/diagram-to-xyflow.d.ts +11 -0
  123. package/dist/state/diagram-to-xyflow.js +113 -0
  124. package/dist/state/diagramStore.d.ts +1705 -0
  125. package/dist/state/diagramStore.js +808 -0
  126. package/dist/state/diagramStore.layout.d.ts +4 -0
  127. package/dist/state/diagramStore.layout.js +56 -0
  128. package/dist/style.css +1 -0
  129. package/dist/theme-vars.css.d.ts +72 -0
  130. package/dist/theme-vars.css.js +6 -0
  131. package/dist/theme-vars.css.ts.vanilla.css.js +1 -0
  132. package/dist/theme-vars.d.ts +3 -0
  133. package/dist/theme-vars.js +5 -0
  134. package/dist/ui/DiagramTitlePanel.css.d.ts +4 -0
  135. package/dist/ui/DiagramTitlePanel.css.js +11 -0
  136. package/dist/ui/DiagramTitlePanel.d.ts +1 -0
  137. package/dist/ui/DiagramTitlePanel.js +159 -0
  138. package/dist/ui/DynamicViewWalkthrough.css.d.ts +4 -0
  139. package/dist/ui/DynamicViewWalkthrough.css.js +11 -0
  140. package/dist/ui/DynamicViewWalkthrough.d.ts +1 -0
  141. package/dist/ui/DynamicViewWalkthrough.js +156 -0
  142. package/dist/ui/EnsureMantine.d.ts +7 -0
  143. package/dist/ui/EnsureMantine.js +14 -0
  144. package/dist/ui/FramerMotionConfig.d.ts +2 -0
  145. package/dist/ui/FramerMotionConfig.js +14 -0
  146. package/dist/ui/Link.d.ts +4 -0
  147. package/dist/ui/Link.js +36 -0
  148. package/dist/ui/notation/NotationPanel.css.d.ts +6 -0
  149. package/dist/ui/notation/NotationPanel.css.js +16 -0
  150. package/dist/ui/notation/NotationPanel.d.ts +1 -0
  151. package/dist/ui/notation/NotationPanel.js +250 -0
  152. package/dist/ui/notation/index.d.ts +1 -0
  153. package/dist/ui/top-left/ChangeAutoLayoutButton.d.ts +2 -0
  154. package/dist/ui/top-left/ChangeAutoLayoutButton.js +159 -0
  155. package/dist/ui/top-left/ManualLayoutToolsButton.d.ts +2 -0
  156. package/dist/ui/top-left/ManualLayoutToolsButton.js +137 -0
  157. package/dist/ui/top-left/TopLeftPanel.d.ts +4 -0
  158. package/dist/ui/top-left/TopLeftPanel.js +211 -0
  159. package/dist/ui/top-left/_shared.d.ts +7 -0
  160. package/dist/ui/top-left/_shared.js +22 -0
  161. package/dist/ui/top-left/styles.css.d.ts +8 -0
  162. package/dist/ui/top-left/styles.css.js +17 -0
  163. package/dist/utils/types.d.ts +8 -0
  164. package/dist/utils/vector.d.ts +24 -0
  165. package/dist/utils/vector.js +55 -0
  166. package/dist/xyflow/EdgeMarkers.d.ts +12 -0
  167. package/dist/xyflow/EdgeMarkers.js +192 -0
  168. package/dist/xyflow/FitviewOnDiagramChange.d.ts +4 -0
  169. package/dist/xyflow/FitviewOnDiagramChange.js +72 -0
  170. package/dist/xyflow/SelectEdgesOnNodeFocus.d.ts +1 -0
  171. package/dist/xyflow/SelectEdgesOnNodeFocus.js +96 -0
  172. package/dist/xyflow/XYFlow.d.ts +8 -0
  173. package/dist/xyflow/XYFlow.js +145 -0
  174. package/dist/xyflow/XYFlowBackground.d.ts +10 -0
  175. package/dist/xyflow/XYFlowBackground.js +25 -0
  176. package/dist/xyflow/XYFlowInner.d.ts +8 -0
  177. package/dist/xyflow/XYFlowInner.js +41 -0
  178. package/dist/xyflow/const.d.ts +7 -0
  179. package/dist/xyflow/const.js +12 -0
  180. package/dist/xyflow/edges/EdgeLabel.d.ts +7 -0
  181. package/dist/xyflow/edges/EdgeLabel.js +160 -0
  182. package/dist/xyflow/edges/RelationshipEdge.d.ts +6 -0
  183. package/dist/xyflow/edges/RelationshipEdge.js +443 -0
  184. package/dist/xyflow/edges/RelationshipsDropdownMenu.css.d.ts +4 -0
  185. package/dist/xyflow/edges/RelationshipsDropdownMenu.css.js +11 -0
  186. package/dist/xyflow/edges/RelationshipsDropdownMenu.d.ts +13 -0
  187. package/dist/xyflow/edges/RelationshipsDropdownMenu.js +211 -0
  188. package/dist/xyflow/edges/edges.css.d.ts +17 -0
  189. package/dist/xyflow/edges/edges.css.js +37 -0
  190. package/dist/xyflow/edges/utils.d.ts +16 -0
  191. package/dist/xyflow/edges/utils.js +24 -0
  192. package/dist/xyflow/nodes/AnimateVariants.d.ts +1313 -0
  193. package/dist/xyflow/nodes/AnimateVariants.js +123 -0
  194. package/dist/xyflow/nodes/Node.css.d.ts +3 -0
  195. package/dist/xyflow/nodes/Node.css.js +9 -0
  196. package/dist/xyflow/nodes/compound/CompoundNode.css.d.ts +14 -0
  197. package/dist/xyflow/nodes/compound/CompoundNode.css.js +27 -0
  198. package/dist/xyflow/nodes/compound/CompoundNode.d.ts +6 -0
  199. package/dist/xyflow/nodes/compound/CompoundNode.js +216 -0
  200. package/dist/xyflow/nodes/compound/index.d.ts +1 -0
  201. package/dist/xyflow/nodes/element/ElementLink.css.d.ts +3 -0
  202. package/dist/xyflow/nodes/element/ElementLink.d.ts +6 -0
  203. package/dist/xyflow/nodes/element/ElementNode.d.ts +6 -0
  204. package/dist/xyflow/nodes/element/ElementNode.js +190 -0
  205. package/dist/xyflow/nodes/element/ElementShapeSvg.d.ts +17 -0
  206. package/dist/xyflow/nodes/element/ElementShapeSvg.js +175 -0
  207. package/dist/xyflow/nodes/element/element.css.d.ts +18 -0
  208. package/dist/xyflow/nodes/element/element.css.js +31 -0
  209. package/dist/xyflow/nodes/element/index.d.ts +1 -0
  210. package/dist/xyflow/nodes/shared/ElementIcon.d.ts +8 -0
  211. package/dist/xyflow/nodes/shared/ElementIcon.js +38 -0
  212. package/dist/xyflow/nodes/shared/Toolbar.d.ts +9 -0
  213. package/dist/xyflow/nodes/shared/Toolbar.js +436 -0
  214. package/dist/xyflow/types.d.ts +36 -0
  215. package/dist/xyflow/useLayoutConstraints.d.ts +42 -0
  216. package/dist/xyflow/useLayoutConstraints.js +226 -0
  217. package/dist/xyflow/useXYFlowEvents.d.ts +160 -0
  218. package/dist/xyflow/useXYFlowEvents.js +275 -0
  219. package/dist/xyflow/utils.d.ts +22 -0
  220. package/dist/xyflow/utils.js +72 -0
  221. package/package.json +34 -27
  222. package/src/LikeC4Diagram.tsx +4 -4
  223. package/src/LikeC4Search.css.ts +12 -0
  224. package/src/LikeC4Search.tsx +39 -90
  225. package/src/controls/Text.ts +5 -0
  226. package/src/controls/action-button-bar/ActionButtonBar.css.ts +13 -0
  227. package/src/controls/action-button-bar/ActionButtonBar.tsx +138 -0
  228. package/src/controls/action-button-bar/useActionButtonBarCtx.ts +13 -0
  229. package/src/controls/action-buttons/ActionButton.css.ts +29 -0
  230. package/src/controls/action-buttons/ActionButton.tsx +66 -0
  231. package/src/controls/action-buttons/ActionButtons.tsx +138 -0
  232. package/src/hooks/useXYFlow.ts +8 -8
  233. package/src/index.ts +12 -6
  234. package/src/likec4model/index.ts +12 -2
  235. package/src/overlays/edge-details/EdgeDetailsXYFlow.tsx +18 -12
  236. package/src/overlays/edge-details/_types.ts +13 -37
  237. package/src/overlays/edge-details/use-layouted-edge-details.ts +16 -14
  238. package/src/overlays/edge-details/xyflow/CompoundNode.tsx +3 -11
  239. package/src/overlays/edge-details/xyflow/ElementNode.tsx +4 -11
  240. package/src/overlays/edge-details/xyflow/RelationshipEdge.tsx +3 -3
  241. package/src/overlays/edge-details/xyflow/styles.css.ts +1 -59
  242. package/src/overlays/relationships-of/RelationshipsXYFlow.tsx +23 -23
  243. package/src/overlays/relationships-of/_types.ts +20 -58
  244. package/src/overlays/relationships-of/use-layouted-relationships.ts +36 -40
  245. package/src/overlays/relationships-of/xyflow/CompoundNode.tsx +9 -13
  246. package/src/overlays/relationships-of/xyflow/ElementNode.tsx +12 -15
  247. package/src/overlays/relationships-of/xyflow/EmptyNode.tsx +4 -7
  248. package/src/overlays/relationships-of/xyflow/RelationshipEdge.tsx +16 -14
  249. package/src/overlays/shared/xyflow/RelationshipEdge.css.ts +60 -0
  250. package/src/overlays/shared/xyflow/_types.ts +87 -0
  251. package/src/state/diagram-to-xyflow.ts +6 -7
  252. package/src/state/diagramStore.layout.ts +3 -4
  253. package/src/state/diagramStore.ts +35 -37
  254. package/src/theme-vars.css.ts +81 -0
  255. package/src/theme-vars.ts +8 -81
  256. package/src/ui/DiagramTitlePanel.tsx +6 -6
  257. package/src/utils/types.ts +6 -0
  258. package/src/xyflow/SelectEdgesOnNodeFocus.tsx +3 -3
  259. package/src/xyflow/XYFlow.tsx +2 -2
  260. package/src/xyflow/edges/EdgeLabel.tsx +25 -18
  261. package/src/xyflow/edges/RelationshipEdge.tsx +5 -3
  262. package/src/xyflow/edges/RelationshipsDropdownMenu.tsx +3 -3
  263. package/src/xyflow/edges/edges.css.ts +68 -74
  264. package/src/xyflow/edges/utils.ts +6 -6
  265. package/src/xyflow/nodes/AnimateVariants.ts +143 -0
  266. package/src/xyflow/nodes/Node.css.ts +44 -0
  267. package/src/xyflow/nodes/compound/CompoundNode.css.ts +1 -64
  268. package/src/xyflow/nodes/compound/CompoundNode.tsx +69 -182
  269. package/src/xyflow/nodes/element/ElementLink.tsx +2 -3
  270. package/src/xyflow/nodes/element/ElementNode.tsx +64 -266
  271. package/src/xyflow/nodes/element/element.css.ts +0 -57
  272. package/src/xyflow/nodes/shared/Toolbar.tsx +30 -30
  273. package/src/xyflow/types.ts +48 -51
  274. package/src/xyflow/useLayoutConstraints.ts +9 -9
  275. package/src/xyflow/useXYFlowEvents.ts +13 -30
  276. package/src/xyflow/utils.ts +2 -2
  277. package/src/xyflow/nodes/use-animate-variants.tsx +0 -64
@@ -0,0 +1,101 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { invariant } from "@likec4/core";
3
+ import { Box } from "@mantine/core";
4
+ import { useReducedMotion, useMergedRef } from "@mantine/hooks";
5
+ import { shallowEqual, deepEqual } from "fast-equals";
6
+ import { useAnimate } from "framer-motion";
7
+ import { createContext, useRef, useCallback, useEffect } from "react";
8
+ import { clone } from "remeda";
9
+ import { useUpdateEffect } from "../hooks/useUpdateEffect.js";
10
+ import { useXYStoreApi, useXYFlow } from "../hooks/useXYFlow.js";
11
+ import { createDiagramStore } from "./diagramStore.js";
12
+ const DiagramContext = createContext(null);
13
+ function DiagramContextProvider({
14
+ children,
15
+ view,
16
+ className,
17
+ keepAspectRatio,
18
+ whereFilter,
19
+ ...props
20
+ }) {
21
+ const isMotionReduced = useReducedMotion() ?? false;
22
+ const [scope, animate] = useAnimate();
23
+ const containerRef = useRef(null);
24
+ const ref = useMergedRef(scope, containerRef);
25
+ const xystore = useXYStoreApi();
26
+ const xyflow = useXYFlow();
27
+ const store = useRef();
28
+ const getContainer = useCallback(() => containerRef.current, [containerRef]);
29
+ if (!store.current) {
30
+ store.current = createDiagramStore({
31
+ xystore,
32
+ xyflow,
33
+ view,
34
+ getContainer,
35
+ whereFilter: clone(whereFilter),
36
+ ...props
37
+ });
38
+ }
39
+ useUpdateEffect(
40
+ () => {
41
+ var _a;
42
+ return (_a = store.current) == null ? void 0 : _a.setState({ xyflow, xystore, getContainer }, false, "update xyflow and xystore");
43
+ },
44
+ [xyflow, xystore, getContainer]
45
+ );
46
+ useUpdateEffect(
47
+ () => {
48
+ var _a;
49
+ return (_a = store.current) == null ? void 0 : _a.setState(props, false, "update incoming props");
50
+ },
51
+ [props]
52
+ );
53
+ useUpdateEffect(
54
+ () => {
55
+ const current = store.current;
56
+ invariant(current, "DiagramContext.store.current is not defined");
57
+ if (!deepEqual(whereFilter, current.getState().whereFilter)) {
58
+ current.setState({ whereFilter: clone(whereFilter) }, false, "update where filter");
59
+ }
60
+ current.getState().updateView(view);
61
+ },
62
+ [view, whereFilter],
63
+ (a, b) => shallowEqual(a[0], b[0]) && deepEqual(a[1], b[1])
64
+ );
65
+ const api = store.current;
66
+ useEffect(() => {
67
+ if (isMotionReduced) {
68
+ return;
69
+ }
70
+ return api.subscribe((s) => !!s.activeOverlay, (isActiveOverlay) => {
71
+ animate(".likec4-diagram .react-flow__renderer", {
72
+ opacity: isActiveOverlay ? 0.7 : 1,
73
+ filter: isActiveOverlay ? "grayscale(1)" : "grayscale(0)",
74
+ transform: isActiveOverlay ? `perspective(300px) translateZ(-10px) translateY(2px)` : `translateY(0)`
75
+ }, {
76
+ duration: isActiveOverlay ? 0.4 : 0.2
77
+ });
78
+ }, {
79
+ fireImmediately: true
80
+ });
81
+ }, [api, isMotionReduced]);
82
+ return /* @__PURE__ */ jsx(
83
+ Box,
84
+ {
85
+ ref,
86
+ className,
87
+ ...keepAspectRatio && {
88
+ style: {
89
+ aspectRatio: `${Math.ceil(view.bounds.width)}/${Math.ceil(view.bounds.height)}`,
90
+ maxHeight: Math.ceil(view.bounds.height)
91
+ }
92
+ },
93
+ children: /* @__PURE__ */ jsx(DiagramContext.Provider, { value: api, children })
94
+ }
95
+ );
96
+ }
97
+ DiagramContextProvider.displayName = "DiagramContextProvider";
98
+ export {
99
+ DiagramContext,
100
+ DiagramContextProvider
101
+ };
@@ -0,0 +1,42 @@
1
+ import { Rect, XYPosition } from '@xyflow/react';
2
+ export type GridAlignmentMode = 'Column' | 'Row';
3
+ export type LinearAlignmentMode = 'Left' | 'Center' | 'Right' | 'Top' | 'Middle' | 'Bottom';
4
+ export declare abstract class Aligner {
5
+ abstract computeLayout(nodes: NodeRect[]): void;
6
+ abstract applyPosition(node: NodeRect): Partial<XYPosition>;
7
+ }
8
+ export declare class LinearAligner extends Aligner {
9
+ private getEdgePosition;
10
+ private computePosition;
11
+ private propertyToEdit;
12
+ private alignTo;
13
+ constructor(getEdgePosition: (nodes: NodeRect[]) => number, computePosition: (alignTo: number, node: NodeRect) => number, propertyToEdit: keyof XYPosition);
14
+ computeLayout(nodes: NodeRect[]): void;
15
+ applyPosition(node: NodeRect): Partial<XYPosition>;
16
+ }
17
+ export type NodeRect = Rect & {
18
+ id: string;
19
+ };
20
+ export declare class GridAligner extends Aligner {
21
+ private layout;
22
+ private axisPreset;
23
+ private get primaryAxisCoord();
24
+ private get secondaryAxisCoord();
25
+ private get primaryAxisDimension();
26
+ private get secondaryAxisDimension();
27
+ constructor(alignmentMode: GridAlignmentMode);
28
+ applyPosition(node: NodeRect): Partial<XYPosition>;
29
+ computeLayout(nodes: NodeRect[]): void;
30
+ private getLayoutRect;
31
+ private getLayers;
32
+ private buildLayout;
33
+ private buildLayerLayout;
34
+ private spaceBetween;
35
+ private spaceAround;
36
+ private placeInGaps;
37
+ private placeInCells;
38
+ private scoreLayout;
39
+ private getGapsPositions;
40
+ private getNodePositions;
41
+ }
42
+ export declare function getLinearAligner(mode: LinearAlignmentMode): Aligner;
@@ -0,0 +1,349 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+ import { invariant } from "@likec4/core";
5
+ import { pipe, sortBy, map, pick, reduce } from "remeda";
6
+ class Aligner {
7
+ }
8
+ class LinearAligner extends Aligner {
9
+ constructor(getEdgePosition, computePosition, propertyToEdit) {
10
+ super();
11
+ __publicField(this, "alignTo");
12
+ this.getEdgePosition = getEdgePosition;
13
+ this.computePosition = computePosition;
14
+ this.propertyToEdit = propertyToEdit;
15
+ }
16
+ computeLayout(nodes) {
17
+ this.alignTo = this.getEdgePosition(nodes);
18
+ }
19
+ applyPosition(node) {
20
+ return {
21
+ [this.propertyToEdit]: this.computePosition(this.alignTo, node)
22
+ };
23
+ }
24
+ }
25
+ class GridAligner extends Aligner {
26
+ constructor(alignmentMode) {
27
+ super();
28
+ __publicField(this, "layout", /* @__PURE__ */ new Map());
29
+ __publicField(this, "axisPreset");
30
+ this.axisPreset = alignmentMode === "Column" ? {
31
+ primaryAxisDimension: "width",
32
+ secondaryAxisDimension: "height",
33
+ primaryAxisCoord: "x",
34
+ secondaryAxisCoord: "y"
35
+ } : {
36
+ primaryAxisDimension: "height",
37
+ secondaryAxisDimension: "width",
38
+ primaryAxisCoord: "y",
39
+ secondaryAxisCoord: "x"
40
+ };
41
+ }
42
+ get primaryAxisCoord() {
43
+ return this.axisPreset.primaryAxisCoord;
44
+ }
45
+ get secondaryAxisCoord() {
46
+ return this.axisPreset.secondaryAxisCoord;
47
+ }
48
+ get primaryAxisDimension() {
49
+ return this.axisPreset.primaryAxisDimension;
50
+ }
51
+ get secondaryAxisDimension() {
52
+ return this.axisPreset.secondaryAxisDimension;
53
+ }
54
+ applyPosition(node) {
55
+ var _a;
56
+ return ((_a = this.layout) == null ? void 0 : _a.get(node.id)) ?? {};
57
+ }
58
+ computeLayout(nodes) {
59
+ const sortedNodeRects = pipe(
60
+ nodes,
61
+ sortBy((r) => r[this.primaryAxisCoord])
62
+ );
63
+ const layoutRect = this.getLayoutRect(sortedNodeRects);
64
+ const layers = this.getLayers(sortedNodeRects);
65
+ this.layout = this.buildLayout(layers, layoutRect, sortedNodeRects);
66
+ }
67
+ getLayoutRect(nodeRects) {
68
+ const x = Math.min(...nodeRects.map((n) => n.x));
69
+ const y = Math.min(...nodeRects.map((n) => n.y));
70
+ const right = Math.max(...nodeRects.map((n) => n.x + n.width));
71
+ const bottom = Math.max(...nodeRects.map((n) => n.y + n.height));
72
+ return {
73
+ x,
74
+ y,
75
+ width: right - x,
76
+ height: bottom - y
77
+ };
78
+ }
79
+ getLayers(sortedNodeRects) {
80
+ const layers = [];
81
+ let layerEnd = 0;
82
+ let layer = null;
83
+ for (let node of sortedNodeRects) {
84
+ if (!!layer && node[this.primaryAxisCoord] < layerEnd) {
85
+ layer.nodes.push(node);
86
+ layer.primaryAxisSize = Math.max(layer.primaryAxisSize, node[this.primaryAxisDimension]);
87
+ layer.occupiedSpace += node[this.secondaryAxisDimension];
88
+ layerEnd = Math.max(
89
+ node[this.primaryAxisCoord] + node[this.primaryAxisDimension],
90
+ layerEnd
91
+ );
92
+ } else {
93
+ layer = {
94
+ primaryAxisSize: node[this.primaryAxisDimension],
95
+ nodes: [node],
96
+ occupiedSpace: node[this.secondaryAxisDimension],
97
+ layout: null
98
+ };
99
+ layers.push(layer);
100
+ layerEnd = node[this.primaryAxisCoord] + node[this.primaryAxisDimension];
101
+ continue;
102
+ }
103
+ }
104
+ layers.forEach(
105
+ (l) => l.nodes.sort((a, b) => a[this.secondaryAxisCoord] - b[this.secondaryAxisCoord])
106
+ );
107
+ return layers;
108
+ }
109
+ buildLayout(layers, layoutRect, nodeRects) {
110
+ const nodeMap = new Map(nodeRects.map((n) => [n.id, n]));
111
+ const layout = [];
112
+ const occupiedSpace = layers.reduce((a, b) => a + b.primaryAxisSize, 0);
113
+ const rowMargin = layers.length > 1 ? (layoutRect[this.primaryAxisDimension] - occupiedSpace) / (layers.length - 1) : 0;
114
+ const baseLayerIndex = layers.reduce(
115
+ (widestLayerIndex, layer, i) => layers[widestLayerIndex].occupiedSpace < layer.occupiedSpace ? i : widestLayerIndex,
116
+ 0
117
+ );
118
+ const baseLayer = layers[baseLayerIndex];
119
+ const baseLayerPosition = layers.slice(0, baseLayerIndex).reduce(
120
+ (a, layer) => a + layer.primaryAxisSize + rowMargin,
121
+ layoutRect[this.primaryAxisCoord]
122
+ );
123
+ const baseLayerLayout = this.buildLayerLayout(
124
+ baseLayer,
125
+ layoutRect,
126
+ baseLayerPosition,
127
+ nodeMap,
128
+ null
129
+ );
130
+ baseLayer.layout = baseLayerLayout;
131
+ layout.push(...baseLayerLayout.nodePositions);
132
+ let placeNextLayerAt = baseLayerPosition + baseLayer.primaryAxisSize + rowMargin;
133
+ let refLayer = baseLayer;
134
+ for (let i = baseLayerIndex + 1; i < layers.length; i++) {
135
+ const layer = layers[i];
136
+ layer.layout = this.buildLayerLayout(layer, layoutRect, placeNextLayerAt, nodeMap, refLayer);
137
+ layout.push(...layer.layout.nodePositions);
138
+ refLayer = layer.layout.refLayer ?? layer;
139
+ placeNextLayerAt += layer.primaryAxisSize + rowMargin;
140
+ }
141
+ placeNextLayerAt = baseLayerPosition;
142
+ refLayer = baseLayer;
143
+ for (let i = baseLayerIndex - 1; i >= 0; i--) {
144
+ const layer = layers[i];
145
+ placeNextLayerAt -= layer.primaryAxisSize + rowMargin;
146
+ layer.layout = this.buildLayerLayout(layer, layoutRect, placeNextLayerAt, nodeMap, refLayer);
147
+ layout.push(...layer.layout.nodePositions);
148
+ refLayer = layer.layout.refLayer ?? layer;
149
+ }
150
+ return new Map(layout);
151
+ }
152
+ buildLayerLayout(layer, layoutRect, placeNextLayerAt, nodeMap, refLayer) {
153
+ let bestLayerLayout = this.scoreLayout(
154
+ this.spaceAround(layer, layoutRect, placeNextLayerAt),
155
+ nodeMap
156
+ );
157
+ if (layer.nodes.length != 1) {
158
+ const currentlayerLayout = this.scoreLayout(
159
+ this.spaceBetween(layer, layoutRect, placeNextLayerAt),
160
+ nodeMap
161
+ );
162
+ bestLayerLayout = currentlayerLayout[0] < bestLayerLayout[0] ? currentlayerLayout : bestLayerLayout;
163
+ }
164
+ if (refLayer && refLayer.nodes.length - 1 >= layer.nodes.length) {
165
+ const currentlayerLayout = this.scoreLayout(
166
+ this.placeInGaps(layer, placeNextLayerAt, refLayer),
167
+ nodeMap
168
+ );
169
+ bestLayerLayout = currentlayerLayout[0] < bestLayerLayout[0] ? currentlayerLayout : bestLayerLayout;
170
+ }
171
+ if (refLayer && refLayer.nodes.length >= layer.nodes.length) {
172
+ const currentlayerLayout = this.scoreLayout(
173
+ this.placeInCells(layer, placeNextLayerAt, refLayer),
174
+ nodeMap
175
+ );
176
+ bestLayerLayout = currentlayerLayout[0] < bestLayerLayout[0] ? currentlayerLayout : bestLayerLayout;
177
+ }
178
+ return bestLayerLayout[1];
179
+ }
180
+ spaceBetween(layer, layoutRect, placeNextLayerAt) {
181
+ const freeSpace = layoutRect[this.secondaryAxisDimension] - layer.occupiedSpace;
182
+ const margin = freeSpace / (layer.nodes.length - 1);
183
+ let placeNextNodeAt = layoutRect[this.secondaryAxisCoord];
184
+ const result = /* @__PURE__ */ new Map();
185
+ for (let node of layer.nodes) {
186
+ result.set(node.id, {
187
+ [this.secondaryAxisCoord]: placeNextNodeAt,
188
+ [this.primaryAxisCoord]: placeNextLayerAt
189
+ });
190
+ placeNextNodeAt += node[this.secondaryAxisDimension] + margin;
191
+ }
192
+ return { nodePositions: result, refLayer: null };
193
+ }
194
+ spaceAround(layer, layoutRect, placeNextLayerAt) {
195
+ const freeSpace = layoutRect[this.secondaryAxisDimension] - layer.occupiedSpace;
196
+ const margin = freeSpace / (layer.nodes.length + 1);
197
+ let placeNextNodeAt = layoutRect[this.secondaryAxisCoord] + margin;
198
+ const result = /* @__PURE__ */ new Map();
199
+ for (let node of sortBy(layer.nodes, (n) => n[this.secondaryAxisCoord])) {
200
+ result.set(node.id, {
201
+ [this.secondaryAxisCoord]: placeNextNodeAt,
202
+ [this.primaryAxisCoord]: placeNextLayerAt
203
+ });
204
+ placeNextNodeAt += node[this.secondaryAxisDimension] + margin;
205
+ }
206
+ return { nodePositions: result, refLayer: null };
207
+ }
208
+ placeInGaps(layer, placeNextLayerAt, refLayer) {
209
+ const result = /* @__PURE__ */ new Map();
210
+ const nodes = layer.nodes;
211
+ const placementOptions = this.getGapsPositions(refLayer);
212
+ let optionIndex = 0;
213
+ for (let i = 0, node = nodes[i]; i < nodes.length; i++, node = nodes[i]) {
214
+ const nodeCenter = node[this.secondaryAxisCoord] + node[this.secondaryAxisDimension] / 2;
215
+ let bestOffset = Infinity;
216
+ while (optionIndex - i <= placementOptions.length - nodes.length) {
217
+ let position = placementOptions[optionIndex];
218
+ const offset = position - nodeCenter;
219
+ if (Math.abs(offset) < Math.abs(bestOffset)) {
220
+ bestOffset = offset;
221
+ optionIndex++;
222
+ } else {
223
+ break;
224
+ }
225
+ }
226
+ result.set(node.id, {
227
+ [this.secondaryAxisCoord]: node[this.secondaryAxisCoord] + bestOffset,
228
+ [this.primaryAxisCoord]: placeNextLayerAt
229
+ });
230
+ }
231
+ return { nodePositions: result, refLayer };
232
+ }
233
+ placeInCells(layer, placeNextLayerAt, refLayer) {
234
+ const result = /* @__PURE__ */ new Map();
235
+ const nodes = layer.nodes;
236
+ const placementOptions = this.getNodePositions(refLayer);
237
+ let optionIndex = 0;
238
+ for (let i = 0, node = nodes[i]; i < nodes.length; i++, node = nodes[i]) {
239
+ const nodeCenter = node[this.secondaryAxisCoord] + node[this.secondaryAxisDimension] / 2;
240
+ let bestOffset = Infinity;
241
+ while (optionIndex - i <= placementOptions.length - nodes.length) {
242
+ let position = placementOptions[optionIndex];
243
+ const offset = position - nodeCenter;
244
+ if (Math.abs(offset) < Math.abs(bestOffset)) {
245
+ bestOffset = offset;
246
+ optionIndex++;
247
+ } else {
248
+ break;
249
+ }
250
+ }
251
+ result.set(node.id, {
252
+ [this.secondaryAxisCoord]: node[this.secondaryAxisCoord] + bestOffset,
253
+ [this.primaryAxisCoord]: placeNextLayerAt
254
+ });
255
+ }
256
+ return { nodePositions: result, refLayer };
257
+ }
258
+ scoreLayout(layout, originalRects) {
259
+ return [
260
+ pipe(
261
+ Array.from(layout.nodePositions),
262
+ map(([id, position]) => {
263
+ const originalRect = originalRects.get(id);
264
+ invariant(originalRect, `Could not find original rect for node ${id}`);
265
+ return [pick(originalRect, ["x", "y"]), position];
266
+ }),
267
+ map(
268
+ ([original, suggested]) => Math.abs(original[this.secondaryAxisCoord] - suggested[this.secondaryAxisCoord])
269
+ ),
270
+ reduce((a, b) => a + b, 0)
271
+ ),
272
+ layout
273
+ ];
274
+ }
275
+ getGapsPositions(layer) {
276
+ const result = [];
277
+ const { layout, nodes } = layer;
278
+ invariant(layout, "Layout of the layer must be computed before calling getGapsPositions");
279
+ for (let i = 1; i < nodes.length; i++) {
280
+ const previousNode = nodes[i - 1];
281
+ const currentNode = nodes[i];
282
+ const previousNodePosition = layout.nodePositions.get(previousNode.id);
283
+ const currentNodePosition = layout.nodePositions.get(currentNode.id);
284
+ result.push(
285
+ (currentNodePosition[this.secondaryAxisCoord] + previousNodePosition[this.secondaryAxisCoord] + previousNode[this.secondaryAxisDimension]) / 2
286
+ );
287
+ }
288
+ return result;
289
+ }
290
+ getNodePositions(layer) {
291
+ const result = [];
292
+ const { layout, nodes } = layer;
293
+ invariant(layout, "Layout of the layer must be computed before calling getGapsPositions");
294
+ for (let i = 0; i < nodes.length; i++) {
295
+ const node = nodes[i];
296
+ const nodePosition = layout.nodePositions.get(node.id);
297
+ result.push(
298
+ nodePosition[this.secondaryAxisCoord] + node[this.secondaryAxisDimension] / 2
299
+ );
300
+ }
301
+ return result;
302
+ }
303
+ }
304
+ function getLinearAligner(mode) {
305
+ switch (mode) {
306
+ case "Left":
307
+ return new LinearAligner(
308
+ (nodes) => Math.min(...nodes.map((n) => n.x)),
309
+ (alignTo, _) => Math.floor(alignTo),
310
+ "x"
311
+ );
312
+ case "Top":
313
+ return new LinearAligner(
314
+ (nodes) => Math.min(...nodes.map((n) => n.y)),
315
+ (alignTo, _) => Math.floor(alignTo),
316
+ "y"
317
+ );
318
+ case "Right":
319
+ return new LinearAligner(
320
+ (nodes) => Math.max(...nodes.map((n) => n.x + n.width)),
321
+ (alignTo, node) => Math.floor(alignTo - node.width),
322
+ "x"
323
+ );
324
+ case "Bottom":
325
+ return new LinearAligner(
326
+ (nodes) => Math.max(...nodes.map((n) => n.y + n.height)),
327
+ (alignTo, node) => Math.floor(alignTo - node.height),
328
+ "y"
329
+ );
330
+ case "Center":
331
+ return new LinearAligner(
332
+ (nodes) => Math.min(...nodes.map((n) => n.x + n.width / 2)),
333
+ (alignTo, node) => Math.floor(alignTo - node.width / 2),
334
+ "x"
335
+ );
336
+ case "Middle":
337
+ return new LinearAligner(
338
+ (nodes) => Math.min(...nodes.map((n) => n.y + n.height / 2)),
339
+ (alignTo, node) => Math.floor(alignTo - node.height / 2),
340
+ "y"
341
+ );
342
+ }
343
+ }
344
+ export {
345
+ Aligner,
346
+ GridAligner,
347
+ LinearAligner,
348
+ getLinearAligner
349
+ };
@@ -0,0 +1,11 @@
1
+ import { DiagramView } from '@likec4/core';
2
+ import { WhereOperator } from '../LikeC4Diagram.props';
3
+ import { DiagramFlowTypes } from '../xyflow/types';
4
+ export declare function diagramViewToXYFlowData(view: Pick<DiagramView, 'id' | 'nodes' | 'edges' | '__'>, opts: {
5
+ where: WhereOperator<string, string> | null;
6
+ draggable: boolean;
7
+ selectable: boolean;
8
+ }): {
9
+ xynodes: DiagramFlowTypes.Node[];
10
+ xyedges: DiagramFlowTypes.Edge[];
11
+ };
@@ -0,0 +1,113 @@
1
+ import { whereOperatorAsPredicate, ElementKind, nonNullable } from "@likec4/core";
2
+ import { hasAtLeast } from "remeda";
3
+ import { ZIndexes } from "../xyflow/const.js";
4
+ function diagramViewToXYFlowData(view, opts) {
5
+ view.__ === "dynamic";
6
+ const xynodes = [], xyedges = [], nodeLookup = /* @__PURE__ */ new Map();
7
+ const traverse = view.nodes.reduce(
8
+ (acc, node) => {
9
+ nodeLookup.set(node.id, node);
10
+ if (!node.parent) {
11
+ acc.push({ node, parent: null });
12
+ }
13
+ return acc;
14
+ },
15
+ new Array()
16
+ );
17
+ let visiblePredicate = (_nodeOrEdge) => true;
18
+ if (opts.where) {
19
+ try {
20
+ visiblePredicate = whereOperatorAsPredicate(opts.where);
21
+ } catch (e) {
22
+ console.error("Error in where filter:", e);
23
+ }
24
+ }
25
+ const ns = "";
26
+ const nodeById = (id) => nonNullable(nodeLookup.get(id), `Node not found: ${id}`);
27
+ let next;
28
+ while (next = traverse.shift()) {
29
+ const { node, parent } = next;
30
+ const isCompound = hasAtLeast(node.children, 1) || node.kind == ElementKind.Group;
31
+ if (isCompound) {
32
+ traverse.push(...node.children.map((child) => ({ node: nodeById(child), parent: node })));
33
+ }
34
+ const position = {
35
+ x: node.position[0],
36
+ y: node.position[1]
37
+ };
38
+ if (parent) {
39
+ position.x -= parent.position[0];
40
+ position.y -= parent.position[1];
41
+ }
42
+ const id = ns + node.id;
43
+ const base = {
44
+ id,
45
+ draggable: opts.draggable,
46
+ selectable: opts.selectable && node.kind !== ElementKind.Group,
47
+ focusable: opts.selectable && !isCompound,
48
+ deletable: false,
49
+ position,
50
+ zIndex: isCompound ? ZIndexes.Compound : ZIndexes.Element,
51
+ width: node.width,
52
+ height: node.height,
53
+ hidden: node.kind !== ElementKind.Group && !visiblePredicate(node),
54
+ ...parent && {
55
+ parentId: ns + parent.id
56
+ }
57
+ };
58
+ xynodes.push(
59
+ isCompound ? {
60
+ ...base,
61
+ type: "compound",
62
+ data: {
63
+ fqn: node.id,
64
+ isViewGroup: node.kind === ElementKind.Group,
65
+ element: node
66
+ },
67
+ dragHandle: ".likec4-compound-title"
68
+ } : {
69
+ ...base,
70
+ type: "element",
71
+ data: {
72
+ fqn: node.id,
73
+ element: node
74
+ }
75
+ }
76
+ );
77
+ }
78
+ for (const edge of view.edges) {
79
+ const source = edge.source;
80
+ const target = edge.target;
81
+ const id = ns + edge.id;
82
+ if (!hasAtLeast(edge.points, 2)) {
83
+ console.error("edge should have at least 2 points", edge);
84
+ continue;
85
+ }
86
+ xyedges.push({
87
+ id,
88
+ type: "relationship",
89
+ source: ns + source,
90
+ target: ns + target,
91
+ zIndex: ZIndexes.Edge,
92
+ selectable: opts.selectable,
93
+ hidden: !visiblePredicate(edge),
94
+ deletable: false,
95
+ data: {
96
+ edge,
97
+ controlPoints: edge.controlPoints || null,
98
+ label: !!edge.labelBBox ? {
99
+ bbox: edge.labelBBox,
100
+ text: edge.label ?? ""
101
+ } : null
102
+ },
103
+ interactionWidth: 20
104
+ });
105
+ }
106
+ return {
107
+ xynodes,
108
+ xyedges
109
+ };
110
+ }
111
+ export {
112
+ diagramViewToXYFlowData
113
+ };