@likec4/diagram 1.36.1 → 1.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/bundle/{chunk-DHvr-RGh.js → chunk-DSORWspW.js} +1008 -988
  2. package/bundle/custom.js +64 -56
  3. package/bundle/index.js +3539 -3315
  4. package/dist/LikeC4Diagram.props.d.ts +5 -5
  5. package/dist/LikeC4Styles.js +17 -15
  6. package/dist/StaticLikeC4Diagram.d.ts +1 -1
  7. package/dist/StaticLikeC4Diagram.js +3 -0
  8. package/dist/base/BaseXYFlow.d.ts +1 -1
  9. package/dist/base/BaseXYFlow.js +25 -27
  10. package/dist/base/const.d.ts +4 -4
  11. package/dist/base/const.js +5 -4
  12. package/dist/base/primitives/MarkdownBlock.js +4 -1
  13. package/dist/base/primitives/compound/CompoundActionButton.js +27 -42
  14. package/dist/base/primitives/compound/CompoundDetailsButton.js +23 -48
  15. package/dist/base/primitives/compound/CompoundNodeContainer.js +16 -48
  16. package/dist/base/primitives/compound/CompoundTitle.js +5 -80
  17. package/dist/base/primitives/compound/actionbtns.css.js +1 -13
  18. package/dist/base/primitives/customEdge.d.ts +1 -1
  19. package/dist/base/primitives/customNode.d.ts +4 -4
  20. package/dist/base/primitives/customNode.js +7 -7
  21. package/dist/base/primitives/edge/EdgeLabel.d.ts +5 -4
  22. package/dist/base/primitives/edge/EdgeLabel.js +39 -21
  23. package/dist/base/primitives/edge/EdgeLabelContainer.js +11 -23
  24. package/dist/base/primitives/edge/edge.css.js +19 -11
  25. package/dist/base/primitives/element/ElementShape.js +38 -18
  26. package/dist/base/primitives/element/ElementTags.js +7 -4
  27. package/dist/base/primitives/element/ElementTitle.js +10 -2
  28. package/dist/base/types.d.ts +17 -21
  29. package/dist/bundle/LikeC4View.d.ts +2 -2
  30. package/dist/bundle/LikeC4View.js +4 -1
  31. package/dist/bundle/LikeC4View.props.d.ts +2 -2
  32. package/dist/bundle/ReactLikeC4.d.ts +3 -3
  33. package/dist/bundle/custom.js +2 -1
  34. package/dist/bundle/index.js +2 -1
  35. package/dist/components/Link.js +3 -2
  36. package/dist/context/ReduceGraphics.js +2 -5
  37. package/dist/context/RootContainer.js +1 -5
  38. package/dist/custom/customNodes.d.ts +32 -26
  39. package/dist/custom/customNodes.js +12 -8
  40. package/dist/custom/hooks.d.ts +2 -1
  41. package/dist/custom/index.js +2 -1
  42. package/dist/globals.css.js +1 -1
  43. package/dist/hooks/index.d.ts +1 -1
  44. package/dist/hooks/useDiagram.d.ts +18 -1
  45. package/dist/hooks/useDiagram.js +18 -2
  46. package/dist/hooks/useXYFlow.d.ts +40 -21
  47. package/dist/index.d.ts +1 -1
  48. package/dist/index.js +2 -1
  49. package/dist/likec4diagram/DiagramUI.js +5 -2
  50. package/dist/likec4diagram/DiagramXYFlow.js +9 -9
  51. package/dist/likec4diagram/custom/edges/RelationshipEdge.d.ts +3 -3
  52. package/dist/likec4diagram/custom/edges/RelationshipEdge.js +27 -44
  53. package/dist/likec4diagram/custom/index.js +3 -3
  54. package/dist/likec4diagram/custom/nodes/nodes.d.ts +8 -6
  55. package/dist/likec4diagram/custom/nodes/nodes.js +13 -14
  56. package/dist/likec4diagram/custom/nodes/toolbar/CompoundToolbar.js +3 -2
  57. package/dist/likec4diagram/custom/nodes/toolbar/_shared.d.ts +2 -2
  58. package/dist/likec4diagram/relationship-popover/RelationshipPopover.d.ts +2 -0
  59. package/dist/likec4diagram/relationship-popover/RelationshipPopover.js +441 -0
  60. package/dist/likec4diagram/relationship-popover/actor.d.ts +177 -0
  61. package/dist/likec4diagram/relationship-popover/actor.js +155 -0
  62. package/dist/likec4diagram/relationship-popover/styles.css.d.ts +2 -0
  63. package/dist/likec4diagram/{custom/edges/RelationshipsDropdownMenu.css.js → relationship-popover/styles.css.js} +4 -17
  64. package/dist/likec4diagram/useLayoutConstraints.js +0 -1
  65. package/dist/likec4model/useLikeC4ElementsTree.js +1 -1
  66. package/dist/likec4model/useLikeC4Project.js +15 -1
  67. package/dist/navigationpanel/NavigationPanelDropdown.js +1 -2
  68. package/dist/navigationpanel/actor.js +1 -2
  69. package/dist/navigationpanel/controls/NavigationButtons.js +1 -5
  70. package/dist/navigationpanel/controls/ViewDetailsCard.js +2 -0
  71. package/dist/overlays/element-details/actor.d.ts +564 -8
  72. package/dist/overlays/overlay/Overlay.css.d.ts +1 -1
  73. package/dist/overlays/relationship-details/actor.d.ts +3 -1
  74. package/dist/overlays/relationship-details/hooks.d.ts +19 -1
  75. package/dist/overlays/relationship-details/layout-to-xyflow.js +0 -1
  76. package/dist/overlays/relationship-details/layout.js +1 -2
  77. package/dist/overlays/relationships-browser/actor.d.ts +26 -2
  78. package/dist/overlays/relationships-browser/custom/nodeTypes.d.ts +16 -0
  79. package/dist/overlays/relationships-browser/custom/nodeTypes.js +18 -8
  80. package/dist/overlays/relationships-browser/useViewToNodesEdges.js +0 -1
  81. package/dist/search/components/_shared.css.d.ts +1 -1
  82. package/dist/state/DiagramActorProvider.js +2 -19
  83. package/dist/state/assign.js +24 -10
  84. package/dist/state/diagram-machine.d.ts +149 -474
  85. package/dist/state/diagram-machine.js +94 -54
  86. package/dist/state/types.d.ts +1 -1
  87. package/dist/styles-min.css +1 -1
  88. package/dist/styles-xyflow.css +1 -1
  89. package/dist/styles.css +1 -1
  90. package/dist/styles.css2.js +1 -1
  91. package/dist/utils/index.d.ts +2 -1
  92. package/dist/utils/roundDpr.d.ts +1 -0
  93. package/dist/utils/roundDpr.js +20 -0
  94. package/dist/utils/xyflow.d.ts +0 -1
  95. package/dist/utils/xyflow.js +1 -7
  96. package/package.json +11 -10
  97. package/panda.buildinfo.json +90 -155
  98. package/src/LikeC4Diagram.props.ts +5 -5
  99. package/src/LikeC4Styles.tsx +22 -14
  100. package/src/StaticLikeC4Diagram.tsx +3 -0
  101. package/src/base/BaseXYFlow.tsx +26 -29
  102. package/src/base/const.ts +5 -4
  103. package/src/base/primitives/MarkdownBlock.tsx +6 -1
  104. package/src/base/primitives/compound/CompoundActionButton.tsx +31 -43
  105. package/src/base/primitives/compound/CompoundDetailsButton.tsx +26 -48
  106. package/src/base/primitives/compound/CompoundNodeContainer.tsx +15 -43
  107. package/src/base/primitives/compound/CompoundTitle.tsx +4 -76
  108. package/src/base/primitives/compound/actionbtns.css.ts +0 -12
  109. package/src/base/primitives/customEdge.ts +1 -1
  110. package/src/base/primitives/customNode.tsx +20 -24
  111. package/src/base/primitives/edge/EdgeLabel.tsx +23 -8
  112. package/src/base/primitives/edge/EdgeLabelContainer.tsx +9 -21
  113. package/src/base/primitives/edge/edge.css.ts +19 -11
  114. package/src/base/primitives/element/ElementShape.tsx +40 -18
  115. package/src/base/primitives/element/ElementTags.tsx +7 -4
  116. package/src/base/primitives/element/ElementTitle.tsx +23 -11
  117. package/src/base/types.ts +21 -25
  118. package/src/bundle/LikeC4View.props.ts +2 -2
  119. package/src/bundle/LikeC4View.tsx +8 -5
  120. package/src/bundle/ReactLikeC4.tsx +3 -3
  121. package/src/components/Link.tsx +3 -2
  122. package/src/context/RootContainer.tsx +1 -5
  123. package/src/context/TagStylesContext.tsx +2 -0
  124. package/src/custom/{customNodes.tsx → customNodes.ts} +58 -52
  125. package/src/custom/hooks.ts +7 -0
  126. package/src/globals.css +58 -5
  127. package/src/hooks/index.ts +1 -1
  128. package/src/hooks/useDiagram.ts +39 -5
  129. package/src/hooks/useXYFlow.ts +3 -1
  130. package/src/index.ts +1 -0
  131. package/src/likec4diagram/DiagramUI.tsx +3 -0
  132. package/src/likec4diagram/DiagramXYFlow.tsx +9 -11
  133. package/src/likec4diagram/custom/edges/RelationshipEdge.tsx +25 -49
  134. package/src/likec4diagram/custom/index.ts +5 -4
  135. package/src/likec4diagram/custom/nodes/nodes.tsx +13 -11
  136. package/src/likec4diagram/custom/nodes/toolbar/CompoundToolbar.tsx +3 -2
  137. package/src/likec4diagram/relationship-popover/RelationshipPopover.tsx +535 -0
  138. package/src/likec4diagram/relationship-popover/actor.ts +192 -0
  139. package/src/likec4diagram/{custom/edges/RelationshipsDropdownMenu.css.ts → relationship-popover/styles.css.ts} +3 -19
  140. package/src/likec4diagram/useLayoutConstraints.ts +0 -1
  141. package/src/likec4model/useLikeC4ElementsTree.ts +1 -1
  142. package/src/navigationpanel/NavigationPanelDropdown.tsx +1 -2
  143. package/src/navigationpanel/actor.ts +2 -2
  144. package/src/navigationpanel/controls/NavigationButtons.tsx +1 -5
  145. package/src/navigationpanel/controls/ViewDetailsCard.tsx +2 -0
  146. package/src/overlays/relationship-details/layout-to-xyflow.ts +0 -1
  147. package/src/overlays/relationship-details/layout.ts +4 -3
  148. package/src/overlays/relationships-browser/custom/nodeTypes.tsx +22 -8
  149. package/src/overlays/relationships-browser/useViewToNodesEdges.ts +0 -1
  150. package/src/state/DiagramActorProvider.tsx +2 -20
  151. package/src/state/assign.ts +24 -10
  152. package/src/state/diagram-machine.ts +101 -53
  153. package/src/state/types.ts +4 -1
  154. package/src/utils/index.ts +2 -1
  155. package/src/utils/roundDpr.ts +27 -0
  156. package/src/utils/xyflow.ts +0 -7
  157. package/dist/base/primitives/compound/CompoundNodeContainer.css.d.ts +0 -35
  158. package/dist/base/primitives/compound/CompoundNodeContainer.css.js +0 -132
  159. package/dist/base/primitives/edge/EdgeLabel.css.d.ts +0 -7
  160. package/dist/base/primitives/edge/EdgeLabel.css.js +0 -57
  161. package/dist/base/primitives/element/ElementShape.css.d.ts +0 -6
  162. package/dist/base/primitives/element/ElementShape.css.js +0 -107
  163. package/dist/likec4diagram/custom/edges/NotePopover.css.js +0 -21
  164. package/dist/likec4diagram/custom/edges/NotePopover.js +0 -91
  165. package/dist/likec4diagram/custom/edges/RelationshipsDropdownMenu.css.d.ts +0 -5
  166. package/dist/likec4diagram/custom/edges/RelationshipsDropdownMenu.d.ts +0 -13
  167. package/dist/likec4diagram/custom/edges/RelationshipsDropdownMenu.js +0 -215
  168. package/dist/likec4diagram/custom/index.d.ts +0 -62
  169. package/dist/overlays/relationship-details/custom/nodeTypes.d.ts +0 -10
  170. package/src/base/primitives/compound/CompoundNodeContainer.css.ts +0 -138
  171. package/src/base/primitives/edge/EdgeLabel.css.ts +0 -64
  172. package/src/base/primitives/element/ElementShape.css.ts +0 -112
  173. package/src/likec4diagram/custom/edges/RelationshipsDropdownMenu.tsx +0 -281
@@ -1,6 +1,6 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { createSafeContext } from '@mantine/core';
3
- import { useStore } from '@nanostores/react';
3
+ import '@nanostores/react';
4
4
  import { atom } from 'nanostores';
5
5
  import { useRef, createContext, useContext } from 'react';
6
6
 
@@ -22,8 +22,5 @@ function ReduceGraphicsContext({ reduceGraphics, children }) {
22
22
  }
23
23
  return /* @__PURE__ */ jsx(PanningAtomSafeCtx, { value: $isPanningRef.current, children: /* @__PURE__ */ jsx(ReduceGraphicsModeCtx.Provider, { value: reduceGraphics, children }) });
24
24
  }
25
- function useIsPanning() {
26
- return useStore(usePanningAtom());
27
- }
28
25
 
29
- export { ReduceGraphicsContext, useIsPanning, useIsReducedGraphics, usePanningAtom };
26
+ export { ReduceGraphicsContext, useIsReducedGraphics, usePanningAtom };
@@ -17,11 +17,7 @@ function RootContainer({
17
17
  const $isPanning = usePanningAtom();
18
18
  useEffect(() => {
19
19
  return $isPanning.listen((isPanning) => {
20
- if (isPanning) {
21
- ref.current?.setAttribute("data-likec4-diagram-panning", "true");
22
- } else {
23
- ref.current?.removeAttribute("data-likec4-diagram-panning");
24
- }
20
+ ref.current?.setAttribute("data-likec4-diagram-panning", isPanning ? "true" : "false");
25
21
  });
26
22
  }, [$isPanning]);
27
23
  return /* @__PURE__ */ jsx(
@@ -1,12 +1,13 @@
1
1
  import { NodeModel } from '@likec4/core/model';
2
2
  import { Any } from '@likec4/core/types';
3
- import { ReactNode } from 'react';
3
+ import { FunctionComponent } from 'react';
4
4
  import { NodeProps } from '../base/types';
5
5
  import { Types } from '../likec4diagram/types';
6
- export type CustomElementNodeProps<M extends Any = Any> = {
7
- nodeProps: NodeProps<Types.ElementNodeData, 'element'>;
8
- nodeModel: NodeModel.WithElement<M>;
6
+ type CustomDiagramNodeProps = {
7
+ nodeProps: NodeProps<Types.NodeData, string>;
8
+ nodeModel: NodeModel;
9
9
  };
10
+ type CustomNodeComponent<P extends CustomDiagramNodeProps> = (impl: FunctionComponent<P>) => FunctionComponent<P['nodeProps']>;
10
11
  /**
11
12
  * Node that will be used to render the element from the model.
12
13
  * It is a leaf node, i.e. it does not have children.
@@ -60,10 +61,10 @@ export type CustomElementNodeProps<M extends Any = Any> = {
60
61
  * ))
61
62
  * ```
62
63
  */
63
- export declare const elementNode: (Node: (props: CustomElementNodeProps<Any>) => ReactNode) => (props: NodeProps<Types.ElementNodeData, "element">) => ReactNode;
64
- export type CustomDeploymentNodeProps<M extends Any = Any> = {
65
- nodeProps: NodeProps<Types.DeploymentElementNodeData, 'deployment'>;
66
- nodeModel: NodeModel.WithDeploymentElement<M>;
64
+ export declare const elementNode: CustomNodeComponent<CustomElementNodeProps>;
65
+ export type CustomElementNodeProps = {
66
+ nodeProps: NodeProps<Types.ElementNodeData, 'element'>;
67
+ nodeModel: NodeModel.WithElement<Any>;
67
68
  };
68
69
  /**
69
70
  * Node that will be used to render the element from deployment model.
@@ -113,10 +114,10 @@ export type CustomDeploymentNodeProps<M extends Any = Any> = {
113
114
  * ))
114
115
  * ```
115
116
  */
116
- export declare const deploymentNode: (Node: (props: CustomDeploymentNodeProps<Any>) => ReactNode) => (props: NodeProps<Types.DeploymentElementNodeData, "deployment">) => ReactNode;
117
- export type CustomCompoundElementNodeProps<M extends Any = Any> = {
118
- nodeProps: NodeProps<Types.CompoundElementNodeData, 'compound-element'>;
119
- nodeModel: NodeModel.WithElement<M>;
117
+ export declare const deploymentNode: CustomNodeComponent<CustomDeploymentNodeProps>;
118
+ export type CustomDeploymentNodeProps = {
119
+ nodeProps: NodeProps<Types.DeploymentElementNodeData, 'deployment'>;
120
+ nodeModel: NodeModel.WithDeploymentElement<Any>;
120
121
  };
121
122
  /**
122
123
  * Node that will be used to render the compound element from the model.
@@ -156,10 +157,10 @@ export type CustomCompoundElementNodeProps<M extends Any = Any> = {
156
157
  * ))
157
158
  * ```
158
159
  */
159
- export declare const compoundElementNode: (Node: (props: CustomCompoundElementNodeProps<Any>) => ReactNode) => (props: NodeProps<Types.CompoundElementNodeData, "compound-element">) => ReactNode;
160
- export type CustomCompoundDeploymentNodeProps<M extends Any = Any> = {
161
- nodeProps: NodeProps<Types.CompoundDeploymentNodeData, 'compound-deployment'>;
162
- nodeModel: NodeModel.WithDeploymentElement<M>;
160
+ export declare const compoundElementNode: CustomNodeComponent<CustomCompoundElementNodeProps>;
161
+ export type CustomCompoundElementNodeProps = {
162
+ nodeProps: NodeProps<Types.CompoundElementNodeData, 'compound-element'>;
163
+ nodeModel: NodeModel.WithElement<Any>;
163
164
  };
164
165
  /**
165
166
  * Node that will be used to render the compound from the deployment model.
@@ -193,10 +194,10 @@ export type CustomCompoundDeploymentNodeProps<M extends Any = Any> = {
193
194
  * </CompoundNodeContainer>
194
195
  * ```
195
196
  */
196
- export declare const compoundDeploymentNode: (Node: (props: CustomCompoundDeploymentNodeProps<Any>) => ReactNode) => (props: NodeProps<Types.CompoundDeploymentNodeData, "compound-deployment">) => ReactNode;
197
- export type CustomViewGroupNodeProps<M extends Any = Any> = {
198
- nodeProps: NodeProps<Types.ViewGroupNodeData, 'view-group'>;
199
- nodeModel: NodeModel.IsGroup<M>;
197
+ export declare const compoundDeploymentNode: CustomNodeComponent<CustomCompoundDeploymentNodeProps>;
198
+ export type CustomCompoundDeploymentNodeProps = {
199
+ nodeProps: NodeProps<Types.CompoundDeploymentNodeData, 'compound-deployment'>;
200
+ nodeModel: NodeModel.WithDeploymentElement<Any>;
200
201
  };
201
202
  /**
202
203
  * Node that will be used to render the view group from the model.
@@ -223,11 +224,16 @@ export type CustomViewGroupNodeProps<M extends Any = Any> = {
223
224
  * </CompoundNodeContainer>
224
225
  * ```
225
226
  */
226
- export declare const viewGroupNode: (Node: (props: CustomViewGroupNodeProps<Any>) => ReactNode) => (props: NodeProps<Types.ViewGroupNodeData, "view-group">) => ReactNode;
227
+ export declare const viewGroupNode: CustomNodeComponent<CustomViewGroupNodeProps>;
228
+ export type CustomViewGroupNodeProps = {
229
+ nodeProps: NodeProps<Types.ViewGroupNodeData, 'view-group'>;
230
+ nodeModel: NodeModel.IsGroup<Any>;
231
+ };
227
232
  export interface CustomNodes {
228
- element?: undefined | ((props: NodeProps<Types.ElementNodeData, 'element'>) => ReactNode);
229
- deployment?: undefined | ((props: NodeProps<Types.DeploymentElementNodeData, 'deployment'>) => ReactNode);
230
- compoundElement?: undefined | ((props: NodeProps<Types.CompoundElementNodeData, 'compound-element'>) => ReactNode);
231
- compoundDeployment?: undefined | ((props: NodeProps<Types.CompoundDeploymentNodeData, 'compound-deployment'>) => ReactNode);
232
- viewGroup?: undefined | ((props: NodeProps<Types.ViewGroupNodeData, 'view-group'>) => ReactNode);
233
+ element?: FunctionComponent<NodeProps<Types.ElementNodeData, 'element'>>;
234
+ deployment?: FunctionComponent<NodeProps<Types.DeploymentElementNodeData, 'deployment'>>;
235
+ compoundElement?: FunctionComponent<NodeProps<Types.CompoundElementNodeData, 'compound-element'>>;
236
+ compoundDeployment?: FunctionComponent<NodeProps<Types.CompoundDeploymentNodeData, 'compound-deployment'>>;
237
+ viewGroup?: FunctionComponent<NodeProps<Types.ViewGroupNodeData, 'view-group'>>;
233
238
  }
239
+ export {};
@@ -1,20 +1,24 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { DEV } from 'esm-env';
3
2
  import { useLikeC4ViewModel } from '../likec4model/useLikeC4Model.js';
4
3
  import { customNode } from '../base/primitives/customNode.js';
5
4
 
6
5
  function customDiagramNode(Node) {
7
6
  return customNode((props) => {
8
- const viewModel = useLikeC4ViewModel(props.data.viewId);
7
+ const viewId = props.data.viewId;
8
+ const viewModel = useLikeC4ViewModel(viewId);
9
9
  if (!viewModel) {
10
- if (DEV) {
11
- throw new Error(`View "${props.data.viewId}" not found, requested by customNode "${props.id}"`);
12
- }
13
- console.error(`View "${props.data.viewId}" not found in likec4model`, { props });
10
+ console.error(`View "${viewId}" not found, requested by customNode "${props.data.id}"`, { props });
14
11
  return null;
15
12
  }
16
- const model = viewModel.node(props.id);
17
- return /* @__PURE__ */ jsx(Node, { nodeProps: props, nodeModel: model });
13
+ const model = viewModel.findNode(props.data.id);
14
+ if (!model) {
15
+ console.error(
16
+ `Node "${props.id}" not found in view "${viewId}", requested by customNode "${props.data.id}"`,
17
+ { props }
18
+ );
19
+ return null;
20
+ }
21
+ return jsx(Node, { nodeProps: props, nodeModel: model });
18
22
  });
19
23
  }
20
24
  const elementNode = customDiagramNode;
@@ -2,10 +2,11 @@ export type { DiagramActorEvent, DiagramActorRef, DiagramContext, } from '../sta
2
2
  export { useDiagramEventHandlers, } from '../context/DiagramEventHandlers';
3
3
  export { type EnabledFeatures, type FeatureName, useEnabledFeatures, } from '../context/DiagramFeatures';
4
4
  export { useCurrentViewId, } from '../hooks/useCurrentViewId';
5
- export { type DiagramApi, useDiagram, useDiagramActorRef, useDiagramContext, } from '../hooks/useDiagram';
5
+ export { type DiagramApi, useDiagram, useDiagramActorRef, useDiagramContext, useOnDiagramEvent, } from '../hooks/useDiagram';
6
6
  export { useXYFlow, useXYInternalNode, useXYStore, useXYStoreApi, type XYFlowInstance, type XYStoreApi, } from '../hooks/useXYFlow';
7
7
  export { useCurrentViewModel, } from '../likec4model/useCurrentViewModel';
8
8
  export { useLikeC4Model, useLikeC4Specification, useLikeC4ViewModel, } from '../likec4model/useLikeC4Model';
9
+ export { useHasProjects, useLikeC4ProjectId, useLikeC4Projects, useLikeC4ProjectsContext, } from '../likec4model/useLikeC4Project';
9
10
  export { useMantinePortalProps } from '../hooks/useMantinePortalProps';
10
11
  export { useSetState } from '../hooks/useSetState';
11
12
  export { useUpdateEffect } from '../hooks/useUpdateEffect';
@@ -22,11 +22,12 @@ export { IfEnabled, IfNotEnabled, IfNotReadOnly, IfReadOnly, useEnabledFeatures
22
22
  export { Overlay } from '../overlays/overlay/Overlay.js';
23
23
  export { useDiagramEventHandlers } from '../context/DiagramEventHandlers.js';
24
24
  export { useCurrentViewId } from '../hooks/useCurrentViewId.js';
25
- export { useDiagram, useDiagramContext } from '../hooks/useDiagram.js';
25
+ export { useDiagram, useDiagramContext, useOnDiagramEvent } from '../hooks/useDiagram.js';
26
26
  export { useDiagramActorRef } from '../hooks/safeContext.js';
27
27
  export { useXYFlow, useXYInternalNode, useXYStore, useXYStoreApi } from '../hooks/useXYFlow.js';
28
28
  export { useCurrentViewModel } from '../likec4model/useCurrentViewModel.js';
29
29
  export { useLikeC4Model, useLikeC4Specification, useLikeC4ViewModel } from '../likec4model/useLikeC4Model.js';
30
+ export { useHasProjects, useLikeC4ProjectId, useLikeC4Projects, useLikeC4ProjectsContext } from '../likec4model/useLikeC4Project.js';
30
31
  export { useMantinePortalProps } from '../hooks/useMantinePortalProps.js';
31
32
  export { useSetState } from '../hooks/useSetState.js';
32
33
  export { useUpdateEffect } from '../hooks/useUpdateEffect.js';
@@ -1,3 +1,3 @@
1
- const globalsCss = ".likec4-root{overflow:hidden;position:relative;padding:0;margin:0;width:100%;height:100%;border:0px solid transparent;container-name:likec4-root;container-type:size}.likec4-root .react-flow:is(.not-initialized){opacity:0}:where(.likec4-root .mantine-ActionIcon-icon) .tabler-icon{width:75%;height:75%}.likec4-root :where(.react-flow__node,.react-flow__edge,.likec4-edge-label-container):has([data-likec4-dimmed]){opacity:.25}.likec4-root:not([data-likec4-reduced-graphics]) :where(.react-flow__node,.react-flow__edge,.likec4-edge-label-container):has([data-likec4-dimmed]){filter:grayscale(85%) blur(3px)}.likec4-root:not([data-likec4-reduced-graphics]) :where(.react-flow__node,.react-flow__edge,.likec4-edge-label-container):has([data-likec4-dimmed=true]){transition-property:opacity,filter;transition-timing-function:cubic-bezier(.5,0,.2,1);transition-duration:.6s}[data-mantine-color-scheme=dark] .likec4-root:not([data-likec4-reduced-graphics]) :where(.react-flow__edges,.react-flow__edgelabel-renderer)>svg{mix-blend-mode:plus-lighter}[data-mantine-color-scheme=light] .likec4-root:not([data-likec4-reduced-graphics]) :where(.react-flow__edges,.react-flow__edgelabel-renderer)>svg{mix-blend-mode:screen}.likec4-root :where(.likec4-edge-container,.likec4-edge-label-container){--xy-edge-stroke-width: 3;--xy-edge-stroke: var(--likec4-palette-relation-stroke);--xy-edge-stroke-selected: var(--likec4-palette-relation-stroke-selected);--xy-edge-label-color: var(--likec4-palette-relation-label);--xy-edge-label-background-color: var(--likec4-palette-relation-label-bg)}.likec4-root :where(.likec4-edge-container,.likec4-edge-label-container):is([data-likec4-hovered=true],[data-edge-active=true]){--xy-edge-stroke-width: 4;--xy-edge-stroke: var(--likec4-palette-relation-stroke-selected)}[data-mantine-color-scheme=dark] .likec4-root :where(.likec4-edge-container,.likec4-edge-label-container){--xy-edge-label-background-color: color-mix(in srgb, var(--likec4-palette-relation-label-bg) 50%, transparent)}[data-mantine-color-scheme=light] .likec4-root :where(.likec4-edge-container,.likec4-edge-label-container){--xy-edge-label-color: color-mix(in srgb, var(--likec4-palette-relation-label), rgba(255 255 255 / .85) 40%);--xy-edge-label-background-color: color-mix(in srgb, var(--likec4-palette-relation-label-bg) 60%, transparent)}";
1
+ const globalsCss = ".likec4-shadow-root dialog{color:var(--mantine-color-text)}.likec4-root{overflow:hidden;position:relative;padding:0;margin:0;width:100%;height:100%;border:0px solid transparent;container-name:likec4-root;container-type:size}.likec4-root .react-flow:is(.not-initialized){opacity:0}.likec4-root .react-flow{contain:paint;--xy-background-color: var(--colors-likec4-background);--xy-background-pattern-color: var(--colors-likec4-background-pattern, var(--colors-likec4-background))}.likec4-root .react-flow:is(.bg-transparent){background:transparent!important;--xy-background-color: transparent !important}.likec4-root .react-flow .react-flow__pane{user-select:none;--webkit-user-select: none}.likec4-static-view .react-flow .react-flow__attribution{display:none}:where(.likec4-root .mantine-ActionIcon-icon) .tabler-icon{width:75%;height:75%}.likec4-root .likec4-edge-label-container{top:0;left:0;position:absolute;width:auto;height:auto}.likec4-root :where(.react-flow__node,.react-flow__edge):has([data-likec4-dimmed]){opacity:.25}.likec4-root .likec4-edge-label-container:is([data-likec4-dimmed]){opacity:.25}.likec4-root:not([data-likec4-reduced-graphics]) :where(.react-flow__node,.react-flow__edge):has([data-likec4-dimmed]){filter:grayscale(85%) blur(3px)}.likec4-root:not([data-likec4-reduced-graphics]) .likec4-edge-label-container:is([data-likec4-dimmed]){filter:grayscale(85%) blur(3px)}.likec4-root:not([data-likec4-reduced-graphics]) :where(.react-flow__node,.react-flow__edge):has([data-likec4-dimmed=true]){transition-property:opacity,filter;transition-timing-function:cubic-bezier(.5,0,.2,1);transition-duration:.6s}.likec4-root:not([data-likec4-reduced-graphics]) .likec4-edge-label-container:is([data-likec4-dimmed=true]){transition-property:opacity,filter;transition-timing-function:cubic-bezier(.5,0,.2,1);transition-duration:.6s}.likec4-root .react-flow :where(.react-flow__nodes,.react-flow__edges,.react-flow__edgelabel-renderer){display:contents}.likec4-root .react-flow__node.draggable:has(.likec4-compound-node){cursor:default}[data-mantine-color-scheme=dark] .likec4-root:not([data-likec4-reduced-graphics]) :where(.react-flow__edges,.react-flow__edgelabel-renderer)>:where(svg,.likec4-edge-label-container){mix-blend-mode:plus-lighter}[data-mantine-color-scheme=light] .likec4-root:not([data-likec4-reduced-graphics]) :where(.react-flow__edges,.react-flow__edgelabel-renderer)>:where(svg,.likec4-edge-label-container){mix-blend-mode:screen}.likec4-root :where(.likec4-edge-container,.likec4-edge-label-container){--xy-edge-stroke-width: 3;--xy-edge-stroke: var(--likec4-palette-relation-stroke);--xy-edge-stroke-selected: var(--likec4-palette-relation-stroke-selected);--xy-edge-label-color: var(--likec4-palette-relation-label);--xy-edge-label-background-color: var(--likec4-palette-relation-label-bg)}.likec4-root :where(.likec4-edge-container,.likec4-edge-label-container):is([data-likec4-hovered=true],[data-edge-active=true]){--xy-edge-stroke-width: 4;--xy-edge-stroke: var(--likec4-palette-relation-stroke-selected)}[data-mantine-color-scheme=dark] .likec4-root :where(.likec4-edge-container,.likec4-edge-label-container){--xy-edge-label-background-color: color-mix(in srgb, var(--likec4-palette-relation-label-bg) 50%, transparent)}[data-mantine-color-scheme=light] .likec4-root :where(.likec4-edge-container,.likec4-edge-label-container){--xy-edge-label-color: color-mix(in srgb, var(--likec4-palette-relation-label), rgba(255 255 255 / .85) 40%);--xy-edge-label-background-color: color-mix(in srgb, var(--likec4-palette-relation-label-bg) 60%, transparent)}";
2
2
 
3
3
  export { globalsCss as default };
@@ -2,4 +2,4 @@ export { useMantinePortalProps } from './useMantinePortalProps';
2
2
  export { useSetState } from './useSetState';
3
3
  export { useUpdateEffect } from './useUpdateEffect';
4
4
  export { useCurrentZoom, useIsZoomTooSmall, useXYFlow, useXYInternalNode, useXYStore, useXYStoreApi } from './useXYFlow';
5
- export type { XYStoreApi } from './useXYFlow';
5
+ export type { XYFlowInstance, XYStoreApi, XYStoreState } from './useXYFlow';
@@ -5,7 +5,7 @@ import { FeatureName } from '../context/DiagramFeatures';
5
5
  import { OpenSourceParams } from '../LikeC4Diagram.props';
6
6
  import { Types } from '../likec4diagram/types';
7
7
  import { AlignmentMode } from '../state/aligners';
8
- import { DiagramActorEvent, DiagramActorRef, DiagramActorSnapshot, DiagramContext } from '../state/types';
8
+ import { DiagramActorEvent, DiagramActorRef, DiagramActorSnapshot, DiagramContext, DiagramEmittedEvents } from '../state/types';
9
9
  import { useDiagramActorRef } from './safeContext';
10
10
  export { useDiagramActorRef };
11
11
  export interface DiagramApi {
@@ -77,6 +77,10 @@ export interface DiagramApi {
77
77
  * @warning Do not use in render phase
78
78
  */
79
79
  findDiagramNode(xynodeId: string): DiagramNode | null;
80
+ /**
81
+ * @warning Do not use in render phase
82
+ */
83
+ findEdge(xyedgeId: string): Types.Edge | null;
80
84
  /**
81
85
  * @warning Do not use in render phase
82
86
  */
@@ -99,3 +103,16 @@ export declare function useDiagramActorSnapshot<T = unknown>(selector: (state: D
99
103
  * Read diagram context
100
104
  */
101
105
  export declare function useDiagramContext<T = unknown>(selector: (context: DiagramContext) => T, compare?: (a: NoInfer<T>, b: NoInfer<T>) => boolean, deps?: DependencyList): T;
106
+ type PickEmittedEvent<T extends DiagramEmittedEvents['type']> = DiagramEmittedEvents & {
107
+ type: T;
108
+ };
109
+ /**
110
+ * Subscribe to diagram emitted events
111
+ * @example
112
+ * ```tsx
113
+ * useOnDiagramEvent('navigateTo', ({viewId}) => {
114
+ * console.log('Navigating to view', viewId)
115
+ * })
116
+ * ```
117
+ */
118
+ export declare function useOnDiagramEvent<T extends DiagramEmittedEvents['type']>(event: T, callback: (event: PickEmittedEvent<T>) => void): void;
@@ -1,7 +1,7 @@
1
1
  import { useCallbackRef } from '@mantine/hooks';
2
2
  import { useSelector } from '@xstate/react';
3
3
  import { shallowEqual } from 'fast-equals';
4
- import { useMemo, useCallback } from 'react';
4
+ import { useMemo, useCallback, useRef, useEffect } from 'react';
5
5
  import { findDiagramEdge, findDiagramNode } from '../state/utils.js';
6
6
  import { useDiagramActorRef } from './safeContext.js';
7
7
 
@@ -89,6 +89,9 @@ function useDiagram() {
89
89
  findDiagramNode: (xynodeId) => {
90
90
  return findDiagramNode(actor.getSnapshot().context, xynodeId);
91
91
  },
92
+ findEdge: (xyedgeId) => {
93
+ return actor.getSnapshot().context.xyedges.find((e) => e.data.id === xyedgeId) ?? null;
94
+ },
92
95
  /**
93
96
  * @warning Do not use in render phase
94
97
  */
@@ -127,5 +130,18 @@ function useDiagramContext(selector, compare = shallowEqual, deps) {
127
130
  const select = useCallback((s) => selector(s.context), deps ?? []);
128
131
  return useSelector(actorRef, select, compare);
129
132
  }
133
+ function useOnDiagramEvent(event, callback) {
134
+ const actorRef = useDiagramActorRef();
135
+ const callbackRef = useRef(callback);
136
+ callbackRef.current = callback;
137
+ useEffect(() => {
138
+ const subscription = actorRef.on(event, (event2) => {
139
+ callbackRef.current(event2);
140
+ });
141
+ return () => {
142
+ subscription.unsubscribe();
143
+ };
144
+ }, [actorRef]);
145
+ }
130
146
 
131
- export { useDiagram, useDiagramActorRef, useDiagramActorSnapshot, useDiagramContext };
147
+ export { useDiagram, useDiagramActorRef, useDiagramActorSnapshot, useDiagramContext, useOnDiagramEvent };
@@ -1,9 +1,9 @@
1
1
  import { ReactFlowInstance, ReactFlowState, InternalNode } from '@xyflow/react';
2
2
  import { Types } from '../likec4diagram/types';
3
3
  import { EdgeMarkerType, HandleType, XYPosition } from '@xyflow/system';
4
- import { ReactNode, CSSProperties } from 'react';
4
+ import { ReactNode, CSSProperties, AriaRole, SVGAttributes } from 'react';
5
5
  import { Dimmed } from '../base/types.Base';
6
- import { EdgeId, NonEmptyArray, Point, Color, RelationshipArrowType, RelationshipLineType, BBox, ViewId, MarkdownOrString } from '@likec4/core';
6
+ import { EdgeId, NonEmptyArray, Point, Color, RelationshipLineType, RelationshipArrowType, BBox, ViewId, MarkdownOrString } from '@likec4/core';
7
7
  export declare const useXYFlow: () => ReactFlowInstance<Types.Node, {
8
8
  id: string;
9
9
  source: string;
@@ -30,6 +30,8 @@ export declare const useXYFlow: () => ReactFlowInstance<Types.Node, {
30
30
  className?: string;
31
31
  reconnectable?: boolean | HandleType;
32
32
  focusable?: boolean;
33
+ ariaRole?: AriaRole;
34
+ domAttributes?: Omit< SVGAttributes<SVGGElement>, "id" | "style" | "className" | "role" | "aria-label">;
33
35
  type: "relationship";
34
36
  data: {
35
37
  hovered?: boolean;
@@ -39,11 +41,11 @@ export declare const useXYFlow: () => ReactFlowInstance<Types.Node, {
39
41
  label: string | null;
40
42
  points: NonEmptyArray<Point>;
41
43
  color: Color | undefined;
42
- head: RelationshipArrowType | undefined;
43
- line: RelationshipLineType | undefined;
44
44
  dir: "forward" | "back" | "both" | undefined;
45
45
  technology: string | undefined;
46
+ line: RelationshipLineType | undefined;
46
47
  tail: RelationshipArrowType | undefined;
48
+ head: RelationshipArrowType | undefined;
47
49
  labelBBox: BBox | null | undefined;
48
50
  navigateTo: ViewId<string> | null | undefined;
49
51
  notes: MarkdownOrString | undefined;
@@ -52,7 +54,8 @@ export declare const useXYFlow: () => ReactFlowInstance<Types.Node, {
52
54
  };
53
55
  }>;
54
56
  export type XYFlowInstance = ReactFlowInstance<Types.Node, Types.Edge>;
55
- export declare function useXYStore<StateSlice = unknown>(selector: (state: ReactFlowState<Types.Node, Types.Edge>) => StateSlice, equalityFn?: (a: NoInfer<StateSlice>, b: NoInfer<StateSlice>) => boolean): StateSlice;
57
+ export type XYStoreState = ReactFlowState<Types.Node, Types.Edge>;
58
+ export declare function useXYStore<StateSlice = unknown>(selector: (state: XYStoreState) => StateSlice, equalityFn?: (a: NoInfer<StateSlice>, b: NoInfer<StateSlice>) => boolean): StateSlice;
56
59
  export declare const useXYStoreApi: () => {
57
60
  getState: () => ReactFlowState<Types.Node, {
58
61
  id: string;
@@ -80,6 +83,8 @@ export declare const useXYStoreApi: () => {
80
83
  className?: string;
81
84
  reconnectable?: boolean | HandleType;
82
85
  focusable?: boolean;
86
+ ariaRole?: AriaRole;
87
+ domAttributes?: Omit< SVGAttributes<SVGGElement>, "id" | "style" | "className" | "role" | "aria-label">;
83
88
  type: "relationship";
84
89
  data: {
85
90
  hovered?: boolean;
@@ -89,11 +94,11 @@ export declare const useXYStoreApi: () => {
89
94
  label: string | null;
90
95
  points: NonEmptyArray<Point>;
91
96
  color: Color | undefined;
92
- head: RelationshipArrowType | undefined;
93
- line: RelationshipLineType | undefined;
94
97
  dir: "forward" | "back" | "both" | undefined;
95
98
  technology: string | undefined;
99
+ line: RelationshipLineType | undefined;
96
100
  tail: RelationshipArrowType | undefined;
101
+ head: RelationshipArrowType | undefined;
97
102
  labelBBox: BBox | null | undefined;
98
103
  navigateTo: ViewId<string> | null | undefined;
99
104
  notes: MarkdownOrString | undefined;
@@ -127,6 +132,8 @@ export declare const useXYStoreApi: () => {
127
132
  className?: string;
128
133
  reconnectable?: boolean | HandleType;
129
134
  focusable?: boolean;
135
+ ariaRole?: AriaRole;
136
+ domAttributes?: Omit< SVGAttributes<SVGGElement>, "id" | "style" | "className" | "role" | "aria-label">;
130
137
  type: "relationship";
131
138
  data: {
132
139
  hovered?: boolean;
@@ -136,11 +143,11 @@ export declare const useXYStoreApi: () => {
136
143
  label: string | null;
137
144
  points: NonEmptyArray<Point>;
138
145
  color: Color | undefined;
139
- head: RelationshipArrowType | undefined;
140
- line: RelationshipLineType | undefined;
141
146
  dir: "forward" | "back" | "both" | undefined;
142
147
  technology: string | undefined;
148
+ line: RelationshipLineType | undefined;
143
149
  tail: RelationshipArrowType | undefined;
150
+ head: RelationshipArrowType | undefined;
144
151
  labelBBox: BBox | null | undefined;
145
152
  navigateTo: ViewId<string> | null | undefined;
146
153
  notes: MarkdownOrString | undefined;
@@ -173,6 +180,8 @@ export declare const useXYStoreApi: () => {
173
180
  className?: string;
174
181
  reconnectable?: boolean | HandleType;
175
182
  focusable?: boolean;
183
+ ariaRole?: AriaRole;
184
+ domAttributes?: Omit< SVGAttributes<SVGGElement>, "id" | "style" | "className" | "role" | "aria-label">;
176
185
  type: "relationship";
177
186
  data: {
178
187
  hovered?: boolean;
@@ -182,11 +191,11 @@ export declare const useXYStoreApi: () => {
182
191
  label: string | null;
183
192
  points: NonEmptyArray<Point>;
184
193
  color: Color | undefined;
185
- head: RelationshipArrowType | undefined;
186
- line: RelationshipLineType | undefined;
187
194
  dir: "forward" | "back" | "both" | undefined;
188
195
  technology: string | undefined;
196
+ line: RelationshipLineType | undefined;
189
197
  tail: RelationshipArrowType | undefined;
198
+ head: RelationshipArrowType | undefined;
190
199
  labelBBox: BBox | null | undefined;
191
200
  navigateTo: ViewId<string> | null | undefined;
192
201
  notes: MarkdownOrString | undefined;
@@ -219,6 +228,8 @@ export declare const useXYStoreApi: () => {
219
228
  className?: string;
220
229
  reconnectable?: boolean | HandleType;
221
230
  focusable?: boolean;
231
+ ariaRole?: AriaRole;
232
+ domAttributes?: Omit< SVGAttributes<SVGGElement>, "id" | "style" | "className" | "role" | "aria-label">;
222
233
  type: "relationship";
223
234
  data: {
224
235
  hovered?: boolean;
@@ -228,11 +239,11 @@ export declare const useXYStoreApi: () => {
228
239
  label: string | null;
229
240
  points: NonEmptyArray<Point>;
230
241
  color: Color | undefined;
231
- head: RelationshipArrowType | undefined;
232
- line: RelationshipLineType | undefined;
233
242
  dir: "forward" | "back" | "both" | undefined;
234
243
  technology: string | undefined;
244
+ line: RelationshipLineType | undefined;
235
245
  tail: RelationshipArrowType | undefined;
246
+ head: RelationshipArrowType | undefined;
236
247
  labelBBox: BBox | null | undefined;
237
248
  navigateTo: ViewId<string> | null | undefined;
238
249
  notes: MarkdownOrString | undefined;
@@ -265,6 +276,8 @@ export declare const useXYStoreApi: () => {
265
276
  className?: string;
266
277
  reconnectable?: boolean | HandleType;
267
278
  focusable?: boolean;
279
+ ariaRole?: AriaRole;
280
+ domAttributes?: Omit< SVGAttributes<SVGGElement>, "id" | "style" | "className" | "role" | "aria-label">;
268
281
  type: "relationship";
269
282
  data: {
270
283
  hovered?: boolean;
@@ -274,11 +287,11 @@ export declare const useXYStoreApi: () => {
274
287
  label: string | null;
275
288
  points: NonEmptyArray<Point>;
276
289
  color: Color | undefined;
277
- head: RelationshipArrowType | undefined;
278
- line: RelationshipLineType | undefined;
279
290
  dir: "forward" | "back" | "both" | undefined;
280
291
  technology: string | undefined;
292
+ line: RelationshipLineType | undefined;
281
293
  tail: RelationshipArrowType | undefined;
294
+ head: RelationshipArrowType | undefined;
282
295
  labelBBox: BBox | null | undefined;
283
296
  navigateTo: ViewId<string> | null | undefined;
284
297
  notes: MarkdownOrString | undefined;
@@ -311,6 +324,8 @@ export declare const useXYStoreApi: () => {
311
324
  className?: string;
312
325
  reconnectable?: boolean | HandleType;
313
326
  focusable?: boolean;
327
+ ariaRole?: AriaRole;
328
+ domAttributes?: Omit< SVGAttributes<SVGGElement>, "id" | "style" | "className" | "role" | "aria-label">;
314
329
  type: "relationship";
315
330
  data: {
316
331
  hovered?: boolean;
@@ -320,11 +335,11 @@ export declare const useXYStoreApi: () => {
320
335
  label: string | null;
321
336
  points: NonEmptyArray<Point>;
322
337
  color: Color | undefined;
323
- head: RelationshipArrowType | undefined;
324
- line: RelationshipLineType | undefined;
325
338
  dir: "forward" | "back" | "both" | undefined;
326
339
  technology: string | undefined;
340
+ line: RelationshipLineType | undefined;
327
341
  tail: RelationshipArrowType | undefined;
342
+ head: RelationshipArrowType | undefined;
328
343
  labelBBox: BBox | null | undefined;
329
344
  navigateTo: ViewId<string> | null | undefined;
330
345
  notes: MarkdownOrString | undefined;
@@ -358,6 +373,8 @@ export declare const useXYStoreApi: () => {
358
373
  className?: string;
359
374
  reconnectable?: boolean | HandleType;
360
375
  focusable?: boolean;
376
+ ariaRole?: AriaRole;
377
+ domAttributes?: Omit< SVGAttributes<SVGGElement>, "id" | "style" | "className" | "role" | "aria-label">;
361
378
  type: "relationship";
362
379
  data: {
363
380
  hovered?: boolean;
@@ -367,11 +384,11 @@ export declare const useXYStoreApi: () => {
367
384
  label: string | null;
368
385
  points: NonEmptyArray<Point>;
369
386
  color: Color | undefined;
370
- head: RelationshipArrowType | undefined;
371
- line: RelationshipLineType | undefined;
372
387
  dir: "forward" | "back" | "both" | undefined;
373
388
  technology: string | undefined;
389
+ line: RelationshipLineType | undefined;
374
390
  tail: RelationshipArrowType | undefined;
391
+ head: RelationshipArrowType | undefined;
375
392
  labelBBox: BBox | null | undefined;
376
393
  navigateTo: ViewId<string> | null | undefined;
377
394
  notes: MarkdownOrString | undefined;
@@ -404,6 +421,8 @@ export declare const useXYStoreApi: () => {
404
421
  className?: string;
405
422
  reconnectable?: boolean | HandleType;
406
423
  focusable?: boolean;
424
+ ariaRole?: AriaRole;
425
+ domAttributes?: Omit< SVGAttributes<SVGGElement>, "id" | "style" | "className" | "role" | "aria-label">;
407
426
  type: "relationship";
408
427
  data: {
409
428
  hovered?: boolean;
@@ -413,11 +432,11 @@ export declare const useXYStoreApi: () => {
413
432
  label: string | null;
414
433
  points: NonEmptyArray<Point>;
415
434
  color: Color | undefined;
416
- head: RelationshipArrowType | undefined;
417
- line: RelationshipLineType | undefined;
418
435
  dir: "forward" | "back" | "both" | undefined;
419
436
  technology: string | undefined;
437
+ line: RelationshipLineType | undefined;
420
438
  tail: RelationshipArrowType | undefined;
439
+ head: RelationshipArrowType | undefined;
421
440
  labelBBox: BBox | null | undefined;
422
441
  navigateTo: ViewId<string> | null | undefined;
423
442
  notes: MarkdownOrString | undefined;
package/dist/index.d.ts CHANGED
@@ -6,5 +6,5 @@ export { Overlay, type OverlayProps, } from './overlays/overlay/Overlay';
6
6
  export { LikeC4ModelProvider, type LikeC4ModelProviderProps, } from './LikeC4ModelProvider';
7
7
  export { LikeC4ProjectsProvider, type LikeC4ProjectsProviderProps, } from './LikeC4ProjectsProvider';
8
8
  export * from './custom/hooks';
9
- export type { ChangeEvent, CustomNodes, DiagramNodeWithNavigate, ElementIconRenderer, LikeC4ColorScheme, LikeC4DiagramEventHandlers, LikeC4DiagramProperties, OnCanvasClick, OnChange, OnEdgeClick, OnNavigateTo, OnNodeClick, OpenSourceParams, PaddingUnit, PaddingWithUnit, WhereOperator, } from './LikeC4Diagram.props';
9
+ export type { ChangeEvent, CustomNodes, DiagramNodeWithNavigate, ElementIconRenderer, ElementIconRendererProps, LikeC4ColorScheme, LikeC4DiagramEventHandlers, LikeC4DiagramProperties, OnCanvasClick, OnChange, OnEdgeClick, OnNavigateTo, OnNodeClick, OpenSourceParams, PaddingUnit, PaddingWithUnit, WhereOperator, } from './LikeC4Diagram.props';
10
10
  export { StaticLikeC4Diagram, type StaticLikeC4DiagramProps, } from './StaticLikeC4Diagram';
package/dist/index.js CHANGED
@@ -8,11 +8,12 @@ export { StaticLikeC4Diagram } from './StaticLikeC4Diagram.js';
8
8
  export { useDiagramEventHandlers } from './context/DiagramEventHandlers.js';
9
9
  export { useEnabledFeatures } from './context/DiagramFeatures.js';
10
10
  export { useCurrentViewId } from './hooks/useCurrentViewId.js';
11
- export { useDiagram, useDiagramContext } from './hooks/useDiagram.js';
11
+ export { useDiagram, useDiagramContext, useOnDiagramEvent } from './hooks/useDiagram.js';
12
12
  export { useDiagramActorRef } from './hooks/safeContext.js';
13
13
  export { useXYFlow, useXYInternalNode, useXYStore, useXYStoreApi } from './hooks/useXYFlow.js';
14
14
  export { useCurrentViewModel } from './likec4model/useCurrentViewModel.js';
15
15
  export { useLikeC4Model, useLikeC4Specification, useLikeC4ViewModel } from './likec4model/useLikeC4Model.js';
16
+ export { useHasProjects, useLikeC4ProjectId, useLikeC4Projects, useLikeC4ProjectsContext } from './likec4model/useLikeC4Project.js';
16
17
  export { useMantinePortalProps } from './hooks/useMantinePortalProps.js';
17
18
  export { useSetState } from './hooks/useSetState.js';
18
19
  export { useUpdateEffect } from './hooks/useUpdateEffect.js';
@@ -5,6 +5,7 @@ import { useSearchActorRef } from '../hooks/useSearchActor.js';
5
5
  import { EnsureCurrentViewModel } from '../likec4model/LikeC4ModelContext.js';
6
6
  import { Overlays } from '../overlays/Overlays.js';
7
7
  import { Search } from '../search/Search.js';
8
+ import { RelationshipPopover } from './relationship-popover/RelationshipPopover.js';
8
9
  import { useEnabledFeatures } from '../context/DiagramFeatures.js';
9
10
  import { NavigationPanel } from '../navigationpanel/NavigationPanel.js';
10
11
  import { Controls } from './ui/controls/Controls.js';
@@ -18,7 +19,8 @@ const DiagramUI = memo(() => {
18
19
  enableViewTitle,
19
20
  enableNotations,
20
21
  enableDynamicViewWalkthrough,
21
- enableSearch
22
+ enableSearch,
23
+ enableRelationshipDetails
22
24
  } = useEnabledFeatures();
23
25
  const overlaysActorRef = useOverlaysActorRef();
24
26
  const searchActorRef = useSearchActorRef();
@@ -30,7 +32,8 @@ const DiagramUI = memo(() => {
30
32
  enableViewTitle && /* @__PURE__ */ jsx(DiagramTitlePanel, {}),
31
33
  enableDynamicViewWalkthrough && /* @__PURE__ */ jsx(DynamicViewWalkthrough, {})
32
34
  ] }),
33
- enableSearch && searchActorRef && /* @__PURE__ */ jsx(Search, { searchActorRef })
35
+ enableSearch && searchActorRef && /* @__PURE__ */ jsx(Search, { searchActorRef }),
36
+ enableRelationshipDetails && /* @__PURE__ */ jsx(RelationshipPopover, {})
34
37
  ] });
35
38
  });
36
39
  DiagramUI.displayName = "DiagramUI";
@@ -84,9 +84,9 @@ function LikeC4DiagramXYFlow({
84
84
  return {
85
85
  element: renderNodes?.element ?? BuiltinNodes.element,
86
86
  deployment: renderNodes?.deployment ?? BuiltinNodes.deployment,
87
- "compound-element": renderNodes?.compoundElement ?? BuiltinNodes["compound-element"],
88
- "compound-deployment": renderNodes?.compoundDeployment ?? BuiltinNodes["compound-deployment"],
89
- "view-group": renderNodes?.viewGroup ?? BuiltinNodes["view-group"]
87
+ "compound-element": renderNodes?.compoundElement ?? BuiltinNodes.compoundElement,
88
+ "compound-deployment": renderNodes?.compoundDeployment ?? BuiltinNodes.compoundDeployment,
89
+ "view-group": renderNodes?.viewGroup ?? BuiltinNodes.viewGroup
90
90
  };
91
91
  },
92
92
  [renderNodes],
@@ -145,16 +145,16 @@ function LikeC4DiagramXYFlow({
145
145
  diagram.send({ type: "xyflow.nodeMouseLeave", node });
146
146
  }
147
147
  }),
148
- onEdgeMouseEnter: useCallbackRef((_event, edge) => {
149
- _event.stopPropagation();
148
+ onEdgeMouseEnter: useCallbackRef((event, edge) => {
149
+ event.stopPropagation();
150
150
  if (!edge.data.hovered) {
151
- diagram.send({ type: "xyflow.edgeMouseEnter", edge });
151
+ diagram.send({ type: "xyflow.edgeMouseEnter", edge, event });
152
152
  }
153
153
  }),
154
- onEdgeMouseLeave: useCallbackRef((_event, edge) => {
155
- _event.stopPropagation();
154
+ onEdgeMouseLeave: useCallbackRef((event, edge) => {
155
+ event.stopPropagation();
156
156
  if (edge.data.hovered) {
157
- diagram.send({ type: "xyflow.edgeMouseLeave", edge });
157
+ diagram.send({ type: "xyflow.edgeMouseLeave", edge, event });
158
158
  }
159
159
  }),
160
160
  ...props.pannable && {
@@ -1,4 +1,4 @@
1
- import { EdgeId, NonEmptyArray, Point, Color, RelationshipArrowType, RelationshipLineType, BBox, ViewId, MarkdownOrString } from '@likec4/core';
1
+ import { EdgeId, NonEmptyArray, Point, Color, RelationshipLineType, RelationshipArrowType, BBox, ViewId, MarkdownOrString } from '@likec4/core';
2
2
  import { XYPosition } from '@xyflow/react';
3
3
  import { FunctionComponent, CSSProperties, ReactNode } from 'react';
4
4
  import { Position } from '@xyflow/system';
@@ -38,11 +38,11 @@ export declare const RelationshipEdge: FunctionComponent<{
38
38
  label: string | null;
39
39
  points: NonEmptyArray<Point>;
40
40
  color: Color | undefined;
41
- head: RelationshipArrowType | undefined;
42
- line: RelationshipLineType | undefined;
43
41
  dir: "forward" | "back" | "both" | undefined;
44
42
  technology: string | undefined;
43
+ line: RelationshipLineType | undefined;
45
44
  tail: RelationshipArrowType | undefined;
45
+ head: RelationshipArrowType | undefined;
46
46
  labelBBox: BBox | null | undefined;
47
47
  navigateTo: ViewId<string> | null | undefined;
48
48
  notes: MarkdownOrString | undefined;