@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
@@ -0,0 +1,182 @@
1
+ import { isTagColorSpecified } from '@likec4/core'
2
+ import { css, cx } from '@likec4/styles/css'
3
+ import { type BoxProps, Box, HStack } from '@likec4/styles/jsx'
4
+ import { hstack } from '@likec4/styles/patterns'
5
+ import { likec4tag } from '@likec4/styles/recipes'
6
+ import { HoverCard } from '@mantine/core'
7
+ import { deepEqual } from 'fast-equals'
8
+ import { forwardRef, memo, useCallback } from 'react'
9
+ import { useTagSpecification } from '../../../context/TagStylesContext'
10
+ import { useDiagram } from '../../../hooks/useDiagram'
11
+ import { useMantinePortalProps } from '../../../hooks/useMantinePortalProps'
12
+ import { useCurrentZoom } from '../../../hooks/useXYFlow'
13
+ import { stopPropagation } from '../../../utils/xyflow'
14
+ import type { NodeProps } from '../../types'
15
+
16
+ export type ElementTagProps = {
17
+ tag: string
18
+ } & Omit<BoxProps, 'children'>
19
+
20
+ export const ElementTag = forwardRef<HTMLDivElement, ElementTagProps>(
21
+ ({ tag, className, ...props }, ref) => {
22
+ const spec = useTagSpecification(tag)
23
+ return (
24
+ <Box
25
+ ref={ref}
26
+ data-likec4-tag={tag}
27
+ className={cx(
28
+ likec4tag({
29
+ autoTextColor: isTagColorSpecified(spec),
30
+ }),
31
+ className,
32
+ )}
33
+ {...props}
34
+ >
35
+ <span style={{ opacity: 0.7, fontSize: '1.05em' }}>#</span>
36
+ <span>{tag}</span>
37
+ </Box>
38
+ )
39
+ },
40
+ )
41
+
42
+ type Data = {
43
+ tags: readonly string[] | null | undefined
44
+ width: number
45
+ }
46
+ type ElementTagsProps = NodeProps<Data>
47
+
48
+ const propsAreEqual = (prev: ElementTagsProps, next: ElementTagsProps) => {
49
+ return prev.data.width === next.data.width && deepEqual(prev.data.tags, next.data.tags)
50
+ }
51
+ export const ElementTags = memo(({ id, data: { tags, width } }: ElementTagsProps) => {
52
+ const zoom = useCurrentZoom()
53
+ const zoomIsLargeEnough = zoom > 1.2
54
+ const portalProps = useMantinePortalProps()
55
+ if (!tags || tags.length === 0) {
56
+ return null
57
+ }
58
+ const maxWidth = Math.max(Math.round(width * zoom) - 10, 200)
59
+
60
+ return (
61
+ <HoverCard
62
+ {...portalProps}
63
+ floatingStrategy="fixed"
64
+ position="bottom-start"
65
+ offset={{
66
+ alignmentAxis: Math.round(4 * zoom),
67
+ mainAxis: 8,
68
+ }}
69
+ keepMounted={false}
70
+ openDelay={300}
71
+ closeDelay={500}
72
+ >
73
+ <HoverCard.Target>
74
+ <div
75
+ className={cx(
76
+ 'likec4-element-tags',
77
+ hstack({
78
+ pointerEvents: 'all',
79
+ gap: 4,
80
+ alignItems: 'flex-end',
81
+ justifyItems: 'stretch',
82
+ position: 'absolute',
83
+ width: '100%',
84
+ bottom: 0,
85
+ left: 0,
86
+ padding: 4,
87
+ _shapeCylinder: {
88
+ bottom: 5,
89
+ },
90
+ _shapeStorage: {
91
+ bottom: 5,
92
+ },
93
+ _shapeQueue: {
94
+ bottom: 0,
95
+ paddingLeft: 14,
96
+ },
97
+ }),
98
+ )}
99
+ onClick={stopPropagation}
100
+ >
101
+ {tags.map((tag) => (
102
+ <Box
103
+ key={id + '#' + tag}
104
+ data-likec4-tag={tag}
105
+ className={css({
106
+ layerStyle: 'likec4.tag',
107
+ flex: 1,
108
+ display: 'flex',
109
+ alignItems: 'center',
110
+ justifyContent: 'center',
111
+ maxWidth: 50,
112
+ height: 5,
113
+ _whenHovered: {
114
+ height: 12,
115
+ borderRadius: 4,
116
+ transitionDelay: '.08s',
117
+ },
118
+ transition: 'fast',
119
+ })}
120
+ />
121
+ ))}
122
+ </div>
123
+ </HoverCard.Target>
124
+ <HoverCard.Dropdown
125
+ p={0}
126
+ w={'auto'}
127
+ maw={maxWidth}
128
+ className={css({
129
+ background: 'transparent',
130
+ border: 'none',
131
+ })}
132
+ >
133
+ <ElementTagsDropdown tags={tags} zoomIsLargeEnough={zoomIsLargeEnough} />
134
+ </HoverCard.Dropdown>
135
+ </HoverCard>
136
+ )
137
+ }, propsAreEqual)
138
+ ElementTags.displayName = 'ElementTags'
139
+
140
+ function ElementTagsDropdown({ tags, zoomIsLargeEnough }: { tags: readonly string[]; zoomIsLargeEnough: boolean }) {
141
+ const diagram = useDiagram()
142
+
143
+ const onHover = (tag: string) => {
144
+ diagram.send({ type: 'tag.highlight', tag })
145
+ }
146
+
147
+ const onLeave = useCallback(() => {
148
+ diagram.send({ type: 'tag.unhighlight' })
149
+ }, [])
150
+
151
+ return (
152
+ <HStack
153
+ css={{
154
+ gap: 4,
155
+ flexWrap: 'wrap',
156
+ pb: 'sm',
157
+ }}
158
+ >
159
+ {tags.map((tag) => (
160
+ <ElementTag
161
+ key={tag}
162
+ tag={tag}
163
+ className={css({
164
+ userSelect: 'none',
165
+ cursor: 'pointer',
166
+ ...(zoomIsLargeEnough && {
167
+ fontSize: 'lg',
168
+ borderRadius: 4,
169
+ px: 6,
170
+ }),
171
+ })}
172
+ onClick={e => {
173
+ e.stopPropagation()
174
+ diagram.openSearch(`#${tag}`)
175
+ }}
176
+ onMouseEnter={() => onHover(tag)}
177
+ onMouseLeave={onLeave}
178
+ />
179
+ ))}
180
+ </HStack>
181
+ )
182
+ }
@@ -1,24 +1,29 @@
1
- import { type DiagramNode } from '@likec4/core'
1
+ import type { DiagramNode } from '@likec4/core/types'
2
2
  import { cx } from '@likec4/styles/css'
3
- import { Box, Text } from '@mantine/core'
3
+ import { Box } from '@likec4/styles/jsx'
4
+ import { Text } from '@mantine/core'
4
5
  import { isEmpty, isNumber, isTruthy } from 'remeda'
6
+ import type { Simplify } from 'type-fest'
5
7
  import { IconRenderer } from '../../../context/IconRenderer'
6
- import type { NodeProps } from '../../types'
8
+ import type { NodeProps, NonOptional } from '../../types'
7
9
  import { nodeSizes } from './ElementNodeContainer'
8
10
  import * as styles from './ElementTitle.css'
9
11
 
10
- type Data =
11
- & Pick<
12
- DiagramNode,
13
- | 'title'
14
- | 'technology'
15
- | 'description'
16
- | 'color'
17
- | 'style'
12
+ type Data = Simplify<
13
+ & NonOptional<
14
+ Pick<
15
+ DiagramNode,
16
+ | 'title'
17
+ | 'technology'
18
+ | 'description'
19
+ | 'color'
20
+ | 'style'
21
+ >
18
22
  >
19
23
  & {
20
24
  icon?: string | null
21
25
  }
26
+ >
22
27
 
23
28
  type ElementTitleProps = NodeProps<Data> & {
24
29
  iconSize?: number
@@ -47,11 +52,12 @@ export function ElementTitle({ id, data, iconSize }: ElementTitleProps) {
47
52
  classes.root,
48
53
  'likec4-element',
49
54
  )}
50
- style={{
51
- ...isNumber(iconSize) && {
55
+ style={isNumber(iconSize)
56
+ ? {
57
+ // @ts-ignore
52
58
  [styles.iconSize]: `${iconSize}px`,
53
- },
54
- }}
59
+ }
60
+ : undefined}
55
61
  >
56
62
  {elementIcon}
57
63
  <Box className={cx(classes.textContainer, 'likec4-element-main-props')}>
@@ -14,5 +14,6 @@ export { ElementActionButtons } from './element/ElementActionButtons'
14
14
  export { ElementDetailsButton } from './element/ElementDetailsButton'
15
15
  export { ElementNodeContainer } from './element/ElementNodeContainer'
16
16
  export { ElementShape } from './element/ElementShape'
17
+ export { ElementTag, ElementTags } from './element/ElementTags'
17
18
  export { ElementTitle } from './element/ElementTitle'
18
19
  export { DefaultHandles } from './NodeHandles'
@@ -0,0 +1,104 @@
1
+ import type {
2
+ Edge as RFEdge,
3
+ Node as RFNode,
4
+ NodeProps as ReactFlowNodeProps,
5
+ } from '@xyflow/react'
6
+ import { hasSubObject } from 'remeda'
7
+ import type { Simplify } from 'type-fest'
8
+
9
+ // 'immediate' means that the node is dimmed without delay
10
+ export type Dimmed = 'immediate' | boolean
11
+
12
+ export type NodeData = {
13
+ /**
14
+ * Whether the cursor is hovering over the node
15
+ */
16
+ hovered?: boolean
17
+ /**
18
+ * Whether the node is dimmed
19
+ * 'immediate' means that the node is dimmed without delay
20
+ */
21
+ dimmed?: Dimmed
22
+ }
23
+ export type Node = RFNode<NodeData>
24
+
25
+ export type NodeProps = ReactFlowNodeProps<RFNode<NodeData, any>>
26
+
27
+ export type EdgeData = {
28
+ /**
29
+ * Whether the cursor is hovering over the edge
30
+ */
31
+ hovered?: boolean
32
+ /**
33
+ * Whether the edge is active (animated and highlighted)
34
+ */
35
+ active?: boolean
36
+ /**
37
+ * Whether the edge is dimmed
38
+ * 'immediate' means that the edge is dimmed without delay
39
+ */
40
+ dimmed?: Dimmed
41
+ }
42
+
43
+ // export type Edge = SetRequired<ReactFlowEdge<EdgeData, 'relation'>, 'data' | 'type'>
44
+ export type Edge = Simplify<Omit<RFEdge, 'data'> & { data: EdgeData }>
45
+
46
+ type WithDimmed = { data: { dimmed?: Dimmed } }
47
+ type WithHovered = { data: { hovered?: boolean } }
48
+
49
+ const _setDimmed = <T extends WithDimmed>(v: T, dimmed: Dimmed): T =>
50
+ (v.data.dimmed ?? false) === dimmed ? v : ({
51
+ ...v,
52
+ data: {
53
+ ...v.data,
54
+ dimmed,
55
+ },
56
+ })
57
+
58
+ export function setDimmed<T extends WithDimmed>(value: T, dimmed: 'immediate' | boolean): T
59
+ export function setDimmed(dimmed: 'immediate' | boolean): <T extends WithDimmed>(value: T) => T
60
+ export function setDimmed<T extends WithDimmed>(arg1: T | Dimmed, arg2?: Dimmed) {
61
+ if (arg2 !== undefined) {
62
+ return _setDimmed(arg1 as T, arg2)
63
+ }
64
+ return (v: T) => _setDimmed(v, arg1 as Dimmed)
65
+ }
66
+
67
+ const _setHovered = <T extends WithHovered>(v: T, hovered: boolean): T =>
68
+ (v.data.hovered ?? false) === hovered ? v : ({
69
+ ...v,
70
+ data: {
71
+ ...v.data,
72
+ hovered,
73
+ },
74
+ })
75
+ export function setHovered<T extends WithHovered>(value: T, hovered: boolean): T
76
+ export function setHovered(hovered: boolean): <T extends WithHovered>(value: T) => T
77
+ export function setHovered<T extends WithHovered>(arg1: T | boolean, arg2?: boolean) {
78
+ if (arg2 !== undefined) {
79
+ return _setHovered(arg1 as T, arg2)
80
+ }
81
+ return (v: T) => _setHovered(v, arg1 as boolean)
82
+ }
83
+
84
+ type WithData<D> = { data: D }
85
+ function _setData<D, E extends WithData<D>>(value: E, state: Partial<NoInfer<D>>): E {
86
+ if (hasSubObject(value.data as any, state as any)) {
87
+ return value
88
+ }
89
+ return {
90
+ ...value,
91
+ data: {
92
+ ...value.data,
93
+ ...state,
94
+ },
95
+ }
96
+ }
97
+ export function setData<E extends WithData<any>>(value: E, state: Partial<E['data']>): E
98
+ export function setData<E extends WithData<any>>(state: Partial<E['data']>): (value: E) => E
99
+ export function setData<E extends WithData<any>>(arg1: E | Partial<E['data']>, arg2?: any) {
100
+ if (arg2 !== undefined) {
101
+ return _setData(arg1 as E, arg2)
102
+ }
103
+ return (edge: E) => _setData(edge, arg1 as Partial<EdgeData>)
104
+ }
package/src/base/types.ts CHANGED
@@ -4,8 +4,8 @@ import type {
4
4
  Node as RFNode,
5
5
  NodeProps as ReactFlowNodeProps,
6
6
  } from '@xyflow/react'
7
- import { hasSubObject } from 'remeda'
8
7
  import type { OptionalKeysOf, SetRequired, Simplify } from 'type-fest'
8
+ import * as Base from './types.Base'
9
9
 
10
10
  /**
11
11
 
@@ -64,101 +64,4 @@ export type ReactFlowEdge<Data extends Record<string, unknown>, EdgeType extends
64
64
  'type' | 'data'
65
65
  >
66
66
 
67
- export namespace Base {
68
- // 'immediate' means that the node is dimmed without delay
69
- export type Dimmed = 'immediate' | boolean
70
-
71
- export type NodeData = {
72
- /**
73
- * Whether the cursor is hovering over the node
74
- */
75
- hovered?: boolean
76
- /**
77
- * Whether the node is dimmed
78
- * 'immediate' means that the node is dimmed without delay
79
- */
80
- dimmed?: Dimmed
81
- }
82
- export type Node = RFNode<NodeData>
83
-
84
- export type NodeProps = ReactFlowNodeProps<RFNode<Base.NodeData, any>>
85
-
86
- export type EdgeData = {
87
- /**
88
- * Whether the cursor is hovering over the edge
89
- */
90
- hovered?: boolean
91
- /**
92
- * Whether the edge is active (animated and highlighted)
93
- */
94
- active?: boolean
95
- /**
96
- * Whether the edge is dimmed
97
- * 'immediate' means that the edge is dimmed without delay
98
- */
99
- dimmed?: Dimmed
100
- }
101
-
102
- // export type Edge = SetRequired<ReactFlowEdge<EdgeData, 'relation'>, 'data' | 'type'>
103
- export type Edge = SetRequired<RFEdge<EdgeData>, 'data'>
104
-
105
- type WithDimmed = { data: { dimmed?: Dimmed } }
106
- type WithHovered = { data: { hovered?: boolean } }
107
-
108
- const _setDimmed = <T extends WithDimmed>(v: T, dimmed: Dimmed): T =>
109
- (v.data.dimmed ?? false) === dimmed ? v : ({
110
- ...v,
111
- data: {
112
- ...v.data,
113
- dimmed,
114
- },
115
- })
116
-
117
- export function setDimmed<T extends WithDimmed>(value: T, dimmed: 'immediate' | boolean): T
118
- export function setDimmed(dimmed: 'immediate' | boolean): <T extends WithDimmed>(value: T) => T
119
- export function setDimmed<T extends WithDimmed>(arg1: T | Dimmed, arg2?: Dimmed) {
120
- if (arg2 !== undefined) {
121
- return _setDimmed(arg1 as T, arg2)
122
- }
123
- return (v: T) => _setDimmed(v, arg1 as Dimmed)
124
- }
125
-
126
- const _setHovered = <T extends WithHovered>(v: T, hovered: boolean): T =>
127
- (v.data.hovered ?? false) === hovered ? v : ({
128
- ...v,
129
- data: {
130
- ...v.data,
131
- hovered,
132
- },
133
- })
134
- export function setHovered<T extends WithHovered>(value: T, hovered: boolean): T
135
- export function setHovered(hovered: boolean): <T extends WithHovered>(value: T) => T
136
- export function setHovered<T extends WithHovered>(arg1: T | boolean, arg2?: boolean) {
137
- if (arg2 !== undefined) {
138
- return _setHovered(arg1 as T, arg2)
139
- }
140
- return (v: T) => _setHovered(v, arg1 as boolean)
141
- }
142
-
143
- type WithData<D> = { data: D }
144
- function _setData<D, E extends WithData<D>>(value: E, state: Partial<NoInfer<D>>): E {
145
- if (hasSubObject(value.data as any, state as any)) {
146
- return value
147
- }
148
- return {
149
- ...value,
150
- data: {
151
- ...value.data,
152
- ...state,
153
- },
154
- }
155
- }
156
- export function setData<E extends WithData<any>>(value: E, state: Partial<E['data']>): E
157
- export function setData<E extends WithData<any>>(state: Partial<E['data']>): (value: E) => E
158
- export function setData<E extends WithData<any>>(arg1: E | Partial<E['data']>, arg2?: any) {
159
- if (arg2 !== undefined) {
160
- return _setData(arg1 as E, arg2)
161
- }
162
- return (edge: E) => _setData(edge, arg1 as Partial<EdgeData>)
163
- }
164
- }
67
+ export * as Base from './types.Base'
@@ -1,12 +1,13 @@
1
- import type { WhereOperator } from '@likec4/core'
1
+ import type { WhereOperator } from '@likec4/core/types'
2
+ import type * as aux from '@likec4/core/types/aux'
2
3
  import type { CSSProperties } from 'react'
3
4
  import type { CustomNodes, ElementIconRenderer, OverrideReactFlowProps, PaddingWithUnit } from '../LikeC4Diagram.props'
4
5
 
5
- export interface LikeC4ViewProps<ViewId = string, Tag = string, Kind = string> {
6
+ export interface LikeC4ViewProps<A extends aux.Any> {
6
7
  /**
7
8
  * View to display.
8
9
  */
9
- viewId: ViewId
10
+ viewId: aux.ViewId<A>
10
11
 
11
12
  /**
12
13
  * Enable/disable panning
@@ -110,6 +111,12 @@ export interface LikeC4ViewProps<ViewId = string, Tag = string, Kind = string> {
110
111
  */
111
112
  enableElementDetails?: boolean | undefined
112
113
 
114
+ /**
115
+ * Display element tags in the bottom left corner
116
+ * @default false
117
+ */
118
+ enableElementTags?: boolean | undefined
119
+
113
120
  /**
114
121
  * Experimental feature to browse relationships
115
122
  *
@@ -130,7 +137,7 @@ export interface LikeC4ViewProps<ViewId = string, Tag = string, Kind = string> {
130
137
  */
131
138
  reduceGraphics?: 'auto' | boolean | undefined
132
139
 
133
- where?: WhereOperator<Tag, Kind> | undefined
140
+ where?: WhereOperator<A> | undefined
134
141
 
135
142
  /**
136
143
  * Override some react flow props
@@ -230,6 +237,12 @@ export interface LikeC4BrowserProps {
230
237
  */
231
238
  enableRelationshipDetails?: boolean | undefined
232
239
 
240
+ /**
241
+ * Display element tags in the bottom left corner
242
+ * @default true
243
+ */
244
+ enableElementTags?: boolean | undefined
245
+
233
246
  /**
234
247
  * Display notations of the view
235
248
  * @default true
@@ -1,28 +1,24 @@
1
- import { memo, useState } from 'react'
2
- import { ShadowRoot } from './ShadowRoot'
3
-
4
- import type { DiagramView, ViewId } from '@likec4/core'
1
+ import type { Any, DiagramView, ViewId } from '@likec4/core/types'
2
+ import type * as aux from '@likec4/core/types/aux'
5
3
  import { cx } from '@likec4/styles/css'
6
4
  import { ActionIcon, Box } from '@mantine/core'
7
5
  import { shallowEqual } from '@mantine/hooks'
8
6
  import { IconX } from '@tabler/icons-react'
7
+ import { memo, useState } from 'react'
9
8
  import { isBoolean } from 'remeda'
10
9
  import { FramerMotionConfig } from '../context/FramerMotionConfig'
11
10
  import { LikeC4Diagram } from '../LikeC4Diagram'
12
11
  import { useLikeC4Model } from '../likec4model/useLikeC4Model'
13
12
  import { Overlay } from '../overlays/overlay/Overlay'
14
13
  import type { LikeC4ViewProps } from './LikeC4View.props'
14
+ import { ShadowRoot } from './ShadowRoot'
15
15
  import { cssInteractive, useColorScheme, useShadowRootStyle } from './styles.css'
16
16
  import { ErrorMessage, ViewNotFound } from './ViewNotFound'
17
17
 
18
- export function LikeC4View<
19
- ViewId extends string = string,
20
- Tag = string,
21
- Kind = string,
22
- >({
18
+ export function LikeC4View<A extends aux.Any = aux.UnknownLayouted>({
23
19
  viewId,
24
20
  ...props
25
- }: LikeC4ViewProps<ViewId, Tag, Kind>) {
21
+ }: LikeC4ViewProps<A>) {
26
22
  const likec4model = useLikeC4Model()
27
23
  const view = likec4model?.findView(viewId)
28
24
 
@@ -33,7 +29,7 @@ export function LikeC4View<
33
29
  </ErrorMessage>
34
30
  )
35
31
  }
36
- if (likec4model.type !== 'layouted') {
32
+ if (likec4model.stage !== 'layouted') {
37
33
  return (
38
34
  <ErrorMessage>
39
35
  LikeC4Model is not layouted. Make sure you have LikeC4ModelProvider with layouted model.
@@ -48,10 +44,10 @@ export function LikeC4View<
48
44
  return <LikeC4ViewInner view={view.$view} {...props} />
49
45
  }
50
46
 
51
- type LikeC4ViewInnerProps = Omit<LikeC4ViewProps<any, any, any>, 'viewId'> & {
52
- view: DiagramView
47
+ type LikeC4ViewInnerProps<A extends aux.Any> = Omit<LikeC4ViewProps<A>, 'viewId'> & {
48
+ view: DiagramView<A>
53
49
  }
54
- const LikeC4ViewInner = memo<LikeC4ViewInnerProps>(({
50
+ const LikeC4ViewInner = memo<LikeC4ViewInnerProps<aux.Any>>(({
55
51
  view,
56
52
  className,
57
53
  pannable = false,
@@ -80,16 +76,16 @@ const LikeC4ViewInner = memo<LikeC4ViewInnerProps>(({
80
76
  renderNodes,
81
77
  ...props
82
78
  }) => {
83
- const likec4model = useLikeC4Model(true, 'layouted')
79
+ const likec4model = useLikeC4Model('layouted')
84
80
  const colorScheme = useColorScheme(explicitColorScheme)
85
81
 
86
82
  const [shadowRootProps, cssstyle] = useShadowRootStyle(keepAspectRatio, view)
87
83
 
88
- const [browserViewId, onNavigateTo] = useState(null as ViewId | null)
84
+ const [browserViewId, onNavigateTo] = useState(null as aux.ViewId<Any> | null)
89
85
 
90
86
  const browserView = browserViewId ? likec4model.findView(browserViewId)?.$view : null
91
87
 
92
- const notations = view.notation?.elements ?? []
88
+ const notations = view.notation?.nodes ?? []
93
89
  const hasNotations = notations.length > 0
94
90
 
95
91
  let nonce
@@ -124,7 +120,7 @@ const LikeC4ViewInner = memo<LikeC4ViewInnerProps>(({
124
120
  style={style}>
125
121
  <FramerMotionConfig>
126
122
  <LikeC4Diagram
127
- view={view as any}
123
+ view={view}
128
124
  readonly
129
125
  pannable={pannable}
130
126
  zoomable={zoomable}
@@ -140,6 +136,7 @@ const LikeC4ViewInner = memo<LikeC4ViewInnerProps>(({
140
136
  enableRelationshipDetails={enableRelationshipDetails}
141
137
  enableElementDetails={enableElementDetails}
142
138
  enableRelationshipBrowser={enableRelationshipBrowser}
139
+ enableElementTags={false}
143
140
  controls={controls}
144
141
  nodesDraggable={false}
145
142
  reduceGraphics={reduceGraphics}
@@ -168,6 +165,7 @@ const LikeC4ViewInner = memo<LikeC4ViewInnerProps>(({
168
165
  enableElementDetails
169
166
  enableRelationshipDetails
170
167
  enableSearch
168
+ enableElementTags
171
169
  controls
172
170
  readonly
173
171
  fitView
@@ -176,7 +174,7 @@ const LikeC4ViewInner = memo<LikeC4ViewInnerProps>(({
176
174
  {...props}
177
175
  {...browserProps}
178
176
  showNotations={(browserProps.showNotations ?? true) &&
179
- (browserView.notation?.elements.length ?? 0) > 0}
177
+ (browserView.notation?.nodes.length ?? 0) > 0}
180
178
  />
181
179
  <Box pos="absolute" top={'1rem'} right={'1rem'}>
182
180
  <ActionIcon