@likec4/diagram 1.39.5 → 1.41.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 (140) hide show
  1. package/bundle/{chunk-CW_KClZe.js → chunk-FGcODVxo.js} +1059 -1023
  2. package/bundle/custom.js +61 -60
  3. package/bundle/index.js +2932 -764
  4. package/dist/LikeC4Diagram.d.ts +1 -1
  5. package/dist/LikeC4Diagram.js +7 -4
  6. package/dist/LikeC4Diagram.props.d.ts +6 -1
  7. package/dist/base/const.d.ts +9 -0
  8. package/dist/base/const.js +10 -1
  9. package/dist/base/index.d.ts +1 -0
  10. package/dist/base/primitives/MarkdownBlock.js +2 -0
  11. package/dist/base/primitives/edge/EdgeLabel.js +2 -1
  12. package/dist/base/primitives/edge/EdgeLabelContainer.js +10 -4
  13. package/dist/base/primitives/edge/EdgePath.js +17 -8
  14. package/dist/base/primitives/edge/edge.css.d.ts +0 -1
  15. package/dist/base/primitives/edge/edge.css.js +6 -14
  16. package/dist/base/primitives/element/ElementActionButtons.js +1 -3
  17. package/dist/base/primitives/element/ElementNodeContainer.d.ts +0 -6
  18. package/dist/base/primitives/element/ElementNodeContainer.js +3 -26
  19. package/dist/base/primitives/element/ElementTitle.js +2 -2
  20. package/dist/base/types.d.ts +3 -3
  21. package/dist/bundle/LikeC4View.js +4 -12
  22. package/dist/bundle/LikeC4View.props.d.ts +12 -3
  23. package/dist/bundle/custom.js +1 -1
  24. package/dist/components/Link.js +28 -20
  25. package/dist/custom/customNodes.d.ts +6 -0
  26. package/dist/custom/customNodes.js +2 -1
  27. package/dist/custom/index.js +1 -1
  28. package/dist/hooks/useDiagram.d.ts +5 -1
  29. package/dist/hooks/useDiagram.js +3 -0
  30. package/dist/hooks/useXYFlow.d.ts +4 -439
  31. package/dist/likec4diagram/DiagramUI.js +1 -1
  32. package/dist/likec4diagram/DiagramXYFlow.js +8 -4
  33. package/dist/likec4diagram/convert-to-xyflow.d.ts +14 -0
  34. package/dist/likec4diagram/convert-to-xyflow.js +29 -0
  35. package/dist/likec4diagram/custom/edges/RelationshipEdge.d.ts +4 -4
  36. package/dist/likec4diagram/custom/edges/RelationshipEdge.js +0 -1
  37. package/dist/likec4diagram/custom/edges/SequenceStepEdge.d.ts +3 -0
  38. package/dist/likec4diagram/custom/edges/SequenceStepEdge.js +71 -0
  39. package/dist/likec4diagram/custom/index.js +7 -2
  40. package/dist/likec4diagram/custom/nodes/ElementActions.d.ts +2 -1
  41. package/dist/likec4diagram/custom/nodes/SequenceActorNode.d.ts +4 -0
  42. package/dist/likec4diagram/custom/nodes/SequenceActorNode.js +157 -0
  43. package/dist/likec4diagram/custom/nodes/index.d.ts +1 -0
  44. package/dist/likec4diagram/custom/nodes/nodes.d.ts +1 -2
  45. package/dist/likec4diagram/relationship-popover/RelationshipPopover.js +31 -27
  46. package/dist/likec4diagram/types.d.ts +41 -7
  47. package/dist/likec4diagram/xyflow-diagram/diagram-view.d.ts +11 -0
  48. package/dist/likec4diagram/{useViewToNodesEdges.js → xyflow-diagram/diagram-view.js} +4 -13
  49. package/dist/likec4diagram/xyflow-sequence/_types.d.ts +41 -0
  50. package/dist/likec4diagram/xyflow-sequence/const.d.ts +17 -0
  51. package/dist/likec4diagram/xyflow-sequence/const.js +16 -0
  52. package/dist/likec4diagram/xyflow-sequence/layouter.d.ts +46 -0
  53. package/dist/likec4diagram/xyflow-sequence/layouter.js +408 -0
  54. package/dist/likec4diagram/xyflow-sequence/sequence-view.d.ts +7 -0
  55. package/dist/likec4diagram/xyflow-sequence/sequence-view.js +273 -0
  56. package/dist/likec4diagram/xyflow-sequence/utils.d.ts +14 -0
  57. package/dist/likec4diagram/xyflow-sequence/utils.js +92 -0
  58. package/dist/navigationpanel/NavigationPanelControls.js +2 -2
  59. package/dist/navigationpanel/controls/ViewDetailsCard.js +27 -12
  60. package/dist/navigationpanel/dropdown/ProjectsMenu.js +53 -44
  61. package/dist/navigationpanel/walkthrough/ActiveWalkthroughControls.d.ts +1 -2
  62. package/dist/navigationpanel/walkthrough/ActiveWalkthroughControls.js +10 -41
  63. package/dist/navigationpanel/walkthrough/DynamicViewControls.d.ts +292 -0
  64. package/dist/navigationpanel/walkthrough/DynamicViewControls.js +119 -0
  65. package/dist/navigationpanel/walkthrough/index.d.ts +2 -1
  66. package/dist/overlays/element-details/ElementDetailsCard.css.js +7 -1
  67. package/dist/overlays/element-details/ElementDetailsCard.js +17 -19
  68. package/dist/overlays/relationship-details/RelationshipDetails.js +4 -1
  69. package/dist/overlays/relationship-details/layout.d.ts +3 -2
  70. package/dist/overlays/relationship-details/layout.js +1 -2
  71. package/dist/overlays/relationships-browser/RelationshipsBrowser.js +2 -1
  72. package/dist/overlays/relationships-browser/layout.js +1 -1
  73. package/dist/search/components/ElementsColumn.js +1 -1
  74. package/dist/state/DiagramActorProvider.d.ts +3 -2
  75. package/dist/state/DiagramActorProvider.js +40 -41
  76. package/dist/state/assign.js +11 -4
  77. package/dist/state/diagram-machine.d.ts +224 -194
  78. package/dist/state/diagram-machine.js +170 -63
  79. package/dist/state/utils.d.ts +7 -1
  80. package/dist/state/utils.js +67 -7
  81. package/dist/styles-min.css +1 -1
  82. package/dist/styles.css +1 -1
  83. package/dist/styles.css2.js +1 -1
  84. package/package.json +8 -7
  85. package/panda.buildinfo.json +45 -24
  86. package/src/LikeC4Diagram.props.ts +14 -1
  87. package/src/LikeC4Diagram.tsx +7 -4
  88. package/src/base/const.ts +12 -0
  89. package/src/base/index.ts +2 -0
  90. package/src/base/primitives/MarkdownBlock.tsx +2 -0
  91. package/src/base/primitives/edge/EdgeLabel.tsx +23 -19
  92. package/src/base/primitives/edge/EdgeLabelContainer.tsx +12 -7
  93. package/src/base/primitives/edge/EdgePath.tsx +25 -14
  94. package/src/base/primitives/edge/edge.css.ts +5 -14
  95. package/src/base/primitives/element/ElementActionButtons.tsx +1 -3
  96. package/src/base/primitives/element/ElementNodeContainer.tsx +3 -30
  97. package/src/base/primitives/element/ElementTitle.tsx +2 -3
  98. package/src/base/types.ts +7 -5
  99. package/src/bundle/LikeC4View.props.ts +14 -3
  100. package/src/bundle/LikeC4View.tsx +4 -14
  101. package/src/bundle/ReactLikeC4.tsx +1 -2
  102. package/src/components/Link.tsx +21 -18
  103. package/src/custom/customNodes.ts +7 -0
  104. package/src/hooks/useDiagram.ts +10 -0
  105. package/src/likec4diagram/DiagramUI.tsx +1 -1
  106. package/src/likec4diagram/DiagramXYFlow.tsx +10 -5
  107. package/src/likec4diagram/convert-to-xyflow.ts +45 -0
  108. package/src/likec4diagram/custom/edges/RelationshipEdge.tsx +0 -1
  109. package/src/likec4diagram/custom/edges/SequenceStepEdge.tsx +65 -0
  110. package/src/likec4diagram/custom/index.ts +7 -1
  111. package/src/likec4diagram/custom/nodes/ElementActions.tsx +4 -2
  112. package/src/likec4diagram/custom/nodes/SequenceActorNode.tsx +175 -0
  113. package/src/likec4diagram/custom/nodes/index.ts +1 -0
  114. package/src/likec4diagram/custom/nodes/nodes.tsx +1 -1
  115. package/src/likec4diagram/relationship-popover/RelationshipPopover.tsx +36 -30
  116. package/src/likec4diagram/types.ts +96 -13
  117. package/src/likec4diagram/{useViewToNodesEdges.ts → xyflow-diagram/diagram-view.ts} +7 -28
  118. package/src/likec4diagram/xyflow-sequence/_types.ts +45 -0
  119. package/src/likec4diagram/xyflow-sequence/const.ts +37 -0
  120. package/src/likec4diagram/xyflow-sequence/layouter.ts +567 -0
  121. package/src/likec4diagram/xyflow-sequence/sequence-view.ts +337 -0
  122. package/src/likec4diagram/xyflow-sequence/utils.ts +112 -0
  123. package/src/navigationpanel/NavigationPanelControls.tsx +2 -2
  124. package/src/navigationpanel/controls/ViewDetailsCard.tsx +29 -12
  125. package/src/navigationpanel/dropdown/ProjectsMenu.tsx +5 -1
  126. package/src/navigationpanel/walkthrough/ActiveWalkthroughControls.tsx +5 -40
  127. package/src/navigationpanel/walkthrough/DynamicViewControls.tsx +125 -0
  128. package/src/navigationpanel/walkthrough/index.tsx +2 -1
  129. package/src/overlays/element-details/ElementDetailsCard.css.ts +7 -1
  130. package/src/overlays/element-details/ElementDetailsCard.tsx +24 -25
  131. package/src/overlays/relationship-details/RelationshipDetails.tsx +5 -2
  132. package/src/overlays/relationship-details/layout.ts +4 -3
  133. package/src/overlays/relationships-browser/RelationshipsBrowser.tsx +2 -1
  134. package/src/overlays/relationships-browser/layout.ts +1 -1
  135. package/src/search/components/ElementsColumn.tsx +1 -1
  136. package/src/state/DiagramActorProvider.tsx +46 -51
  137. package/src/state/assign.ts +18 -5
  138. package/src/state/diagram-machine.ts +207 -75
  139. package/src/state/utils.ts +81 -7
  140. package/dist/likec4diagram/useViewToNodesEdges.d.ts +0 -12
@@ -0,0 +1,71 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { getSmoothStepPath } from '@xyflow/system';
3
+ import { useDiagram } from '../../../hooks/useDiagram.js';
4
+ import { EdgeContainer } from '../../../base/primitives/edge/EdgeContainer.js';
5
+ import { EdgePath } from '../../../base/primitives/edge/EdgePath.js';
6
+ import { EdgeLabelContainer } from '../../../base/primitives/edge/EdgeLabelContainer.js';
7
+ import { EdgeLabel } from '../../../base/primitives/edge/EdgeLabel.js';
8
+ import { EdgeActionButton } from '../../../base/primitives/edge/EdgeActionButton.js';
9
+
10
+ const LABEL_OFFSET = 16;
11
+ function SequenceStepEdge(props) {
12
+ const diagram = useDiagram();
13
+ const { navigateTo } = props.data;
14
+ const isSelfLoop = props.source === props.target;
15
+ const isBack = props.sourceX > props.targetX;
16
+ const [path] = getSmoothStepPath({
17
+ sourceX: props.sourceX,
18
+ sourceY: props.sourceY,
19
+ sourcePosition: props.sourcePosition,
20
+ targetX: props.targetX,
21
+ targetY: props.targetY,
22
+ targetPosition: props.targetPosition,
23
+ ...isSelfLoop && {
24
+ offset: 30,
25
+ borderRadius: 16
26
+ }
27
+ });
28
+ let labelX = props.sourceX;
29
+ switch (true) {
30
+ case isSelfLoop:
31
+ labelX = props.sourceX + 24 + LABEL_OFFSET;
32
+ break;
33
+ case isBack:
34
+ labelX = props.sourceX - LABEL_OFFSET;
35
+ break;
36
+ default:
37
+ labelX = props.sourceX + LABEL_OFFSET;
38
+ break;
39
+ }
40
+ return /* @__PURE__ */ jsxs(EdgeContainer, { ...props, children: [
41
+ /* @__PURE__ */ jsx(
42
+ EdgePath,
43
+ {
44
+ edgeProps: props,
45
+ svgPath: path
46
+ }
47
+ ),
48
+ /* @__PURE__ */ jsx(
49
+ EdgeLabelContainer,
50
+ {
51
+ edgeProps: props,
52
+ labelPosition: {
53
+ x: labelX,
54
+ y: props.sourceY + (!isSelfLoop ? LABEL_OFFSET : 0),
55
+ translate: isBack ? "translate(-100%, 0)" : void 0
56
+ },
57
+ children: /* @__PURE__ */ jsx(EdgeLabel, { edgeProps: props, children: navigateTo && /* @__PURE__ */ jsx(
58
+ EdgeActionButton,
59
+ {
60
+ onClick: (e) => {
61
+ e.stopPropagation();
62
+ diagram.navigateTo(navigateTo);
63
+ }
64
+ }
65
+ ) })
66
+ }
67
+ )
68
+ ] });
69
+ }
70
+
71
+ export { SequenceStepEdge };
@@ -1,4 +1,7 @@
1
1
  import { RelationshipEdge } from './edges/RelationshipEdge.js';
2
+ import { SequenceStepEdge } from './edges/SequenceStepEdge.js';
3
+ import { SequenceActorNode } from './nodes/SequenceActorNode.js';
4
+ export { SequenceParallelArea } from './nodes/SequenceActorNode.js';
2
5
  import { ViewGroupNode, CompoundDeploymentNode, CompoundElementNode, DeploymentNode, ElementNode } from './nodes/nodes.js';
3
6
 
4
7
  const BuiltinNodes = {
@@ -6,10 +9,12 @@ const BuiltinNodes = {
6
9
  deployment: DeploymentNode,
7
10
  compoundElement: CompoundElementNode,
8
11
  compoundDeployment: CompoundDeploymentNode,
9
- viewGroup: ViewGroupNode
12
+ viewGroup: ViewGroupNode,
13
+ sequenceActor: SequenceActorNode
10
14
  };
11
15
  const edgeTypes = {
12
- relationship: RelationshipEdge
16
+ relationship: RelationshipEdge,
17
+ "seq-step": SequenceStepEdge
13
18
  };
14
19
 
15
20
  export { BuiltinNodes, edgeTypes };
@@ -1,6 +1,7 @@
1
1
  import { ElementActionButtons } from '../../../base/primitives';
2
2
  import { NodeProps } from '../../../base/types';
3
3
  import { Types } from '../../types';
4
+ type RequiredData = Pick<Types.ElementNodeData, 'modelFqn' | 'navigateTo'>;
4
5
  type WithExtraButtons = {
5
6
  /**
6
7
  * Add extra action buttons
@@ -23,7 +24,7 @@ type WithExtraButtons = {
23
24
  */
24
25
  extraButtons?: ElementActionButtons.Item[];
25
26
  };
26
- export type ElementActionsProps = NodeProps<Types.ElementNodeData> & WithExtraButtons;
27
+ export type ElementActionsProps = NodeProps<RequiredData> & WithExtraButtons;
27
28
  export declare const ElementActions: ({ extraButtons, ...props }: ElementActionsProps) => import("react/jsx-runtime").JSX.Element;
28
29
  export type DeploymentElementActionsProps = NodeProps<Types.DeploymentElementNodeData> & WithExtraButtons;
29
30
  export declare const DeploymentElementActions: ({ extraButtons, ...props }: DeploymentElementActionsProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,4 @@
1
+ import { NodeProps } from '@xyflow/react';
2
+ import { Types } from '../../types';
3
+ export declare function SequenceActorNode(props: NodeProps<Types.SequenceActorNode>): import("react/jsx-runtime").JSX.Element;
4
+ export declare function SequenceParallelArea(props: NodeProps<Types.SequenceActorNode>): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,157 @@
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { defaultTheme } from '@likec4/core';
3
+ import { css } from '@likec4/styles/css';
4
+ import { Box } from '@likec4/styles/jsx';
5
+ import { Handle } from '@xyflow/react';
6
+ import { Position } from '@xyflow/system';
7
+ import { ElementActions } from './ElementActions.js';
8
+ import { ElementDetailsButtonWithHandler } from './nodes.js';
9
+ import { ElementNodeContainer } from '../../../base/primitives/element/ElementNodeContainer.js';
10
+ import { ElementShape } from '../../../base/primitives/element/ElementShape.js';
11
+ import { ElementTitle } from '../../../base/primitives/element/ElementTitle.js';
12
+
13
+ const positionMap = {
14
+ left: Position.Left,
15
+ right: Position.Right,
16
+ top: Position.Top,
17
+ bottom: Position.Bottom
18
+ };
19
+ const ActorStepPort = ({
20
+ data,
21
+ port: p
22
+ }) => {
23
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
24
+ /* @__PURE__ */ jsx(
25
+ Box,
26
+ {
27
+ "data-likec4-color": data.color,
28
+ className: css({
29
+ position: "absolute",
30
+ backgroundColor: "var(--likec4-palette-fill)",
31
+ rounded: "xs",
32
+ width: {
33
+ base: "5px",
34
+ _whenHovered: "7px",
35
+ _whenSelected: "7px"
36
+ },
37
+ // pointerEvents: 'none',
38
+ transition: "fast",
39
+ translateX: "-1/2",
40
+ translateY: "-1/2",
41
+ translate: "auto"
42
+ // transform: 'translate',
43
+ }),
44
+ style: {
45
+ top: p.cy,
46
+ left: p.cx,
47
+ height: p.height
48
+ // transform: p.type === 'source' ? 'translate(-50%, -16px)' : 'translate(-50%, -50%)',
49
+ // transform: 'translate(-50%, -50%)',
50
+ // zIndex: p.type === 'source' ? 1 : 0,
51
+ }
52
+ }
53
+ ),
54
+ /* @__PURE__ */ jsx(
55
+ Handle,
56
+ {
57
+ id: p.id,
58
+ type: p.type,
59
+ position: positionMap[p.position],
60
+ style: {
61
+ top: p.cy - 3,
62
+ left: p.cx - 3,
63
+ width: 6,
64
+ height: 6,
65
+ right: "unset",
66
+ bottom: "unset",
67
+ visibility: "hidden",
68
+ transform: p.position === "left" ? "translate(-150%, 0)" : "translate(100%, 0)"
69
+ }
70
+ }
71
+ )
72
+ ] });
73
+ };
74
+ function SequenceActorNode(props) {
75
+ const data = props.data;
76
+ const {
77
+ positionAbsoluteY,
78
+ data: {
79
+ viewHeight,
80
+ hovered: isHovered = false,
81
+ ports
82
+ }
83
+ } = props;
84
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
85
+ /* @__PURE__ */ jsx(
86
+ Box,
87
+ {
88
+ className: css({
89
+ position: "absolute",
90
+ rounded: "xs",
91
+ top: "1",
92
+ pointerEvents: "none",
93
+ transition: "fast",
94
+ translateX: "-1/2",
95
+ translate: "auto"
96
+ // transform: 'translate',
97
+ }),
98
+ style: {
99
+ // position: 'absolute',
100
+ backgroundColor: defaultTheme.elements.gray.fill,
101
+ opacity: isHovered ? 0.5 : 0.4,
102
+ left: "50%",
103
+ width: isHovered ? 3 : 2,
104
+ height: viewHeight - positionAbsoluteY,
105
+ zIndex: -1,
106
+ pointerEvents: "none"
107
+ // top: p.y,
108
+ // left: p.width / 2,
109
+ // height: p.type === 'source' ? 48 : 32,
110
+ // transform: p.type === 'source' ? 'translate(-50%, -16px)' : 'translate(-50%, -50%)',
111
+ // transform: 'translate(-50%, -50%)',
112
+ // zIndex: p.type === 'source' ? 1 : 0,
113
+ }
114
+ }
115
+ ),
116
+ /* @__PURE__ */ jsxs(ElementNodeContainer, { nodeProps: props, children: [
117
+ /* @__PURE__ */ jsx(ElementShape, { ...props }),
118
+ /* @__PURE__ */ jsx(ElementTitle, { ...props }),
119
+ data.modelFqn && /* @__PURE__ */ jsxs(Fragment, { children: [
120
+ /* @__PURE__ */ jsx(ElementActions, { ...props, data }),
121
+ /* @__PURE__ */ jsx(ElementDetailsButtonWithHandler, { ...props, data })
122
+ ] })
123
+ ] }),
124
+ ports.map((p) => /* @__PURE__ */ jsx(ActorStepPort, { port: p, data: props.data }, p.id))
125
+ ] });
126
+ }
127
+ function SequenceParallelArea(props) {
128
+ return /* @__PURE__ */ jsx(
129
+ Box,
130
+ {
131
+ "data-likec4-color": props.data.color,
132
+ css: {
133
+ width: "100%",
134
+ height: "100%",
135
+ border: "default",
136
+ rounded: "sm",
137
+ borderWidth: 1,
138
+ "--_color": {
139
+ base: "var(--likec4-palette-stroke)",
140
+ _dark: "[color-mix(in srgb, var(--likec4-palette-hiContrast) 40%, var(--likec4-palette-fill))]"
141
+ },
142
+ borderColor: "[var(--_color)/30]",
143
+ backgroundColor: "var(--likec4-palette-fill)/15",
144
+ pointerEvents: "none",
145
+ paddingLeft: "2",
146
+ paddingTop: "0.5",
147
+ fontSize: "xs",
148
+ fontWeight: "bold",
149
+ letterSpacing: ".75px",
150
+ color: "[var(--_color)/75]"
151
+ },
152
+ children: "PARALLEL"
153
+ }
154
+ );
155
+ }
156
+
157
+ export { SequenceActorNode, SequenceParallelArea };
@@ -1,6 +1,7 @@
1
1
  export { CompoundActions } from './CompoundActions';
2
2
  export { DeploymentElementActions, ElementActions } from './ElementActions';
3
3
  export { CompoundDeploymentNode, CompoundDetailsButtonWithHandler, CompoundElementNode, DeploymentNode, ElementDetailsButtonWithHandler, ElementNode, ViewGroupNode, } from './nodes';
4
+ export { SequenceActorNode, SequenceParallelArea } from './SequenceActorNode';
4
5
  export * from './CompoundActions';
5
6
  export * from './ElementActions';
6
7
  export * from './toolbar/CompoundToolbar';
@@ -1,7 +1,7 @@
1
1
  import { NodeProps } from '../../../base';
2
2
  import { CustomNodes as CustomNodesType } from '../../../custom/customNodes';
3
3
  import { Types } from '../../types';
4
- type CustomNodes = Required<CustomNodesType>;
4
+ export type CustomNodes = Required<CustomNodesType>;
5
5
  export declare function ElementDetailsButtonWithHandler(props: NodeProps<Types.ElementNodeData | Types.DeploymentElementNodeData>): import("react/jsx-runtime").JSX.Element | null;
6
6
  export declare function CompoundDetailsButtonWithHandler(props: NodeProps<Types.CompoundElementNodeData | Types.CompoundDeploymentNodeData>): import("react/jsx-runtime").JSX.Element | null;
7
7
  export declare const ElementNode: CustomNodes['element'];
@@ -9,4 +9,3 @@ export declare const DeploymentNode: CustomNodes['deployment'];
9
9
  export declare const CompoundElementNode: CustomNodes['compoundElement'];
10
10
  export declare const CompoundDeploymentNode: CustomNodes['compoundDeployment'];
11
11
  export declare const ViewGroupNode: CustomNodes['viewGroup'];
12
- export {};
@@ -8,7 +8,7 @@ import { Portal, ScrollAreaAutosize, Button, Divider, TooltipGroup, Tooltip as T
8
8
  import { useActorRef, useSelector } from '@xstate/react';
9
9
  import { shallowEqual } from 'fast-equals';
10
10
  import { memo, useEffect, useCallback, useRef, useState, Fragment as Fragment$1, forwardRef } from 'react';
11
- import { pipe, map, filter, isTruthy, partition, clamp } from 'remeda';
11
+ import { isEmpty, pipe, map, filter, isTruthy, partition, clamp } from 'remeda';
12
12
  import { Link } from '../../components/Link.js';
13
13
  import { useDiagramEventHandlers } from '../../context/DiagramEventHandlers.js';
14
14
  import { useEnabledFeatures } from '../../context/DiagramFeatures.js';
@@ -41,6 +41,7 @@ function selectDiagramContext(c) {
41
41
  };
42
42
  }
43
43
  const RelationshipPopover = memo(() => {
44
+ const likec4model = useLikeC4Model();
44
45
  const actorRef = useActorRef(RelationshipPopoverActorLogic);
45
46
  const diagram = useDiagram();
46
47
  const { viewId, selected } = useDiagramContext(selectDiagramContext);
@@ -101,13 +102,39 @@ const RelationshipPopover = memo(() => {
101
102
  shallowEqual,
102
103
  [openedEdgeId]
103
104
  );
104
- if (!diagramEdge || !sourceNode || !targetNode) {
105
+ if (!diagramEdge || !sourceNode || !targetNode || isEmpty(diagramEdge.relations)) {
106
+ return null;
107
+ }
108
+ const [direct, nested] = pipe(
109
+ diagramEdge.relations,
110
+ map((id) => {
111
+ try {
112
+ return likec4model.relationship(id);
113
+ } catch (e) {
114
+ console.error(
115
+ `View is cached and likec4model missing relationship ${id} from ${sourceNode.id} -> ${targetNode.id}`,
116
+ e
117
+ );
118
+ return null;
119
+ }
120
+ }),
121
+ filter(isTruthy),
122
+ partition((r) => r.source.id === sourceNode.id && r.target.id === targetNode.id)
123
+ );
124
+ if (direct.length === 0 && nested.length === 0) {
125
+ console.warn("No relationships found diagram edge", {
126
+ diagramEdge,
127
+ sourceNode,
128
+ targetNode
129
+ });
105
130
  return null;
106
131
  }
107
132
  return /* @__PURE__ */ jsx(
108
133
  RelationshipPopoverInternal,
109
134
  {
110
135
  viewId,
136
+ direct,
137
+ nested,
111
138
  diagramEdge,
112
139
  sourceNode,
113
140
  targetNode,
@@ -123,6 +150,8 @@ const POPOVER_PADDING = 8;
123
150
  const RelationshipPopoverInternal = ({
124
151
  viewId,
125
152
  diagramEdge,
153
+ direct,
154
+ nested,
126
155
  sourceNode,
127
156
  targetNode,
128
157
  onMouseEnter,
@@ -194,32 +223,7 @@ const RelationshipPopoverInternal = ({
194
223
  cleanup();
195
224
  };
196
225
  }, [referenceEl]);
197
- const likec4model = useLikeC4Model();
198
226
  const diagram = useDiagram();
199
- const [direct, nested] = pipe(
200
- diagramEdge.relations,
201
- map((id) => {
202
- try {
203
- return likec4model.relationship(id);
204
- } catch (e) {
205
- console.error(
206
- `View is cached and likec4model missing relationship ${id} from ${sourceNode.id} -> ${targetNode.id}`,
207
- e
208
- );
209
- return null;
210
- }
211
- }),
212
- filter(isTruthy),
213
- partition((r) => r.source.id === sourceNode.id && r.target.id === targetNode.id)
214
- );
215
- if (direct.length === 0 && nested.length === 0) {
216
- console.error("No relationships found diagram edge", {
217
- diagramEdge,
218
- sourceNode,
219
- targetNode
220
- });
221
- return null;
222
- }
223
227
  const navigateTo = enableNavigateTo ? (viewId2) => {
224
228
  diagram.navigateTo(viewId2);
225
229
  } : void 0;
@@ -1,4 +1,4 @@
1
- import { DeploymentFqn, DiagramEdge, DiagramNode, Fqn, IconUrl, RichTextOrEmpty, ViewId } from '@likec4/core/types';
1
+ import { BBox, DeploymentFqn, DiagramEdge, DiagramNode, ExclusiveUnion, Fqn, IconUrl, RichTextOrEmpty, ViewId } from '@likec4/core/types';
2
2
  import { XYPosition } from '@xyflow/system';
3
3
  import { OptionalKeysOf, Simplify } from 'type-fest';
4
4
  import { Base, ReactFlowEdge, ReactFlowNode } from '../base/types';
@@ -20,14 +20,14 @@ export declare namespace Types {
20
20
  /**
21
21
  * Represents element from logical model
22
22
  */
23
- type ElementNodeData = LeafNodeData & {
23
+ type ElementNodeData = Simplify<LeafNodeData & {
24
24
  modelFqn: Fqn;
25
25
  deploymentFqn?: never;
26
26
  /**
27
27
  * If set - this node has navigation to another view and diagram has handler for this
28
28
  */
29
29
  navigateTo: ViewId | null;
30
- };
30
+ }>;
31
31
  /**
32
32
  * Represents element from deployment model
33
33
  */
@@ -36,6 +36,23 @@ export declare namespace Types {
36
36
  deploymentFqn: DeploymentFqn;
37
37
  modelFqn: Fqn | null;
38
38
  };
39
+ type SequenceActorNodePort = {
40
+ id: string;
41
+ cx: number;
42
+ cy: number;
43
+ height: number;
44
+ type: 'target' | 'source';
45
+ position: 'left' | 'right' | 'top' | 'bottom';
46
+ };
47
+ type SequenceActorNodeData = Simplify<LeafNodeData & {
48
+ navigateTo: ViewId | null;
49
+ modelFqn: Fqn | null;
50
+ ports: Array<SequenceActorNodePort>;
51
+ viewHeight: number;
52
+ }>;
53
+ type SequenceParallelAreaData = Simplify<LeafNodeData & {
54
+ parallelPrefix: string;
55
+ }>;
39
56
  type CompoundNodeData = Base.NodeData & NonOptional<Pick<DiagramNode, 'id' | 'title' | 'color' | 'shape' | 'style' | 'tags' | 'position'>> & {
40
57
  /**
41
58
  * View this node belongs to
@@ -68,18 +85,35 @@ export declare namespace Types {
68
85
  };
69
86
  type ElementNode = ReactFlowNode<ElementNodeData, 'element'>;
70
87
  type DeploymentElementNode = ReactFlowNode<DeploymentElementNodeData, 'deployment'>;
88
+ type SequenceActorNode = ReactFlowNode<SequenceActorNodeData, 'seq-actor'>;
89
+ type SequenceParallelArea = ReactFlowNode<SequenceParallelAreaData, 'seq-parallel'>;
71
90
  type CompoundElementNode = ReactFlowNode<CompoundElementNodeData, 'compound-element'>;
72
91
  type CompoundDeploymentNode = ReactFlowNode<CompoundDeploymentNodeData, 'compound-deployment'>;
73
92
  type ViewGroupNode = ReactFlowNode<ViewGroupNodeData, 'view-group'>;
74
- type Node = ElementNode | DeploymentElementNode | CompoundElementNode | CompoundDeploymentNode | ViewGroupNode;
75
- type NodeData = Node['data'];
93
+ type Node = ElementNode | DeploymentElementNode | CompoundElementNode | CompoundDeploymentNode | ViewGroupNode | SequenceActorNode | SequenceParallelArea;
94
+ type NodeData = ExclusiveUnion<{
95
+ ElementNodeData: ElementNodeData;
96
+ DeploymentElementNodeData: DeploymentElementNodeData;
97
+ CompoundElementNodeData: CompoundElementNodeData;
98
+ CompoundDeploymentNodeData: CompoundDeploymentNodeData;
99
+ ViewGroupNodeData: ViewGroupNodeData;
100
+ SequenceActorNodeData: SequenceActorNodeData;
101
+ SequenceParallelAreaData: SequenceParallelAreaData;
102
+ }>;
76
103
  type RelationshipEdgeData = Simplify<Base.EdgeData & NonOptional<Pick<DiagramEdge, 'id' | 'label' | 'labelBBox' | 'technology' | 'points' | 'dir' | 'color' | 'line' | 'head' | 'tail' | 'navigateTo'>> & {
77
104
  notes: RichTextOrEmpty;
78
105
  labelXY: XYPosition | null;
79
106
  controlPoints: XYPosition[] | undefined | null;
80
107
  }>;
108
+ type SequenceStepEdgeData = Simplify<Base.EdgeData & NonOptional<Pick<DiagramEdge, 'id' | 'label' | 'technology' | 'points' | 'dir' | 'color' | 'line' | 'head' | 'tail' | 'navigateTo'>> & {
109
+ notes: RichTextOrEmpty;
110
+ labelXY: XYPosition | null;
111
+ labelBBox: BBox;
112
+ controlPoints: XYPosition[] | undefined | null;
113
+ }>;
81
114
  type RelationshipEdge = ReactFlowEdge<RelationshipEdgeData, 'relationship'>;
82
- type Edge = RelationshipEdge;
83
- type EdgeData = RelationshipEdgeData;
115
+ type SequenceStepEdge = ReactFlowEdge<SequenceStepEdgeData, 'seq-step'>;
116
+ type Edge = RelationshipEdge | SequenceStepEdge;
117
+ type EdgeData = RelationshipEdgeData | SequenceStepEdgeData;
84
118
  }
85
119
  export {};
@@ -0,0 +1,11 @@
1
+ import { BBox, DiagramView, WhereOperator } from '@likec4/core';
2
+ import { Types } from '../types';
3
+ export declare function diagramToXY(opts: {
4
+ view: Pick<DiagramView, 'id' | 'nodes' | 'edges' | 'bounds' | '_type'>;
5
+ where: WhereOperator | null;
6
+ nodesSelectable: boolean;
7
+ }): {
8
+ bounds: BBox;
9
+ xynodes: Types.Node[];
10
+ xyedges: Types.Edge[];
11
+ };
@@ -1,10 +1,8 @@
1
1
  import { Queue, whereOperatorAsPredicate, nonNullable, GroupElementKind, RichText, invariant } from '@likec4/core';
2
- import { useCustomCompareMemo } from '@react-hookz/web';
3
- import { shallowEqual, deepEqual } from 'fast-equals';
4
2
  import { pick, hasAtLeast } from 'remeda';
5
- import { ZIndexes } from '../base/const.js';
3
+ import { ZIndexes } from '../../base/const.js';
6
4
 
7
- function viewToNodesEdge(opts) {
5
+ function diagramToXY(opts) {
8
6
  const {
9
7
  view,
10
8
  nodesSelectable: selectable
@@ -220,17 +218,10 @@ function viewToNodesEdge(opts) {
220
218
  });
221
219
  }
222
220
  return {
221
+ bounds: view.bounds,
223
222
  xynodes,
224
223
  xyedges
225
224
  };
226
225
  }
227
- const viewToNodesEdgeEqual = (a, b) => a.view.id === b.view.id && a.view._type === b.view._type && a.nodesSelectable === b.nodesSelectable && shallowEqual(a.view.nodes, b.view.nodes) && shallowEqual(a.view.edges, b.view.edges) && deepEqual(a.where, b.where);
228
- function useViewToNodesEdges(params) {
229
- return useCustomCompareMemo(
230
- () => viewToNodesEdge(params),
231
- [params],
232
- ([a], [b]) => !!a && !!b && viewToNodesEdgeEqual(a, b)
233
- );
234
- }
235
226
 
236
- export { useViewToNodesEdges };
227
+ export { diagramToXY };
@@ -0,0 +1,41 @@
1
+ import { DiagramEdge, DiagramNode, EdgeId } from '@likec4/core/types';
2
+ export type Step = {
3
+ id: EdgeId;
4
+ from: {
5
+ column: number;
6
+ row: number;
7
+ };
8
+ to: {
9
+ column: number;
10
+ row: number;
11
+ };
12
+ source: DiagramNode;
13
+ target: DiagramNode;
14
+ label: null | {
15
+ height: number;
16
+ width: number;
17
+ text: string | null;
18
+ };
19
+ isSelfLoop: boolean;
20
+ isBack: boolean;
21
+ parallelPrefix: string | null;
22
+ offset: number;
23
+ edge: DiagramEdge;
24
+ };
25
+ export type Compound = {
26
+ node: DiagramNode;
27
+ from: DiagramNode;
28
+ to: DiagramNode;
29
+ nested: Compound[];
30
+ };
31
+ export type ParallelRect = {
32
+ parallelPrefix: string;
33
+ min: {
34
+ column: number;
35
+ row: number;
36
+ };
37
+ max: {
38
+ column: number;
39
+ row: number;
40
+ };
41
+ };
@@ -0,0 +1,17 @@
1
+ export declare const ACTOR_GAP = 60;
2
+ export declare const COLUMN_GAP = 32;
3
+ export declare const MIN_ROW_HEIGHT = 80;
4
+ export declare const PORT_HEIGHT = 32;
5
+ export declare const STEP_LABEL_MARGIN = 50;
6
+ export declare const FIRST_STEP_OFFSET = 30;
7
+ export declare const CONTINUOUS_OFFSET = 22;
8
+ export declare const SeqZIndex: {
9
+ compound: number;
10
+ parallel: number;
11
+ actor: number;
12
+ step: number;
13
+ };
14
+ export declare const SeqParallelAreaColor: {
15
+ default: "gray";
16
+ active: "amber";
17
+ };
@@ -0,0 +1,16 @@
1
+ const ACTOR_GAP = 60;
2
+ const COLUMN_GAP = 32;
3
+ const MIN_ROW_HEIGHT = 80;
4
+ const PORT_HEIGHT = 32;
5
+ const STEP_LABEL_MARGIN = 50;
6
+ const FIRST_STEP_OFFSET = 30;
7
+ const CONTINUOUS_OFFSET = 22;
8
+ const SeqZIndex = {
9
+ parallel: 1,
10
+ actor: 10};
11
+ const SeqParallelAreaColor = {
12
+ default: "gray",
13
+ active: "amber"
14
+ };
15
+
16
+ export { ACTOR_GAP, COLUMN_GAP, CONTINUOUS_OFFSET, FIRST_STEP_OFFSET, MIN_ROW_HEIGHT, PORT_HEIGHT, STEP_LABEL_MARGIN, SeqParallelAreaColor, SeqZIndex };
@@ -0,0 +1,46 @@
1
+ import { BBox, DiagramNode, NonEmptyArray } from '@likec4/core/types';
2
+ import { Compound, Step } from './_types';
3
+ export declare class SequenceViewLayouter {
4
+ #private;
5
+ constructor({ actors, steps, compounds, }: {
6
+ actors: NonEmptyArray<DiagramNode>;
7
+ steps: Array<Step>;
8
+ compounds: Array<Compound>;
9
+ });
10
+ getParallelBoxes(): Array<BBox & {
11
+ parallelPrefix: string;
12
+ }>;
13
+ getActorBox(actor: DiagramNode): BBox;
14
+ getCompoundBoxes(): Array<BBox & {
15
+ node: DiagramNode;
16
+ depth: number;
17
+ }>;
18
+ getPortCenter(step: Step, type: 'source' | 'target'): {
19
+ cx: number;
20
+ cy: number;
21
+ height: number;
22
+ };
23
+ getViewBounds(): {
24
+ x: number;
25
+ y: number;
26
+ width: number;
27
+ height: number;
28
+ };
29
+ private actorBox;
30
+ private addActors;
31
+ private addStep;
32
+ private addParallelRect;
33
+ private addCompound;
34
+ private ensureRow;
35
+ private newVar;
36
+ /**
37
+ * Adds a required constraint:
38
+ * Also adds a weak constraint == if the operator is <= or >=
39
+ */
40
+ private require;
41
+ /**
42
+ * Adds a constraint with medium strength by default
43
+ */
44
+ private constraint;
45
+ private put;
46
+ }