@likec4/diagram 1.31.0 → 1.32.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 (264) hide show
  1. package/bundle/{chunk-BBzMXzCg.js → chunk-BvTQaUYl.js} +1675 -1207
  2. package/bundle/custom.js +50 -47
  3. package/bundle/index.js +2482 -2438
  4. package/dist/LikeC4CustomColors.d.ts +2 -7
  5. package/dist/LikeC4CustomColors.js +17 -6
  6. package/dist/LikeC4Diagram.d.ts +3 -2
  7. package/dist/LikeC4Diagram.js +10 -14
  8. package/dist/LikeC4Diagram.props.d.ts +28 -22
  9. package/dist/LikeC4ModelProvider.d.ts +5 -4
  10. package/dist/StaticLikeC4Diagram.d.ts +3 -2
  11. package/dist/StaticLikeC4Diagram.js +2 -2
  12. package/dist/base/BaseXYFlow.js +5 -5
  13. package/dist/base/const.d.ts +1 -1
  14. package/dist/base/const.js +1 -1
  15. package/dist/base/index.d.ts +2 -1
  16. package/dist/base/primitives/compound/CompoundActionButton.js +2 -1
  17. package/dist/base/primitives/compound/CompoundDetailsButton.js +2 -1
  18. package/dist/base/primitives/compound/CompoundTitle.d.ts +1 -1
  19. package/dist/base/primitives/compound/CompoundTitle.js +2 -1
  20. package/dist/base/primitives/edge/EdgeContainer.d.ts +1 -1
  21. package/dist/base/primitives/edge/EdgeLabel.css.js +1 -0
  22. package/dist/base/primitives/edge/EdgeLabel.d.ts +3 -3
  23. package/dist/base/primitives/edge/EdgeLabel.js +6 -4
  24. package/dist/base/primitives/edge/EdgeLabelContainer.d.ts +1 -1
  25. package/dist/base/primitives/edge/EdgeMarkers.d.ts +1 -1
  26. package/dist/base/primitives/edge/EdgePath.d.ts +1 -1
  27. package/dist/base/primitives/element/ElementActionButtons.js +10 -9
  28. package/dist/base/primitives/element/ElementDetailsButton.js +2 -1
  29. package/dist/base/primitives/element/ElementShape.d.ts +1 -1
  30. package/dist/base/primitives/element/ElementTags.d.ts +14 -0
  31. package/dist/base/primitives/element/ElementTags.js +176 -0
  32. package/dist/base/primitives/element/ElementTitle.d.ts +5 -4
  33. package/dist/base/primitives/element/ElementTitle.js +6 -6
  34. package/dist/base/primitives/index.d.ts +1 -0
  35. package/dist/base/types.Base.d.ts +54 -0
  36. package/dist/base/types.Base.js +48 -0
  37. package/dist/base/types.d.ts +2 -52
  38. package/dist/bundle/LikeC4View.d.ts +2 -1
  39. package/dist/bundle/LikeC4View.js +8 -6
  40. package/dist/bundle/LikeC4View.props.d.ts +15 -4
  41. package/dist/bundle/ReactLikeC4.d.ts +4 -7
  42. package/dist/bundle/ReactLikeC4.js +3 -2
  43. package/dist/bundle/index.js +1 -1
  44. package/dist/components/ErrorFallback.d.ts +2 -0
  45. package/dist/components/ErrorFallback.js +29 -0
  46. package/dist/context/DiagramEventHandlers.d.ts +6 -5
  47. package/dist/context/DiagramFeatures.d.ts +2 -2
  48. package/dist/context/DiagramFeatures.js +3 -31
  49. package/dist/context/EnsureMantine.js +1 -1
  50. package/dist/context/IconRenderer.js +1 -4
  51. package/dist/context/RootContainer.js +5 -1
  52. package/dist/context/TagStylesContext.d.ts +7 -0
  53. package/dist/context/TagStylesContext.js +85 -0
  54. package/dist/custom/components.d.ts +1 -1
  55. package/dist/custom/customNodes.d.ts +27 -17
  56. package/dist/custom/hooks.d.ts +1 -1
  57. package/dist/hooks/index.d.ts +1 -1
  58. package/dist/hooks/useDiagram.d.ts +73 -38
  59. package/dist/hooks/useDiagram.js +7 -3
  60. package/dist/hooks/useMantinePortalProps.d.ts +2 -2
  61. package/dist/hooks/useSearchActor.d.ts +2 -0
  62. package/dist/hooks/useSearchActor.js +10 -0
  63. package/dist/hooks/useUpdateEffect.js +3 -0
  64. package/dist/hooks/useXYFlow.d.ts +39 -37
  65. package/dist/hooks/useXYFlow.js +5 -1
  66. package/dist/index.js +1 -1
  67. package/dist/likec4diagram/DiagramUI.js +7 -2
  68. package/dist/likec4diagram/DiagramXYFlow.d.ts +4 -3
  69. package/dist/likec4diagram/DiagramXYFlow.js +104 -107
  70. package/dist/likec4diagram/custom/edges/RelationshipEdge.d.ts +7 -6
  71. package/dist/likec4diagram/custom/edges/RelationshipEdge.js +8 -0
  72. package/dist/likec4diagram/custom/edges/RelationshipsDropdownMenu.js +7 -5
  73. package/dist/likec4diagram/custom/index.d.ts +7 -6
  74. package/dist/likec4diagram/custom/nodes/nodes.js +39 -26
  75. package/dist/likec4diagram/custom/nodes/toolbar/_shared.d.ts +3 -3
  76. package/dist/likec4diagram/types.d.ts +5 -5
  77. package/dist/likec4diagram/ui/controls/Controls.js +12 -4
  78. package/dist/likec4diagram/ui/notation/NotationPanel.js +1 -1
  79. package/dist/likec4diagram/useViewToNodesEdges.d.ts +5 -3
  80. package/dist/likec4diagram/useViewToNodesEdges.js +20 -30
  81. package/dist/likec4model/LikeC4ModelContext.d.ts +2 -2
  82. package/dist/likec4model/useLikeC4ElementsTree.js +1 -1
  83. package/dist/likec4model/useLikeC4Model.d.ts +22 -10
  84. package/dist/likec4model/useLikeC4Model.js +11 -7
  85. package/dist/overlays/Overlays.js +4 -27
  86. package/dist/overlays/element-details/ElementDetailsCard.d.ts +1 -1
  87. package/dist/overlays/element-details/ElementDetailsCard.js +19 -12
  88. package/dist/overlays/element-details/TabPanelDeployments.d.ts +1 -1
  89. package/dist/overlays/element-details/TabPanelDeployments.js +1 -1
  90. package/dist/overlays/element-details/TabPanelRelationships.d.ts +1 -1
  91. package/dist/overlays/element-details/TabPanelStructure.d.ts +1 -1
  92. package/dist/overlays/element-details/actor.d.ts +288 -286
  93. package/dist/overlays/overlay/Overlay.css.d.ts +57 -2
  94. package/dist/overlays/overlay/Overlay.css.js +76 -39
  95. package/dist/overlays/overlay/Overlay.d.ts +12 -0
  96. package/dist/overlays/overlay/Overlay.js +36 -25
  97. package/dist/overlays/overlaysActor.d.ts +1 -1
  98. package/dist/overlays/relationship-details/RelationshipDetails.d.ts +3 -2
  99. package/dist/overlays/relationship-details/RelationshipDetails.js +3 -3
  100. package/dist/overlays/relationship-details/_types.d.ts +2 -2
  101. package/dist/overlays/relationship-details/actor.js +7 -7
  102. package/dist/overlays/relationship-details/custom/edgeTypes.d.ts +3 -2
  103. package/dist/overlays/relationship-details/custom/nodeTypes.js +4 -0
  104. package/dist/overlays/relationship-details/hooks.d.ts +10 -9
  105. package/dist/overlays/relationship-details/layout-to-xyflow.js +1 -0
  106. package/dist/overlays/relationship-details/layout.js +3 -1
  107. package/dist/overlays/relationships-browser/RelationshipsBrowser.d.ts +3 -2
  108. package/dist/overlays/relationships-browser/SelectElement.js +1 -1
  109. package/dist/overlays/relationships-browser/_types.d.ts +2 -2
  110. package/dist/overlays/relationships-browser/actor.d.ts +1 -1
  111. package/dist/overlays/relationships-browser/actor.js +7 -7
  112. package/dist/overlays/relationships-browser/custom/edgeTypes.d.ts +3 -2
  113. package/dist/overlays/relationships-browser/custom/nodeTypes.d.ts +8 -5
  114. package/dist/overlays/relationships-browser/custom/nodeTypes.js +4 -0
  115. package/dist/overlays/relationships-browser/layout.d.ts +2 -2
  116. package/dist/overlays/relationships-browser/layout.js +10 -6
  117. package/dist/overlays/relationships-browser/useViewToNodesEdges.js +4 -3
  118. package/dist/search/Search.d.ts +5 -0
  119. package/dist/search/Search.js +192 -0
  120. package/dist/{likec4diagram/ui/search → search/components}/ElementsColumn.css.js +0 -1
  121. package/dist/search/components/ElementsColumn.d.ts +2 -0
  122. package/dist/{likec4diagram/ui/search → search/components}/ElementsColumn.js +21 -19
  123. package/dist/search/components/PickView.d.ts +4 -0
  124. package/dist/search/components/PickView.js +135 -0
  125. package/dist/search/components/SearchByTags.d.ts +1 -0
  126. package/dist/search/components/SearchByTags.js +116 -0
  127. package/dist/search/components/SearchInput.d.ts +2 -0
  128. package/dist/{likec4diagram/ui/search → search/components}/SearchInput.js +53 -34
  129. package/dist/{likec4diagram/ui/search → search/components}/ViewsColum.d.ts +3 -2
  130. package/dist/{likec4diagram/ui/search → search/components}/ViewsColum.js +14 -13
  131. package/dist/{likec4diagram/ui/search → search/components}/_shared.css.js +26 -35
  132. package/dist/{likec4diagram/ui/search/LikeC4Search.css.d.ts → search/components/styles.css.d.ts} +0 -2
  133. package/dist/search/components/styles.css.js +60 -0
  134. package/dist/{likec4diagram/ui/search → search/components}/utils.d.ts +1 -0
  135. package/dist/{likec4diagram/ui/search → search/components}/utils.js +7 -1
  136. package/dist/search/hooks.d.ts +16 -0
  137. package/dist/search/hooks.js +35 -0
  138. package/dist/search/searchActor.d.ts +90 -0
  139. package/dist/search/searchActor.js +75 -0
  140. package/dist/state/DiagramActorProvider.d.ts +9 -7
  141. package/dist/state/DiagramActorProvider.js +24 -18
  142. package/dist/state/assign.d.ts +0 -1
  143. package/dist/state/assign.js +9 -19
  144. package/dist/state/diagram-machine.d.ts +430 -176
  145. package/dist/state/diagram-machine.js +119 -54
  146. package/dist/state/syncManualLayoutActor.d.ts +2 -2
  147. package/dist/state/types.d.ts +2 -0
  148. package/dist/state/utils.d.ts +2 -0
  149. package/dist/state/utils.js +3 -0
  150. package/dist/styles-min.css +1 -1
  151. package/dist/styles-xyflow.css +1 -1
  152. package/dist/styles.css +1 -1
  153. package/dist/styles.css2.js +1 -1
  154. package/package.json +18 -18
  155. package/panda.buildinfo.json +171 -148
  156. package/src/LikeC4CustomColors.tsx +21 -6
  157. package/src/LikeC4Diagram.props.ts +35 -30
  158. package/src/LikeC4Diagram.tsx +19 -20
  159. package/src/LikeC4ModelProvider.tsx +6 -5
  160. package/src/StaticLikeC4Diagram.tsx +8 -6
  161. package/src/base/const.ts +1 -1
  162. package/src/base/index.ts +2 -1
  163. package/src/base/primitives/compound/CompoundActionButton.tsx +2 -1
  164. package/src/base/primitives/compound/CompoundDetailsButton.tsx +2 -1
  165. package/src/base/primitives/compound/CompoundTitle.tsx +3 -2
  166. package/src/base/primitives/edge/EdgeContainer.tsx +2 -1
  167. package/src/base/primitives/edge/EdgeLabel.css.ts +1 -0
  168. package/src/base/primitives/edge/EdgeLabel.tsx +20 -15
  169. package/src/base/primitives/edge/EdgeLabelContainer.tsx +1 -1
  170. package/src/base/primitives/edge/EdgeMarkers.tsx +2 -1
  171. package/src/base/primitives/edge/EdgePath.tsx +1 -1
  172. package/src/base/primitives/element/ElementActionButtons.tsx +11 -10
  173. package/src/base/primitives/element/ElementDetailsButton.tsx +2 -1
  174. package/src/base/primitives/element/ElementShape.tsx +2 -1
  175. package/src/base/primitives/element/ElementTags.tsx +182 -0
  176. package/src/base/primitives/element/ElementTitle.tsx +21 -15
  177. package/src/base/primitives/index.ts +1 -0
  178. package/src/base/types.Base.ts +104 -0
  179. package/src/base/types.ts +2 -99
  180. package/src/bundle/LikeC4View.props.ts +17 -4
  181. package/src/bundle/LikeC4View.tsx +17 -19
  182. package/src/bundle/ReactLikeC4.tsx +14 -26
  183. package/src/components/ErrorFallback.tsx +30 -0
  184. package/src/context/DiagramEventHandlers.tsx +5 -4
  185. package/src/context/DiagramFeatures.tsx +3 -22
  186. package/src/context/EnsureMantine.tsx +1 -1
  187. package/src/context/IconRenderer.tsx +1 -4
  188. package/src/context/RootContainer.tsx +9 -3
  189. package/src/context/TagStylesContext.tsx +96 -0
  190. package/src/custom/components.ts +2 -0
  191. package/src/custom/customNodes.tsx +24 -14
  192. package/src/custom/hooks.ts +1 -0
  193. package/src/hooks/index.ts +1 -1
  194. package/src/hooks/useCurrentViewId.ts +1 -4
  195. package/src/hooks/useDiagram.ts +104 -12
  196. package/src/hooks/useMantinePortalProps.ts +10 -1
  197. package/src/hooks/useSearchActor.ts +11 -0
  198. package/src/hooks/useUpdateEffect.ts +7 -4
  199. package/src/hooks/useXYFlow.ts +5 -0
  200. package/src/likec4diagram/DiagramUI.tsx +5 -0
  201. package/src/likec4diagram/DiagramXYFlow.tsx +115 -118
  202. package/src/likec4diagram/custom/edges/RelationshipEdge.tsx +9 -0
  203. package/src/likec4diagram/custom/edges/RelationshipsDropdownMenu.tsx +10 -9
  204. package/src/likec4diagram/custom/nodes/nodes.tsx +45 -43
  205. package/src/likec4diagram/custom/nodes/toolbar/_shared.tsx +11 -3
  206. package/src/likec4diagram/types.ts +5 -3
  207. package/src/likec4diagram/ui/controls/Controls.tsx +11 -4
  208. package/src/likec4diagram/ui/notation/NotationPanel.tsx +2 -2
  209. package/src/likec4diagram/useViewToNodesEdges.ts +34 -36
  210. package/src/likec4model/LikeC4ModelContext.ts +2 -2
  211. package/src/likec4model/useLikeC4ElementsTree.ts +1 -1
  212. package/src/likec4model/useLikeC4Model.ts +18 -16
  213. package/src/overlays/Overlays.tsx +5 -32
  214. package/src/overlays/element-details/ElementDetailsCard.tsx +25 -18
  215. package/src/overlays/element-details/TabPanelDeployments.tsx +3 -2
  216. package/src/overlays/element-details/TabPanelRelationships.tsx +2 -1
  217. package/src/overlays/element-details/TabPanelStructure.tsx +1 -1
  218. package/src/overlays/element-details/actor.ts +2 -2
  219. package/src/overlays/overlay/Overlay.css.ts +75 -38
  220. package/src/overlays/overlay/Overlay.tsx +43 -26
  221. package/src/overlays/overlaysActor.ts +1 -1
  222. package/src/overlays/relationship-details/RelationshipDetails.tsx +4 -4
  223. package/src/overlays/relationship-details/_types.ts +2 -1
  224. package/src/overlays/relationship-details/custom/nodeTypes.tsx +4 -0
  225. package/src/overlays/relationship-details/layout-to-xyflow.ts +1 -0
  226. package/src/overlays/relationship-details/layout.ts +3 -1
  227. package/src/overlays/relationships-browser/SelectElement.tsx +1 -1
  228. package/src/overlays/relationships-browser/_types.ts +2 -1
  229. package/src/overlays/relationships-browser/custom/nodeTypes.tsx +4 -0
  230. package/src/overlays/relationships-browser/layout.ts +12 -7
  231. package/src/overlays/relationships-browser/useViewToNodesEdges.ts +4 -4
  232. package/src/search/Search.tsx +237 -0
  233. package/src/{likec4diagram/ui/search → search/components}/ElementsColumn.css.ts +0 -29
  234. package/src/{likec4diagram/ui/search → search/components}/ElementsColumn.tsx +24 -22
  235. package/src/search/components/PickView.tsx +140 -0
  236. package/src/search/components/SearchByTags.tsx +109 -0
  237. package/src/{likec4diagram/ui/search → search/components}/SearchInput.tsx +63 -36
  238. package/src/{likec4diagram/ui/search → search/components}/ViewsColum.tsx +17 -18
  239. package/src/{likec4diagram/ui/search → search/components}/_shared.css.ts +26 -37
  240. package/src/{likec4diagram/ui/search/LikeC4Search.css.ts → search/components/styles.css.ts} +9 -36
  241. package/src/{likec4diagram/ui/search → search/components}/utils.ts +7 -0
  242. package/src/search/hooks.ts +41 -0
  243. package/src/search/searchActor.ts +99 -0
  244. package/src/state/DiagramActorProvider.tsx +36 -25
  245. package/src/state/assign.ts +10 -10
  246. package/src/state/diagram-machine.ts +115 -52
  247. package/src/state/syncManualLayoutActor.ts +1 -1
  248. package/src/state/types.ts +2 -0
  249. package/src/state/utils.ts +4 -0
  250. package/dist/base/types.js +0 -54
  251. package/dist/likec4diagram/ui/search/ElementsColumn.d.ts +0 -1
  252. package/dist/likec4diagram/ui/search/LikeC4Search.css.js +0 -87
  253. package/dist/likec4diagram/ui/search/LikeC4Search.d.ts +0 -2
  254. package/dist/likec4diagram/ui/search/LikeC4Search.js +0 -267
  255. package/dist/likec4diagram/ui/search/SearchInput.d.ts +0 -1
  256. package/dist/likec4diagram/ui/search/state.d.ts +0 -19
  257. package/dist/likec4diagram/ui/search/state.js +0 -63
  258. package/src/likec4diagram/ui/search/LikeC4Search.tsx +0 -301
  259. package/src/likec4diagram/ui/search/state.ts +0 -78
  260. /package/dist/{likec4diagram/ui/search → search/components}/ElementsColumn.css.d.ts +0 -0
  261. /package/dist/{likec4diagram/ui/search → search/components}/ViewsColumn.css.d.ts +0 -0
  262. /package/dist/{likec4diagram/ui/search → search/components}/ViewsColumn.css.js +0 -0
  263. /package/dist/{likec4diagram/ui/search → search/components}/_shared.css.d.ts +0 -0
  264. /package/src/{likec4diagram/ui/search → search/components}/ViewsColumn.css.ts +0 -0
@@ -9,9 +9,10 @@ import {
9
9
  ElementDetailsButton,
10
10
  ElementNodeContainer,
11
11
  ElementShape,
12
+ ElementTags,
12
13
  ElementTitle,
13
14
  } from '../../../base/primitives'
14
- import { IfEnabled, IfNotReadOnly, useEnabledFeatures } from '../../../context/DiagramFeatures'
15
+ import { useEnabledFeatures } from '../../../context/DiagramFeatures'
15
16
  import { useDiagram } from '../../../hooks/useDiagram'
16
17
  import type { Types } from '../../types'
17
18
  import { CompoundActions } from './CompoundActions'
@@ -57,63 +58,64 @@ export function CompoundDetailsButtonWithHandler(
57
58
  )
58
59
  }
59
60
 
60
- export const ElementNode = customNode<Types.ElementNodeData, 'element'>((props) => (
61
- <ElementNodeContainer nodeProps={props}>
62
- <ElementShape {...props} />
63
- <ElementTitle {...props} />
64
- <ElementActions {...props} />
65
- <ElementDetailsButtonWithHandler {...props} />
66
- <IfNotReadOnly>
67
- <ElementToolbar {...props} />
68
- </IfNotReadOnly>
69
- <DefaultHandles />
70
- </ElementNodeContainer>
71
- ))
61
+ export const ElementNode = customNode<Types.ElementNodeData, 'element'>(props => {
62
+ const { enableElementTags, enableReadOnly } = useEnabledFeatures()
63
+ return (
64
+ <ElementNodeContainer nodeProps={props}>
65
+ <ElementShape {...props} />
66
+ <ElementTitle {...props} />
67
+ {enableElementTags && <ElementTags {...props} />}
68
+ <ElementActions {...props} />
69
+ <ElementDetailsButtonWithHandler {...props} />
70
+ {!enableReadOnly && <ElementToolbar {...props} />}
71
+ <DefaultHandles />
72
+ </ElementNodeContainer>
73
+ )
74
+ })
72
75
  ElementNode.displayName = 'ElementNode'
73
76
 
74
- export const DeploymentNode = customNode<Types.DeploymentElementNodeData, 'deployment'>((props) => (
75
- <ElementNodeContainer nodeProps={props}>
76
- <ElementShape {...props} />
77
- <ElementTitle {...props} />
78
- <DeploymentElementActions {...props} />
79
- <ElementDetailsButtonWithHandler {...props} />
80
- <IfNotReadOnly>
81
- <DeploymentElementToolbar {...props} />
82
- </IfNotReadOnly>
83
- <DefaultHandles />
84
- </ElementNodeContainer>
85
- ))
77
+ export const DeploymentNode = customNode<Types.DeploymentElementNodeData, 'deployment'>((props) => {
78
+ const { enableElementTags, enableReadOnly } = useEnabledFeatures()
79
+ return (
80
+ <ElementNodeContainer nodeProps={props}>
81
+ <ElementShape {...props} />
82
+ <ElementTitle {...props} />
83
+ {enableElementTags && <ElementTags {...props} />}
84
+ <DeploymentElementActions {...props} />
85
+ <ElementDetailsButtonWithHandler {...props} />
86
+ {!enableReadOnly && <DeploymentElementToolbar {...props} />}
87
+ <DefaultHandles />
88
+ </ElementNodeContainer>
89
+ )
90
+ })
86
91
  DeploymentNode.displayName = 'DeploymentNode'
87
92
 
88
93
  export const CompoundElementNode = customNode<Types.CompoundElementNodeData, 'compound-element'>((props) => {
89
- const diagram = useDiagram()
90
-
94
+ const { enableElementDetails, enableReadOnly } = useEnabledFeatures()
91
95
  return (
92
96
  <CompoundNodeContainer nodeProps={props}>
93
97
  <CompoundTitle {...props} />
94
98
  <CompoundActions {...props} />
95
- <IfEnabled feature="ElementDetails">
96
- <CompoundDetailsButtonWithHandler {...props} />
97
- </IfEnabled>
98
- <IfNotReadOnly>
99
- <CompoundElementToolbar {...props} />
100
- </IfNotReadOnly>
99
+ {enableElementDetails && <CompoundDetailsButtonWithHandler {...props} />}
100
+ {!enableReadOnly && <CompoundElementToolbar {...props} />}
101
101
  <DefaultHandles />
102
102
  </CompoundNodeContainer>
103
103
  )
104
104
  })
105
105
  CompoundElementNode.displayName = 'CompoundElementNode'
106
106
 
107
- export const CompoundDeploymentNode = customNode<Types.CompoundDeploymentNodeData, 'compound-deployment'>((props) => (
108
- <CompoundNodeContainer nodeProps={props}>
109
- <CompoundTitle {...props} />
110
- <CompoundActions {...props} />
111
- <IfNotReadOnly>
112
- <CompoundDeploymentToolbar {...props} />
113
- </IfNotReadOnly>
114
- <DefaultHandles />
115
- </CompoundNodeContainer>
116
- ))
107
+ export const CompoundDeploymentNode = customNode<Types.CompoundDeploymentNodeData, 'compound-deployment'>((props) => {
108
+ const { enableElementDetails, enableReadOnly } = useEnabledFeatures()
109
+ return (
110
+ <CompoundNodeContainer nodeProps={props}>
111
+ <CompoundTitle {...props} />
112
+ <CompoundActions {...props} />
113
+ {enableElementDetails && <CompoundDetailsButtonWithHandler {...props} />}
114
+ {!enableReadOnly && <CompoundDeploymentToolbar {...props} />}
115
+ <DefaultHandles />
116
+ </CompoundNodeContainer>
117
+ )
118
+ })
117
119
  CompoundDeploymentNode.displayName = 'CompoundDeploymentNode'
118
120
 
119
121
  export const ViewGroupNode = customNode<Types.ViewGroupNodeData, 'view-group'>((props) => (
@@ -1,4 +1,12 @@
1
- import { type Fqn, type NodeId, type ThemeColor, type ViewChange, defaultTheme, invariant } from '@likec4/core'
1
+ import {
2
+ type DeploymentFqn,
3
+ type Fqn,
4
+ type NodeId,
5
+ type ThemeColor,
6
+ type ViewChange,
7
+ defaultTheme,
8
+ invariant,
9
+ } from '@likec4/core'
2
10
  import { ActionIcon, Tooltip as MantineTooltip } from '@mantine/core'
3
11
  import { useCallbackRef } from '@mantine/hooks'
4
12
  import { IconFileSymlink, IconTransform } from '@tabler/icons-react'
@@ -45,7 +53,7 @@ export const Tooltip = MantineTooltip.withProps({
45
53
  })
46
54
 
47
55
  export function useHandlers(
48
- target: Fqn,
56
+ target: Fqn | DeploymentFqn,
49
57
  props: NodeProps<Types.NodeData>,
50
58
  ) {
51
59
  const { onChange: triggerOnChange } = useDiagramEventHandlers()
@@ -113,7 +121,7 @@ export function BrowseRelationshipsButton({ fqn }: { fqn: Fqn }) {
113
121
  )
114
122
  }
115
123
 
116
- export function GoToSourceButton(props: MergeExclusive<{ elementId: Fqn }, { deploymentId: Fqn }>) {
124
+ export function GoToSourceButton(props: MergeExclusive<{ elementId: Fqn }, { deploymentId: DeploymentFqn }>) {
117
125
  const { onOpenSource } = useDiagramEventHandlers()
118
126
  if (!onOpenSource) return null
119
127
  // const diagramApi = useDiagramStoreApi()
@@ -1,4 +1,4 @@
1
- import type { DiagramEdge, DiagramNode, Fqn, IconUrl, ViewId } from '@likec4/core'
1
+ import type { DeploymentFqn, DiagramEdge, DiagramNode, Fqn, IconUrl, ViewId } from '@likec4/core/types'
2
2
  import type { XYPosition } from '@xyflow/system'
3
3
  import type { OptionalKeysOf, Simplify } from 'type-fest'
4
4
  import type { Base, ReactFlowEdge, ReactFlowNode } from '../base/types'
@@ -28,6 +28,7 @@ export namespace Types {
28
28
  | 'level'
29
29
  | 'height'
30
30
  | 'style'
31
+ | 'tags'
31
32
  | 'position'
32
33
  >
33
34
  >
@@ -59,7 +60,7 @@ export namespace Types {
59
60
  & LeafNodeData
60
61
  & {
61
62
  navigateTo: ViewId | null
62
- deploymentFqn: Fqn
63
+ deploymentFqn: DeploymentFqn
63
64
  // If set - this node refers to a model element
64
65
  modelFqn: Fqn | null
65
66
  }
@@ -74,6 +75,7 @@ export namespace Types {
74
75
  | 'color'
75
76
  | 'shape'
76
77
  | 'style'
78
+ | 'tags'
77
79
  | 'position'
78
80
  >
79
81
  >
@@ -96,7 +98,7 @@ export namespace Types {
96
98
  }
97
99
 
98
100
  export type CompoundDeploymentNodeData = CompoundNodeData & {
99
- deploymentFqn: Fqn
101
+ deploymentFqn: DeploymentFqn
100
102
  /**
101
103
  * If set - this node refers to a model element
102
104
  */
@@ -3,12 +3,12 @@ import { ActionIconGroup, Badge, Box, Group, Loader, Stack } from '@mantine/core
3
3
  import { IconFileSymlink, IconFocusCentered, IconMenu2 } from '@tabler/icons-react'
4
4
  import { LayoutGroup, m } from 'motion/react'
5
5
  import { memo } from 'react'
6
+ import { SearchControl } from '../../../components/SearchControl'
6
7
  import { useDiagramEventHandlers, useEnabledFeatures } from '../../../context'
7
8
  import { type ControlsCustomLayout, useControlsCustomLayout } from '../../../context/ControlsCustomLayout'
8
9
  import { useMantinePortalProps } from '../../../hooks'
9
10
  import { useDiagram, useDiagramContext, useDiagramSyncLayoutState } from '../../../hooks/useDiagram'
10
11
  import { stopPropagation } from '../../../utils'
11
- import { LikeC4Search } from '../search/LikeC4Search'
12
12
  import { ActionIcon, Tooltip } from './_shared'
13
13
  import { ChangeAutoLayoutButton } from './ChangeAutoLayoutButton'
14
14
  import { LayoutDriftNotification } from './LayoutDriftNotification'
@@ -68,8 +68,7 @@ const ControlsDefaultLayout: ControlsCustomLayout = ({
68
68
  )
69
69
 
70
70
  export const Controls = memo(() => {
71
- const { viewId, hasLayoutDrift, viewportChanged, isNotActiveWalkthrough } = useDiagramContext(c => ({
72
- viewId: c.view.id,
71
+ const { hasLayoutDrift, viewportChanged, isNotActiveWalkthrough } = useDiagramContext(c => ({
73
72
  hasLayoutDrift: c.view.hasLayoutDrift ?? false,
74
73
  viewportChanged: c.viewportChangedManually,
75
74
  isNotActiveWalkthrough: c.activeWalkthrough === null,
@@ -103,7 +102,14 @@ export const Controls = memo(() => {
103
102
  </ActionIcon>
104
103
  )}
105
104
  navigationButtons={enableNavigationButtons && <NavigationButtons />}
106
- search={enableSearch && <LikeC4Search />}
105
+ search={enableSearch && (
106
+ <SearchControl
107
+ onClick={e => {
108
+ e.stopPropagation()
109
+ diagram.openSearch()
110
+ }}
111
+ />
112
+ )}
107
113
  syncInProgressBadge={<SyncLayoutBadge />}
108
114
  actionsGroup={
109
115
  <ActionIconGroup className={css.actionIconGroup} orientation="vertical">
@@ -112,6 +118,7 @@ export const Controls = memo(() => {
112
118
  <ActionIcon
113
119
  onClick={e => {
114
120
  e.stopPropagation()
121
+ const viewId = diagram.currentView.id
115
122
  onOpenSource?.({ view: viewId })
116
123
  }}>
117
124
  <IconFileSymlink stroke={1.5} />
@@ -1,4 +1,4 @@
1
- import { type ComputedNode, type ElementNotation as ElementNotationData } from '@likec4/core'
1
+ import { type ComputedNode, type NodeNotation as ElementNotationData } from '@likec4/core'
2
2
  import { css, cx, cx as clsx } from '@likec4/styles/css'
3
3
  import {
4
4
  ActionIcon,
@@ -122,7 +122,7 @@ const ElementNotation = ({ value }: { value: ElementNotationData }) => {
122
122
 
123
123
  const selector = (s: DiagramContext) => ({
124
124
  id: s.view.id,
125
- notations: s.view.notation?.elements ?? [],
125
+ notations: s.view.notation?.nodes ?? [],
126
126
  isVisible: true,
127
127
  // isVisible: isNullish(s.focusedNodeId ?? s.activeWalkthrough),
128
128
  })
@@ -1,26 +1,27 @@
1
1
  import {
2
2
  type DiagramEdge,
3
+ type DiagramNode,
3
4
  type DiagramView,
4
5
  type EdgeId,
5
6
  type Fqn,
6
7
  type NodeId,
7
8
  type WhereOperator,
8
- DiagramNode,
9
- ElementKind,
9
+ GroupElementKind,
10
10
  invariant,
11
11
  nonNullable,
12
12
  Queue,
13
13
  whereOperatorAsPredicate,
14
14
  } from '@likec4/core'
15
- import { useDeepCompareMemo } from '@react-hookz/web'
15
+ import { useCustomCompareMemo } from '@react-hookz/web'
16
+ import { deepEqual, shallowEqual } from 'fast-equals'
16
17
  import { hasAtLeast, pick } from 'remeda'
17
18
  import { ZIndexes } from '../base/const'
18
19
  import type { Types } from './types'
19
20
 
20
21
  // const nodeZIndex = (node: DiagramNode) => node.level - (node.children.length > 0 ? 1 : 0)
21
22
  function viewToNodesEdge(opts: {
22
- view: Pick<DiagramView, 'id' | 'nodes' | 'edges' | '__'>
23
- where: WhereOperator<string, string> | undefined
23
+ view: Pick<DiagramView, 'id' | 'nodes' | 'edges' | '_type'>
24
+ where: WhereOperator | null
24
25
  nodesSelectable: boolean
25
26
  }): {
26
27
  xynodes: Types.Node[]
@@ -30,7 +31,7 @@ function viewToNodesEdge(opts: {
30
31
  view,
31
32
  nodesSelectable: selectable,
32
33
  } = opts
33
- const isDynamicView = view.__ === 'dynamic',
34
+ const isDynamicView = view._type === 'dynamic',
34
35
  xynodes = [] as Types.Node[],
35
36
  xyedges = [] as Types.Edge[],
36
37
  nodeLookup = new Map<Fqn, DiagramNode>()
@@ -73,7 +74,7 @@ function viewToNodesEdge(opts: {
73
74
  let next: TraverseItem | undefined
74
75
  while ((next = queue.dequeue())) {
75
76
  const { node, parent } = next
76
- const isCompound = hasAtLeast(node.children, 1) || node.kind == ElementKind.Group
77
+ const isCompound = hasAtLeast(node.children, 1) || node.kind == GroupElementKind
77
78
  if (isCompound) {
78
79
  for (const child of node.children) {
79
80
  queue.enqueue({ node: nodeById(child), parent: node })
@@ -93,8 +94,8 @@ function viewToNodesEdge(opts: {
93
94
 
94
95
  const base = {
95
96
  id,
96
- selectable: selectable && node.kind !== ElementKind.Group,
97
- focusable: selectable && node.kind !== ElementKind.Group,
97
+ selectable: selectable && node.kind !== GroupElementKind,
98
+ focusable: selectable && node.kind !== GroupElementKind,
98
99
  deletable: false,
99
100
  position,
100
101
  zIndex: isCompound ? ZIndexes.Compound : ZIndexes.Element,
@@ -104,7 +105,7 @@ function viewToNodesEdge(opts: {
104
105
  },
105
106
  initialWidth: node.width,
106
107
  initialHeight: node.height,
107
- hidden: node.kind !== ElementKind.Group && !visiblePredicate(node),
108
+ hidden: node.kind !== GroupElementKind && !visiblePredicate(node),
108
109
  ...(parent && {
109
110
  parentId: ns + parent.id,
110
111
  }),
@@ -119,6 +120,7 @@ function viewToNodesEdge(opts: {
119
120
  style: node.style,
120
121
  depth: node.depth ?? 0,
121
122
  icon: node.icon ?? 'none',
123
+ tags: node.tags ?? null,
122
124
  position: node.position,
123
125
  } satisfies Types.CompoundNodeData
124
126
 
@@ -135,11 +137,12 @@ function viewToNodesEdge(opts: {
135
137
  shape: node.shape,
136
138
  style: node.style,
137
139
  icon: node.icon ?? null,
140
+ tags: node.tags,
138
141
  position: node.position,
139
142
  isMultiple: node.style?.multiple ?? false,
140
143
  } satisfies Types.LeafNodeData
141
144
 
142
- if (node.kind === ElementKind.Group) {
145
+ if (node.kind === GroupElementKind) {
143
146
  xynodes.push({
144
147
  ...base,
145
148
  type: 'view-group',
@@ -152,8 +155,8 @@ function viewToNodesEdge(opts: {
152
155
  continue
153
156
  }
154
157
 
155
- const modelFqn = DiagramNode.modelRef(node)
156
- const deploymentFqn = DiagramNode.deploymentRef(node)
158
+ const modelFqn = node.modelRef ?? null
159
+ const deploymentFqn = node.deploymentRef ?? null
157
160
  if (!modelFqn && !deploymentFqn) {
158
161
  console.error('Invalid node', node)
159
162
  throw new Error('Element should have either modelRef or deploymentRef')
@@ -269,29 +272,24 @@ function viewToNodesEdge(opts: {
269
272
  xyedges,
270
273
  }
271
274
  }
272
-
273
- export function useViewToNodesEdges({
274
- view: {
275
- id,
276
- nodes,
277
- edges,
278
- __ = 'element',
279
- },
280
- ...opts
281
- }: {
275
+ type ViewToNodesEdgeInput = {
282
276
  view: DiagramView
283
- where: WhereOperator<string, string> | undefined
277
+ where: WhereOperator | null
284
278
  nodesSelectable: boolean
285
- }) {
286
- return useDeepCompareMemo(() => {
287
- return viewToNodesEdge({
288
- view: {
289
- id,
290
- nodes,
291
- edges,
292
- __,
293
- },
294
- ...opts,
295
- })
296
- }, [id, __, nodes, edges, opts])
279
+ }
280
+ const viewToNodesEdgeEqual = (a: ViewToNodesEdgeInput, b: ViewToNodesEdgeInput) => (
281
+ a.view.id === b.view.id
282
+ && a.view._type === b.view._type
283
+ && a.nodesSelectable === b.nodesSelectable
284
+ && shallowEqual(a.view.nodes, b.view.nodes)
285
+ && shallowEqual(a.view.edges, b.view.edges)
286
+ && deepEqual(a.where, b.where)
287
+ )
288
+
289
+ export function useViewToNodesEdges(params: ViewToNodesEdgeInput) {
290
+ return useCustomCompareMemo(
291
+ () => viewToNodesEdge(params),
292
+ [params],
293
+ ([a], [b]) => !!a && !!b && viewToNodesEdgeEqual(a, b),
294
+ )
297
295
  }
@@ -1,4 +1,4 @@
1
- import type { AnyAux, LikeC4Model } from '@likec4/core/model'
1
+ import type { LikeC4Model } from '@likec4/core/model'
2
2
  import { createContext } from 'react'
3
3
 
4
- export const LikeC4ModelContext = createContext<LikeC4Model<AnyAux> | null>(null)
4
+ export const LikeC4ModelContext = createContext<LikeC4Model<any> | null>(null)
@@ -27,7 +27,7 @@ function buildNode(
27
27
  * If `viewId` is provided, returns the tree of elements in the view.
28
28
  */
29
29
  export function useLikeC4ElementsTree(viewId?: ViewId): LikeC4ModelTreeNodeData[] {
30
- const model = useLikeC4Model(true)
30
+ const model = useLikeC4Model()
31
31
  return useMemo(() => {
32
32
  if (viewId) {
33
33
  const view = model.view(viewId)
@@ -1,26 +1,28 @@
1
- import type { LikeC4Model } from '@likec4/core/model'
1
+ import type { aux, LikeC4Model } from '@likec4/core/model'
2
2
  import { useContext } from 'react'
3
- import { isDefined, isNonNullish, isString } from 'remeda'
3
+ import { isString } from 'remeda'
4
4
  import { LikeC4ModelContext } from './LikeC4ModelContext'
5
5
 
6
- export function useLikeC4Model(): LikeC4Model | null
7
- export function useLikeC4Model(strict: true): LikeC4Model
8
- export function useLikeC4Model(strict: boolean): LikeC4Model | null
9
- export function useLikeC4Model(strict: true, type: 'layouted'): LikeC4Model.Layouted
10
- export function useLikeC4Model(strict: true, type: 'computed'): LikeC4Model.Computed
11
- export function useLikeC4Model(strict: true, type: 'layouted' | 'computed' | undefined): LikeC4Model
12
- export function useLikeC4Model(strict: boolean, type: 'layouted'): LikeC4Model.Layouted | null
13
- export function useLikeC4Model(strict: boolean, type: 'computed'): LikeC4Model.Computed | null
14
- export function useLikeC4Model(strict: boolean, type: 'layouted' | 'computed' | undefined): LikeC4Model | null
15
- export function useLikeC4Model(strict?: boolean, type?: 'layouted' | 'computed') {
6
+ export function useLikeC4Model<A extends aux.Any = aux.Unknown>(): LikeC4Model<A>
7
+ export function useLikeC4Model<A extends aux.Any = aux.Unknown>(type: 'layouted'): LikeC4Model.Layouted<A>
8
+ export function useLikeC4Model<A extends aux.Any = aux.Unknown>(type: 'computed'): LikeC4Model.Computed<A>
9
+ // dprint-ignore
10
+ export function useLikeC4Model<A extends aux.Any = aux.Unknown>(type: 'layouted' | 'computed' | undefined): LikeC4Model<A>
11
+ export function useLikeC4Model(type?: 'layouted' | 'computed') {
16
12
  const model = useContext(LikeC4ModelContext)
17
13
 
18
- if (isString(type) && isNonNullish(model) && model.type !== type) {
19
- throw new Error(`Invalid LikeC4ModelContext, expected "${type}" but got "${model.type}" in context`)
14
+ if (!model) {
15
+ throw new Error('No LikeC4Model found in context')
20
16
  }
21
17
 
22
- if (isDefined(strict) && strict === true && !model) {
23
- throw new Error('No LikeC4Model found in context')
18
+ if (isString(type) && model.stage !== type) {
19
+ throw new Error(`Invalid LikeC4ModelContext, expected "${type}" but got "${model.stage}" in context`)
24
20
  }
21
+
25
22
  return model
26
23
  }
24
+
25
+ export function useLikeC4Specification() {
26
+ const model = useLikeC4Model()
27
+ return model.$data.specification
28
+ }
@@ -1,13 +1,12 @@
1
1
  import { nonexhaustive } from '@likec4/core'
2
- import { Box, Button, Code, Group, Notification, ScrollAreaAutosize } from '@mantine/core'
3
- import { IconX } from '@tabler/icons-react'
4
2
  import { useSelector } from '@xstate/react'
5
3
  import { animate } from 'motion'
6
4
  import { AnimatePresence, LayoutGroup, useReducedMotionConfig } from 'motion/react'
7
- import { memo, useEffect, useMemo } from 'react'
8
- import { type FallbackProps, ErrorBoundary } from 'react-error-boundary'
5
+ import { useEffect, useMemo } from 'react'
6
+ import { ErrorBoundary } from 'react-error-boundary'
9
7
  import { isNonNullish } from 'remeda'
10
8
  import type { AnyActorRef } from 'xstate'
9
+ import { ErrorFallback } from '../components/ErrorFallback'
11
10
  import { DiagramFeatures } from '../context'
12
11
  import { useXYStore } from '../hooks'
13
12
  import { ElementDetails } from './element-details/ElementDetails'
@@ -16,32 +15,6 @@ import { type OverlaysActorRef, type OverlaysActorSnapshot } from './overlaysAct
16
15
  import { RelationshipDetails } from './relationship-details/RelationshipDetails'
17
16
  import { RelationshipsBrowser } from './relationships-browser/RelationshipsBrowser'
18
17
 
19
- function Fallback({ error, resetErrorBoundary }: FallbackProps) {
20
- const errorString = error instanceof Error ? error.message : 'Unknown error'
21
- return (
22
- <Box pos={'fixed'} top={0} left={0} w={'100%'} p={0} style={{ zIndex: 1000 }}>
23
- <Notification
24
- icon={<IconX style={{ width: 16, height: 16 }} />}
25
- styles={{
26
- icon: {
27
- alignSelf: 'flex-start',
28
- },
29
- }}
30
- color={'red'}
31
- title={'Oops, something went wrong'}
32
- p={'xl'}
33
- withCloseButton={false}>
34
- <ScrollAreaAutosize maw={'100%'} mah={400}>
35
- <Code block>{errorString}</Code>
36
- </ScrollAreaAutosize>
37
- <Group gap={'xs'} mt="xl">
38
- <Button color="gray" size="xs" variant="light" onClick={() => resetErrorBoundary()}>Reset</Button>
39
- </Group>
40
- </Notification>
41
- </Box>
42
- )
43
- }
44
-
45
18
  const selectOverlays = (s: OverlaysActorSnapshot) => {
46
19
  return s.context.overlays.map((overlay) => {
47
20
  switch (overlay.type) {
@@ -85,7 +58,7 @@ export function Overlays({ overlaysActorRef }: { overlaysActorRef: OverlaysActor
85
58
  const overlays = useSelector(overlaysActorRef, selectOverlays, compareSelectOverlays)
86
59
  const isMotionReduced = useReducedMotionConfig() ?? false
87
60
 
88
- const isActiveOverlay = overlays.length > 0
61
+ const isActiveOverlay = overlays.some((overlay) => overlay.type === 'elementDetails')
89
62
 
90
63
  useEffect(() => {
91
64
  if (!xyflowRendererDom || isMotionReduced) return
@@ -136,7 +109,7 @@ export function Overlays({ overlaysActorRef }: { overlaysActorRef: OverlaysActor
136
109
 
137
110
  return (
138
111
  <DiagramFeatures.Overlays>
139
- <ErrorBoundary FallbackComponent={Fallback} onReset={() => overlaysActorRef.send({ type: 'close.all' })}>
112
+ <ErrorBoundary FallbackComponent={ErrorFallback} onReset={() => overlaysActorRef.send({ type: 'close.all' })}>
140
113
  <LayoutGroup>
141
114
  <AnimatePresence>
142
115
  {overlaysReact}
@@ -1,14 +1,13 @@
1
1
  import {
2
+ type Any,
2
3
  type ComputedView,
3
4
  type DiagramView,
4
5
  type Element,
5
6
  type Fqn,
6
- type LikeC4View,
7
7
  type NodeId,
8
+ type scalar,
8
9
  type ViewId,
9
- isDeploymentView,
10
- isScopedElementView,
11
- } from '@likec4/core'
10
+ } from '@likec4/core/types'
12
11
  import { css, cx } from '@likec4/styles/css'
13
12
  import {
14
13
  type TextProps,
@@ -41,6 +40,7 @@ import type { Rect } from '@xyflow/system'
41
40
  import { type PanInfo, m, useDragControls, useMotionValue } from 'motion/react'
42
41
  import { type PropsWithChildren, useCallback, useRef, useState } from 'react'
43
42
  import { clamp, isNullish, map, only, partition, pipe } from 'remeda'
43
+ import { ElementTag } from '../../base/primitives/element/ElementTags'
44
44
  import { Link } from '../../components/Link'
45
45
  import { DiagramFeatures, IconRenderer, IfEnabled } from '../../context'
46
46
  import { useUpdateEffect } from '../../hooks'
@@ -113,7 +113,7 @@ export function ElementDetailsCard({
113
113
  defaultValue: 'Properties',
114
114
  })
115
115
  const diagram = useDiagram()
116
- const likec4model = useLikeC4Model(true)
116
+ const likec4model = useLikeC4Model()
117
117
  const viewModel = likec4model.view(viewId)
118
118
  const nodeModel = fromNode ? viewModel.findNode(fromNode) : viewModel.findNodeWithElement(fqn)
119
119
 
@@ -122,10 +122,7 @@ export function ElementDetailsCard({
122
122
  const [viewsOf, otherViews] = pipe(
123
123
  [...elementModel.views()],
124
124
  map(v => v.$view),
125
- partition(view => {
126
- const v = view as LikeC4View
127
- return isScopedElementView(v) && v.viewOf === fqn
128
- }),
125
+ partition(v => v._type === 'element' && v.viewOf === fqn),
129
126
  )
130
127
 
131
128
  let defaultView = nodeModel?.navigateTo?.$view ?? elementModel.defaultView?.$view ?? null
@@ -331,16 +328,26 @@ export function ElementDetailsCard({
331
328
  </div>
332
329
  <div style={{ flex: 1 }}>
333
330
  <SmallLabel>tags</SmallLabel>
334
- <Flex gap={4} flex={1} mt={6}>
331
+ <Flex gap={4} flex={1} mt={6} wrap="wrap">
335
332
  {elementModel.tags.map((tag) => (
336
- <Badge key={tag} radius={'sm'} size="sm" fw={600} variant="gradient">#{tag}</Badge>
333
+ <ElementTag
334
+ key={tag}
335
+ tag={tag}
336
+ css={{
337
+ cursor: 'pointer',
338
+ }}
339
+ onClick={e => {
340
+ e.stopPropagation()
341
+ diagram.openSearch(`#${tag}`)
342
+ }}
343
+ />
337
344
  ))}
338
345
  {elementModel.tags.length === 0 && <Badge radius={'sm'} size="sm" fw={600} color="gray">—</Badge>}
339
346
  </Flex>
340
347
  </div>
341
348
  <ActionIconGroup
342
349
  style={{
343
- alignSelf: 'flex-end',
350
+ alignSelf: 'flex-start',
344
351
  }}>
345
352
  {defaultLink && (
346
353
  <ActionIcon
@@ -454,7 +461,7 @@ export function ElementDetailsCard({
454
461
  <ViewButton
455
462
  key={view.id}
456
463
  view={view}
457
- onNavigateTo={to => diagram.navigateTo(to, fromNode ?? undefined)} />
464
+ onNavigateTo={to => diagram.navigateTo(to as scalar.ViewId, fromNode ?? undefined)} />
458
465
  ))}
459
466
  </Stack>
460
467
  </Box>
@@ -467,7 +474,7 @@ export function ElementDetailsCard({
467
474
  <ViewButton
468
475
  key={view.id}
469
476
  view={view}
470
- onNavigateTo={to => diagram.navigateTo(to, fromNode ?? undefined)} />
477
+ onNavigateTo={to => diagram.navigateTo(to as scalar.ViewId, fromNode ?? undefined)} />
471
478
  ))}
472
479
  </Stack>
473
480
  </Box>
@@ -501,18 +508,18 @@ export function ElementDetailsCard({
501
508
  )
502
509
  }
503
510
 
504
- const ViewButton = ({
511
+ const ViewButton = <A extends Any>({
505
512
  view,
506
513
  onNavigateTo,
507
514
  }: {
508
- view: ComputedView | DiagramView
509
- onNavigateTo: OnNavigateTo
515
+ view: ComputedView<A> | DiagramView<A>
516
+ onNavigateTo: OnNavigateTo<A>
510
517
  }) => {
511
518
  return (
512
519
  <UnstyledButton className={styles.viewButton} onClick={e => onNavigateTo(view.id, e)}>
513
520
  <Group gap={6} align="start" wrap="nowrap">
514
521
  <ThemeIcon size={'sm'} variant="transparent">
515
- {isDeploymentView(view)
522
+ {view._type === 'deployment'
516
523
  ? <IconStack2 stroke={1.8} />
517
524
  : <IconZoomScan stroke={1.8} />}
518
525
  </ThemeIcon>