@likec4/diagram 1.16.0 → 1.17.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 (52) hide show
  1. package/package.json +22 -18
  2. package/src/LikeC4CustomColors.tsx +24 -21
  3. package/src/LikeC4Diagram.props.ts +15 -9
  4. package/src/LikeC4Diagram.tsx +33 -27
  5. package/src/LikeC4Search.tsx +146 -0
  6. package/src/StaticLikeC4Diagram.tsx +10 -5
  7. package/src/overlays/OverlayContext.tsx +1 -1
  8. package/src/overlays/Overlays.css.ts +28 -23
  9. package/src/overlays/Overlays.tsx +116 -64
  10. package/src/overlays/edge-details/xyflow/ElementNode.tsx +15 -12
  11. package/src/overlays/edge-details/xyflow/RelationshipEdge.tsx +7 -3
  12. package/src/overlays/edge-details/xyflow/styles.css.ts +22 -16
  13. package/src/overlays/element-details/ElementDetailsCard.css.ts +322 -0
  14. package/src/overlays/element-details/ElementDetailsCard.tsx +639 -0
  15. package/src/overlays/element-details/TabPanelRelationships.css.ts +106 -0
  16. package/src/overlays/element-details/TabPanelRelationships.tsx +201 -0
  17. package/src/overlays/element-details/TabPanelStructure.css.ts +36 -0
  18. package/src/overlays/element-details/TabPanelStructure.tsx +120 -0
  19. package/src/overlays/relationships-of/RelationshipsOverlay.tsx +185 -0
  20. package/src/overlays/relationships-of/RelationshipsXYFlow.tsx +179 -213
  21. package/src/overlays/relationships-of/_types.ts +15 -4
  22. package/src/overlays/relationships-of/use-layouted-relationships.ts +301 -207
  23. package/src/overlays/relationships-of/xyflow/CompoundNode.tsx +68 -14
  24. package/src/overlays/relationships-of/xyflow/ElementNode.tsx +54 -14
  25. package/src/overlays/relationships-of/xyflow/EmptyNode.tsx +1 -1
  26. package/src/overlays/relationships-of/xyflow/RelationshipEdge.tsx +51 -23
  27. package/src/overlays/relationships-of/xyflow/styles.css.ts +34 -27
  28. package/src/state/DiagramContext.tsx +15 -8
  29. package/src/state/aligners.ts +473 -0
  30. package/src/state/diagramStore.layout.ts +67 -0
  31. package/src/state/diagramStore.ts +18 -73
  32. package/src/theme-vars.ts +9 -0
  33. package/src/ui/FramerMotionConfig.tsx +18 -0
  34. package/src/ui/notation/NotationPanel.tsx +3 -3
  35. package/src/ui/top-left/ManualLayoutToolsButton.tsx +15 -0
  36. package/src/ui/top-left/TopLeftPanel.tsx +14 -1
  37. package/src/xyflow/XYFlow.tsx +18 -35
  38. package/src/xyflow/XYFlowInner.tsx +2 -2
  39. package/src/xyflow/edges/EdgeLabel.tsx +3 -3
  40. package/src/xyflow/edges/RelationshipsDropdownMenu.tsx +25 -18
  41. package/src/xyflow/nodes/compound/CompoundNode.css.ts +96 -30
  42. package/src/xyflow/nodes/compound/CompoundNode.tsx +149 -165
  43. package/src/xyflow/nodes/element/ElementDetails.css.ts +101 -0
  44. package/src/xyflow/nodes/element/ElementDetails.tsx +393 -0
  45. package/src/xyflow/nodes/element/ElementNode.tsx +165 -133
  46. package/src/xyflow/nodes/element/element.css.ts +46 -17
  47. package/src/xyflow/nodes/shared/ElementIcon.tsx +43 -0
  48. package/src/xyflow/nodes/shared/Toolbar.tsx +6 -6
  49. package/src/xyflow/{XYFlowEvents.tsx → useXYFlowEvents.ts} +26 -22
  50. package/src/xyflow/utils.ts +12 -3
  51. package/src/LikeC4CustomColors.props.ts +0 -5
  52. /package/src/{mantine → ui}/EnsureMantine.tsx +0 -0
@@ -121,8 +121,10 @@ export function useXYFlowEvents() {
121
121
  enableFocusMode,
122
122
  lastClickedNodeId,
123
123
  nodesSelectable,
124
+ enableElementDetails,
124
125
  setLastClickedNode,
125
- onOpenSourceElement
126
+ onOpenSourceElement,
127
+ openOverlay
126
128
  } = diagramApi.getState()
127
129
  setLastClickedNode(xynode.id)
128
130
  // if we focused on a node, and clicked on another node - focus on the clicked node
@@ -130,30 +132,45 @@ export function useXYFlowEvents() {
130
132
  // if user clicked on the same node twice in a short time, focus on it
131
133
  const clickedRecently = lastClickWasRecent() && lastClickedNodeId === xynode.id
132
134
 
135
+ let stopPropagation = false
136
+
133
137
  if (clickedRecently && !!onOpenSourceElement) {
134
138
  onOpenSourceElement(xynode.data.element.id)
135
- if (!onNodeClick) {
136
- event.stopPropagation()
137
- }
139
+ stopPropagation = true
138
140
  }
139
141
 
140
142
  if (enableFocusMode) {
141
143
  switch (true) {
144
+ case shallChangeFocus || (clickedRecently && !focusedNodeId): {
145
+ focusOnNode(xynode.id)
146
+ stopPropagation = true
147
+ break
148
+ }
142
149
  case clickedRecently && focusedNodeId === xynode.id: {
143
150
  focusOnNode(false)
144
151
  fitDiagram()
152
+ stopPropagation = true
145
153
  break
146
154
  }
147
- case (shallChangeFocus || clickedRecently): {
148
- focusOnNode(xynode.id)
155
+ case !clickedRecently && focusedNodeId === xynode.id && enableElementDetails: {
156
+ openOverlay({
157
+ elementDetails: xynode.data.element.id
158
+ })
159
+ stopPropagation = true
149
160
  break
150
161
  }
151
162
  }
163
+ } else if (enableElementDetails && (clickedRecently || focusedNodeId === xynode.id) && !onNodeClick) {
164
+ openOverlay({
165
+ elementDetails: xynode.data.element.id
166
+ })
167
+ stopPropagation = true
152
168
  } else if (nodesSelectable) {
153
169
  xystore.getState().addSelectedNodes([xynode.id])
170
+ stopPropagation = true
154
171
  }
155
172
 
156
- if (!onNodeClick && (enableFocusMode || nodesSelectable)) {
173
+ if (!onNodeClick && stopPropagation) {
157
174
  event.stopPropagation()
158
175
  return
159
176
  }
@@ -165,23 +182,10 @@ export function useXYFlowEvents() {
165
182
  },
166
183
  onNodeDoubleClick: (event, xynode) => {
167
184
  const {
168
- focusedNodeId,
169
- enableFocusMode,
170
- fitDiagram,
171
- focusOnNode,
172
185
  setLastClickedNode
173
186
  } = diagramApi.getState()
174
187
  setLastClickedNode(xynode.id)
175
188
  lastClickWasRecent()
176
- if (isNonNullish(focusedNodeId) || enableFocusMode) {
177
- // if we are already focused on the node, cancel
178
- if (focusedNodeId === xynode.id) {
179
- focusOnNode(false)
180
- fitDiagram()
181
- } else {
182
- focusOnNode(xynode.id)
183
- }
184
- }
185
189
  event.stopPropagation()
186
190
  },
187
191
  onEdgeClick: (event, xyedge) => {
@@ -249,7 +253,7 @@ export function useXYFlowEvents() {
249
253
  activeWalkthrough,
250
254
  activateWalkthrough,
251
255
  openOverlay,
252
- showRelationshipDetails
256
+ enableRelationshipDetails
253
257
  } = diagramApi.getState()
254
258
  // if we are in dynamic view, and clicked on an edge, activate the step
255
259
  if (isDynamicView && enableDynamicViewWalkthrough) {
@@ -261,7 +265,7 @@ export function useXYFlowEvents() {
261
265
  return
262
266
  }
263
267
 
264
- if (showRelationshipDetails) {
268
+ if (enableRelationshipDetails) {
265
269
  openOverlay({
266
270
  edgeDetails: xyedge.data.edge.id
267
271
  })
@@ -1,6 +1,7 @@
1
1
  import { hasAtLeast, invariant } from '@likec4/core'
2
2
  import type { DiagramEdge, Point } from '@likec4/core'
3
- import type { Rect, XYPosition } from '@xyflow/react'
3
+ import type { InternalNode, Rect, XYPosition } from '@xyflow/react'
4
+ import { getNodeDimensions } from '@xyflow/system'
4
5
  import { Bezier } from 'bezier-js'
5
6
  import { isArray } from 'remeda'
6
7
  import type { InternalXYFlowNode } from './types'
@@ -19,8 +20,8 @@ export function distance(a: XYPosition, b: XYPosition) {
19
20
  export const nodeToRect = (nd: InternalXYFlowNode): Rect => ({
20
21
  x: nd.internals.positionAbsolute.x,
21
22
  y: nd.internals.positionAbsolute.y,
22
- width: nd.width ?? nd.data.element.width,
23
- height: nd.height ?? nd.data.element.height
23
+ width: nd.measured.width ?? nd.width ?? nd.data.element.width,
24
+ height: nd.measured.height ?? nd.height ?? nd.data.element.height
24
25
  })
25
26
 
26
27
  /**
@@ -87,3 +88,11 @@ export function distanceBetweenPoints(a: XYPosition, b: XYPosition) {
87
88
  export function stopPropagation(e: React.MouseEvent) {
88
89
  return e.stopPropagation()
89
90
  }
91
+
92
+ export function centerXYInternalNode<N extends InternalNode>(nd: N) {
93
+ const { width, height } = getNodeDimensions(nd)
94
+ return {
95
+ x: nd.internals.positionAbsolute.x + width / 2,
96
+ y: nd.internals.positionAbsolute.y + height / 2
97
+ }
98
+ }
@@ -1,5 +0,0 @@
1
- import { type CustomColorDefinitions } from '@likec4/core'
2
-
3
- export interface LikeC4CustomColorsProperties {
4
- customColors: CustomColorDefinitions
5
- }
File without changes