@likec4/diagram 1.35.0 → 1.36.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 (224) hide show
  1. package/bundle/{chunk-C0Eg81Gj.js → chunk-DHvr-RGh.js} +323 -311
  2. package/bundle/custom.js +52 -52
  3. package/bundle/index.js +1594 -749
  4. package/dist/LikeC4Diagram.js +6 -6
  5. package/dist/LikeC4Diagram.props.d.ts +2 -3
  6. package/dist/LikeC4ModelProvider.d.ts +3 -3
  7. package/dist/LikeC4ProjectsProvider.d.ts +17 -0
  8. package/dist/LikeC4ProjectsProvider.js +22 -0
  9. package/dist/LikeC4Styles.d.ts +1 -0
  10. package/dist/LikeC4Styles.js +94 -0
  11. package/dist/StaticLikeC4Diagram.d.ts +3 -3
  12. package/dist/base/BaseXYFlow.js +23 -26
  13. package/dist/base/primitives/MarkdownBlock.d.ts +7 -1
  14. package/dist/base/primitives/MarkdownBlock.js +1 -1
  15. package/dist/base/primitives/compound/CompoundActionButton.js +2 -2
  16. package/dist/base/primitives/compound/CompoundDetailsButton.js +2 -2
  17. package/dist/base/primitives/compound/CompoundNodeContainer.css.js +4 -4
  18. package/dist/base/primitives/compound/CompoundNodeContainer.js +1 -4
  19. package/dist/base/primitives/compound/CompoundTitle.js +9 -8
  20. package/dist/base/primitives/compound/actionbtns.css.js +6 -6
  21. package/dist/base/primitives/edge/EdgeActionButton.js +2 -2
  22. package/dist/base/primitives/edge/EdgeContainer.js +4 -7
  23. package/dist/base/primitives/edge/EdgeLabel.css.d.ts +0 -22
  24. package/dist/base/primitives/edge/EdgeLabel.css.js +6 -84
  25. package/dist/base/primitives/edge/EdgeLabel.js +16 -6
  26. package/dist/base/primitives/edge/EdgeLabelContainer.js +1 -6
  27. package/dist/base/primitives/edge/EdgeMarkers.js +3 -3
  28. package/dist/base/primitives/edge/edge.css.d.ts +0 -2
  29. package/dist/base/primitives/edge/edge.css.js +1 -55
  30. package/dist/base/primitives/element/ElementActionButtons.js +2 -2
  31. package/dist/base/primitives/element/ElementDetailsButton.js +8 -7
  32. package/dist/base/primitives/element/ElementNodeContainer.css.js +4 -4
  33. package/dist/base/primitives/element/ElementNodeContainer.js +1 -4
  34. package/dist/base/primitives/element/ElementShape.css.js +11 -11
  35. package/dist/base/primitives/element/ElementTags.d.ts +1 -0
  36. package/dist/base/primitives/element/ElementTags.js +17 -14
  37. package/dist/bundle/LikeC4View.d.ts +1 -1
  38. package/dist/bundle/LikeC4View.js +7 -1
  39. package/dist/bundle/LikeC4View.props.d.ts +1 -2
  40. package/dist/bundle/ReactLikeC4.d.ts +1 -1
  41. package/dist/bundle/ViewNotFound.js +1 -1
  42. package/dist/bundle/index.d.ts +2 -1
  43. package/dist/bundle/index.js +1 -0
  44. package/dist/bundle/styles.css.js +1 -1
  45. package/dist/components/ErrorFallback.js +1 -1
  46. package/dist/components/GithubIcon.d.ts +2 -0
  47. package/dist/components/GithubIcon.js +17 -0
  48. package/dist/components/Link.d.ts +4 -3
  49. package/dist/components/Link.js +84 -87
  50. package/dist/components/NavigationLink.d.ts +2 -2
  51. package/dist/components/SearchControl.css.js +6 -5
  52. package/dist/context/DiagramEventHandlers.d.ts +6 -6
  53. package/dist/context/DiagramEventHandlers.js +4 -7
  54. package/dist/globals.css.js +3 -0
  55. package/dist/hooks/useXYFlow.d.ts +10 -10
  56. package/dist/index.d.ts +1 -0
  57. package/dist/index.js +1 -0
  58. package/dist/likec4diagram/DiagramUI.js +2 -1
  59. package/dist/likec4diagram/custom/edges/NotePopover.css.js +2 -2
  60. package/dist/likec4diagram/custom/edges/RelationshipEdge.d.ts +2 -2
  61. package/dist/likec4diagram/custom/edges/RelationshipEdge.js +1 -1
  62. package/dist/likec4diagram/custom/edges/RelationshipsDropdownMenu.css.js +7 -7
  63. package/dist/likec4diagram/custom/edges/RelationshipsDropdownMenu.js +3 -3
  64. package/dist/likec4diagram/custom/edges/edges.css.js +4 -4
  65. package/dist/likec4diagram/custom/index.d.ts +2 -2
  66. package/dist/likec4diagram/custom/nodes/toolbar/CompoundToolbar.js +2 -2
  67. package/dist/likec4diagram/ui/controls/styles.css.js +5 -5
  68. package/dist/likec4diagram/ui/diagram-title/DiagramTitlePanel.js +4 -4
  69. package/dist/likec4diagram/ui/notation/NotationPanel.css.js +11 -11
  70. package/dist/likec4diagram/ui/notation/NotationPanel.js +2 -5
  71. package/dist/likec4diagram/ui/walkthrough/DynamicViewWalkthrough.css.js +10 -10
  72. package/dist/likec4model/LikeC4ModelContext.d.ts +2 -1
  73. package/dist/likec4model/LikeC4ModelContext.js +10 -2
  74. package/dist/likec4model/LikeC4ProjectsContext.d.ts +7 -0
  75. package/dist/likec4model/LikeC4ProjectsContext.js +5 -0
  76. package/dist/likec4model/index.d.ts +1 -0
  77. package/dist/likec4model/useCurrentViewModel.d.ts +1 -0
  78. package/dist/likec4model/useCurrentViewModel.js +4 -1
  79. package/dist/likec4model/useLikeC4Project.d.ts +22 -0
  80. package/dist/likec4model/useLikeC4Project.js +23 -0
  81. package/dist/navigationpanel/NavigationPanel.js +15 -17
  82. package/dist/navigationpanel/NavigationPanelControls.js +34 -21
  83. package/dist/navigationpanel/NavigationPanelDropdown.js +33 -17
  84. package/dist/navigationpanel/_common.js +4 -1
  85. package/dist/navigationpanel/actor.d.ts +11 -15
  86. package/dist/navigationpanel/actor.js +14 -15
  87. package/dist/navigationpanel/controls/BurgerButton.js +5 -7
  88. package/dist/navigationpanel/controls/NavigationButtons.js +37 -24
  89. package/dist/navigationpanel/controls/OpenSource.js +1 -1
  90. package/dist/navigationpanel/controls/SearchControl.js +6 -4
  91. package/dist/navigationpanel/controls/ToggleReadonly.js +3 -3
  92. package/dist/navigationpanel/controls/ViewDetailsCard.d.ts +2 -0
  93. package/dist/navigationpanel/controls/ViewDetailsCard.js +232 -0
  94. package/dist/navigationpanel/controls/index.d.ts +1 -0
  95. package/dist/navigationpanel/dropdown/ProjectsMenu.d.ts +2 -0
  96. package/dist/navigationpanel/dropdown/ProjectsMenu.js +75 -0
  97. package/dist/navigationpanel/editorpanel/EditorPanel.js +3 -3
  98. package/dist/navigationpanel/editorpanel/ManualLayoutToolsButton.js +19 -20
  99. package/dist/navigationpanel/editorpanel/styles.js +5 -5
  100. package/dist/navigationpanel/hooks.d.ts +2 -2
  101. package/dist/navigationpanel/styles.css.js +0 -2
  102. package/dist/navigationpanel/walkthrough/ActiveWalkthroughControls.js +12 -7
  103. package/dist/node_modules/.pnpm/@tabler_icons-react@3.34.1_react@19.1.1/node_modules/@tabler/icons-react/dist/esm/icons/IconChevronDown.js +14 -0
  104. package/dist/node_modules/.pnpm/@tabler_icons-react@3.34.1_react@19.1.1/node_modules/@tabler/icons-react/dist/esm/icons/IconLink.js +14 -0
  105. package/dist/overlays/element-details/ElementDetailsCard.css.js +18 -17
  106. package/dist/overlays/element-details/ElementDetailsCard.js +8 -13
  107. package/dist/overlays/element-details/TabPanelDeployments.css.js +5 -4
  108. package/dist/overlays/element-details/TabPanelRelationships.css.js +7 -7
  109. package/dist/overlays/overlay/Overlay.css.d.ts +3 -3
  110. package/dist/overlays/overlay/Overlay.css.js +8 -7
  111. package/dist/overlays/relationship-details/SelectEdge.css.js +8 -8
  112. package/dist/overlays/relationships-browser/SelectElement.css.js +1 -1
  113. package/dist/search/Search.js +6 -6
  114. package/dist/search/components/ElementsColumn.css.js +5 -5
  115. package/dist/search/components/SearchByTags.js +3 -2
  116. package/dist/search/components/ViewsColum.js +1 -1
  117. package/dist/search/components/ViewsColumn.css.js +1 -1
  118. package/dist/search/components/_shared.css.js +3 -3
  119. package/dist/search/components/styles.css.js +5 -5
  120. package/dist/state/DiagramActorProvider.js +43 -25
  121. package/dist/state/diagram-machine.d.ts +29 -247
  122. package/dist/state/diagram-machine.js +16 -16
  123. package/dist/styles-min.css +1 -1
  124. package/dist/styles.css +1 -1
  125. package/dist/styles.css2.js +1 -1
  126. package/package.json +10 -8
  127. package/panda.buildinfo.json +254 -326
  128. package/src/LikeC4Diagram.props.ts +2 -2
  129. package/src/LikeC4Diagram.tsx +2 -2
  130. package/src/LikeC4ModelProvider.tsx +4 -4
  131. package/src/LikeC4ProjectsProvider.tsx +41 -0
  132. package/src/LikeC4Styles.tsx +107 -0
  133. package/src/StaticLikeC4Diagram.tsx +3 -3
  134. package/src/base/BaseXYFlow.tsx +24 -29
  135. package/src/base/primitives/MarkdownBlock.tsx +11 -3
  136. package/src/base/primitives/compound/CompoundActionButton.tsx +2 -2
  137. package/src/base/primitives/compound/CompoundDetailsButton.tsx +2 -2
  138. package/src/base/primitives/compound/CompoundNodeContainer.css.ts +4 -13
  139. package/src/base/primitives/compound/CompoundNodeContainer.tsx +0 -3
  140. package/src/base/primitives/compound/CompoundTitle.tsx +8 -8
  141. package/src/base/primitives/compound/actionbtns.css.ts +6 -6
  142. package/src/base/primitives/edge/EdgeActionButton.tsx +2 -2
  143. package/src/base/primitives/edge/EdgeContainer.tsx +3 -6
  144. package/src/base/primitives/edge/EdgeLabel.css.ts +4 -83
  145. package/src/base/primitives/edge/EdgeLabel.tsx +16 -10
  146. package/src/base/primitives/edge/EdgeLabelContainer.tsx +1 -6
  147. package/src/base/primitives/edge/EdgeMarkers.tsx +3 -3
  148. package/src/base/primitives/edge/edge.css.ts +0 -60
  149. package/src/base/primitives/element/ElementActionButtons.tsx +2 -2
  150. package/src/base/primitives/element/ElementDetailsButton.tsx +7 -7
  151. package/src/base/primitives/element/ElementNodeContainer.css.ts +4 -4
  152. package/src/base/primitives/element/ElementNodeContainer.tsx +0 -3
  153. package/src/base/primitives/element/ElementShape.css.ts +11 -11
  154. package/src/base/primitives/element/ElementTags.tsx +17 -14
  155. package/src/bundle/LikeC4View.props.ts +1 -2
  156. package/src/bundle/LikeC4View.tsx +10 -3
  157. package/src/bundle/ReactLikeC4.tsx +1 -2
  158. package/src/bundle/ViewNotFound.tsx +1 -1
  159. package/src/bundle/index.ts +2 -1
  160. package/src/bundle/styles.css.ts +1 -1
  161. package/src/components/ErrorFallback.tsx +1 -1
  162. package/src/components/GithubIcon.tsx +16 -0
  163. package/src/components/Link.tsx +102 -113
  164. package/src/components/NavigationLink.tsx +2 -1
  165. package/src/components/SearchControl.css.ts +5 -5
  166. package/src/context/DiagramEventHandlers.tsx +12 -12
  167. package/src/globals.css +71 -0
  168. package/src/index.ts +5 -0
  169. package/src/likec4diagram/DiagramUI.tsx +8 -2
  170. package/src/likec4diagram/custom/edges/NotePopover.css.ts +2 -2
  171. package/src/likec4diagram/custom/edges/RelationshipEdge.tsx +1 -1
  172. package/src/likec4diagram/custom/edges/RelationshipsDropdownMenu.css.ts +7 -7
  173. package/src/likec4diagram/custom/edges/RelationshipsDropdownMenu.tsx +3 -3
  174. package/src/likec4diagram/custom/edges/edges.css.ts +4 -4
  175. package/src/likec4diagram/custom/nodes/toolbar/CompoundToolbar.tsx +2 -2
  176. package/src/likec4diagram/ui/controls/styles.css.ts +5 -5
  177. package/src/likec4diagram/ui/diagram-title/DiagramTitlePanel.tsx +4 -5
  178. package/src/likec4diagram/ui/notation/NotationPanel.css.ts +11 -11
  179. package/src/likec4diagram/ui/notation/NotationPanel.tsx +1 -4
  180. package/src/likec4diagram/ui/walkthrough/DynamicViewWalkthrough.css.ts +10 -10
  181. package/src/likec4model/{LikeC4ModelContext.ts → LikeC4ModelContext.tsx} +9 -1
  182. package/src/likec4model/LikeC4ProjectsContext.ts +9 -0
  183. package/src/likec4model/index.ts +8 -0
  184. package/src/likec4model/useCurrentViewModel.ts +4 -0
  185. package/src/likec4model/useLikeC4Project.ts +61 -0
  186. package/src/navigationpanel/NavigationPanel.tsx +16 -17
  187. package/src/navigationpanel/NavigationPanelControls.tsx +24 -46
  188. package/src/navigationpanel/NavigationPanelDropdown.tsx +32 -16
  189. package/src/navigationpanel/_common.tsx +4 -1
  190. package/src/navigationpanel/actor.ts +14 -15
  191. package/src/navigationpanel/controls/BurgerButton.tsx +5 -7
  192. package/src/navigationpanel/controls/NavigationButtons.tsx +9 -1
  193. package/src/navigationpanel/controls/OpenSource.tsx +1 -1
  194. package/src/navigationpanel/controls/SearchControl.tsx +6 -4
  195. package/src/navigationpanel/controls/ToggleReadonly.tsx +3 -3
  196. package/src/navigationpanel/controls/ViewDetailsCard.tsx +244 -0
  197. package/src/navigationpanel/controls/index.ts +1 -0
  198. package/src/navigationpanel/dropdown/ProjectsMenu.tsx +74 -0
  199. package/src/navigationpanel/editorpanel/EditorPanel.tsx +3 -3
  200. package/src/navigationpanel/editorpanel/ManualLayoutToolsButton.tsx +19 -22
  201. package/src/navigationpanel/editorpanel/styles.ts +5 -5
  202. package/src/navigationpanel/hooks.tsx +2 -2
  203. package/src/navigationpanel/styles.css.ts +0 -2
  204. package/src/navigationpanel/walkthrough/ActiveWalkthroughControls.tsx +9 -4
  205. package/src/overlays/element-details/ElementDetailsCard.css.ts +17 -17
  206. package/src/overlays/element-details/ElementDetailsCard.tsx +8 -13
  207. package/src/overlays/element-details/TabPanelDeployments.css.ts +4 -4
  208. package/src/overlays/element-details/TabPanelRelationships.css.ts +7 -7
  209. package/src/overlays/overlay/Overlay.css.ts +7 -7
  210. package/src/overlays/relationship-details/SelectEdge.css.ts +8 -8
  211. package/src/overlays/relationships-browser/SelectElement.css.ts +1 -1
  212. package/src/search/Search.tsx +6 -6
  213. package/src/search/components/ElementsColumn.css.ts +5 -5
  214. package/src/search/components/SearchByTags.tsx +2 -2
  215. package/src/search/components/ViewsColum.tsx +1 -1
  216. package/src/search/components/ViewsColumn.css.ts +1 -1
  217. package/src/search/components/_shared.css.ts +3 -3
  218. package/src/search/components/styles.css.ts +5 -5
  219. package/src/state/DiagramActorProvider.tsx +56 -30
  220. package/src/state/diagram-machine.ts +22 -16
  221. package/dist/LikeC4CustomColors.d.ts +0 -2
  222. package/dist/LikeC4CustomColors.js +0 -45
  223. package/dist/overlays/relationships-browser/custom/nodeTypes.d.ts +0 -45
  224. package/src/LikeC4CustomColors.tsx +0 -85
@@ -1,10 +1,10 @@
1
1
  import { IconMenu2 } from '@tabler/icons-react'
2
- import { useDiagramEventHandlers } from '../../context'
2
+ import { useDiagramEventHandlers } from '../../context/DiagramEventHandlers'
3
3
  import { PanelActionIcon } from '../_common'
4
- import { useNavigationActorRef } from '../hooks'
4
+ import { useNavigationActor } from '../hooks'
5
5
 
6
6
  export const BurgerButton = () => {
7
- const actor = useNavigationActorRef()
7
+ const actor = useNavigationActor()
8
8
  const { onBurgerMenuClick } = useDiagramEventHandlers()
9
9
  return (
10
10
  <PanelActionIcon
@@ -17,14 +17,12 @@ export const BurgerButton = () => {
17
17
  }}
18
18
  onClick={e => {
19
19
  e.stopPropagation()
20
- if (onBurgerMenuClick) {
21
- actor.send({ type: 'breadcrumbs.mouseLeave.root' })
20
+ if (onBurgerMenuClick && actor.isOpened()) {
22
21
  setTimeout(() => {
23
22
  onBurgerMenuClick()
24
23
  }, 100)
25
- } else {
26
- actor.send({ type: 'breadcrumbs.click.root' })
27
24
  }
25
+ actor.send({ type: 'breadcrumbs.click.root' })
28
26
  }}
29
27
  children={<IconMenu2 style={{ width: '80%', height: '80%' }} />}
30
28
  />
@@ -14,7 +14,15 @@ export const NavigationButtons = () => {
14
14
  hasStepForward: s.navigationHistory.currentIndex < s.navigationHistory.history.length - 1,
15
15
  }))
16
16
  return (
17
- <m.div layout="position" className={hstack({ gap: 1, mdDown: { display: 'none' } })}>
17
+ <m.div
18
+ layout="position"
19
+ className={hstack({
20
+ gap: '[1px]',
21
+ display: {
22
+ base: 'none',
23
+ '@likec4-root/sm': 'flex',
24
+ },
25
+ })}>
18
26
  <PanelActionIcon
19
27
  disabled={!hasStepBack}
20
28
  onClick={e => {
@@ -21,7 +21,7 @@ export const OpenSource = () => {
21
21
  e.stopPropagation()
22
22
  onOpenSource?.({ view: viewId })
23
23
  }}
24
- children={<IconFileSymlink size={12} stroke={1.5} style={{ width: '65%' }} />}
24
+ children={<IconFileSymlink style={{ width: '60%', height: '60%' }} />}
25
25
  />
26
26
  </Tooltip>
27
27
  )
@@ -24,14 +24,15 @@ export function SearchControl() {
24
24
  diagram.openSearch()
25
25
  }}
26
26
  whileTap={{
27
+ scale: 0.95,
27
28
  translateY: 1,
28
29
  }}
29
30
  className={cx(
30
31
  'group',
31
32
  hstack({
32
- gap: '2xs',
33
+ gap: 'xxs',
33
34
  paddingInline: 'sm',
34
- paddingBlock: '2xs',
35
+ paddingBlock: 'xxs',
35
36
  rounded: 'sm',
36
37
  userSelect: 'none',
37
38
  cursor: 'pointer',
@@ -43,8 +44,9 @@ export function SearchControl() {
43
44
  base: 'likec4.panel.action-icon.bg',
44
45
  _hover: 'likec4.panel.action-icon.bg.hover',
45
46
  },
46
- smDown: {
47
- display: 'none',
47
+ display: {
48
+ base: 'none',
49
+ '@/md': 'flex',
48
50
  },
49
51
  }),
50
52
  )}>
@@ -33,9 +33,9 @@ export const ToggleReadonly = () => {
33
33
  className={cx(
34
34
  'group',
35
35
  hstack({
36
- gap: '2',
37
- paddingInline: '2xs',
38
- paddingBlock: '2xs',
36
+ gap: '0.5',
37
+ paddingInline: 'xxs',
38
+ paddingBlock: 'xxs',
39
39
  rounded: 'sm',
40
40
  userSelect: 'none',
41
41
  cursor: 'pointer',
@@ -0,0 +1,244 @@
1
+ import { css, cx } from '@likec4/styles/css'
2
+ import { Box, HStack, styled } from '@likec4/styles/jsx'
3
+ import { hstack, vstack } from '@likec4/styles/patterns'
4
+ import {
5
+ type PopoverProps,
6
+ Badge,
7
+ Popover,
8
+ Text,
9
+ UnstyledButton,
10
+ } from '@mantine/core'
11
+ import { IconId, IconLink } from '@tabler/icons-react'
12
+ import * as m from 'motion/react-m'
13
+ import { ElementTag, MarkdownBlock } from '../../base/primitives'
14
+ import { Link } from '../../components/Link'
15
+ import { useDiagram } from '../../hooks/useDiagram'
16
+ import { useMantinePortalProps } from '../../hooks/useMantinePortalProps'
17
+ import type { NavigationPanelActorSnapshot } from '../actor'
18
+ import { useNavigationActorSnapshot } from '../hooks'
19
+
20
+ const selector = ({ context }: NavigationPanelActorSnapshot) => {
21
+ const view = context.viewModel
22
+ return {
23
+ id: view.id,
24
+ title: view.titleOrUntitled,
25
+ description: view.description,
26
+ tags: view.tags,
27
+ links: view.links,
28
+ relativePath: view.$view.relativePath,
29
+ }
30
+ }
31
+
32
+ type ViewDetailsCardData = ReturnType<typeof selector>
33
+
34
+ export const ViewDetailsCard = (props: PopoverProps) => {
35
+ const data = useNavigationActorSnapshot(selector)
36
+ const portalProps = useMantinePortalProps()
37
+
38
+ return (
39
+ <Popover
40
+ position="bottom-end"
41
+ shadow="xl"
42
+ clickOutsideEvents={['pointerdown', 'mousedown', 'click']}
43
+ trapFocus
44
+ {...portalProps}
45
+ {...props}
46
+ >
47
+ <ViewDetailsCardTrigger linksCount={data.links.length} />
48
+ <ViewDetailsCardDropdown data={data} />
49
+ </Popover>
50
+ )
51
+ }
52
+
53
+ const ViewDetailsCardTrigger = ({ linksCount }: { linksCount: number }) => (
54
+ <Popover.Target>
55
+ <UnstyledButton
56
+ component={m.button}
57
+ layout="position"
58
+ whileTap={{
59
+ scale: 0.95,
60
+ translateY: 1,
61
+ }}
62
+ className={cx(
63
+ 'group',
64
+ hstack({
65
+ gap: '2',
66
+ paddingInline: 'xxs',
67
+ paddingBlock: 'xxs',
68
+ rounded: 'sm',
69
+ userSelect: 'none',
70
+ cursor: 'pointer',
71
+ color: {
72
+ base: 'likec4.panel.action-icon.text',
73
+ _hover: 'likec4.panel.action-icon.text.hover',
74
+ },
75
+ backgroundColor: {
76
+ _hover: 'likec4.panel.action-icon.bg.hover',
77
+ },
78
+ display: {
79
+ base: 'none',
80
+ '@/xs': 'flex',
81
+ },
82
+ }),
83
+ ``,
84
+ )}>
85
+ <IconId size={16} stroke={1.8} />
86
+ {linksCount > 0 && (
87
+ <HStack gap={'[1px]'}>
88
+ <IconLink size={14} stroke={2} />
89
+ <Box
90
+ css={{
91
+ fontSize: '11px',
92
+ fontWeight: 600,
93
+ lineHeight: 1,
94
+ opacity: 0.8,
95
+ }}>
96
+ {linksCount}
97
+ </Box>
98
+ </HStack>
99
+ )}
100
+ </UnstyledButton>
101
+ </Popover.Target>
102
+ )
103
+
104
+ const SectionHeader = styled('div', {
105
+ base: {
106
+ fontSize: 'xs',
107
+ color: 'mantine.colors.dimmed',
108
+ fontWeight: 500,
109
+ userSelect: 'none',
110
+ mb: 'xxs',
111
+ },
112
+ })
113
+
114
+ const ViewDetailsCardDropdown = ({
115
+ data: {
116
+ id,
117
+ title,
118
+ description,
119
+ tags,
120
+ links,
121
+ relativePath,
122
+ },
123
+ }: { data: ViewDetailsCardData }) => {
124
+ const diagram = useDiagram()
125
+ return (
126
+ <Popover.Dropdown
127
+ className={cx(
128
+ 'nowheel nopan nodrag',
129
+ vstack({
130
+ margin: 'xs',
131
+ layerStyle: 'likec4.dropdown',
132
+ gap: 'md',
133
+ padding: 'md',
134
+ pointerEvents: 'all',
135
+ maxWidth: 'calc(100cqw - 32px)',
136
+ minWidth: 'calc(100cqw - 50px)',
137
+ maxHeight: 'calc(100cqh - 100px)',
138
+ width: 'max-content',
139
+ cursor: 'default',
140
+ '@/sm': {
141
+ minWidth: 400,
142
+ maxWidth: 550,
143
+ },
144
+ '@/lg': {
145
+ maxWidth: 700,
146
+ },
147
+ }),
148
+ )}>
149
+ <section>
150
+ <Text component="div" fw={500} size="xl">{title}</Text>
151
+ <HStack alignItems={'flex-start'} mt="1">
152
+ <ViewBadge label="id" value={id} />
153
+ {/* {relativePath && <ViewBadge label="source" value={relativePath} />} */}
154
+ <HStack gap="xs" flexWrap="wrap">
155
+ {tags.map((tag, i) => (
156
+ <ElementTag
157
+ key={tag}
158
+ tag={tag}
159
+ cursor="pointer"
160
+ onClick={e => {
161
+ e.stopPropagation()
162
+ diagram.openSearch(`#${tag}`)
163
+ }} />
164
+ ))}
165
+ </HStack>
166
+ </HStack>
167
+ </section>
168
+ {links.length > 0 && (
169
+ <section className={hstack({ alignItems: 'baseline' })}>
170
+ <SectionHeader>Links</SectionHeader>
171
+ <HStack gap="xs" flexWrap="wrap">
172
+ {links.map((link, i) => <Link key={`${i}-${link.url}`} value={link} />)}
173
+ </HStack>
174
+ </section>
175
+ )}
176
+ {description.isEmpty && (
177
+ <Text component="div" fw={500} size="xs" c="dimmed" my="md" style={{ userSelect: 'none' }}>No description</Text>
178
+ )}
179
+ {description.nonEmpty && (
180
+ <section>
181
+ <SectionHeader>Description</SectionHeader>
182
+ <MarkdownBlock
183
+ value={description}
184
+ fontSize="sm"
185
+ emptyText="No description"
186
+ className={css({
187
+ userSelect: 'all',
188
+ })}
189
+ />
190
+ </section>
191
+ )}
192
+ </Popover.Dropdown>
193
+ )
194
+ }
195
+
196
+ const ViewBadge = ({
197
+ label,
198
+ value,
199
+ }: {
200
+ label: string
201
+ value: string
202
+ }) => {
203
+ return (
204
+ <HStack gap="0.5">
205
+ <ViewBadgeLabel>{label}</ViewBadgeLabel>
206
+ <Badge
207
+ size="sm"
208
+ radius="sm"
209
+ variant="light"
210
+ color="gray"
211
+ tt="none"
212
+ fw={500}
213
+ classNames={{
214
+ root: css({
215
+ width: 'max-content',
216
+ overflow: 'visible',
217
+ px: '1',
218
+ color: {
219
+ _light: 'mantine.colors.gray[8]',
220
+ },
221
+ }),
222
+ label: css({
223
+ overflow: 'visible',
224
+ }),
225
+ section: css({
226
+ opacity: 0.5,
227
+ userSelect: 'none',
228
+ marginInlineEnd: '0.5',
229
+ }),
230
+ }}>
231
+ {value}
232
+ </Badge>
233
+ </HStack>
234
+ )
235
+ }
236
+
237
+ const ViewBadgeLabel = styled('div', {
238
+ base: {
239
+ color: 'mantine.colors.dimmed',
240
+ fontWeight: 500,
241
+ fontSize: 'xxs',
242
+ userSelect: 'none',
243
+ },
244
+ })
@@ -3,3 +3,4 @@ export { NavigationButtons } from './NavigationButtons'
3
3
  export { OpenSource } from './OpenSource'
4
4
  export { SearchControl } from './SearchControl'
5
5
  export { ToggleReadonly } from './ToggleReadonly'
6
+ export { ViewDetailsCard } from './ViewDetailsCard'
@@ -0,0 +1,74 @@
1
+ import { css } from '@likec4/styles/css'
2
+ import { Box, HStack } from '@likec4/styles/jsx'
3
+ import { type ButtonProps, Button, Menu, MenuDropdown, MenuItem, MenuTarget } from '@mantine/core'
4
+ import { IconChevronDown } from '@tabler/icons-react'
5
+ import { useLikeC4ProjectId, useLikeC4ProjectsContext } from '../../likec4model/useLikeC4Project'
6
+
7
+ export function ProjectsMenu(props: ButtonProps) {
8
+ const { projects, onProjectChange } = useLikeC4ProjectsContext()
9
+ const projectId = useLikeC4ProjectId()
10
+
11
+ if (projects.length <= 1) {
12
+ return null
13
+ }
14
+
15
+ return (
16
+ <HStack gap="0.5" alignItems="baseline">
17
+ <Box
18
+ css={{
19
+ fontWeight: '400',
20
+ fontSize: 'xxs',
21
+ color: 'mantine.colors.dimmed',
22
+ userSelect: 'none',
23
+ }}>
24
+ Project
25
+ </Box>
26
+ <Menu shadow="md" position="bottom-start" offset={{ mainAxis: 2 }} closeOnItemClick>
27
+ <MenuTarget>
28
+ <Button
29
+ tabIndex={-1}
30
+ autoFocus={false}
31
+ variant="subtle"
32
+ size="compact-xs"
33
+ color="gray"
34
+ classNames={{
35
+ root: css({
36
+ fontWeight: '400',
37
+ fontSize: 'xxs',
38
+ height: 'auto',
39
+ lineHeight: 1.1,
40
+ color: {
41
+ _light: 'mantine.colors.gray[9]',
42
+ },
43
+ }),
44
+ section: css({
45
+ '&:is([data-position="right"])': {
46
+ marginInlineStart: '1',
47
+ },
48
+ }),
49
+ }}
50
+ rightSection={<IconChevronDown opacity={0.5} size={12} stroke={1.5} />}
51
+ {...props}>
52
+ {projectId}
53
+ </Button>
54
+ </MenuTarget>
55
+
56
+ <MenuDropdown>
57
+ {projects.map(({ id, title }) => (
58
+ <MenuItem
59
+ key={id}
60
+ onClick={(e) => {
61
+ if (projectId === id) {
62
+ e.stopPropagation()
63
+ return
64
+ }
65
+ onProjectChange(id)
66
+ }}>
67
+ {title ?? id}
68
+ </MenuItem>
69
+ ))}
70
+ </MenuDropdown>
71
+ </Menu>
72
+ </HStack>
73
+ )
74
+ }
@@ -16,11 +16,11 @@ export function EditorPanel() {
16
16
  <m.div
17
17
  layout="position"
18
18
  className={vstack({
19
- gap: 'sm',
19
+ gap: 'xs',
20
20
  layerStyle: 'likec4.panel',
21
21
  position: 'relative',
22
22
  cursor: 'pointer',
23
- padding: '4',
23
+ padding: 'xxs',
24
24
  pointerEvents: 'all',
25
25
  })}
26
26
  initial={{
@@ -36,7 +36,7 @@ export function EditorPanel() {
36
36
  translateX: -20,
37
37
  }}
38
38
  >
39
- <TooltipGroup>
39
+ <TooltipGroup openDelay={600} closeDelay={120}>
40
40
  <ChangeAutoLayoutButton />
41
41
  <ManualLayoutToolsButton />
42
42
  <LayoutDriftNotification />
@@ -2,7 +2,6 @@ import { css } from '@likec4/styles/css'
2
2
  import { hstack } from '@likec4/styles/patterns'
3
3
  import {
4
4
  type PopoverProps,
5
- ActionIcon,
6
5
  Popover,
7
6
  PopoverDropdown,
8
7
  PopoverTarget,
@@ -20,6 +19,7 @@ import {
20
19
  IconRouteOff,
21
20
  } from '@tabler/icons-react'
22
21
  import { useDiagram } from '../../hooks/useDiagram'
22
+ import { useMantinePortalProps } from '../../hooks/useMantinePortalProps'
23
23
  import { PanelActionIcon } from '../_common'
24
24
  import { Tooltip } from './_common'
25
25
 
@@ -33,7 +33,7 @@ const Action = ({
33
33
  onClick: React.MouseEventHandler
34
34
  }) => (
35
35
  <Tooltip label={label} withinPortal={false} position="top">
36
- <ActionIcon
36
+ <PanelActionIcon
37
37
  classNames={{
38
38
  root: 'action-icon',
39
39
  icon: css({
@@ -43,29 +43,25 @@ const Action = ({
43
43
  },
44
44
  }),
45
45
  }}
46
- variant="subtle"
47
- color="gray"
48
46
  onClick={onClick}>
49
47
  {icon}
50
- </ActionIcon>
48
+ </PanelActionIcon>
51
49
  </Tooltip>
52
50
  )
53
51
 
54
52
  export const ManualLayoutToolsButton = (props: PopoverProps) => {
55
53
  const diagram = useDiagram()
56
-
54
+ const portalProps = useMantinePortalProps()
57
55
  return (
58
56
  <Popover
59
- position="right-start"
57
+ position="right"
60
58
  offset={{
61
- mainAxis: 10,
62
- crossAxis: -2,
59
+ mainAxis: 12,
63
60
  }}
64
61
  clickOutsideEvents={[
65
62
  'pointerdown',
66
63
  ]}
67
- radius="sm"
68
- shadow="lg"
64
+ {...portalProps}
69
65
  {...props}>
70
66
  <PopoverTarget>
71
67
  <Tooltip label="Manual layouting tools">
@@ -76,70 +72,71 @@ export const ManualLayoutToolsButton = (props: PopoverProps) => {
76
72
  </PopoverTarget>
77
73
  <PopoverDropdown
78
74
  className={hstack({
79
- gap: 1,
75
+ gap: '0.5',
80
76
  layerStyle: 'likec4.panel',
81
- p: '2',
77
+ padding: '1',
78
+ pointerEvents: 'all',
82
79
  })}>
83
80
  <TooltipGroup>
84
81
  <Action
85
82
  label="Align in columns"
86
- icon={<IconLayoutBoardSplit stroke={1.2} />}
83
+ icon={<IconLayoutBoardSplit />}
87
84
  onClick={e => {
88
85
  e.stopPropagation()
89
86
  diagram.align('Column')
90
87
  }} />
91
88
  <Action
92
89
  label="Align left"
93
- icon={<IconLayoutAlignLeft stroke={1.5} />}
90
+ icon={<IconLayoutAlignLeft />}
94
91
  onClick={e => {
95
92
  e.stopPropagation()
96
93
  diagram.align('Left')
97
94
  }} />
98
95
  <Action
99
96
  label="Align center"
100
- icon={<IconLayoutAlignCenter stroke={1.5} />}
97
+ icon={<IconLayoutAlignCenter />}
101
98
  onClick={e => {
102
99
  e.stopPropagation()
103
100
  diagram.align('Center')
104
101
  }} />
105
102
  <Action
106
103
  label="Align right"
107
- icon={<IconLayoutAlignRight stroke={1.5} />}
104
+ icon={<IconLayoutAlignRight />}
108
105
  onClick={e => {
109
106
  e.stopPropagation()
110
107
  diagram.align('Right')
111
108
  }} />
112
109
  <Action
113
110
  label="Align in rows"
114
- icon={<IconLayoutBoardSplit stroke={1.5} style={{ transform: 'rotate(90deg)' }} />}
111
+ icon={<IconLayoutBoardSplit style={{ transform: 'rotate(90deg)' }} />}
115
112
  onClick={e => {
116
113
  e.stopPropagation()
117
114
  diagram.align('Row')
118
115
  }} />
119
116
  <Action
120
117
  label="Align top"
121
- icon={<IconLayoutAlignTop stroke={1.5} />}
118
+ icon={<IconLayoutAlignTop />}
122
119
  onClick={e => {
123
120
  e.stopPropagation()
124
121
  diagram.align('Top')
125
122
  }} />
126
123
  <Action
127
124
  label="Align middle"
128
- icon={<IconLayoutAlignMiddle stroke={1.5} />}
125
+ icon={<IconLayoutAlignMiddle />}
129
126
  onClick={e => {
130
127
  e.stopPropagation()
131
128
  diagram.align('Middle')
132
129
  }} />
133
130
  <Action
134
131
  label="Align bottom"
135
- icon={<IconLayoutAlignBottom stroke={1.5} />}
132
+ icon={<IconLayoutAlignBottom />}
136
133
  onClick={e => {
137
134
  e.stopPropagation()
138
135
  diagram.align('Bottom')
139
136
  }} />
140
137
  <Action
141
138
  label="Reset all control points"
142
- icon={<IconRouteOff stroke={1.5} />}
139
+ icon={<IconRouteOff />}
143
140
  onClick={e => {
144
141
  e.stopPropagation()
145
142
  diagram.resetEdgeControlPoints()
@@ -1,16 +1,16 @@
1
1
  import { css } from '@likec4/styles/css'
2
2
 
3
3
  export const navigationButtons = css({
4
- gap: 'micro',
4
+ gap: 'xxs',
5
5
  _empty: {
6
6
  display: 'none',
7
7
  },
8
8
  })
9
9
 
10
10
  export const panel = css({
11
- top: '1rem',
12
- left: '1rem',
13
- margin: 0,
11
+ top: 'md',
12
+ left: 'md',
13
+ margin: '0',
14
14
  pointerEvents: 'none',
15
15
  '& :where(button, .action-icon, [role=\'dialog\'])': {
16
16
  pointerEvents: 'all',
@@ -47,7 +47,7 @@ export const autolayoutButton = css({
47
47
  flex: '1 1 40%',
48
48
  textAlign: 'center',
49
49
  fontWeight: 500,
50
- padding: '4px 6px',
50
+ padding: '[4px 6px]',
51
51
  fontSize: '11px',
52
52
  zIndex: 1,
53
53
  })
@@ -14,7 +14,7 @@ NavigationPanelActorSafeContext.displayName = 'NavigationPanelActorSafeContext'
14
14
 
15
15
  export const NavigationPanelActorContextProvider = NavigationPanelActorSafeContext.Provider
16
16
 
17
- export const useNavigationActorRef = () => {
17
+ export const useNavigationActorRef = (): NavigationPanelActorRef => {
18
18
  const ctx = useContext(NavigationPanelActorSafeContext)
19
19
  if (ctx === null) {
20
20
  throw new Error('NavigationPanelActorRef is not found in the context')
@@ -39,7 +39,7 @@ export function useNavigationActorContext<T = unknown>(
39
39
  return useNavigationActorSnapshot(snapshot => selector(snapshot.context), compare, deps)
40
40
  }
41
41
 
42
- export type NavigationActor = {
42
+ export interface NavigationActor {
43
43
  readonly actorRef: NavigationPanelActorRef
44
44
  send: (event: NavigationPanelActorEvent) => void
45
45
  selectFolder: (folderPath: string) => void
@@ -5,8 +5,6 @@ export const breadcrumbTitle = cva({
5
5
  fontSize: 'sm',
6
6
  fontWeight: '500',
7
7
  transition: 'fast',
8
- // width: 'max-content',
9
- alignSelf: 'stretch',
10
8
  color: {
11
9
  base: 'mantine.colors.text/90',
12
10
  _hover: 'mantine.colors.text',