@tldiagram/core-ui 1.87.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 (272) hide show
  1. package/dist/App.d.ts +1 -0
  2. package/dist/api/client.d.ts +143 -0
  3. package/dist/api/transport-vscode.d.ts +8 -0
  4. package/dist/api/transport.d.ts +1 -0
  5. package/dist/components/CodePreviewPanel-vscode.d.ts +7 -0
  6. package/dist/components/CodePreviewPanel.d.ts +9 -0
  7. package/dist/components/ConfirmDialog.d.ts +12 -0
  8. package/dist/components/ConnectorPanel.d.ts +21 -0
  9. package/dist/components/ContextBoundaryElement.d.ts +11 -0
  10. package/dist/components/ContextNeighborElement.d.ts +29 -0
  11. package/dist/components/ContextStraightConnector.d.ts +4 -0
  12. package/dist/components/CrossBranchControls.d.ts +9 -0
  13. package/dist/components/DependenciesOnboarding.d.ts +5 -0
  14. package/dist/components/DrawingCanvas.d.ts +39 -0
  15. package/dist/components/ElementLibrary-vscode.d.ts +7 -0
  16. package/dist/components/ElementLibrary.d.ts +22 -0
  17. package/dist/components/ElementNode.d.ts +36 -0
  18. package/dist/components/ElementPanel.d.ts +25 -0
  19. package/dist/components/ExploreOnboarding.d.ts +5 -0
  20. package/dist/components/ExplorePageOnboarding.d.ts +5 -0
  21. package/dist/components/ExportModal.d.ts +16 -0
  22. package/dist/components/FloatingEdge.d.ts +9 -0
  23. package/dist/components/GitSourceLinker.d.ts +8 -0
  24. package/dist/components/HeaderContext.d.ts +16 -0
  25. package/dist/components/Icons.d.ts +95 -0
  26. package/dist/components/ImportModal.d.ts +10 -0
  27. package/dist/components/InlineElementAdder.d.ts +17 -0
  28. package/dist/components/LayoutSection.d.ts +7 -0
  29. package/dist/components/LocalSourceLinker.d.ts +8 -0
  30. package/dist/components/MiniZoomOnboarding.d.ts +5 -0
  31. package/dist/components/NavBreadcrumb.d.ts +6 -0
  32. package/dist/components/NodeBody.d.ts +12 -0
  33. package/dist/components/NodeContainer.d.ts +8 -0
  34. package/dist/components/NodeHoverCard.d.ts +10 -0
  35. package/dist/components/PanelHeader.d.ts +8 -0
  36. package/dist/components/PanelUI.d.ts +3 -0
  37. package/dist/components/ProxyConnectorEdge.d.ts +4 -0
  38. package/dist/components/ProxyConnectorPanel.d.ts +9 -0
  39. package/dist/components/SafeBackground.d.ts +13 -0
  40. package/dist/components/ScrollIndicatorWrapper.d.ts +8 -0
  41. package/dist/components/SetChildModal.d.ts +10 -0
  42. package/dist/components/SetParentModal.d.ts +10 -0
  43. package/dist/components/SlidingPanel.d.ts +16 -0
  44. package/dist/components/TagUpsert.d.ts +8 -0
  45. package/dist/components/TopMenuBar.d.ts +8 -0
  46. package/dist/components/ViewBezierConnector.d.ts +4 -0
  47. package/dist/components/ViewDrawMenu.d.ts +22 -0
  48. package/dist/components/ViewEditorEdgeLabelLayout.d.ts +16 -0
  49. package/dist/components/ViewEditorOnboarding.d.ts +5 -0
  50. package/dist/components/ViewExplorer/TagManager/ColorPicker.d.ts +7 -0
  51. package/dist/components/ViewExplorer/TagManager/GroupNamingPopover.d.ts +10 -0
  52. package/dist/components/ViewExplorer/TagManager/LayerItem.d.ts +27 -0
  53. package/dist/components/ViewExplorer/TagManager/TagItem.d.ts +25 -0
  54. package/dist/components/ViewExplorer/TagManager/index.d.ts +21 -0
  55. package/dist/components/ViewExplorer/ViewNavigator.d.ts +11 -0
  56. package/dist/components/ViewExplorer/ViewSearch.d.ts +8 -0
  57. package/dist/components/ViewExplorer/ViewTree.d.ts +18 -0
  58. package/dist/components/ViewExplorer/index.d.ts +31 -0
  59. package/dist/components/ViewExplorer/types.d.ts +11 -0
  60. package/dist/components/ViewExplorer/utils.d.ts +6 -0
  61. package/dist/components/ViewExplorer-vscode.d.ts +6 -0
  62. package/dist/components/ViewFloatingMenu-vscode.d.ts +27 -0
  63. package/dist/components/ViewFloatingMenu.d.ts +39 -0
  64. package/dist/components/ViewGridNode.d.ts +29 -0
  65. package/dist/components/ViewHeaderButton.d.ts +11 -0
  66. package/dist/components/ViewPanel.d.ts +18 -0
  67. package/dist/components/ViewsGridOnboarding.d.ts +5 -0
  68. package/dist/components/ZUI/ZUICanvas.d.ts +18 -0
  69. package/dist/components/ZUI/index.d.ts +2 -0
  70. package/dist/components/ZUI/layout.d.ts +18 -0
  71. package/dist/components/ZUI/proxy.d.ts +25 -0
  72. package/dist/components/ZUI/renderer.d.ts +30 -0
  73. package/dist/components/ZUI/types.d.ts +140 -0
  74. package/dist/components/ZUI/useZUIInteraction.d.ts +21 -0
  75. package/dist/config/runtime-vscode.d.ts +22 -0
  76. package/dist/config/runtime.d.ts +5 -0
  77. package/dist/constants/colors.d.ts +27 -0
  78. package/dist/constants/diagramColors.d.ts +1 -0
  79. package/dist/context/ThemeContext.d.ts +27 -0
  80. package/dist/crossBranch/graph.d.ts +13 -0
  81. package/dist/crossBranch/resolve.d.ts +22 -0
  82. package/dist/crossBranch/settings.d.ts +6 -0
  83. package/dist/crossBranch/store.d.ts +11 -0
  84. package/dist/crossBranch/types.d.ts +96 -0
  85. package/dist/demo/DemoPage.d.ts +9 -0
  86. package/dist/demo/seed.d.ts +9 -0
  87. package/dist/demo/store.d.ts +137 -0
  88. package/dist/demo/viewEditor.d.ts +26 -0
  89. package/dist/favicon.svg +35 -0
  90. package/dist/hooks/useSafeFitView.d.ts +16 -0
  91. package/dist/index.css +1 -0
  92. package/dist/index.d.ts +115 -0
  93. package/dist/index.js +19966 -0
  94. package/dist/lib/vscodeBridge-vscode.d.ts +13 -0
  95. package/dist/lib/vscodeBridge.d.ts +5 -0
  96. package/dist/logo-120.png +0 -0
  97. package/dist/logo-bw.png +0 -0
  98. package/dist/logo-bw.svg +15 -0
  99. package/dist/logo-text.svg +51 -0
  100. package/dist/logo.svg +35 -0
  101. package/dist/pages/AppearanceSettings.d.ts +3 -0
  102. package/dist/pages/Dependencies.d.ts +1 -0
  103. package/dist/pages/InfiniteZoom.d.ts +7 -0
  104. package/dist/pages/Settings.d.ts +7 -0
  105. package/dist/pages/ViewEditor/components/EditorMenus.d.ts +24 -0
  106. package/dist/pages/ViewEditor/components/EditorOverlays.d.ts +30 -0
  107. package/dist/pages/ViewEditor/components/EmptyCanvasState.d.ts +7 -0
  108. package/dist/pages/ViewEditor/context.d.ts +13 -0
  109. package/dist/pages/ViewEditor/hooks/useCanvasInteractions.d.ts +201 -0
  110. package/dist/pages/ViewEditor/hooks/useDrawingEngine.d.ts +40 -0
  111. package/dist/pages/ViewEditor/hooks/useViewContextNeighbours.d.ts +20 -0
  112. package/dist/pages/ViewEditor/hooks/useViewData.d.ts +74 -0
  113. package/dist/pages/ViewEditor/index.d.ts +8 -0
  114. package/dist/pages/ViewEditor/utils.d.ts +14 -0
  115. package/dist/pages/Views.d.ts +6 -0
  116. package/dist/pages/ViewsGrid.d.ts +6 -0
  117. package/dist/pkg/importer/mermaid.d.ts +7 -0
  118. package/dist/pkg/importer/mermaid.test.d.ts +1 -0
  119. package/dist/platform/PlatformContext.d.ts +6 -0
  120. package/dist/platform/context.d.ts +3 -0
  121. package/dist/platform/local.d.ts +2 -0
  122. package/dist/platform/types.d.ts +17 -0
  123. package/dist/slots.d.ts +67 -0
  124. package/dist/theme.d.ts +2 -0
  125. package/dist/types/index.d.ts +193 -0
  126. package/dist/types/vscode-messages.d.ts +60 -0
  127. package/dist/utils/edgeDistribution.d.ts +34 -0
  128. package/dist/utils/githubApi.d.ts +4 -0
  129. package/dist/utils/githubCache.d.ts +17 -0
  130. package/dist/utils/ids.d.ts +2 -0
  131. package/dist/utils/technologyCatalog.d.ts +15 -0
  132. package/dist/utils/toast.d.ts +15 -0
  133. package/dist/utils/treesitter.d.ts +13 -0
  134. package/dist/utils/url.d.ts +12 -0
  135. package/package.json +159 -0
  136. package/src/App.tsx +141 -0
  137. package/src/api/client.ts +618 -0
  138. package/src/api/transport-vscode.ts +28 -0
  139. package/src/api/transport.ts +7 -0
  140. package/src/assets/logo-mark.svg +31 -0
  141. package/src/assets/logo-wordmark.svg +22 -0
  142. package/src/assets/logo.svg +35 -0
  143. package/src/components/CodePreviewPanel-vscode.tsx +85 -0
  144. package/src/components/CodePreviewPanel.tsx +384 -0
  145. package/src/components/ConfirmDialog.tsx +66 -0
  146. package/src/components/ConnectorPanel.tsx +403 -0
  147. package/src/components/ContextBoundaryElement.tsx +35 -0
  148. package/src/components/ContextNeighborElement.tsx +282 -0
  149. package/src/components/ContextStraightConnector.tsx +144 -0
  150. package/src/components/CrossBranchControls.tsx +105 -0
  151. package/src/components/DependenciesOnboarding.tsx +427 -0
  152. package/src/components/DrawingCanvas.tsx +391 -0
  153. package/src/components/ElementLibrary-vscode.tsx +9 -0
  154. package/src/components/ElementLibrary.tsx +512 -0
  155. package/src/components/ElementNode.tsx +1033 -0
  156. package/src/components/ElementPanel.tsx +928 -0
  157. package/src/components/ExploreOnboarding.tsx +347 -0
  158. package/src/components/ExplorePageOnboarding.tsx +383 -0
  159. package/src/components/ExportModal.tsx +132 -0
  160. package/src/components/FloatingEdge.tsx +115 -0
  161. package/src/components/GitSourceLinker.tsx +1053 -0
  162. package/src/components/HeaderContext.tsx +30 -0
  163. package/src/components/Icons.tsx +245 -0
  164. package/src/components/ImportModal.tsx +219 -0
  165. package/src/components/InlineElementAdder.tsx +216 -0
  166. package/src/components/LayoutSection.tsx +624 -0
  167. package/src/components/LocalSourceLinker.tsx +330 -0
  168. package/src/components/MiniZoomOnboarding.tsx +78 -0
  169. package/src/components/NavBreadcrumb.tsx +24 -0
  170. package/src/components/NodeBody.tsx +89 -0
  171. package/src/components/NodeContainer.tsx +58 -0
  172. package/src/components/NodeHoverCard.tsx +135 -0
  173. package/src/components/PanelHeader.tsx +36 -0
  174. package/src/components/PanelUI.tsx +24 -0
  175. package/src/components/ProxyConnectorEdge.tsx +169 -0
  176. package/src/components/ProxyConnectorPanel.tsx +130 -0
  177. package/src/components/SafeBackground.tsx +19 -0
  178. package/src/components/ScrollIndicatorWrapper.tsx +117 -0
  179. package/src/components/SetChildModal.tsx +191 -0
  180. package/src/components/SetParentModal.tsx +187 -0
  181. package/src/components/SlidingPanel.tsx +114 -0
  182. package/src/components/TagUpsert.tsx +142 -0
  183. package/src/components/TopMenuBar.tsx +380 -0
  184. package/src/components/ViewBezierConnector.tsx +143 -0
  185. package/src/components/ViewDrawMenu.tsx +270 -0
  186. package/src/components/ViewEditorEdgeLabelLayout.ts +189 -0
  187. package/src/components/ViewEditorOnboarding.tsx +445 -0
  188. package/src/components/ViewExplorer/TagManager/ColorPicker.tsx +49 -0
  189. package/src/components/ViewExplorer/TagManager/GroupNamingPopover.tsx +96 -0
  190. package/src/components/ViewExplorer/TagManager/LayerItem.tsx +228 -0
  191. package/src/components/ViewExplorer/TagManager/TagItem.tsx +242 -0
  192. package/src/components/ViewExplorer/TagManager/index.tsx +418 -0
  193. package/src/components/ViewExplorer/ViewNavigator.tsx +121 -0
  194. package/src/components/ViewExplorer/ViewSearch.tsx +33 -0
  195. package/src/components/ViewExplorer/ViewTree.tsx +98 -0
  196. package/src/components/ViewExplorer/index.tsx +384 -0
  197. package/src/components/ViewExplorer/types.ts +13 -0
  198. package/src/components/ViewExplorer/utils.ts +56 -0
  199. package/src/components/ViewExplorer-vscode.tsx +8 -0
  200. package/src/components/ViewFloatingMenu-vscode.tsx +248 -0
  201. package/src/components/ViewFloatingMenu.tsx +379 -0
  202. package/src/components/ViewGridNode.tsx +451 -0
  203. package/src/components/ViewHeaderButton.tsx +60 -0
  204. package/src/components/ViewPanel.tsx +162 -0
  205. package/src/components/ViewsGridOnboarding.tsx +400 -0
  206. package/src/components/ZUI/ZUICanvas.tsx +853 -0
  207. package/src/components/ZUI/index.ts +3 -0
  208. package/src/components/ZUI/layout.ts +323 -0
  209. package/src/components/ZUI/proxy.ts +278 -0
  210. package/src/components/ZUI/renderer.ts +1189 -0
  211. package/src/components/ZUI/types.ts +150 -0
  212. package/src/components/ZUI/useZUIInteraction.ts +720 -0
  213. package/src/config/runtime-vscode.ts +46 -0
  214. package/src/config/runtime.ts +30 -0
  215. package/src/constants/colors.ts +80 -0
  216. package/src/constants/diagramColors.ts +9 -0
  217. package/src/context/ThemeContext.tsx +158 -0
  218. package/src/crossBranch/graph.ts +207 -0
  219. package/src/crossBranch/resolve.ts +643 -0
  220. package/src/crossBranch/settings.ts +59 -0
  221. package/src/crossBranch/store.ts +71 -0
  222. package/src/crossBranch/types.ts +102 -0
  223. package/src/demo/DemoPage.tsx +184 -0
  224. package/src/demo/seed.ts +67 -0
  225. package/src/demo/store.ts +536 -0
  226. package/src/demo/viewEditor.ts +110 -0
  227. package/src/hooks/useSafeFitView.ts +60 -0
  228. package/src/index.css +309 -0
  229. package/src/index.ts +184 -0
  230. package/src/kafka-ss.png +0 -0
  231. package/src/lib/vscodeBridge-vscode.ts +27 -0
  232. package/src/lib/vscodeBridge.ts +7 -0
  233. package/src/main.tsx +46 -0
  234. package/src/pages/AppearanceSettings.tsx +135 -0
  235. package/src/pages/Dependencies.tsx +926 -0
  236. package/src/pages/InfiniteZoom.tsx +404 -0
  237. package/src/pages/Settings.tsx +91 -0
  238. package/src/pages/ViewEditor/EDGE_DISTRIBUTION.md +64 -0
  239. package/src/pages/ViewEditor/components/EditorMenus.tsx +112 -0
  240. package/src/pages/ViewEditor/components/EditorOverlays.tsx +172 -0
  241. package/src/pages/ViewEditor/components/EmptyCanvasState.tsx +42 -0
  242. package/src/pages/ViewEditor/context.tsx +21 -0
  243. package/src/pages/ViewEditor/hooks/useCanvasInteractions.ts +1349 -0
  244. package/src/pages/ViewEditor/hooks/useDrawingEngine.ts +127 -0
  245. package/src/pages/ViewEditor/hooks/useViewContextNeighbours.ts +501 -0
  246. package/src/pages/ViewEditor/hooks/useViewData.ts +491 -0
  247. package/src/pages/ViewEditor/index.tsx +1366 -0
  248. package/src/pages/ViewEditor/utils.ts +88 -0
  249. package/src/pages/Views.tsx +171 -0
  250. package/src/pages/ViewsGrid.tsx +1310 -0
  251. package/src/pkg/importer/mermaid.test.ts +141 -0
  252. package/src/pkg/importer/mermaid.ts +76 -0
  253. package/src/platform/PlatformContext.tsx +17 -0
  254. package/src/platform/context.ts +9 -0
  255. package/src/platform/local.tsx +15 -0
  256. package/src/platform/types.ts +19 -0
  257. package/src/slots.ts +92 -0
  258. package/src/styles/editor-panels.css +66 -0
  259. package/src/styles/theme.css +56 -0
  260. package/src/theme.ts +336 -0
  261. package/src/types/index.ts +234 -0
  262. package/src/types/offline-ambient.d.ts +14 -0
  263. package/src/types/vscode-messages.ts +32 -0
  264. package/src/utils/edgeDistribution.ts +103 -0
  265. package/src/utils/githubApi.ts +121 -0
  266. package/src/utils/githubCache.ts +108 -0
  267. package/src/utils/ids.ts +9 -0
  268. package/src/utils/technologyCatalog.ts +143 -0
  269. package/src/utils/toast.ts +100 -0
  270. package/src/utils/treesitter.ts +147 -0
  271. package/src/utils/url.ts +72 -0
  272. package/src/vite-env.d.ts +1 -0
@@ -0,0 +1,30 @@
1
+ /* eslint-disable react-refresh/only-export-components */
2
+ import React, { createContext, useContext, useState } from 'react'
3
+
4
+ type HeaderPayload = { node: React.ReactNode | null; hideMobileBar?: boolean } | React.ReactNode | null
5
+ type HeaderSetter = (payload: HeaderPayload) => void
6
+
7
+ const HeaderContext = createContext<{ header: HeaderPayload; setHeader: HeaderSetter } | undefined>(undefined)
8
+
9
+ export function HeaderProvider({ children }: { children: React.ReactNode }) {
10
+ const [header, setHeader] = useState<HeaderPayload>(null)
11
+ return (
12
+ <HeaderContext.Provider value={{ header, setHeader }}>
13
+ {children}
14
+ </HeaderContext.Provider>
15
+ )
16
+ }
17
+
18
+ export function useSetHeader() {
19
+ const ctx = useContext(HeaderContext)
20
+ if (!ctx) throw new Error('useSetHeader must be used within HeaderProvider')
21
+ return ctx.setHeader
22
+ }
23
+
24
+ export function useHeader() {
25
+ const ctx = useContext(HeaderContext)
26
+ if (!ctx) throw new Error('useHeader must be used within HeaderProvider')
27
+ return ctx.header
28
+ }
29
+
30
+ export default HeaderContext
@@ -0,0 +1,245 @@
1
+ import React from 'react'
2
+
3
+
4
+ export function ZoomOutIcon({ size = 14, strokeWidth = 3 }: { size?: number, strokeWidth?: number }) {
5
+ return (
6
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor"
7
+ strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
8
+ <circle cx="11" cy="11" r="8" />
9
+ <line x1="21" y1="21" x2="16.65" y2="16.65" />
10
+ <line x1="8" y1="11" x2="14" y2="11" />
11
+ </svg>
12
+ )
13
+ }
14
+
15
+ export function ZoomInIcon({ size = 14, strokeWidth = 3 }: { size?: number, strokeWidth?: number }) {
16
+ return (
17
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor"
18
+ strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
19
+ <circle cx="11" cy="11" r="8" />
20
+ <line x1="21" y1="21" x2="16.65" y2="16.65" />
21
+ <line x1="11" y1="8" x2="11" y2="14" />
22
+ <line x1="8" y1="11" x2="14" y2="11" />
23
+ </svg>
24
+ )
25
+ }
26
+
27
+ export function AddElementIcon({ size = 12, strokeWidth = 3 }: { size?: number, strokeWidth?: number }) {
28
+ return (
29
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor"
30
+ strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
31
+ <line x1="12" y1="5" x2="12" y2="19" />
32
+ <line x1="5" y1="12" x2="19" y2="12" />
33
+ </svg>
34
+ )
35
+ }
36
+
37
+ export function FitViewIcon({ size = 14, strokeWidth = 2.5 }: { size?: number, strokeWidth?: number }) {
38
+ return (
39
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor"
40
+ strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
41
+ <rect x="3" y="3" width="18" height="18" rx="2" />
42
+ <path d="M7 12h10" />
43
+ <path d="M12 7v10" />
44
+ </svg>
45
+ )
46
+ }
47
+
48
+ export function ShareIcon({ size = 14, strokeWidth = 2.5 }: { size?: number, strokeWidth?: number }) {
49
+ return (
50
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor"
51
+ strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
52
+ <path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8" />
53
+ <polyline points="16 6 12 2 8 6" />
54
+ <line x1="12" y1="2" x2="12" y2="15" />
55
+ </svg>
56
+ )
57
+ }
58
+
59
+ export function TrashIcon({ size = 13, strokeWidth = 2.5 }: { size?: number, strokeWidth?: number }) {
60
+ return (
61
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor"
62
+ strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
63
+ <polyline points="3 6 5 6 21 6" />
64
+ <path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" />
65
+ <path d="M10 11v6M14 11v6" />
66
+ <path d="M9 6V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2" />
67
+ </svg>
68
+ )
69
+ }
70
+
71
+ export function EditIcon({ size = 13, strokeWidth = 2.5 }: { size?: number, strokeWidth?: number }) {
72
+ return (
73
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor"
74
+ strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
75
+ <path d="M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z" />
76
+ </svg>
77
+ )
78
+ }
79
+
80
+ export function GitIcon({ size = 14, strokeWidth = 2 }: { size?: number, strokeWidth?: number }) {
81
+ return (
82
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
83
+ <circle cx="12" cy="18" r="3" />
84
+ <circle cx="6" cy="6" r="3" />
85
+ <circle cx="18" cy="6" r="3" />
86
+ <path d="M18 9v2c0 1.1-.9 2-2 2H8a2 2 0 0 1-2-2V9" />
87
+ <path d="M12 13V15" />
88
+ </svg>
89
+ )
90
+ }
91
+
92
+ export function MoveSourceIcon({ size = 13, strokeWidth = 2.5 }: { size?: number, strokeWidth?: number }) {
93
+ return (
94
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
95
+ <circle cx="5" cy="12" r="2" />
96
+ <line x1="7" y1="12" x2="17" y2="12" />
97
+ <polyline points="14 9 17 12 14 15" />
98
+ </svg>
99
+ )
100
+ }
101
+
102
+ export function MoveTargetIcon({ size = 13, strokeWidth = 2.5 }: { size?: number, strokeWidth?: number }) {
103
+ return (
104
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
105
+ <line x1="7" y1="12" x2="17" y2="12" />
106
+ <polyline points="14 9 17 12 14 15" />
107
+ <circle cx="19" cy="12" r="2" />
108
+ </svg>
109
+ )
110
+ }
111
+
112
+ export function NavigationIcon({ size = 14, strokeWidth = 1.8 }: { size?: number, strokeWidth?: number }) {
113
+ return (
114
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
115
+ <rect x="8" y="2" width="8" height="5" rx="1.5" fill="none" />
116
+ <line x1="12" y1="7" x2="12" y2="11.5" />
117
+ <line x1="4.5" y1="11.5" x2="19.5" y2="11.5" />
118
+ <line x1="4.5" y1="11.5" x2="4.5" y2="14" />
119
+ <rect x="1.5" y="14" width="6" height="4.5" rx="1.5" fill="none" />
120
+ <line x1="19.5" y1="11.5" x2="19.5" y2="14" />
121
+ <rect x="16.5" y="14" width="6" height="4.5" rx="1.5" fill="none" />
122
+ </svg>
123
+ )
124
+ }
125
+
126
+ export function LibraryIcon({ size = 14 }: { size?: number }) {
127
+ return (
128
+ <svg width={size} height={size} viewBox="0 0 14 14" fill="none">
129
+ <rect x="1" y="1" width="5" height="5" rx="1" fill="currentColor" opacity="0.85" />
130
+ <rect x="8" y="1" width="5" height="5" rx="1" fill="currentColor" opacity="0.85" />
131
+ <rect x="1" y="8" width="5" height="5" rx="1" fill="currentColor" opacity="0.85" />
132
+ <rect x="8" y="8" width="5" height="5" rx="1" fill="currentColor" opacity="0.85" />
133
+ </svg>
134
+ )
135
+ }
136
+
137
+ export function ExpandExtrasIcon({ size = 14, strokeWidth = 2.5 }: { size?: number, strokeWidth?: number }) {
138
+ return (
139
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
140
+ <polyline points="8 6 14 12 8 18" />
141
+ <polyline points="13 6 19 12 13 18" />
142
+ </svg>
143
+ )
144
+ }
145
+
146
+ export function CollapseExtrasIcon({ size = 14, strokeWidth = 2.5 }: { size?: number, strokeWidth?: number }) {
147
+ return (
148
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
149
+ <polyline points="16 6 10 12 16 18" />
150
+ <polyline points="11 6 5 12 11 18" />
151
+ </svg>
152
+ )
153
+ }
154
+
155
+ export function EyeIcon({ size = 14, strokeWidth = 2.5 }: { size?: number, strokeWidth?: number }) {
156
+ return (
157
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
158
+ <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" />
159
+ <circle cx="12" cy="12" r="3" />
160
+ </svg>
161
+ )
162
+ }
163
+
164
+ export function EyeOffIcon({ size = 14, strokeWidth = 2.5 }: { size?: number, strokeWidth?: number }) {
165
+ return (
166
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
167
+ <path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24" />
168
+ <line x1="1" y1="1" x2="23" y2="23" />
169
+ </svg>
170
+ )
171
+ }
172
+
173
+ export function ImportIcon({ size = 12, strokeWidth = 2.5 }: { size?: number, strokeWidth?: number }) {
174
+ return (
175
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
176
+ <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
177
+ <polyline points="7 10 12 15 17 10" />
178
+ <line x1="12" y1="15" x2="12" y2="3" />
179
+ </svg>
180
+ )
181
+ }
182
+
183
+ export function LayerIcon({ size = 14, strokeWidth = 2.5 }: { size?: number, strokeWidth?: number }) {
184
+ return (
185
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
186
+ <polygon points="12 2 2 7 12 12 22 7 12 2" />
187
+ <polyline points="2 17 12 22 22 17" />
188
+ <polyline points="2 12 12 17 22 12" />
189
+ </svg>
190
+ )
191
+ }
192
+
193
+ export function ChevronLeftIcon({ size = 14, strokeWidth = 3 }: { size?: number, strokeWidth?: number }) {
194
+ return (
195
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
196
+ <path d="M15 18l-6-6 6-6" />
197
+ </svg>
198
+ )
199
+ }
200
+
201
+ export function ChevronRightIcon({ size = 14, strokeWidth = 3 }: { size?: number, strokeWidth?: number }) {
202
+ return (
203
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
204
+ <path d="M9 6l6 6-6 6" />
205
+ </svg>
206
+ )
207
+ }
208
+
209
+ export function ChevronDownIcon({ size = 14, strokeWidth = 3 }: { size?: number, strokeWidth?: number }) {
210
+ return (
211
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
212
+ <path d="M6 9l6 6 6-6" />
213
+ </svg>
214
+ )
215
+ }
216
+
217
+ export function TagsIcon({ size = 14, strokeWidth = 2.5 }: { size?: number, strokeWidth?: number }) {
218
+ return (
219
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
220
+ <path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z" />
221
+ <line x1="7" y1="7" x2="7.01" y2="7" />
222
+ </svg>
223
+ )
224
+ }
225
+
226
+ export function GridIcon({ size = 12, strokeWidth = 2.5 }: { size?: number, strokeWidth?: number }) {
227
+ return (
228
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor"
229
+ strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
230
+ <rect x="3" y="3" width="18" height="18" rx="2" />
231
+ <line x1="3" y1="9" x2="21" y2="9" />
232
+ <line x1="3" y1="15" x2="21" y2="15" />
233
+ <line x1="9" y1="3" x2="9" y2="21" />
234
+ <line x1="15" y1="3" x2="15" y2="21" />
235
+ </svg>
236
+ )
237
+ }
238
+ export function FocusIcon({ size = 14, strokeWidth = 2.5 }: { size?: number, strokeWidth?: number }) {
239
+ return (
240
+ <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round">
241
+ <circle cx="12" cy="12" r="10" />
242
+ <circle cx="12" cy="12" r="3" />
243
+ </svg>
244
+ )
245
+ }
@@ -0,0 +1,219 @@
1
+ import { memo, useEffect, useState } from 'react'
2
+ import {
3
+ Button,
4
+ FormControl,
5
+ FormLabel,
6
+ Modal,
7
+ ModalBody,
8
+ ModalCloseButton,
9
+ ModalContent,
10
+ ModalFooter,
11
+ ModalHeader,
12
+ ModalOverlay,
13
+ Textarea,
14
+ Text,
15
+ VStack,
16
+ Box,
17
+ Divider,
18
+ Tabs,
19
+ TabList,
20
+ Tab,
21
+ TabPanels,
22
+ TabPanel,
23
+ } from '@chakra-ui/react'
24
+ import { parseMermaid, ParsedImport } from '../pkg/importer/mermaid'
25
+ import { api } from '../api/client'
26
+ import type { PlanConnector, PlanElement } from '@buf/tldiagramcom_diagram.bufbuild_es/diag/v1/workspace_service_pb'
27
+
28
+ interface Props {
29
+ isOpen: boolean
30
+ onClose: () => void
31
+ isImporting?: boolean
32
+ onImport: (parsed: ParsedImport) => Promise<void> | void
33
+ }
34
+
35
+ type Format = 'mermaid' | 'structurizr'
36
+
37
+ const MERMAID_PLACEHOLDER = `flowchart LR
38
+ A[Start] --> B[End]`
39
+
40
+ const STRUCTURIZR_PLACEHOLDER = `workspace {
41
+ model {
42
+ user = person "User"
43
+ app = softwareSystem "App"
44
+ user -> app "Uses"
45
+ }
46
+ }`
47
+
48
+ function ImportModal({ isOpen, onClose, isImporting, onImport }: Props) {
49
+ const [code, setCode] = useState('')
50
+ const [format, setFormat] = useState<Format>('mermaid')
51
+ const [step, setStep] = useState<'input' | 'summary'>('input')
52
+ const [parsed, setParsed] = useState<ParsedImport | null>(null)
53
+ const [parseError, setParseError] = useState<string | null>(null)
54
+ const [isParsing, setIsParsing] = useState(false)
55
+
56
+ useEffect(() => {
57
+ if (!isOpen) return
58
+ setCode('')
59
+ setStep('input')
60
+ setParsed(null)
61
+ setParseError(null)
62
+ }, [isOpen])
63
+
64
+ const handleTabChange = (index: number) => {
65
+ setFormat(index === 0 ? 'mermaid' : 'structurizr')
66
+ setCode('')
67
+ setParseError(null)
68
+ }
69
+
70
+ const handleNext = async () => {
71
+ if (!code.trim()) return
72
+ setParseError(null)
73
+
74
+ if (format === 'mermaid') {
75
+ const result = parseMermaid(code)
76
+ setParsed(result)
77
+ setStep('summary')
78
+ return
79
+ }
80
+
81
+ // Structurizr: parse server-side
82
+ setIsParsing(true)
83
+ try {
84
+ const res = await api.import.parseStructurizr(code)
85
+ const result: ParsedImport = {
86
+ elements: res.elements as PlanElement[],
87
+ connectors: res.connectors as PlanConnector[],
88
+ warnings: res.warnings,
89
+ }
90
+ setParsed(result)
91
+ setStep('summary')
92
+ } catch (e: unknown) {
93
+ setParseError(e instanceof Error ? e.message : 'Failed to parse Structurizr DSL')
94
+ } finally {
95
+ setIsParsing(false)
96
+ }
97
+ }
98
+
99
+ const handleSubmit = async () => {
100
+ if (!parsed) return
101
+ await onImport(parsed)
102
+ }
103
+
104
+ return (
105
+ <Modal isOpen={isOpen} onClose={onClose} size="xl" isCentered>
106
+ <ModalOverlay bg="blackAlpha.700" backdropFilter="blur(4px)" />
107
+ <ModalContent mx={4}>
108
+ <ModalHeader>{step === 'input' ? 'Import Diagram' : 'Confirm Import'}</ModalHeader>
109
+ <ModalCloseButton />
110
+ <ModalBody>
111
+ <VStack spacing={4} align="stretch">
112
+ {step === 'input' ? (
113
+ <Tabs onChange={handleTabChange} size="sm" variant="enclosed">
114
+ <TabList>
115
+ <Tab>Mermaid</Tab>
116
+ <Tab>Structurizr DSL</Tab>
117
+ </TabList>
118
+ <TabPanels>
119
+ <TabPanel px={0} pb={0}>
120
+ <FormControl>
121
+ <FormLabel fontSize="sm">Mermaid code</FormLabel>
122
+ <Textarea
123
+ value={code}
124
+ onChange={(e) => setCode(e.target.value)}
125
+ placeholder={MERMAID_PLACEHOLDER}
126
+ size="sm"
127
+ rows={12}
128
+ fontFamily="mono"
129
+ />
130
+ <Text mt={1.5} fontSize="xs" color="gray.400">
131
+ Supported: flowchart / graph, C4Context.
132
+ </Text>
133
+ </FormControl>
134
+ </TabPanel>
135
+ <TabPanel px={0} pb={0}>
136
+ <FormControl>
137
+ <FormLabel fontSize="sm">Structurizr DSL</FormLabel>
138
+ <Textarea
139
+ value={code}
140
+ onChange={(e) => setCode(e.target.value)}
141
+ placeholder={STRUCTURIZR_PLACEHOLDER}
142
+ size="sm"
143
+ rows={12}
144
+ fontFamily="mono"
145
+ />
146
+ <Text mt={1.5} fontSize="xs" color="gray.400">
147
+ Paste a Structurizr workspace DSL. Imports people, software systems, containers, and their relationships.
148
+ </Text>
149
+ </FormControl>
150
+ </TabPanel>
151
+ </TabPanels>
152
+ </Tabs>
153
+ ) : (
154
+ <Box fontSize="sm">
155
+ <Text fontWeight="bold" mb={2}>Summary:</Text>
156
+ <VStack align="start" spacing={1} pl={4} mb={4}>
157
+ <Text>• Elements: {parsed?.elements.length}</Text>
158
+ <Text>• Connectors: {parsed?.connectors.length}</Text>
159
+ </VStack>
160
+ {parsed?.warnings && parsed.warnings.length > 0 && (
161
+ <Box p={3} bg="orange.50" color="orange.800" borderRadius="md" mb={4}>
162
+ <Text fontWeight="bold" fontSize="xs">Warnings:</Text>
163
+ {parsed.warnings.map((w, i) => (
164
+ <Text key={i} fontSize="xs">• {w}</Text>
165
+ ))}
166
+ </Box>
167
+ )}
168
+ <Divider mb={4} />
169
+ <Text color="gray.500">
170
+ This will create the resources listed above in your current workspace.
171
+ </Text>
172
+ </Box>
173
+ )}
174
+ {parseError && (
175
+ <Box p={3} bg="red.50" color="red.800" borderRadius="md">
176
+ <Text fontSize="xs">{parseError}</Text>
177
+ </Box>
178
+ )}
179
+ </VStack>
180
+ </ModalBody>
181
+
182
+ <ModalFooter gap={2}>
183
+ {step === 'input' ? (
184
+ <>
185
+ <Button variant="ghost" size="sm" onClick={onClose}>
186
+ Cancel
187
+ </Button>
188
+ <Button
189
+ size="sm"
190
+ colorScheme="blue"
191
+ onClick={handleNext}
192
+ isDisabled={!code.trim()}
193
+ isLoading={isParsing}
194
+ >
195
+ Next
196
+ </Button>
197
+ </>
198
+ ) : (
199
+ <>
200
+ <Button variant="ghost" size="sm" onClick={() => setStep('input')} isDisabled={isImporting}>
201
+ Back
202
+ </Button>
203
+ <Button
204
+ size="sm"
205
+ colorScheme="green"
206
+ onClick={handleSubmit}
207
+ isLoading={isImporting}
208
+ >
209
+ Confirm & Import
210
+ </Button>
211
+ </>
212
+ )}
213
+ </ModalFooter>
214
+ </ModalContent>
215
+ </Modal>
216
+ )
217
+ }
218
+
219
+ export default memo(ImportModal)