@likec4/diagram 1.35.0 → 1.36.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 (214) hide show
  1. package/bundle/{chunk-C0Eg81Gj.js → chunk-7MPUJFHj.js} +315 -311
  2. package/bundle/custom.js +52 -52
  3. package/bundle/index.js +1583 -739
  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/custom/edges/NotePopover.css.js +2 -2
  59. package/dist/likec4diagram/custom/edges/RelationshipEdge.d.ts +2 -2
  60. package/dist/likec4diagram/custom/edges/RelationshipEdge.js +1 -1
  61. package/dist/likec4diagram/custom/edges/RelationshipsDropdownMenu.css.js +7 -7
  62. package/dist/likec4diagram/custom/edges/RelationshipsDropdownMenu.js +3 -3
  63. package/dist/likec4diagram/custom/edges/edges.css.js +4 -4
  64. package/dist/likec4diagram/custom/index.d.ts +2 -2
  65. package/dist/likec4diagram/custom/nodes/toolbar/CompoundToolbar.js +2 -2
  66. package/dist/likec4diagram/ui/controls/styles.css.js +5 -5
  67. package/dist/likec4diagram/ui/notation/NotationPanel.css.js +11 -11
  68. package/dist/likec4diagram/ui/notation/NotationPanel.js +2 -5
  69. package/dist/likec4diagram/ui/walkthrough/DynamicViewWalkthrough.css.js +10 -10
  70. package/dist/likec4model/LikeC4ProjectsContext.d.ts +7 -0
  71. package/dist/likec4model/LikeC4ProjectsContext.js +5 -0
  72. package/dist/likec4model/index.d.ts +1 -0
  73. package/dist/likec4model/useLikeC4Project.d.ts +22 -0
  74. package/dist/likec4model/useLikeC4Project.js +23 -0
  75. package/dist/navigationpanel/NavigationPanel.js +15 -17
  76. package/dist/navigationpanel/NavigationPanelControls.js +34 -21
  77. package/dist/navigationpanel/NavigationPanelDropdown.js +33 -17
  78. package/dist/navigationpanel/_common.js +4 -1
  79. package/dist/navigationpanel/actor.d.ts +11 -15
  80. package/dist/navigationpanel/actor.js +14 -15
  81. package/dist/navigationpanel/controls/BurgerButton.js +5 -7
  82. package/dist/navigationpanel/controls/NavigationButtons.js +37 -24
  83. package/dist/navigationpanel/controls/OpenSource.js +1 -1
  84. package/dist/navigationpanel/controls/SearchControl.js +6 -4
  85. package/dist/navigationpanel/controls/ToggleReadonly.js +3 -3
  86. package/dist/navigationpanel/controls/ViewDetailsCard.d.ts +2 -0
  87. package/dist/navigationpanel/controls/ViewDetailsCard.js +232 -0
  88. package/dist/navigationpanel/controls/index.d.ts +1 -0
  89. package/dist/navigationpanel/dropdown/ProjectsMenu.d.ts +2 -0
  90. package/dist/navigationpanel/dropdown/ProjectsMenu.js +75 -0
  91. package/dist/navigationpanel/editorpanel/EditorPanel.js +3 -3
  92. package/dist/navigationpanel/editorpanel/ManualLayoutToolsButton.js +19 -20
  93. package/dist/navigationpanel/editorpanel/styles.js +5 -5
  94. package/dist/navigationpanel/hooks.d.ts +2 -2
  95. package/dist/navigationpanel/styles.css.js +0 -2
  96. package/dist/navigationpanel/walkthrough/ActiveWalkthroughControls.js +12 -7
  97. 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
  98. 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
  99. package/dist/overlays/element-details/ElementDetailsCard.css.js +18 -17
  100. package/dist/overlays/element-details/ElementDetailsCard.js +8 -13
  101. package/dist/overlays/element-details/TabPanelDeployments.css.js +5 -4
  102. package/dist/overlays/element-details/TabPanelRelationships.css.js +7 -7
  103. package/dist/overlays/overlay/Overlay.css.d.ts +3 -3
  104. package/dist/overlays/overlay/Overlay.css.js +8 -7
  105. package/dist/overlays/relationship-details/SelectEdge.css.js +8 -8
  106. package/dist/overlays/relationships-browser/SelectElement.css.js +1 -1
  107. package/dist/search/Search.js +6 -6
  108. package/dist/search/components/ElementsColumn.css.js +5 -5
  109. package/dist/search/components/SearchByTags.js +3 -2
  110. package/dist/search/components/ViewsColum.js +1 -1
  111. package/dist/search/components/ViewsColumn.css.js +1 -1
  112. package/dist/search/components/_shared.css.js +3 -3
  113. package/dist/search/components/styles.css.js +5 -5
  114. package/dist/state/DiagramActorProvider.js +34 -15
  115. package/dist/state/diagram-machine.d.ts +29 -247
  116. package/dist/state/diagram-machine.js +16 -16
  117. package/dist/styles-min.css +1 -1
  118. package/dist/styles.css +1 -1
  119. package/dist/styles.css2.js +1 -1
  120. package/package.json +10 -8
  121. package/panda.buildinfo.json +254 -326
  122. package/src/LikeC4Diagram.props.ts +2 -2
  123. package/src/LikeC4Diagram.tsx +2 -2
  124. package/src/LikeC4ModelProvider.tsx +4 -4
  125. package/src/LikeC4ProjectsProvider.tsx +41 -0
  126. package/src/LikeC4Styles.tsx +107 -0
  127. package/src/StaticLikeC4Diagram.tsx +3 -3
  128. package/src/base/BaseXYFlow.tsx +24 -29
  129. package/src/base/primitives/MarkdownBlock.tsx +11 -3
  130. package/src/base/primitives/compound/CompoundActionButton.tsx +2 -2
  131. package/src/base/primitives/compound/CompoundDetailsButton.tsx +2 -2
  132. package/src/base/primitives/compound/CompoundNodeContainer.css.ts +4 -13
  133. package/src/base/primitives/compound/CompoundNodeContainer.tsx +0 -3
  134. package/src/base/primitives/compound/CompoundTitle.tsx +8 -8
  135. package/src/base/primitives/compound/actionbtns.css.ts +6 -6
  136. package/src/base/primitives/edge/EdgeActionButton.tsx +2 -2
  137. package/src/base/primitives/edge/EdgeContainer.tsx +3 -6
  138. package/src/base/primitives/edge/EdgeLabel.css.ts +4 -83
  139. package/src/base/primitives/edge/EdgeLabel.tsx +16 -10
  140. package/src/base/primitives/edge/EdgeLabelContainer.tsx +1 -6
  141. package/src/base/primitives/edge/EdgeMarkers.tsx +3 -3
  142. package/src/base/primitives/edge/edge.css.ts +0 -60
  143. package/src/base/primitives/element/ElementActionButtons.tsx +2 -2
  144. package/src/base/primitives/element/ElementDetailsButton.tsx +7 -7
  145. package/src/base/primitives/element/ElementNodeContainer.css.ts +4 -4
  146. package/src/base/primitives/element/ElementNodeContainer.tsx +0 -3
  147. package/src/base/primitives/element/ElementShape.css.ts +11 -11
  148. package/src/base/primitives/element/ElementTags.tsx +17 -14
  149. package/src/bundle/LikeC4View.props.ts +1 -2
  150. package/src/bundle/LikeC4View.tsx +10 -3
  151. package/src/bundle/ReactLikeC4.tsx +1 -2
  152. package/src/bundle/ViewNotFound.tsx +1 -1
  153. package/src/bundle/index.ts +2 -1
  154. package/src/bundle/styles.css.ts +1 -1
  155. package/src/components/ErrorFallback.tsx +1 -1
  156. package/src/components/GithubIcon.tsx +16 -0
  157. package/src/components/Link.tsx +102 -113
  158. package/src/components/NavigationLink.tsx +2 -1
  159. package/src/components/SearchControl.css.ts +5 -5
  160. package/src/context/DiagramEventHandlers.tsx +12 -12
  161. package/src/globals.css +71 -0
  162. package/src/index.ts +5 -0
  163. package/src/likec4diagram/custom/edges/NotePopover.css.ts +2 -2
  164. package/src/likec4diagram/custom/edges/RelationshipEdge.tsx +1 -1
  165. package/src/likec4diagram/custom/edges/RelationshipsDropdownMenu.css.ts +7 -7
  166. package/src/likec4diagram/custom/edges/RelationshipsDropdownMenu.tsx +3 -3
  167. package/src/likec4diagram/custom/edges/edges.css.ts +4 -4
  168. package/src/likec4diagram/custom/nodes/toolbar/CompoundToolbar.tsx +2 -2
  169. package/src/likec4diagram/ui/controls/styles.css.ts +5 -5
  170. package/src/likec4diagram/ui/notation/NotationPanel.css.ts +11 -11
  171. package/src/likec4diagram/ui/notation/NotationPanel.tsx +1 -4
  172. package/src/likec4diagram/ui/walkthrough/DynamicViewWalkthrough.css.ts +10 -10
  173. package/src/likec4model/LikeC4ProjectsContext.ts +9 -0
  174. package/src/likec4model/index.ts +8 -0
  175. package/src/likec4model/useLikeC4Project.ts +61 -0
  176. package/src/navigationpanel/NavigationPanel.tsx +16 -17
  177. package/src/navigationpanel/NavigationPanelControls.tsx +24 -46
  178. package/src/navigationpanel/NavigationPanelDropdown.tsx +32 -16
  179. package/src/navigationpanel/_common.tsx +4 -1
  180. package/src/navigationpanel/actor.ts +14 -15
  181. package/src/navigationpanel/controls/BurgerButton.tsx +5 -7
  182. package/src/navigationpanel/controls/NavigationButtons.tsx +9 -1
  183. package/src/navigationpanel/controls/OpenSource.tsx +1 -1
  184. package/src/navigationpanel/controls/SearchControl.tsx +6 -4
  185. package/src/navigationpanel/controls/ToggleReadonly.tsx +3 -3
  186. package/src/navigationpanel/controls/ViewDetailsCard.tsx +244 -0
  187. package/src/navigationpanel/controls/index.ts +1 -0
  188. package/src/navigationpanel/dropdown/ProjectsMenu.tsx +74 -0
  189. package/src/navigationpanel/editorpanel/EditorPanel.tsx +3 -3
  190. package/src/navigationpanel/editorpanel/ManualLayoutToolsButton.tsx +19 -22
  191. package/src/navigationpanel/editorpanel/styles.ts +5 -5
  192. package/src/navigationpanel/hooks.tsx +2 -2
  193. package/src/navigationpanel/styles.css.ts +0 -2
  194. package/src/navigationpanel/walkthrough/ActiveWalkthroughControls.tsx +9 -4
  195. package/src/overlays/element-details/ElementDetailsCard.css.ts +17 -17
  196. package/src/overlays/element-details/ElementDetailsCard.tsx +8 -13
  197. package/src/overlays/element-details/TabPanelDeployments.css.ts +4 -4
  198. package/src/overlays/element-details/TabPanelRelationships.css.ts +7 -7
  199. package/src/overlays/overlay/Overlay.css.ts +7 -7
  200. package/src/overlays/relationship-details/SelectEdge.css.ts +8 -8
  201. package/src/overlays/relationships-browser/SelectElement.css.ts +1 -1
  202. package/src/search/Search.tsx +6 -6
  203. package/src/search/components/ElementsColumn.css.ts +5 -5
  204. package/src/search/components/SearchByTags.tsx +2 -2
  205. package/src/search/components/ViewsColum.tsx +1 -1
  206. package/src/search/components/ViewsColumn.css.ts +1 -1
  207. package/src/search/components/_shared.css.ts +3 -3
  208. package/src/search/components/styles.css.ts +5 -5
  209. package/src/state/DiagramActorProvider.tsx +45 -20
  210. package/src/state/diagram-machine.ts +22 -16
  211. package/dist/LikeC4CustomColors.d.ts +0 -2
  212. package/dist/LikeC4CustomColors.js +0 -45
  213. package/dist/overlays/relationships-browser/custom/nodeTypes.d.ts +0 -45
  214. package/src/LikeC4CustomColors.tsx +0 -85
@@ -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',
@@ -23,6 +23,9 @@ const TriggerWalkthroughButton = Button.withProps({
23
23
  variant: 'filled',
24
24
  size: 'xs',
25
25
  fw: '500',
26
+ className: css({
27
+ flexShrink: 0,
28
+ }),
26
29
  })
27
30
 
28
31
  export const StartWalkthroughButton = () => {
@@ -59,10 +62,10 @@ const ParallelFrame = () => {
59
62
  <Box
60
63
  css={{
61
64
  position: 'absolute',
62
- margin: 0,
63
- padding: 0,
64
- top: 0,
65
- left: 0,
65
+ margin: '0',
66
+ padding: '0',
67
+ top: '0',
68
+ left: '0',
66
69
  width: '100%',
67
70
  height: '100%',
68
71
  border: `2px solid`,
@@ -100,6 +103,7 @@ export const ActiveWalkthroughControls = () => {
100
103
  return (
101
104
  <AnimatePresence propagate>
102
105
  <TriggerWalkthroughButton
106
+ key="trigger-dynamic-walkthrough"
103
107
  variant="light"
104
108
  color="orange"
105
109
  mr={'sm'}
@@ -122,6 +126,7 @@ export const ActiveWalkthroughControls = () => {
122
126
  </PrevNextButton>
123
127
 
124
128
  <Badge
129
+ key="step-badge"
125
130
  component={m.div}
126
131
  size="md"
127
132
  radius="sm"
@@ -5,10 +5,10 @@ export const backdropOpacity = '--_opacity'
5
5
 
6
6
  export const dialog = css({
7
7
  boxSizing: 'border-box',
8
- margin: 0,
9
- padding: 0,
8
+ margin: '0',
9
+ padding: '0',
10
10
  position: 'fixed',
11
- inset: 0,
11
+ inset: '0',
12
12
  width: '100vw',
13
13
  height: '100vh',
14
14
  maxWidth: '100vw',
@@ -34,12 +34,12 @@ export const card = css({
34
34
  border: `none`,
35
35
  backgroundImage: `
36
36
  linear-gradient(180deg,
37
- color-mix(in srgb, {colors.likec4.palette.fill} 60%, transparent),
38
- color-mix(in srgb, {colors.likec4.palette.fill} 20%, transparent) 8px,
39
- color-mix(in srgb, {colors.likec4.palette.fill} 14%, transparent) 20px,
37
+ color-mix(in srgb, var(--likec4-palette-fill) 60%, transparent),
38
+ color-mix(in srgb, var(--likec4-palette-fill) 20%, transparent) 8px,
39
+ color-mix(in srgb, var(--likec4-palette-fill) 14%, transparent) 20px,
40
40
  transparent 80px
41
41
  ),
42
- linear-gradient(180deg, {colors.likec4.palette.fill}, {colors.likec4.palette.fill} 4px, transparent 4px)
42
+ linear-gradient(180deg, var(--likec4-palette-fill), var(--likec4-palette-fill) 4px, transparent 4px)
43
43
  `,
44
44
  '& .react-flow__attribution': {
45
45
  display: 'none',
@@ -99,7 +99,7 @@ export const viewButton = css({
99
99
  width: '100%',
100
100
  background: 'mantine.colors.body',
101
101
  borderRadius: 'sm',
102
- padding: `10px 8px`,
102
+ padding: `[10px 8px]`,
103
103
  // gap: 6,
104
104
  // alignItems: 'flex-start',
105
105
  transition: 'fast',
@@ -163,8 +163,8 @@ export const tabsList = css({
163
163
  background: 'mantine.colors.gray[1]',
164
164
  borderRadius: 'sm',
165
165
  flexWrap: 'nowrap',
166
- gap: '6px',
167
- padding: '4px',
166
+ gap: '1.5', // 6px
167
+ padding: '1',
168
168
  _dark: {
169
169
  background: 'mantine.colors.dark[7]',
170
170
  },
@@ -174,7 +174,7 @@ export const tabsTab = css({
174
174
  fontSize: 'xs',
175
175
  fontWeight: 500,
176
176
  flexGrow: 1,
177
- padding: '6px 8px',
177
+ padding: '[6px 8px]',
178
178
  transition: 'fast',
179
179
  borderRadius: 'sm',
180
180
  color: 'mantine.colors.gray[7]',
@@ -208,15 +208,15 @@ export const tabsPanel = css({
208
208
  overflow: 'hidden',
209
209
  position: 'relative',
210
210
  '&:not(:has(.mantine-ScrollArea-root))': {
211
- paddingLeft: '4px',
212
- paddingRight: '4px',
211
+ paddingLeft: '1',
212
+ paddingRight: '1',
213
213
  },
214
214
  '& .mantine-ScrollArea-root': {
215
215
  width: '100%',
216
216
  height: '100%',
217
217
  '& > div': {
218
- paddingLeft: '4px',
219
- paddingRight: '4px',
218
+ paddingLeft: '1',
219
+ paddingRight: '1',
220
220
  },
221
221
  },
222
222
  })
@@ -246,8 +246,8 @@ export const resizeHandle = css({
246
246
  borderTop: 'none',
247
247
  borderLeft: 'none',
248
248
  borderRadius: '2px',
249
- bottom: '2px',
250
- right: '2px',
249
+ bottom: '0.5',
250
+ right: '0.5',
251
251
  transition: 'fast',
252
252
  cursor: 'se-resize',
253
253
  _hover: {