@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
@@ -1,43 +1,47 @@
1
- import type { ViewId, WhereOperator } from '@likec4/core'
2
- import { useDeepCompareEffect } from '@react-hookz/web'
1
+ import type { DiagramView, WhereOperator } from '@likec4/core/types'
3
2
  import { useActorRef, useSelector } from '@xstate/react'
4
3
  import { useStoreApi } from '@xyflow/react'
5
4
  import { shallowEqual } from 'fast-equals'
6
- import { type PropsWithChildren, useEffect } from 'react'
5
+ import { type PropsWithChildren, useEffect, useRef } from 'react'
7
6
  import { useDiagramEventHandlersRef } from '../context/DiagramEventHandlers'
8
7
  import { DiagramFeatures, useEnabledFeatures } from '../context/DiagramFeatures'
9
8
  import { DiagramActorContextProvider } from '../hooks/safeContext'
10
- import { useUpdateEffect } from '../hooks/useUpdateEffect'
9
+ import type { PaddingWithUnit } from '../LikeC4Diagram.props'
11
10
  import type { Types } from '../likec4diagram/types'
12
11
  import { useViewToNodesEdges } from '../likec4diagram/useViewToNodesEdges'
13
- import { type Input, diagramMachine } from './diagram-machine'
12
+ import { type DiagramMachine, diagramMachine } from './diagram-machine'
14
13
  import { syncManualLayoutActorLogic } from './syncManualLayoutActor'
15
14
  import type { DiagramActorSnapshot } from './types'
16
15
 
17
16
  const selectToggledFeatures = (state: DiagramActorSnapshot) => state.context.toggledFeatures
18
- type ActorContextInput = Omit<Input, 'xystore' | 'xynodes' | 'xyedges'>
19
17
  export function DiagramActorProvider({
20
- input: {
21
- view,
22
- ...inputs
23
- },
18
+ view,
19
+ zoomable,
20
+ pannable,
21
+ fitViewPadding,
22
+ nodesSelectable,
24
23
  where,
25
24
  children,
26
25
  }: PropsWithChildren<{
27
- input: ActorContextInput
28
- where?: WhereOperator<string, string> | undefined
26
+ view: DiagramView
27
+ zoomable: boolean
28
+ pannable: boolean
29
+ fitViewPadding: PaddingWithUnit
30
+ nodesSelectable: boolean
31
+ where: WhereOperator | null
29
32
  }>) {
30
33
  const handlersRef = useDiagramEventHandlersRef()
31
34
  const xystore = useStoreApi<Types.Node, Types.Edge>()
32
35
 
33
- const actorRef = useActorRef(
34
- diagramMachine.provide({
36
+ const machineRef = useRef<DiagramMachine | null>(null)
37
+ if (!machineRef.current) {
38
+ machineRef.current = diagramMachine.provide({
35
39
  actions: {
36
40
  'trigger:NavigateTo': ((_, { viewId }) => {
37
41
  // Slightly defer callback for better responsiveness
38
42
  setTimeout(() => {
39
- handlersRef.current.onNavigateTo?.(viewId as ViewId)
40
- }, 50)
43
+ handlersRef.current.onNavigateTo?.(viewId)
44
+ }, 30)
41
45
  }),
42
46
 
43
47
  'trigger:OnChange': ((_, params) => {
@@ -57,35 +61,42 @@ export function DiagramActorProvider({
57
61
  },
58
62
  }),
59
63
  },
60
- }),
64
+ })
65
+ }
66
+
67
+ const actorRef = useActorRef(
68
+ machineRef.current,
61
69
  {
62
- id: `diagram:${view.id}`,
70
+ id: `diagram`,
63
71
  systemId: 'diagram',
64
72
  // ...inspector,
65
73
  input: {
66
74
  xystore,
67
75
  view,
68
- ...inputs,
76
+ zoomable,
77
+ pannable,
78
+ fitViewPadding,
79
+ nodesSelectable,
69
80
  },
70
81
  },
71
82
  )
72
83
 
73
84
  const features = useEnabledFeatures()
74
- useUpdateEffect(() => {
75
- actorRef.send({ type: 'update.inputs', inputs })
76
- }, [inputs])
77
-
78
85
  useEffect(() => {
79
86
  actorRef.send({ type: 'update.features', features })
80
87
  }, [features])
81
88
 
89
+ useEffect(() => {
90
+ actorRef.send({ type: 'update.inputs', inputs: { zoomable, pannable, fitViewPadding, nodesSelectable } })
91
+ }, [zoomable, pannable, fitViewPadding, nodesSelectable])
92
+
82
93
  const { xyedges, xynodes } = useViewToNodesEdges({
83
94
  view,
84
95
  where,
85
- nodesSelectable: inputs.nodesSelectable,
96
+ nodesSelectable,
86
97
  })
87
98
 
88
- useDeepCompareEffect(() => {
99
+ useEffect(() => {
89
100
  actorRef.send({ type: 'update.view', view, xyedges, xynodes })
90
101
  }, [view, xyedges, xynodes])
91
102
 
@@ -140,16 +140,16 @@ export function focusNodesEdges(params: ActionArg): Partial<DiagramContext> {
140
140
  }
141
141
  }
142
142
 
143
- export function unfocusNodesEdges({ context }: ActionArg): Partial<DiagramContext> {
144
- const { xynodes, xyedges } = context
145
- return {
146
- xynodes: xynodes.map(Base.setDimmed(false)),
147
- xyedges: xyedges.map(Base.setData({
148
- dimmed: false,
149
- active: false,
150
- })),
151
- }
152
- }
143
+ // export function unfocusNodesEdges({ context }: ActionArg): Partial<DiagramContext> {
144
+ // const { xynodes, xyedges } = context
145
+ // return {
146
+ // xynodes: xynodes.map(Base.setDimmed(false)),
147
+ // xyedges: xyedges.map(Base.setData({
148
+ // dimmed: false,
149
+ // active: false,
150
+ // })),
151
+ // }
152
+ // }
153
153
 
154
154
  export function updateNavigationHistory({ context, event }: ActionArg): Partial<DiagramContext> {
155
155
  assertEvent(event, 'update.view')
@@ -1,16 +1,15 @@
1
1
  import {
2
- type BBox,
2
+ type DiagramNode,
3
3
  type DiagramView,
4
4
  type EdgeId,
5
- type ElementNotation,
6
5
  type Fqn,
7
6
  type NodeId,
7
+ type NodeNotation as ElementNotation,
8
8
  type StepEdgeId,
9
9
  type ViewChange,
10
10
  type ViewId,
11
11
  type XYPoint,
12
- DiagramNode,
13
- getBBoxCenter,
12
+ BBox,
14
13
  getParallelStepsPrefix,
15
14
  invariant,
16
15
  isStepEdgeId,
@@ -51,6 +50,7 @@ import type { OpenSourceParams, PaddingWithUnit } from '../LikeC4Diagram.props'
51
50
  import type { Types } from '../likec4diagram/types'
52
51
  import { createLayoutConstraints } from '../likec4diagram/useLayoutConstraints'
53
52
  import { overlaysActorLogic } from '../overlays/overlaysActor'
53
+ import { searchActorLogic } from '../search/searchActor'
54
54
  import { type AlignmentMode, getAligner, toNodeRect } from './aligners'
55
55
  import {
56
56
  focusNodesEdges,
@@ -59,7 +59,6 @@ import {
59
59
  navigateBack,
60
60
  navigateForward,
61
61
  resetEdgeControlPoints,
62
- unfocusNodesEdges,
63
62
  updateActiveWalkthrough,
64
63
  updateEdgeData,
65
64
  updateNavigationHistory,
@@ -161,6 +160,7 @@ export type Events =
161
160
  | { type: 'open.elementDetails'; fqn: Fqn; fromNode?: NodeId | undefined }
162
161
  | { type: 'open.relationshipDetails'; params: { edgeId: EdgeId } | { source: Fqn; target: Fqn } }
163
162
  | { type: 'open.relationshipsBrowser'; fqn: Fqn }
163
+ | { type: 'open.search'; search?: string }
164
164
  // | { type: 'close.overlay' }
165
165
  | { type: 'navigate.to'; viewId: ViewId; fromNode?: NodeId | undefined }
166
166
  | { type: 'navigate.back' }
@@ -175,6 +175,8 @@ export type Events =
175
175
  | { type: 'walkthrough.end' }
176
176
  | { type: 'notations.highlight'; notation: ElementNotation; kind?: string }
177
177
  | { type: 'notations.unhighlight' }
178
+ | { type: 'tag.highlight'; tag: string }
179
+ | { type: 'tag.unhighlight' }
178
180
  | { type: 'toggle.feature'; feature: FeatureName; forceValue?: boolean }
179
181
 
180
182
  export type ActionArg = { context: Context; event: Events }
@@ -188,6 +190,7 @@ const _diagramMachine = setup({
188
190
  syncLayout: 'syncManualLayoutActorLogic'
189
191
  hotkey: 'hotkeyActorLogic'
190
192
  overlays: 'overlaysActorLogic'
193
+ search: 'searchActorLogic'
191
194
  },
192
195
  events: {} as Events,
193
196
  },
@@ -195,6 +198,7 @@ const _diagramMachine = setup({
195
198
  syncManualLayoutActorLogic,
196
199
  hotkeyActorLogic,
197
200
  overlaysActorLogic,
201
+ searchActorLogic,
198
202
  },
199
203
  guards: {
200
204
  'isReady': ({ context }) => context.initialized.xydata && context.initialized.xyflow,
@@ -202,8 +206,9 @@ const _diagramMachine = setup({
202
206
  'enabled: FocusMode': ({ context }) => context.features.enableFocusMode,
203
207
  'enabled: Readonly': ({ context }) => context.features.enableReadOnly,
204
208
  'enabled: RelationshipDetails': ({ context }) => context.features.enableRelationshipDetails,
209
+ 'enabled: Search': ({ context }) => context.features.enableSearch,
205
210
  'not readonly': ({ context }) => !context.features.enableReadOnly,
206
- 'is dynamic view': ({ context }) => context.view.__ === 'dynamic',
211
+ 'is dynamic view': ({ context }) => context.view._type === 'dynamic',
207
212
  'is another view': ({ context, event }) => {
208
213
  assertEvent(event, ['update.view', 'navigate.to'])
209
214
  if (event.type === 'update.view') {
@@ -258,10 +263,10 @@ const _diagramMachine = setup({
258
263
  const diagramNode = findDiagramNode(context, nodeId)
259
264
  if (!diagramNode) return
260
265
 
261
- if (DiagramNode.deploymentRef(diagramNode)) {
262
- enqueue.raise({ type: 'open.source', deployment: DiagramNode.deploymentRef(diagramNode)! })
263
- } else if (DiagramNode.modelRef(diagramNode)) {
264
- enqueue.raise({ type: 'open.source', element: DiagramNode.modelRef(diagramNode)! })
266
+ if (diagramNode.deploymentRef) {
267
+ enqueue.raise({ type: 'open.source', deployment: diagramNode.deploymentRef })
268
+ } else if (diagramNode.modelRef) {
269
+ enqueue.raise({ type: 'open.source', element: diagramNode.modelRef })
265
270
  }
266
271
  }),
267
272
 
@@ -270,7 +275,7 @@ const _diagramMachine = setup({
270
275
  bounds = context.view.bounds,
271
276
  duration = 450,
272
277
  } = params ?? {}
273
- const { width, height, panZoom, transform } = context.xystore.getState()
278
+ const { width, height, panZoom, transform } = nonNullable(context.xystore).getState()
274
279
 
275
280
  const maxZoom = Math.max(1, transform[2])
276
281
  const viewport = getViewportForBounds(
@@ -288,7 +293,7 @@ const _diagramMachine = setup({
288
293
 
289
294
  'xyflow:fitFocusedBounds': ({ context }) => {
290
295
  const { bounds, duration = 450 } = focusedBounds({ context })
291
- const { width, height, panZoom, transform } = context.xystore.getState()
296
+ const { width, height, panZoom, transform } = nonNullable(context.xystore).getState()
292
297
 
293
298
  const maxZoom = Math.max(1, transform[2])
294
299
  const viewport = getViewportForBounds(
@@ -316,7 +321,7 @@ const _diagramMachine = setup({
316
321
  viewport,
317
322
  duration = 350,
318
323
  } = params
319
- const { panZoom } = context.xystore.getState()
324
+ const panZoom = context.xystore?.getState().panZoom
320
325
  panZoom?.setViewport(viewport, duration > 0 ? { duration } : undefined)
321
326
  },
322
327
 
@@ -333,12 +338,12 @@ const _diagramMachine = setup({
333
338
  x: Math.round(fromPos.x - toPos.x),
334
339
  y: Math.round(fromPos.y - toPos.y),
335
340
  }
336
- context.xystore.getState().panBy(diff)
341
+ context.xystore!.getState().panBy(diff)
337
342
  },
338
343
 
339
344
  'layout.align': ({ context }, params: { mode: AlignmentMode }) => {
340
345
  const { mode } = params
341
- const { xystore } = context
346
+ const xystore = nonNullable(context.xystore, 'xystore is not initialized')
342
347
  const { nodeLookup, parentLookup } = xystore.getState()
343
348
 
344
349
  const selectedNodes = new Set(nodeLookup.values().filter(n => n.selected).map(n => n.id))
@@ -365,14 +370,7 @@ const _diagramMachine = setup({
365
370
  }
366
371
  constraints.updateXYFlowNodes()
367
372
  },
368
-
369
- 'updateFeatures': enqueueActions(({ enqueue, system, event }) => {
370
- assertEvent(event, 'update.features')
371
- const { features } = event
372
- enqueue.assign({
373
- features: { ...features },
374
- })
375
-
373
+ 'ensure overlays actor state': enqueueActions(({ enqueue, context: { features }, system }) => {
376
374
  const enableOverlays = features.enableElementDetails || features.enableRelationshipDetails ||
377
375
  features.enableRelationshipBrowser
378
376
  const hasRunning = typedSystem(system).overlaysActorRef
@@ -387,14 +385,37 @@ const _diagramMachine = setup({
387
385
  enqueue.stopChild('overlays')
388
386
  }
389
387
  }),
390
-
388
+ 'ensure search actor state': enqueueActions(({ enqueue, context: { features: { enableSearch } }, system }) => {
389
+ const hasRunning = typedSystem(system).searchActorRef
390
+ if (enableSearch && !hasRunning) {
391
+ enqueue.spawnChild('searchActorLogic', { id: 'search', systemId: 'search' })
392
+ return
393
+ }
394
+ if (!enableSearch && hasRunning) {
395
+ enqueue.sendTo(hasRunning, {
396
+ type: 'close',
397
+ })
398
+ enqueue.stopChild('search')
399
+ }
400
+ }),
401
+ 'updateFeatures': assign(({ event }) => {
402
+ assertEvent(event, 'update.features')
403
+ return {
404
+ features: { ...event.features },
405
+ }
406
+ }),
407
+ 'closeSearch': sendTo(
408
+ ({ system }) => typedSystem(system).searchActorRef!,
409
+ {
410
+ type: 'close',
411
+ },
412
+ ),
391
413
  'closeAllOverlays': sendTo(
392
414
  ({ system }) => typedSystem(system).overlaysActorRef!,
393
415
  {
394
416
  type: 'close.all',
395
417
  },
396
418
  ),
397
-
398
419
  'startSyncLayout': assign(({ context, spawn, self }) => ({
399
420
  syncLayoutActorRef: spawn('syncManualLayoutActorLogic', {
400
421
  id: 'syncLayout',
@@ -450,6 +471,7 @@ const _diagramMachine = setup({
450
471
  }),
451
472
  }
452
473
  }),
474
+ 'focus on nodes and edges': assign(focusNodesEdges),
453
475
  'notations.highlight': assign(({ context }, params: { notation: ElementNotation; kind?: string }) => {
454
476
  const kinds = params.kind ? [params.kind] : params.notation.kinds
455
477
  const xynodes = context.xynodes.map((n) => {
@@ -470,10 +492,29 @@ const _diagramMachine = setup({
470
492
  xyedges: context.xyedges.map(Base.setDimmed('immediate')),
471
493
  }
472
494
  }),
495
+ 'tag.highlight': assign(({ context, event }) => {
496
+ assertEvent(event, 'tag.highlight')
497
+ return {
498
+ xynodes: context.xynodes.map((n) => {
499
+ if (n.data.tags?.includes(event.tag)) {
500
+ return Base.setDimmed(n, false)
501
+ }
502
+ return Base.setDimmed(n, 'immediate')
503
+ }),
504
+ }
505
+ }),
506
+ 'undim everything': assign(({ context }) => ({
507
+ xynodes: context.xynodes.map(Base.setDimmed(false)),
508
+ xyedges: context.xyedges.map(Base.setData({
509
+ dimmed: false,
510
+ active: false,
511
+ })),
512
+ })),
513
+ 'update active walkthrough': assign(updateActiveWalkthrough),
473
514
  },
474
515
  }).createMachine({
475
516
  initial: 'initializing',
476
- context: ({ input, self, spawn }) => ({
517
+ context: ({ input }): Context => ({
477
518
  ...input,
478
519
  xyedges: [],
479
520
  xynodes: [],
@@ -528,7 +569,7 @@ const _diagramMachine = setup({
528
569
  },
529
570
  },
530
571
  },
531
- 'isReady': {
572
+ isReady: {
532
573
  always: [{
533
574
  guard: 'isReady',
534
575
  actions: [
@@ -609,8 +650,8 @@ const _diagramMachine = setup({
609
650
  node: NodeId
610
651
  clientRect: Rect
611
652
  }
612
- const fromNodeId = event.fromNode ?? context.view.nodes.find(n => DiagramNode.modelRef(n) === event.fqn)?.id
613
- const internalNode = fromNodeId ? context.xystore.getState().nodeLookup.get(fromNodeId) : null
653
+ const fromNodeId = event.fromNode ?? context.view.nodes.find(n => n.modelRef === event.fqn)?.id
654
+ const internalNode = fromNodeId ? nonNullable(context.xystore).getState().nodeLookup.get(fromNodeId) : null
614
655
  if (fromNodeId && internalNode) {
615
656
  const nodeRect = nodeToRect(internalNode)
616
657
  const zoom = context.xyflow!.getZoom()
@@ -703,10 +744,13 @@ const _diagramMachine = setup({
703
744
  },
704
745
  },
705
746
  'notations.unhighlight': {
706
- actions: assign(({ context }) => ({
707
- xynodes: context.xynodes.map(Base.setDimmed(false)),
708
- xyedges: context.xyedges.map(Base.setDimmed(false)),
709
- })),
747
+ actions: 'undim everything',
748
+ },
749
+ 'tag.highlight': {
750
+ actions: 'tag.highlight',
751
+ },
752
+ 'tag.unhighlight': {
753
+ actions: 'undim everything',
710
754
  },
711
755
  'saveManualLayout.*': {
712
756
  guard: 'not readonly',
@@ -720,6 +764,13 @@ const _diagramMachine = setup({
720
764
  nonexhaustive(event)
721
765
  }),
722
766
  },
767
+ 'open.search': {
768
+ guard: 'enabled: Search',
769
+ actions: sendTo(({ system }) => typedSystem(system).searchActorRef!, ({ event }) => ({
770
+ type: 'open',
771
+ search: event.search,
772
+ })),
773
+ },
723
774
  },
724
775
  exit: [
725
776
  cancel('fitDiagram'),
@@ -798,8 +849,8 @@ const _diagramMachine = setup({
798
849
  },
799
850
  focused: {
800
851
  entry: [
852
+ 'focus on nodes and edges',
801
853
  assign(s => ({
802
- ...focusNodesEdges(s),
803
854
  viewportBeforeFocus: { ...s.context.viewport },
804
855
  })),
805
856
  'open source of focused or last clicked node',
@@ -811,10 +862,10 @@ const _diagramMachine = setup({
811
862
  if (context.viewportBeforeFocus) {
812
863
  enqueue({ type: 'xyflow:setViewport', params: { viewport: context.viewportBeforeFocus } })
813
864
  } else {
814
- enqueue({ type: 'xyflow:fitDiagram' })
865
+ enqueue('xyflow:fitDiagram')
815
866
  }
867
+ enqueue('undim everything')
816
868
  enqueue.assign({
817
- ...unfocusNodesEdges({ context, event }),
818
869
  viewportBeforeFocus: null,
819
870
  focusedNode: null,
820
871
  })
@@ -842,7 +893,7 @@ const _diagramMachine = setup({
842
893
  assign({
843
894
  focusedNode: ({ event }) => event.nodeId,
844
895
  }),
845
- assign(focusNodesEdges),
896
+ 'focus on nodes and edges',
846
897
  'open source of focused or last clicked node',
847
898
  'xyflow:fitFocusedBounds',
848
899
  ],
@@ -857,9 +908,10 @@ const _diagramMachine = setup({
857
908
  target: 'idle',
858
909
  },
859
910
  'notations.unhighlight': {
860
- actions: assign(s => ({
861
- ...focusNodesEdges(s),
862
- })),
911
+ actions: 'focus on nodes and edges',
912
+ },
913
+ 'tag.unhighlight': {
914
+ actions: 'focus on nodes and edges',
863
915
  },
864
916
  },
865
917
  },
@@ -877,7 +929,7 @@ const _diagramMachine = setup({
877
929
  }
878
930
  },
879
931
  }),
880
- assign(updateActiveWalkthrough),
932
+ 'update active walkthrough',
881
933
  'xyflow:fitFocusedBounds',
882
934
  ],
883
935
  on: {
@@ -908,7 +960,7 @@ const _diagramMachine = setup({
908
960
  parallelPrefix: getParallelStepsPrefix(nextStepId),
909
961
  },
910
962
  })
911
- enqueue.assign(updateActiveWalkthrough)
963
+ enqueue('update active walkthrough')
912
964
  enqueue('xyflow:fitFocusedBounds')
913
965
  }),
914
966
  },
@@ -925,14 +977,15 @@ const _diagramMachine = setup({
925
977
  },
926
978
  }
927
979
  }),
928
- assign(updateActiveWalkthrough),
980
+ 'update active walkthrough',
929
981
  'xyflow:fitFocusedBounds',
930
982
  ],
931
983
  },
932
984
  'notations.unhighlight': {
933
- actions: assign(s => ({
934
- ...updateActiveWalkthrough(s),
935
- })),
985
+ actions: 'update active walkthrough',
986
+ },
987
+ 'tag.unhighlight': {
988
+ actions: 'update active walkthrough',
936
989
  },
937
990
  'walkthrough.end': {
938
991
  target: 'idle',
@@ -952,11 +1005,11 @@ const _diagramMachine = setup({
952
1005
  if (context.viewportBeforeFocus) {
953
1006
  enqueue({ type: 'xyflow:setViewport', params: { viewport: context.viewportBeforeFocus } })
954
1007
  } else {
955
- enqueue({ type: 'xyflow:fitDiagram' })
1008
+ enqueue('xyflow:fitDiagram')
956
1009
  }
1010
+ enqueue('undim everything')
957
1011
  enqueue.assign({
958
1012
  activeWalkthrough: null,
959
- ...unfocusNodesEdges({ context, event }),
960
1013
  viewportBeforeFocus: null,
961
1014
  })
962
1015
  }),
@@ -968,6 +1021,7 @@ const _diagramMachine = setup({
968
1021
  id: 'navigating',
969
1022
  entry: [
970
1023
  'closeAllOverlays',
1024
+ 'closeSearch',
971
1025
  'stopSyncLayout',
972
1026
  {
973
1027
  type: 'trigger:NavigateTo',
@@ -994,7 +1048,7 @@ const _diagramMachine = setup({
994
1048
  } else {
995
1049
  enqueue({
996
1050
  type: 'xyflow:setViewportCenter',
997
- params: getBBoxCenter(event.view.bounds),
1051
+ params: BBox.center(event.view.bounds),
998
1052
  })
999
1053
  }
1000
1054
  enqueue.assign(updateNavigationHistory)
@@ -1047,6 +1101,7 @@ const _diagramMachine = setup({
1047
1101
  const isAnotherView = check('is another view')
1048
1102
  if (isAnotherView) {
1049
1103
  enqueue('closeAllOverlays')
1104
+ enqueue('closeSearch')
1050
1105
  enqueue('stopSyncLayout')
1051
1106
  enqueue.assign({
1052
1107
  focusedNode: null,
@@ -1067,7 +1122,7 @@ const _diagramMachine = setup({
1067
1122
  } else {
1068
1123
  enqueue({
1069
1124
  type: 'xyflow:setViewportCenter',
1070
- params: getBBoxCenter(event.view.bounds),
1125
+ params: BBox.center(event.view.bounds),
1071
1126
  })
1072
1127
  enqueue.raise({ type: 'fitDiagram', duration: 200 }, { id: 'fitDiagram', delay: 25 })
1073
1128
  }
@@ -1091,13 +1146,19 @@ const _diagramMachine = setup({
1091
1146
  actions: assign(({ event }) => ({ ...event.inputs })),
1092
1147
  },
1093
1148
  'update.features': {
1094
- actions: 'updateFeatures',
1149
+ actions: [
1150
+ 'updateFeatures',
1151
+ 'ensure overlays actor state',
1152
+ 'ensure search actor state',
1153
+ ],
1095
1154
  },
1096
1155
  },
1097
1156
  exit: [
1098
1157
  'stopSyncLayout',
1099
1158
  cancel('fitDiagram'),
1100
1159
  stopChild('hotkey'),
1160
+ stopChild('overlays'),
1161
+ stopChild('search'),
1101
1162
  assign({
1102
1163
  xyflow: null,
1103
1164
  xystore: null as any,
@@ -1112,7 +1173,9 @@ const _diagramMachine = setup({
1112
1173
  ],
1113
1174
  })
1114
1175
 
1115
- const nodeRef = (node: DiagramNode) => DiagramNode.modelRef(node) ?? DiagramNode.deploymentRef(node)
1176
+ function nodeRef(node: DiagramNode) {
1177
+ return node.modelRef ?? node.deploymentRef
1178
+ }
1116
1179
  function findCorrespondingNode(context: Context, event: { view: DiagramView }) {
1117
1180
  const fromNodeId = context.lastOnNavigate?.fromNode
1118
1181
  const fromNode = fromNodeId && context.view.nodes.find(n => n.id === fromNodeId)
@@ -1,4 +1,4 @@
1
- import type { ViewChange, ViewId } from '@likec4/core'
1
+ import type { ViewChange, ViewId } from '@likec4/core/types'
2
2
  import { type Rect, boxToRect, getBoundsOfRects, getNodeDimensions } from '@xyflow/system'
3
3
  import { hasAtLeast, reduce } from 'remeda'
4
4
  import {
@@ -1,5 +1,6 @@
1
1
  import type { ActorRefFromLogic, ActorSystem, EventFromLogic, SnapshotFrom } from 'xstate'
2
2
  import type { OverlaysActorRef } from '../overlays/overlaysActor'
3
+ import type { SearchActorRef } from '../search/searchActor'
3
4
  import type { DiagramMachineLogic } from './diagram-machine'
4
5
  import type { SyncLayoutActorLogic } from './syncManualLayoutActor'
5
6
 
@@ -7,6 +8,7 @@ export type System = ActorSystem<{
7
8
  actors: {
8
9
  diagram: ActorRefFromLogic<DiagramMachineLogic>
9
10
  overlays: OverlaysActorRef
11
+ search: SearchActorRef
10
12
  }
11
13
  }>
12
14
 
@@ -1,6 +1,7 @@
1
1
  import type { BBox, DiagramEdge, DiagramNode, XYPoint } from '@likec4/core/types'
2
2
  import type { ActorSystem } from 'xstate'
3
3
  import type { OverlaysActorRef } from '../overlays/overlaysActor'
4
+ import type { SearchActorRef } from '../search/searchActor'
4
5
  import type { Context } from './diagram-machine'
5
6
  import type { DiagramActorRef, System } from './types'
6
7
 
@@ -12,6 +13,9 @@ export function typedSystem(system: ActorSystem<any>) {
12
13
  get diagramActorRef(): DiagramActorRef | null {
13
14
  return (system as System).get('diagram') ?? null
14
15
  },
16
+ get searchActorRef(): SearchActorRef | null {
17
+ return (system as System).get('search') ?? null
18
+ },
15
19
  }
16
20
  }
17
21
 
@@ -1,54 +0,0 @@
1
- import { hasSubObject } from 'remeda';
2
-
3
- var Base;
4
- ((Base2) => {
5
- const _setDimmed = (v, dimmed) => (v.data.dimmed ?? false) === dimmed ? v : {
6
- ...v,
7
- data: {
8
- ...v.data,
9
- dimmed
10
- }
11
- };
12
- function setDimmed(arg1, arg2) {
13
- if (arg2 !== void 0) {
14
- return _setDimmed(arg1, arg2);
15
- }
16
- return (v) => _setDimmed(v, arg1);
17
- }
18
- Base2.setDimmed = setDimmed;
19
- const _setHovered = (v, hovered) => (v.data.hovered ?? false) === hovered ? v : {
20
- ...v,
21
- data: {
22
- ...v.data,
23
- hovered
24
- }
25
- };
26
- function setHovered(arg1, arg2) {
27
- if (arg2 !== void 0) {
28
- return _setHovered(arg1, arg2);
29
- }
30
- return (v) => _setHovered(v, arg1);
31
- }
32
- Base2.setHovered = setHovered;
33
- function _setData(value, state) {
34
- if (hasSubObject(value.data, state)) {
35
- return value;
36
- }
37
- return {
38
- ...value,
39
- data: {
40
- ...value.data,
41
- ...state
42
- }
43
- };
44
- }
45
- function setData(arg1, arg2) {
46
- if (arg2 !== void 0) {
47
- return _setData(arg1, arg2);
48
- }
49
- return (edge) => _setData(edge, arg1);
50
- }
51
- Base2.setData = setData;
52
- })(Base || (Base = {}));
53
-
54
- export { Base };
@@ -1 +0,0 @@
1
- export declare function ElementsColumn(): import("react/jsx-runtime").JSX.Element;