@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
@@ -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,57 +1,46 @@
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 } 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
- const view = likec4model?.findView(viewId)
23
+ const view = likec4model.findView(viewId)
28
24
 
29
- if (!likec4model) {
30
- return (
31
- <ErrorMessage>
32
- LikeC4Model not found. Make sure you have LikeC4ModelProvider.
33
- </ErrorMessage>
34
- )
25
+ if (!view) {
26
+ return <ViewNotFound viewId={viewId} />
35
27
  }
36
- if (likec4model.type !== 'layouted') {
28
+
29
+ if (!view.isDiagram()) {
37
30
  return (
38
31
  <ErrorMessage>
39
- LikeC4Model is not layouted. Make sure you have LikeC4ModelProvider with layouted model.
32
+ LikeC4 View "${viewId}" is not layouted. Make sure you have LikeC4ModelProvider with layouted model.
40
33
  </ErrorMessage>
41
34
  )
42
35
  }
43
36
 
44
- if (!view || !view.isDiagram()) {
45
- return <ViewNotFound viewId={viewId} />
46
- }
47
-
48
37
  return <LikeC4ViewInner view={view.$view} {...props} />
49
38
  }
50
39
 
51
- type LikeC4ViewInnerProps = Omit<LikeC4ViewProps<any, any, any>, 'viewId'> & {
52
- view: DiagramView
40
+ type LikeC4ViewInnerProps<A extends aux.Any> = Omit<LikeC4ViewProps<A>, 'viewId'> & {
41
+ view: DiagramView<A>
53
42
  }
54
- const LikeC4ViewInner = memo<LikeC4ViewInnerProps>(({
43
+ const LikeC4ViewInner = memo<LikeC4ViewInnerProps<aux.Any>>(({
55
44
  view,
56
45
  className,
57
46
  pannable = false,
@@ -61,7 +50,7 @@ const LikeC4ViewInner = memo<LikeC4ViewInnerProps>(({
61
50
  injectFontCss = true,
62
51
  controls = false,
63
52
  fitView = true,
64
- fitViewPadding = '8px',
53
+ fitViewPadding = '16px',
65
54
  background = 'transparent',
66
55
  browser = true,
67
56
  showDiagramTitle = false,
@@ -80,16 +69,16 @@ const LikeC4ViewInner = memo<LikeC4ViewInnerProps>(({
80
69
  renderNodes,
81
70
  ...props
82
71
  }) => {
83
- const likec4model = useLikeC4Model(true, 'layouted')
72
+ const likec4model = useLikeC4Model('layouted')
84
73
  const colorScheme = useColorScheme(explicitColorScheme)
85
74
 
86
75
  const [shadowRootProps, cssstyle] = useShadowRootStyle(keepAspectRatio, view)
87
76
 
88
- const [browserViewId, onNavigateTo] = useState(null as ViewId | null)
77
+ const [browserViewId, onNavigateTo] = useState(null as aux.ViewId<Any> | null)
89
78
 
90
79
  const browserView = browserViewId ? likec4model.findView(browserViewId)?.$view : null
91
80
 
92
- const notations = view.notation?.elements ?? []
81
+ const notations = view.notation?.nodes ?? []
93
82
  const hasNotations = notations.length > 0
94
83
 
95
84
  let nonce
@@ -124,7 +113,7 @@ const LikeC4ViewInner = memo<LikeC4ViewInnerProps>(({
124
113
  style={style}>
125
114
  <FramerMotionConfig>
126
115
  <LikeC4Diagram
127
- view={view as any}
116
+ view={view}
128
117
  readonly
129
118
  pannable={pannable}
130
119
  zoomable={zoomable}
@@ -140,6 +129,7 @@ const LikeC4ViewInner = memo<LikeC4ViewInnerProps>(({
140
129
  enableRelationshipDetails={enableRelationshipDetails}
141
130
  enableElementDetails={enableElementDetails}
142
131
  enableRelationshipBrowser={enableRelationshipBrowser}
132
+ enableElementTags={false}
143
133
  controls={controls}
144
134
  nodesDraggable={false}
145
135
  reduceGraphics={reduceGraphics}
@@ -157,26 +147,27 @@ const LikeC4ViewInner = memo<LikeC4ViewInnerProps>(({
157
147
  {...props}
158
148
  />
159
149
  {browserView && (
160
- <Overlay onClose={() => onNavigateTo(null)}>
150
+ <Overlay openDelay={0} onClose={() => onNavigateTo(null)}>
161
151
  <LikeC4Diagram
162
152
  view={browserView}
163
153
  background="dots"
164
- onNavigateTo={to => onNavigateTo(to as ViewId)}
154
+ onNavigateTo={onNavigateTo}
165
155
  enableDynamicViewWalkthrough
166
156
  enableFocusMode
167
157
  enableRelationshipBrowser
168
158
  enableElementDetails
169
159
  enableRelationshipDetails
170
160
  enableSearch
161
+ enableElementTags
171
162
  controls
172
163
  readonly
173
164
  fitView
174
- fitViewPadding={'16px'}
175
- renderNodes={renderNodes}
165
+ fitViewPadding={'32px'}
176
166
  {...props}
177
167
  {...browserProps}
178
168
  showNotations={(browserProps.showNotations ?? true) &&
179
- (browserView.notation?.elements.length ?? 0) > 0}
169
+ (browserView.notation?.nodes.length ?? 0) > 0}
170
+ renderNodes={renderNodes}
180
171
  />
181
172
  <Box pos="absolute" top={'1rem'} right={'1rem'}>
182
173
  <ActionIcon