@likec4/diagram 1.31.0 → 1.32.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 (269) hide show
  1. package/bundle/{chunk-BBzMXzCg.js → chunk-DlHyKoeo.js} +1700 -1206
  2. package/bundle/custom.js +51 -47
  3. package/bundle/index.js +5495 -5428
  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 +41 -24
  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 +22 -19
  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 +10 -8
  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 +32 -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 +107 -110
  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 +7 -7
  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/index.d.ts +1 -1
  83. package/dist/likec4model/useLikeC4ElementsTree.js +1 -1
  84. package/dist/likec4model/useLikeC4Model.d.ts +23 -10
  85. package/dist/likec4model/useLikeC4Model.js +22 -7
  86. package/dist/overlays/Overlays.js +4 -27
  87. package/dist/overlays/element-details/ElementDetailsCard.d.ts +1 -1
  88. package/dist/overlays/element-details/ElementDetailsCard.js +19 -12
  89. package/dist/overlays/element-details/TabPanelDeployments.d.ts +1 -1
  90. package/dist/overlays/element-details/TabPanelDeployments.js +1 -1
  91. package/dist/overlays/element-details/TabPanelRelationships.d.ts +1 -1
  92. package/dist/overlays/element-details/TabPanelStructure.d.ts +1 -1
  93. package/dist/overlays/element-details/actor.d.ts +288 -286
  94. package/dist/overlays/overlay/Overlay.css.d.ts +57 -2
  95. package/dist/overlays/overlay/Overlay.css.js +76 -39
  96. package/dist/overlays/overlay/Overlay.d.ts +12 -0
  97. package/dist/overlays/overlay/Overlay.js +58 -27
  98. package/dist/overlays/overlaysActor.d.ts +1 -1
  99. package/dist/overlays/relationship-details/RelationshipDetails.d.ts +3 -2
  100. package/dist/overlays/relationship-details/RelationshipDetails.js +3 -3
  101. package/dist/overlays/relationship-details/_types.d.ts +2 -2
  102. package/dist/overlays/relationship-details/actor.js +7 -7
  103. package/dist/overlays/relationship-details/custom/edgeTypes.d.ts +3 -2
  104. package/dist/overlays/relationship-details/custom/nodeTypes.js +4 -0
  105. package/dist/overlays/relationship-details/hooks.d.ts +10 -9
  106. package/dist/overlays/relationship-details/layout-to-xyflow.js +1 -0
  107. package/dist/overlays/relationship-details/layout.js +3 -1
  108. package/dist/overlays/relationships-browser/RelationshipsBrowser.d.ts +3 -2
  109. package/dist/overlays/relationships-browser/SelectElement.js +1 -1
  110. package/dist/overlays/relationships-browser/_types.d.ts +2 -2
  111. package/dist/overlays/relationships-browser/actor.d.ts +1 -1
  112. package/dist/overlays/relationships-browser/actor.js +7 -7
  113. package/dist/overlays/relationships-browser/custom/edgeTypes.d.ts +3 -2
  114. package/dist/overlays/relationships-browser/custom/nodeTypes.d.ts +8 -5
  115. package/dist/overlays/relationships-browser/custom/nodeTypes.js +4 -0
  116. package/dist/overlays/relationships-browser/layout.d.ts +2 -2
  117. package/dist/overlays/relationships-browser/layout.js +10 -6
  118. package/dist/overlays/relationships-browser/useViewToNodesEdges.js +4 -3
  119. package/dist/search/Search.d.ts +4 -0
  120. package/dist/search/Search.js +173 -0
  121. package/dist/{likec4diagram/ui/search → search/components}/ElementsColumn.css.js +0 -1
  122. package/dist/search/components/ElementsColumn.d.ts +2 -0
  123. package/dist/{likec4diagram/ui/search → search/components}/ElementsColumn.js +26 -25
  124. package/dist/search/components/PickView.d.ts +4 -0
  125. package/dist/search/components/PickView.js +135 -0
  126. package/dist/search/components/SearchByTags.d.ts +1 -0
  127. package/dist/search/components/SearchByTags.js +119 -0
  128. package/dist/search/components/SearchInput.d.ts +2 -0
  129. package/dist/{likec4diagram/ui/search → search/components}/SearchInput.js +61 -40
  130. package/dist/{likec4diagram/ui/search → search/components}/ViewsColum.d.ts +3 -2
  131. package/dist/{likec4diagram/ui/search → search/components}/ViewsColum.js +25 -17
  132. package/dist/{likec4diagram/ui/search → search/components}/_shared.css.js +26 -35
  133. package/dist/{likec4diagram/ui/search/LikeC4Search.css.d.ts → search/components/styles.css.d.ts} +0 -2
  134. package/dist/search/components/styles.css.js +60 -0
  135. package/dist/search/components/utils.d.ts +5 -0
  136. package/dist/search/components/utils.js +58 -0
  137. package/dist/search/hooks.d.ts +10 -0
  138. package/dist/search/hooks.js +35 -0
  139. package/dist/search/searchActor.d.ts +90 -0
  140. package/dist/search/searchActor.js +75 -0
  141. package/dist/state/DiagramActorProvider.d.ts +9 -7
  142. package/dist/state/DiagramActorProvider.js +24 -18
  143. package/dist/state/assign.d.ts +0 -1
  144. package/dist/state/assign.js +9 -19
  145. package/dist/state/diagram-machine.d.ts +645 -183
  146. package/dist/state/diagram-machine.js +127 -60
  147. package/dist/state/syncManualLayoutActor.d.ts +2 -2
  148. package/dist/state/types.d.ts +2 -0
  149. package/dist/state/utils.d.ts +2 -0
  150. package/dist/state/utils.js +3 -0
  151. package/dist/styles-min.css +1 -1
  152. package/dist/styles-xyflow.css +1 -1
  153. package/dist/styles.css +1 -1
  154. package/dist/styles.css2.js +1 -1
  155. package/package.json +20 -19
  156. package/panda.buildinfo.json +171 -148
  157. package/src/LikeC4CustomColors.tsx +21 -6
  158. package/src/LikeC4Diagram.props.ts +48 -32
  159. package/src/LikeC4Diagram.tsx +19 -20
  160. package/src/LikeC4ModelProvider.tsx +6 -5
  161. package/src/StaticLikeC4Diagram.tsx +8 -6
  162. package/src/base/const.ts +1 -1
  163. package/src/base/index.ts +2 -1
  164. package/src/base/primitives/compound/CompoundActionButton.tsx +2 -1
  165. package/src/base/primitives/compound/CompoundDetailsButton.tsx +2 -1
  166. package/src/base/primitives/compound/CompoundTitle.tsx +3 -2
  167. package/src/base/primitives/edge/EdgeContainer.tsx +2 -1
  168. package/src/base/primitives/edge/EdgeLabel.css.ts +1 -0
  169. package/src/base/primitives/edge/EdgeLabel.tsx +20 -15
  170. package/src/base/primitives/edge/EdgeLabelContainer.tsx +1 -1
  171. package/src/base/primitives/edge/EdgeMarkers.tsx +2 -1
  172. package/src/base/primitives/edge/EdgePath.tsx +1 -1
  173. package/src/base/primitives/element/ElementActionButtons.tsx +11 -10
  174. package/src/base/primitives/element/ElementDetailsButton.tsx +2 -1
  175. package/src/base/primitives/element/ElementShape.tsx +2 -1
  176. package/src/base/primitives/element/ElementTags.tsx +182 -0
  177. package/src/base/primitives/element/ElementTitle.tsx +21 -15
  178. package/src/base/primitives/index.ts +1 -0
  179. package/src/base/types.Base.ts +104 -0
  180. package/src/base/types.ts +2 -99
  181. package/src/bundle/LikeC4View.props.ts +17 -4
  182. package/src/bundle/LikeC4View.tsx +27 -36
  183. package/src/bundle/ReactLikeC4.tsx +16 -36
  184. package/src/components/ErrorFallback.tsx +30 -0
  185. package/src/context/DiagramEventHandlers.tsx +5 -4
  186. package/src/context/DiagramFeatures.tsx +3 -22
  187. package/src/context/EnsureMantine.tsx +1 -1
  188. package/src/context/IconRenderer.tsx +1 -4
  189. package/src/context/RootContainer.tsx +9 -3
  190. package/src/context/TagStylesContext.tsx +96 -0
  191. package/src/custom/components.ts +2 -0
  192. package/src/custom/customNodes.tsx +29 -14
  193. package/src/custom/hooks.ts +2 -0
  194. package/src/hooks/index.ts +1 -1
  195. package/src/hooks/useCurrentViewId.ts +1 -4
  196. package/src/hooks/useDiagram.ts +104 -12
  197. package/src/hooks/useMantinePortalProps.ts +10 -1
  198. package/src/hooks/useSearchActor.ts +11 -0
  199. package/src/hooks/useUpdateEffect.ts +7 -4
  200. package/src/hooks/useXYFlow.ts +5 -0
  201. package/src/likec4diagram/DiagramUI.tsx +5 -0
  202. package/src/likec4diagram/DiagramXYFlow.tsx +118 -121
  203. package/src/likec4diagram/custom/edges/RelationshipEdge.tsx +9 -0
  204. package/src/likec4diagram/custom/edges/RelationshipsDropdownMenu.tsx +10 -9
  205. package/src/likec4diagram/custom/nodes/nodes.tsx +45 -43
  206. package/src/likec4diagram/custom/nodes/toolbar/_shared.tsx +11 -3
  207. package/src/likec4diagram/types.ts +5 -3
  208. package/src/likec4diagram/ui/controls/Controls.tsx +11 -4
  209. package/src/likec4diagram/ui/notation/NotationPanel.tsx +2 -2
  210. package/src/likec4diagram/useViewToNodesEdges.ts +34 -36
  211. package/src/likec4model/LikeC4ModelContext.ts +2 -2
  212. package/src/likec4model/index.ts +2 -0
  213. package/src/likec4model/useLikeC4ElementsTree.ts +1 -1
  214. package/src/likec4model/useLikeC4Model.ts +32 -16
  215. package/src/overlays/Overlays.tsx +5 -32
  216. package/src/overlays/element-details/ElementDetailsCard.tsx +25 -18
  217. package/src/overlays/element-details/TabPanelDeployments.tsx +3 -2
  218. package/src/overlays/element-details/TabPanelRelationships.tsx +2 -1
  219. package/src/overlays/element-details/TabPanelStructure.tsx +1 -1
  220. package/src/overlays/element-details/actor.ts +2 -2
  221. package/src/overlays/overlay/Overlay.css.ts +75 -38
  222. package/src/overlays/overlay/Overlay.tsx +61 -29
  223. package/src/overlays/overlaysActor.ts +1 -1
  224. package/src/overlays/relationship-details/RelationshipDetails.tsx +4 -4
  225. package/src/overlays/relationship-details/_types.ts +2 -1
  226. package/src/overlays/relationship-details/custom/nodeTypes.tsx +4 -0
  227. package/src/overlays/relationship-details/layout-to-xyflow.ts +1 -0
  228. package/src/overlays/relationship-details/layout.ts +3 -1
  229. package/src/overlays/relationships-browser/SelectElement.tsx +1 -1
  230. package/src/overlays/relationships-browser/_types.ts +2 -1
  231. package/src/overlays/relationships-browser/custom/nodeTypes.tsx +4 -0
  232. package/src/overlays/relationships-browser/layout.ts +12 -7
  233. package/src/overlays/relationships-browser/useViewToNodesEdges.ts +4 -4
  234. package/src/search/Search.tsx +220 -0
  235. package/src/{likec4diagram/ui/search → search/components}/ElementsColumn.css.ts +0 -29
  236. package/src/{likec4diagram/ui/search → search/components}/ElementsColumn.tsx +28 -29
  237. package/src/search/components/PickView.tsx +134 -0
  238. package/src/search/components/SearchByTags.tsx +112 -0
  239. package/src/{likec4diagram/ui/search → search/components}/SearchInput.tsx +72 -42
  240. package/src/{likec4diagram/ui/search → search/components}/ViewsColum.tsx +29 -22
  241. package/src/{likec4diagram/ui/search → search/components}/_shared.css.ts +26 -37
  242. package/src/{likec4diagram/ui/search/LikeC4Search.css.ts → search/components/styles.css.ts} +9 -36
  243. package/src/search/components/utils.ts +64 -0
  244. package/src/search/hooks.ts +38 -0
  245. package/src/search/searchActor.ts +99 -0
  246. package/src/state/DiagramActorProvider.tsx +37 -25
  247. package/src/state/assign.ts +10 -10
  248. package/src/state/diagram-machine.ts +123 -58
  249. package/src/state/syncManualLayoutActor.ts +1 -1
  250. package/src/state/types.ts +2 -0
  251. package/src/state/utils.ts +4 -0
  252. package/dist/base/types.js +0 -54
  253. package/dist/likec4diagram/ui/search/ElementsColumn.d.ts +0 -1
  254. package/dist/likec4diagram/ui/search/LikeC4Search.css.js +0 -87
  255. package/dist/likec4diagram/ui/search/LikeC4Search.d.ts +0 -2
  256. package/dist/likec4diagram/ui/search/LikeC4Search.js +0 -267
  257. package/dist/likec4diagram/ui/search/SearchInput.d.ts +0 -1
  258. package/dist/likec4diagram/ui/search/state.d.ts +0 -19
  259. package/dist/likec4diagram/ui/search/state.js +0 -63
  260. package/dist/likec4diagram/ui/search/utils.d.ts +0 -3
  261. package/dist/likec4diagram/ui/search/utils.js +0 -20
  262. package/src/likec4diagram/ui/search/LikeC4Search.tsx +0 -301
  263. package/src/likec4diagram/ui/search/state.ts +0 -78
  264. package/src/likec4diagram/ui/search/utils.ts +0 -20
  265. /package/dist/{likec4diagram/ui/search → search/components}/ElementsColumn.css.d.ts +0 -0
  266. /package/dist/{likec4diagram/ui/search → search/components}/ViewsColumn.css.d.ts +0 -0
  267. /package/dist/{likec4diagram/ui/search → search/components}/ViewsColumn.css.js +0 -0
  268. /package/dist/{likec4diagram/ui/search → search/components}/_shared.css.d.ts +0 -0
  269. /package/src/{likec4diagram/ui/search → search/components}/ViewsColumn.css.ts +0 -0
@@ -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>
@@ -1,4 +1,5 @@
1
- import type { Fqn, LikeC4Model } from '@likec4/core'
1
+ import type { LikeC4Model } from '@likec4/core/model'
2
+ import type { Fqn } from '@likec4/core/types'
2
3
  import { Alert, Box, Button, Group, Menu, rem, Text, ThemeIcon, Tree, useTree } from '@mantine/core'
3
4
  import { IconInfoCircle, IconTarget, IconZoomScan } from '@tabler/icons-react'
4
5
  import { type ReactNode, memo, useEffect, useMemo } from 'react'
@@ -107,7 +108,7 @@ const DeployedInstanceRenderer = (
107
108
 
108
109
  const setHoveredNode = () => {}
109
110
  export const TabPanelDeployments = memo<TabPanelDeploymentsProps>(({ elementFqn }) => {
110
- const element = useLikeC4Model(true).element(elementFqn)
111
+ const element = useLikeC4Model().element(elementFqn)
111
112
  const deployments = [...element.deployments()]
112
113
 
113
114
  const tree = useTree({
@@ -1,4 +1,5 @@
1
- import { type LikeC4Model, nameFromFqn } from '@likec4/core'
1
+ import { nameFromFqn } from '@likec4/core'
2
+ import type { LikeC4Model } from '@likec4/core/model'
2
3
  import { ActionIcon, Box, Group, Paper, Stack, Text, ThemeIcon, Tooltip as MantineTooltip } from '@mantine/core'
3
4
  import { IconArrowRight, IconExternalLink, IconInfoCircle } from '@tabler/icons-react'
4
5
  import { useSelector } from '@xstate/react'
@@ -1,4 +1,4 @@
1
- import type { LikeC4Model } from '@likec4/core'
1
+ import type { LikeC4Model } from '@likec4/core/model'
2
2
  import { Alert, Anchor, Box, Pill, Text, Tree, useTree } from '@mantine/core'
3
3
  import { IconInfoCircle } from '@tabler/icons-react'
4
4
  import { type ReactNode, useEffect, useMemo } from 'react'
@@ -1,5 +1,5 @@
1
- import { type DiagramView, type Fqn, type NodeId } from '@likec4/core'
2
- import { type Rect } from '@xyflow/system'
1
+ import type { DiagramView, Fqn, NodeId } from '@likec4/core/types'
2
+ import type { Rect } from '@xyflow/system'
3
3
  import {
4
4
  type ActorLogicFrom,
5
5
  type ActorRefFromLogic,
@@ -12,8 +12,8 @@ const dialog = css.raw({
12
12
  boxSizing: 'border-box',
13
13
  margin: 0,
14
14
  position: 'fixed',
15
- width: 'auto',
16
- height: 'auto',
15
+ width: '100vw',
16
+ height: '100vh',
17
17
  maxWidth: '100vw',
18
18
  maxHeight: '100vh',
19
19
  background: `mantine.colors.defaultBorder/50`,
@@ -26,41 +26,12 @@ const dialog = css.raw({
26
26
  [offset]: '0px',
27
27
  [inset]: 'calc((1 + var(--_level) * 0.75) * var(--_offset))',
28
28
  [backdropOpacity]: '0%',
29
+ [borderRadius]: '0px',
29
30
  _backdrop: {
30
31
  cursor: 'zoom-out',
31
- backdropFilter: `blur(var(${backdropBlur}))`,
32
- backgroundColor: {
33
- _dark: `[rgb(34 34 34 / var(${backdropOpacity}))]`,
34
- _light: `[rgb(15 15 15/ var(${backdropOpacity}))]`,
35
- },
36
- },
37
- smDown: {
38
- [borderRadius]: '0px',
39
- border: 'none',
40
- inset: 0,
41
- padding: 0,
42
- // [offset]: '0px',
43
- // [inset]: '0px',
44
- width: '100vw',
45
- height: '100vh',
46
- },
47
- sm: {
48
- inset: '[var(--_inset) var(--_inset) var(--_offset) var(--_inset)]',
49
- width: 'calc(100vw - 2 * var(--_inset))',
50
- height: 'calc(100vh - var(--_offset) - var(--_inset))',
51
- [borderRadius]: '6px',
52
- padding: '6px',
53
- [offset]: '1rem',
54
- },
55
- md: {
56
- [offset]: '1rem',
57
- },
58
- lg: {
59
- [offset]: '2rem',
60
- },
61
- xl: {
62
- [offset]: '4rem',
63
32
  },
33
+ inset: 0,
34
+ padding: 0,
64
35
  })
65
36
 
66
37
  const body = css.raw({
@@ -68,13 +39,10 @@ const body = css.raw({
68
39
  containerName: 'overlay-dialog',
69
40
  containerType: 'size',
70
41
  border: `0 solid transparent`,
71
- background: 'mantine.colors.body',
72
42
  overflow: 'hidden',
73
43
  width: '100%',
74
44
  height: '100%',
75
- sm: {
76
- borderRadius: `calc(var(${borderRadius}) - 2px)`,
77
- },
45
+ background: 'mantine.colors.body',
78
46
  })
79
47
 
80
48
  export const overlay = sva({
@@ -83,4 +51,73 @@ export const overlay = sva({
83
51
  dialog: dialog,
84
52
  body: body,
85
53
  },
54
+ variants: {
55
+ fullscreen: {
56
+ false: {
57
+ dialog: {
58
+ sm: {
59
+ inset: '[var(--_inset) var(--_inset) var(--_offset) var(--_inset)]',
60
+ width: 'calc(100vw - 2 * var(--_inset))',
61
+ height: 'calc(100vh - var(--_offset) - var(--_inset))',
62
+ [borderRadius]: '6px',
63
+ padding: '6px',
64
+ [offset]: '1rem',
65
+ },
66
+ md: {
67
+ [offset]: '1rem',
68
+ },
69
+ lg: {
70
+ [offset]: '2rem',
71
+ },
72
+ xl: {
73
+ [offset]: '4rem',
74
+ },
75
+ },
76
+ body: {
77
+ sm: {
78
+ borderRadius: `calc(var(${borderRadius}) - 2px)`,
79
+ },
80
+ },
81
+ },
82
+ true: {
83
+ dialog: {
84
+ inset: 0,
85
+ padding: 0,
86
+ },
87
+ },
88
+ },
89
+ // transparent: {
90
+ // false: {
91
+ // },
92
+ // true: {
93
+ // dialog: {
94
+ // background: 'transparent',
95
+ // },
96
+ // },
97
+ // },
98
+ withBackdrop: {
99
+ false: {
100
+ dialog: {
101
+ _backdrop: {
102
+ display: 'none',
103
+ },
104
+ },
105
+ },
106
+ true: {
107
+ dialog: {
108
+ _backdrop: {
109
+ backdropFilter: `blur(var(${backdropBlur}))`,
110
+ backgroundColor: {
111
+ _dark: `[rgb(34 34 34 / var(${backdropOpacity}))]`,
112
+ _light: `[rgb(15 15 15/ var(${backdropOpacity}))]`,
113
+ },
114
+ },
115
+ },
116
+ },
117
+ },
118
+ },
119
+ defaultVariants: {
120
+ fullscreen: false,
121
+ withBackdrop: true,
122
+ },
86
123
  })
@@ -2,20 +2,26 @@ import { cx } from '@likec4/styles/css'
2
2
  import {
3
3
  RemoveScroll,
4
4
  } from '@mantine/core'
5
- import { useMergedRef } from '@mantine/hooks'
6
- import { useDebouncedCallback, useSyncedRef, useTimeoutEffect } from '@react-hookz/web'
5
+ import { useFocusTrap, useMergedRef } from '@mantine/hooks'
6
+ import { useDebouncedCallback, useTimeoutEffect } from '@react-hookz/web'
7
7
  import { m, useReducedMotionConfig } from 'motion/react'
8
- import { type PropsWithChildren, forwardRef, useEffect, useRef, useState } from 'react'
8
+ import { type PropsWithChildren, forwardRef, useLayoutEffect, useRef, useState } from 'react'
9
9
  import { stopPropagation } from '../../utils'
10
10
  import { backdropBlur, backdropOpacity, level as cssVarLevel, overlay as overlayCVA } from './Overlay.css'
11
11
 
12
12
  export type OverlayProps = PropsWithChildren<{
13
+ fullscreen?: boolean | undefined
14
+ withBackdrop?: boolean | undefined
13
15
  overlayLevel?: number
14
16
  className?: string
15
17
  classes?: {
16
18
  dialog?: string
17
19
  body?: string
18
20
  }
21
+ backdrop?: {
22
+ opacity?: number
23
+ }
24
+ openDelay?: number
19
25
  onClose: () => void
20
26
  onClick?: never
21
27
  }>
@@ -26,15 +32,22 @@ export const Overlay = forwardRef<HTMLDialogElement, OverlayProps>(({
26
32
  classes,
27
33
  overlayLevel = 0,
28
34
  children,
35
+ fullscreen = false,
36
+ withBackdrop = true,
37
+ backdrop,
38
+ openDelay = 130,
29
39
  ...rest
30
40
  }, ref) => {
31
- const [opened, setOpened] = useState(false)
41
+ const [opened, setOpened] = useState(openDelay === 0)
42
+ const focusTrapRef = useFocusTrap(opened)
32
43
  const dialogRef = useRef<HTMLDialogElement>(null)
33
44
  const isClosingRef = useRef(false)
34
45
 
35
46
  const motionNotReduced = useReducedMotionConfig() !== true
36
47
 
37
- const onCloseRef = useSyncedRef(onClose)
48
+ const onCloseRef = useRef(onClose)
49
+ onCloseRef.current = onClose
50
+
38
51
  const close = useDebouncedCallback(
39
52
  () => {
40
53
  if (isClosingRef.current) return
@@ -45,37 +58,39 @@ export const Overlay = forwardRef<HTMLDialogElement, OverlayProps>(({
45
58
  50,
46
59
  )
47
60
 
48
- useEffect(() => {
49
- const cancel = (e: Event) => {
50
- e.preventDefault()
51
- e.stopPropagation()
52
- close()
53
- }
54
- dialogRef.current?.addEventListener('cancel', cancel, { capture: true })
55
- return () => {
56
- dialogRef.current?.removeEventListener('cancel', cancel, { capture: true })
57
- }
58
- }, [])
59
-
60
- useTimeoutEffect(() => {
61
+ useLayoutEffect(() => {
61
62
  if (!dialogRef.current?.open) {
62
63
  // Move dialog to the top of the DOM
63
64
  dialogRef.current?.showModal()
64
65
  }
65
- }, 30)
66
+ }, [])
66
67
 
67
68
  useTimeoutEffect(() => {
68
69
  setOpened(true)
69
- }, 120)
70
+ }, openDelay > 0 ? openDelay : undefined)
70
71
 
71
72
  const styles = overlayCVA({
72
- level: overlayLevel as 0 | 1 | 2 | 3,
73
+ fullscreen,
74
+ withBackdrop,
73
75
  })
74
76
 
77
+ let targetBackdropOpacity = overlayLevel > 0 ? '50%' : '60%'
78
+ if (backdrop?.opacity !== undefined) {
79
+ targetBackdropOpacity = `${backdrop.opacity * 100}%`
80
+ }
75
81
  return (
76
82
  <m.dialog
77
- ref={useMergedRef(dialogRef, ref)}
78
- className={cx(RemoveScroll.classNames.fullWidth, styles.dialog, classes?.dialog, className)}
83
+ ref={useMergedRef(
84
+ dialogRef,
85
+ focusTrapRef,
86
+ ref,
87
+ )}
88
+ className={cx(
89
+ classes?.dialog,
90
+ className,
91
+ styles.dialog,
92
+ fullscreen && RemoveScroll.classNames.fullWidth,
93
+ )}
79
94
  layout
80
95
  style={{
81
96
  // @ts-ignore
@@ -86,21 +101,28 @@ export const Overlay = forwardRef<HTMLDialogElement, OverlayProps>(({
86
101
  initial: {
87
102
  [backdropBlur]: '0px',
88
103
  [backdropOpacity]: '0%',
89
- scale: overlayLevel > 0 ? 0.9 : 1.075,
104
+ scale: 0.95,
105
+ originY: 0,
106
+ translateY: -20,
90
107
  opacity: 0,
91
108
  },
92
109
  animate: {
93
110
  [backdropBlur]: overlayLevel > 0 ? '4px' : '8px',
94
- [backdropOpacity]: overlayLevel > 0 ? '50%' : '60%',
111
+ [backdropOpacity]: targetBackdropOpacity,
95
112
  scale: 1,
96
113
  opacity: 1,
114
+ translateY: 0,
97
115
  transition: {
98
116
  delay: 0.075,
99
117
  },
100
118
  },
101
119
  exit: {
102
- scale: 1.2,
103
120
  opacity: 0,
121
+ scale: 0.98,
122
+ translateY: -20,
123
+ transition: {
124
+ duration: 0.1,
125
+ },
104
126
  [backdropBlur]: '0px',
105
127
  [backdropOpacity]: '0%',
106
128
  },
@@ -108,7 +130,7 @@ export const Overlay = forwardRef<HTMLDialogElement, OverlayProps>(({
108
130
  : {
109
131
  initial: {
110
132
  [backdropBlur]: '8px',
111
- [backdropOpacity]: '60%',
133
+ [backdropOpacity]: targetBackdropOpacity,
112
134
  },
113
135
  }}
114
136
  onClick={e => {
@@ -118,6 +140,11 @@ export const Overlay = forwardRef<HTMLDialogElement, OverlayProps>(({
118
140
  return
119
141
  }
120
142
  }}
143
+ onCancel={e => {
144
+ e.preventDefault()
145
+ e.stopPropagation()
146
+ close()
147
+ }}
121
148
  onDoubleClick={stopPropagation}
122
149
  onPointerDown={stopPropagation}
123
150
  onClose={e => {
@@ -126,8 +153,13 @@ export const Overlay = forwardRef<HTMLDialogElement, OverlayProps>(({
126
153
  }}
127
154
  {...rest}
128
155
  >
129
- <RemoveScroll forwardProps removeScrollBar={false}>
130
- <div className={cx(styles.body, 'overlay-body', classes?.body)}>
156
+ <RemoveScroll forwardProps>
157
+ <div
158
+ className={cx(
159
+ classes?.body,
160
+ styles.body,
161
+ 'overlay-body',
162
+ )}>
131
163
  {opened && <>{children}</>}
132
164
  </div>
133
165
  </RemoveScroll>
@@ -1,4 +1,4 @@
1
- import type { Fqn } from '@likec4/core'
1
+ import type { Fqn } from '@likec4/core/types'
2
2
  import { getHotkeyHandler } from '@mantine/hooks'
3
3
  import type { KeyboardEvent } from 'react'
4
4
  import { isString, last, reverse } from 'remeda'
@@ -83,7 +83,7 @@ const selectSubject = (state: RelationshipDetailsSnapshot) => ({
83
83
  const SyncRelationshipDetailsXYFlow = memo(() => {
84
84
  const actor = useRelationshipDetailsActor()
85
85
  const subject = useSelector(actor, selectSubject, deepEqual)
86
- const likec4model = useLikeC4Model(true)
86
+ const likec4model = useLikeC4Model()
87
87
  const view = likec4model.findView(subject.viewId) ?? null
88
88
  const data = useMemo(() => {
89
89
  let data: RelationshipDetailsViewData
@@ -224,7 +224,7 @@ const topLeftPanelselector = ({ context }: RelationshipDetailsSnapshot) => ({
224
224
  })
225
225
  const TopLeftPanel = memo(() => {
226
226
  const { subject, viewId } = useRelationshipDetailsState(topLeftPanelselector, deepEqual)
227
- const likec4model = useLikeC4Model(true)
227
+ const likec4model = useLikeC4Model()
228
228
  const view = likec4model.findView(viewId)
229
229
 
230
230
  if (!view || !view.isDiagram()) {
@@ -239,8 +239,8 @@ const TopLeftPanel = memo(() => {
239
239
  find(edges, (e) => e.source.element?.id === subject.source && e.target.element?.id === subject.target)
240
240
  || find(edges, (e) => {
241
241
  return (e.source.element?.id === subject.source ||
242
- isAncestor(e.source.element?.id ?? '--', subject.source ?? '__')) &&
243
- (e.target.element?.id === subject.target || isAncestor(e.target.element?.id ?? '', subject.target ?? '__'))
242
+ isAncestor(e.source.element?.id ?? '__', subject.source ?? '__')) &&
243
+ (e.target.element?.id === subject.target || isAncestor(e.target.element?.id ?? '__', subject.target ?? '__'))
244
244
  })
245
245
  )
246
246
  if (!edge) {
@@ -1,4 +1,4 @@
1
- import type { Color, DiagramNode, Fqn, IconUrl, RelationId, RelationshipLineType, ViewId } from '@likec4/core'
1
+ import type { Color, DiagramNode, Fqn, IconUrl, RelationId, RelationshipLineType, ViewId } from '@likec4/core/types'
2
2
  import type { Simplify } from 'type-fest'
3
3
  import type { Base, NonOptional, ReactFlowEdge, ReactFlowNode } from '../../base/types'
4
4
 
@@ -26,6 +26,7 @@ export namespace RelationshipDetailsTypes {
26
26
  | 'height'
27
27
  | 'navigateTo'
28
28
  | 'style'
29
+ | 'tags'
29
30
  >
30
31
  >
31
32
  & {
@@ -5,6 +5,7 @@ import {
5
5
  ElementDetailsButton,
6
6
  ElementNodeContainer,
7
7
  ElementShape,
8
+ ElementTags,
8
9
  ElementTitle,
9
10
  } from '../../../base/primitives'
10
11
  import { ElementActions } from './ElementActions'
@@ -12,6 +13,7 @@ import { ElementActions } from './ElementActions'
12
13
  import { Handle } from '@xyflow/react'
13
14
  import { Position } from '@xyflow/system'
14
15
  import type { NodeProps } from '../../../base'
16
+ import { useEnabledFeatures } from '../../../context/DiagramFeatures'
15
17
  import { useDiagram } from '../../../hooks/useDiagram'
16
18
  import type { RelationshipDetailsTypes } from '../_types'
17
19
 
@@ -30,10 +32,12 @@ const ElementDetailsButtonWithHandler = (props: NodeProps<RelationshipDetailsTyp
30
32
  }
31
33
 
32
34
  export const ElementNode = customNode<RelationshipDetailsTypes.ElementNodeData>((props) => {
35
+ const { enableElementTags } = useEnabledFeatures()
33
36
  return (
34
37
  <ElementNodeContainer nodeProps={props}>
35
38
  <ElementShape {...props} />
36
39
  <ElementTitle {...props} />
40
+ {enableElementTags && <ElementTags {...props} />}
37
41
  <ElementDetailsButtonWithHandler {...props} />
38
42
  <ElementActions {...props} />
39
43
  <ElementPorts {...props} />
@@ -119,6 +119,7 @@ export function layoutResultToXYFlow(
119
119
  icon: node.icon ?? 'none',
120
120
  ports: node.ports,
121
121
  style: node.style,
122
+ tags: node.tags,
122
123
  ...navigateTo,
123
124
  },
124
125
  },
@@ -394,11 +394,13 @@ export function layoutRelationshipDetails(
394
394
  return {
395
395
  id: id as NodeId,
396
396
  parent: parentId as NodeId ?? null,
397
+ x: position.x,
398
+ y: position.y,
397
399
  position: [position.x, position.y],
398
400
  title: element.title,
399
401
  description: element.description,
400
402
  technology: element.technology,
401
- tags: null,
403
+ tags: [...element.tags],
402
404
  links: null,
403
405
  color: inheritFromNodeOrAncestor?.color ?? element.color,
404
406
  shape: inheritFromNode?.shape ?? element.shape,
@@ -47,7 +47,7 @@ export const SelectElement = memo(() => {
47
47
 
48
48
  const root = useRef<HTMLDivElement>(null)
49
49
  const viewport = useRef<HTMLDivElement>(null)
50
- const model = useLikeC4Model(true)
50
+ const model = useLikeC4Model()
51
51
  const subject = model.findElement(subjectId)
52
52
  const data = useLikeC4ElementsTree(scope === 'view' && viewId ? viewId : undefined)
53
53
  const tree = useTree({
@@ -7,7 +7,7 @@ import type {
7
7
  RelationId,
8
8
  RelationshipLineType,
9
9
  ViewId,
10
- } from '@likec4/core'
10
+ } from '@likec4/core/types'
11
11
  import type { Simplify } from 'type-fest'
12
12
  import type { Base, NonOptional, ReactFlowEdge, ReactFlowNode } from '../../base/types'
13
13
 
@@ -35,6 +35,7 @@ export namespace RelationshipsBrowserTypes {
35
35
  | 'style'
36
36
  | 'width'
37
37
  | 'height'
38
+ | 'tags'
38
39
  | 'navigateTo'
39
40
  >
40
41
  >
@@ -8,8 +8,10 @@ import {
8
8
  ElementDetailsButton,
9
9
  ElementNodeContainer,
10
10
  ElementShape,
11
+ ElementTags,
11
12
  ElementTitle,
12
13
  } from '../../../base/primitives'
14
+ import { useEnabledFeatures } from '../../../context/DiagramFeatures'
13
15
  import { useDiagram } from '../../../hooks/useDiagram'
14
16
  import type { RelationshipsBrowserTypes } from '../_types'
15
17
  import { ElementActions } from './ElementActions'
@@ -32,10 +34,12 @@ const ElementDetailsButtonWithHandler = (
32
34
  }
33
35
 
34
36
  export const ElementNode = customNode<RelationshipsBrowserTypes.ElementNodeData>((props) => {
37
+ const { enableElementTags } = useEnabledFeatures()
35
38
  return (
36
39
  <ElementNodeContainer key={props.id} layoutId={props.id} nodeProps={props}>
37
40
  <ElementShape {...props} />
38
41
  <ElementTitle {...props} />
42
+ {enableElementTags && <ElementTags {...props} />}
39
43
  <ElementDetailsButtonWithHandler {...props} />
40
44
  <ElementActions {...props} />
41
45
  <ElementPorts {...props} />