@coral-viz/viz 0.2.3

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 (191) hide show
  1. package/LICENSE +4 -0
  2. package/README.md +11 -0
  3. package/dist/compatibility/CompatibilityEdge.d.ts +106 -0
  4. package/dist/compatibility/CompatibilityEdge.d.ts.map +1 -0
  5. package/dist/compatibility/CompatibilityEdge.js +233 -0
  6. package/dist/compatibility/CompatibilityEdge.js.map +1 -0
  7. package/dist/compatibility/IncompatibilityTooltip.d.ts +44 -0
  8. package/dist/compatibility/IncompatibilityTooltip.d.ts.map +1 -0
  9. package/dist/compatibility/IncompatibilityTooltip.js +145 -0
  10. package/dist/compatibility/IncompatibilityTooltip.js.map +1 -0
  11. package/dist/compatibility/index.d.ts +10 -0
  12. package/dist/compatibility/index.d.ts.map +1 -0
  13. package/dist/compatibility/index.js +10 -0
  14. package/dist/compatibility/index.js.map +1 -0
  15. package/dist/compatibility/useEdgeCompatibility.d.ts +82 -0
  16. package/dist/compatibility/useEdgeCompatibility.d.ts.map +1 -0
  17. package/dist/compatibility/useEdgeCompatibility.js +170 -0
  18. package/dist/compatibility/useEdgeCompatibility.js.map +1 -0
  19. package/dist/compatibility/validateConnection.d.ts +56 -0
  20. package/dist/compatibility/validateConnection.d.ts.map +1 -0
  21. package/dist/compatibility/validateConnection.js +382 -0
  22. package/dist/compatibility/validateConnection.js.map +1 -0
  23. package/dist/components/EditContext.d.ts +45 -0
  24. package/dist/components/EditContext.d.ts.map +1 -0
  25. package/dist/components/EditContext.js +41 -0
  26. package/dist/components/EditContext.js.map +1 -0
  27. package/dist/components/ShapeRenderer.d.ts +35 -0
  28. package/dist/components/ShapeRenderer.d.ts.map +1 -0
  29. package/dist/components/ShapeRenderer.js +77 -0
  30. package/dist/components/ShapeRenderer.js.map +1 -0
  31. package/dist/components/SymbolNode.d.ts +53 -0
  32. package/dist/components/SymbolNode.d.ts.map +1 -0
  33. package/dist/components/SymbolNode.js +333 -0
  34. package/dist/components/SymbolNode.js.map +1 -0
  35. package/dist/components/index.d.ts +8 -0
  36. package/dist/components/index.d.ts.map +1 -0
  37. package/dist/components/index.js +10 -0
  38. package/dist/components/index.js.map +1 -0
  39. package/dist/components/nodes.d.ts +43 -0
  40. package/dist/components/nodes.d.ts.map +1 -0
  41. package/dist/components/nodes.js +111 -0
  42. package/dist/components/nodes.js.map +1 -0
  43. package/dist/editor/CoralEditor.d.ts +29 -0
  44. package/dist/editor/CoralEditor.d.ts.map +1 -0
  45. package/dist/editor/CoralEditor.js +112 -0
  46. package/dist/editor/CoralEditor.js.map +1 -0
  47. package/dist/editor/FileControls.d.ts +34 -0
  48. package/dist/editor/FileControls.d.ts.map +1 -0
  49. package/dist/editor/FileControls.js +139 -0
  50. package/dist/editor/FileControls.js.map +1 -0
  51. package/dist/editor/LayoutControls.d.ts +41 -0
  52. package/dist/editor/LayoutControls.d.ts.map +1 -0
  53. package/dist/editor/LayoutControls.js +124 -0
  54. package/dist/editor/LayoutControls.js.map +1 -0
  55. package/dist/editor/converter.d.ts +37 -0
  56. package/dist/editor/converter.d.ts.map +1 -0
  57. package/dist/editor/converter.js +256 -0
  58. package/dist/editor/converter.js.map +1 -0
  59. package/dist/editor/index.d.ts +8 -0
  60. package/dist/editor/index.d.ts.map +1 -0
  61. package/dist/editor/index.js +8 -0
  62. package/dist/editor/index.js.map +1 -0
  63. package/dist/file/deserialize.d.ts +15 -0
  64. package/dist/file/deserialize.d.ts.map +1 -0
  65. package/dist/file/deserialize.js +145 -0
  66. package/dist/file/deserialize.js.map +1 -0
  67. package/dist/file/index.d.ts +15 -0
  68. package/dist/file/index.d.ts.map +1 -0
  69. package/dist/file/index.js +20 -0
  70. package/dist/file/index.js.map +1 -0
  71. package/dist/file/migrate.d.ts +29 -0
  72. package/dist/file/migrate.d.ts.map +1 -0
  73. package/dist/file/migrate.js +103 -0
  74. package/dist/file/migrate.js.map +1 -0
  75. package/dist/file/schema.d.ts +385 -0
  76. package/dist/file/schema.d.ts.map +1 -0
  77. package/dist/file/schema.js +180 -0
  78. package/dist/file/schema.js.map +1 -0
  79. package/dist/file/serialize.d.ts +30 -0
  80. package/dist/file/serialize.d.ts.map +1 -0
  81. package/dist/file/serialize.js +218 -0
  82. package/dist/file/serialize.js.map +1 -0
  83. package/dist/file/validate.d.ts +21 -0
  84. package/dist/file/validate.d.ts.map +1 -0
  85. package/dist/file/validate.js +165 -0
  86. package/dist/file/validate.js.map +1 -0
  87. package/dist/index.d.ts +24 -0
  88. package/dist/index.d.ts.map +1 -0
  89. package/dist/index.js +42 -0
  90. package/dist/index.js.map +1 -0
  91. package/dist/layout/elk.d.ts +77 -0
  92. package/dist/layout/elk.d.ts.map +1 -0
  93. package/dist/layout/elk.js +379 -0
  94. package/dist/layout/elk.js.map +1 -0
  95. package/dist/layout/index.d.ts +12 -0
  96. package/dist/layout/index.d.ts.map +1 -0
  97. package/dist/layout/index.js +12 -0
  98. package/dist/layout/index.js.map +1 -0
  99. package/dist/layout/nodeSizing.d.ts +65 -0
  100. package/dist/layout/nodeSizing.d.ts.map +1 -0
  101. package/dist/layout/nodeSizing.js +319 -0
  102. package/dist/layout/nodeSizing.js.map +1 -0
  103. package/dist/layout/positionStability.d.ts +73 -0
  104. package/dist/layout/positionStability.d.ts.map +1 -0
  105. package/dist/layout/positionStability.js +199 -0
  106. package/dist/layout/positionStability.js.map +1 -0
  107. package/dist/layout/useAxisConstrain.d.ts +20 -0
  108. package/dist/layout/useAxisConstrain.d.ts.map +1 -0
  109. package/dist/layout/useAxisConstrain.js +106 -0
  110. package/dist/layout/useAxisConstrain.js.map +1 -0
  111. package/dist/layout/useDiagramState.d.ts +92 -0
  112. package/dist/layout/useDiagramState.d.ts.map +1 -0
  113. package/dist/layout/useDiagramState.js +256 -0
  114. package/dist/layout/useDiagramState.js.map +1 -0
  115. package/dist/layout/useLayoutHistory.d.ts +53 -0
  116. package/dist/layout/useLayoutHistory.d.ts.map +1 -0
  117. package/dist/layout/useLayoutHistory.js +124 -0
  118. package/dist/layout/useLayoutHistory.js.map +1 -0
  119. package/dist/properties/NodePropertiesPanel.d.ts +47 -0
  120. package/dist/properties/NodePropertiesPanel.d.ts.map +1 -0
  121. package/dist/properties/NodePropertiesPanel.js +199 -0
  122. package/dist/properties/NodePropertiesPanel.js.map +1 -0
  123. package/dist/properties/index.d.ts +10 -0
  124. package/dist/properties/index.d.ts.map +1 -0
  125. package/dist/properties/index.js +10 -0
  126. package/dist/properties/index.js.map +1 -0
  127. package/dist/properties/propertyUtils.d.ts +60 -0
  128. package/dist/properties/propertyUtils.d.ts.map +1 -0
  129. package/dist/properties/propertyUtils.js +89 -0
  130. package/dist/properties/propertyUtils.js.map +1 -0
  131. package/dist/settings/FontSettingsForm.d.ts +28 -0
  132. package/dist/settings/FontSettingsForm.d.ts.map +1 -0
  133. package/dist/settings/FontSettingsForm.js +129 -0
  134. package/dist/settings/FontSettingsForm.js.map +1 -0
  135. package/dist/settings/LayoutSettingsForm.d.ts +37 -0
  136. package/dist/settings/LayoutSettingsForm.d.ts.map +1 -0
  137. package/dist/settings/LayoutSettingsForm.js +165 -0
  138. package/dist/settings/LayoutSettingsForm.js.map +1 -0
  139. package/dist/settings/SettingsPanel.d.ts +55 -0
  140. package/dist/settings/SettingsPanel.d.ts.map +1 -0
  141. package/dist/settings/SettingsPanel.js +84 -0
  142. package/dist/settings/SettingsPanel.js.map +1 -0
  143. package/dist/settings/index.d.ts +13 -0
  144. package/dist/settings/index.d.ts.map +1 -0
  145. package/dist/settings/index.js +13 -0
  146. package/dist/settings/index.js.map +1 -0
  147. package/dist/settings/useSettings.d.ts +51 -0
  148. package/dist/settings/useSettings.d.ts.map +1 -0
  149. package/dist/settings/useSettings.js +154 -0
  150. package/dist/settings/useSettings.js.map +1 -0
  151. package/dist/text-editor/SplitEditor.d.ts +72 -0
  152. package/dist/text-editor/SplitEditor.d.ts.map +1 -0
  153. package/dist/text-editor/SplitEditor.js +172 -0
  154. package/dist/text-editor/SplitEditor.js.map +1 -0
  155. package/dist/text-editor/TextEditor.d.ts +53 -0
  156. package/dist/text-editor/TextEditor.d.ts.map +1 -0
  157. package/dist/text-editor/TextEditor.js +181 -0
  158. package/dist/text-editor/TextEditor.js.map +1 -0
  159. package/dist/text-editor/hooks/useBidirectionalSync.d.ts +106 -0
  160. package/dist/text-editor/hooks/useBidirectionalSync.d.ts.map +1 -0
  161. package/dist/text-editor/hooks/useBidirectionalSync.js +151 -0
  162. package/dist/text-editor/hooks/useBidirectionalSync.js.map +1 -0
  163. package/dist/text-editor/index.d.ts +9 -0
  164. package/dist/text-editor/index.d.ts.map +1 -0
  165. package/dist/text-editor/index.js +11 -0
  166. package/dist/text-editor/index.js.map +1 -0
  167. package/dist/types.d.ts +242 -0
  168. package/dist/types.d.ts.map +1 -0
  169. package/dist/types.js +5 -0
  170. package/dist/types.js.map +1 -0
  171. package/dist/waypoints/index.d.ts +8 -0
  172. package/dist/waypoints/index.d.ts.map +1 -0
  173. package/dist/waypoints/index.js +7 -0
  174. package/dist/waypoints/index.js.map +1 -0
  175. package/dist/waypoints/operations.d.ts +29 -0
  176. package/dist/waypoints/operations.d.ts.map +1 -0
  177. package/dist/waypoints/operations.js +85 -0
  178. package/dist/waypoints/operations.js.map +1 -0
  179. package/dist/waypoints/router.d.ts +23 -0
  180. package/dist/waypoints/router.d.ts.map +1 -0
  181. package/dist/waypoints/router.js +109 -0
  182. package/dist/waypoints/router.js.map +1 -0
  183. package/dist/waypoints/types.d.ts +15 -0
  184. package/dist/waypoints/types.d.ts.map +1 -0
  185. package/dist/waypoints/types.js +5 -0
  186. package/dist/waypoints/types.js.map +1 -0
  187. package/dist/waypoints/useWaypointManager.d.ts +38 -0
  188. package/dist/waypoints/useWaypointManager.d.ts.map +1 -0
  189. package/dist/waypoints/useWaypointManager.js +106 -0
  190. package/dist/waypoints/useWaypointManager.js.map +1 -0
  191. package/package.json +76 -0
@@ -0,0 +1,112 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * CoralEditor - Main visual editor component
4
+ *
5
+ * Renders Graph-IR as an interactive diagram using React Flow.
6
+ */
7
+ import { useCallback, useMemo, useState } from 'react';
8
+ import { ReactFlow, Background, Controls, MiniMap, useNodesState, useEdgesState, BackgroundVariant, } from '@xyflow/react';
9
+ import { nodeTypes } from '../components/nodes.js';
10
+ import { convertGraphToFlow, convertFlowToGraphNodes, convertFlowToGraphEdges } from './converter.js';
11
+ const defaultConfig = {
12
+ draggable: true,
13
+ connectable: false,
14
+ selectable: true,
15
+ zoomable: true,
16
+ pannable: true,
17
+ showMinimap: true,
18
+ showControls: true,
19
+ fitViewOnLoad: true,
20
+ };
21
+ /**
22
+ * Main Coral Editor component
23
+ */
24
+ export const CoralEditor = ({ graph, config: userConfig, callbacks, className, style, }) => {
25
+ const config = useMemo(() => ({ ...defaultConfig, ...userConfig }), [userConfig]);
26
+ // Convert Graph-IR to React Flow format
27
+ const initialData = useMemo(() => convertGraphToFlow(graph), [graph]);
28
+ // React Flow state
29
+ const [nodes, setNodes, onNodesChange] = useNodesState(initialData.nodes);
30
+ const [edges, setEdges, onEdgesChange] = useEdgesState(initialData.edges);
31
+ const [selectedNodes, setSelectedNodes] = useState([]);
32
+ const [selectedEdges, setSelectedEdges] = useState([]);
33
+ // Handle node changes and notify parent
34
+ const handleNodesChange = useCallback((changes) => {
35
+ onNodesChange(changes);
36
+ // Notify parent of changes
37
+ if (callbacks?.onNodesChange) {
38
+ // Get updated nodes after change
39
+ setNodes((currentNodes) => {
40
+ callbacks.onNodesChange?.(currentNodes);
41
+ return currentNodes;
42
+ });
43
+ }
44
+ }, [onNodesChange, callbacks, setNodes]);
45
+ // Handle edge changes and notify parent
46
+ const handleEdgesChange = useCallback((changes) => {
47
+ onEdgesChange(changes);
48
+ if (callbacks?.onEdgesChange) {
49
+ setEdges((currentEdges) => {
50
+ callbacks.onEdgesChange?.(currentEdges);
51
+ return currentEdges;
52
+ });
53
+ }
54
+ }, [onEdgesChange, callbacks, setEdges]);
55
+ // Handle selection changes
56
+ const handleSelectionChange = useCallback(({ nodes: selectedNodeList, edges: selectedEdgeList }) => {
57
+ const nodeIds = selectedNodeList.map((n) => n.id);
58
+ const edgeIds = selectedEdgeList.map((e) => e.id);
59
+ setSelectedNodes(nodeIds);
60
+ setSelectedEdges(edgeIds);
61
+ callbacks?.onNodeSelect?.(nodeIds);
62
+ callbacks?.onEdgeSelect?.(edgeIds);
63
+ }, [callbacks]);
64
+ // Handle node double click
65
+ const handleNodeDoubleClick = useCallback((_event, node) => {
66
+ callbacks?.onNodeDoubleClick?.(node.id);
67
+ }, [callbacks]);
68
+ // Minimap node color based on type
69
+ const getMinimapNodeColor = useCallback((node) => {
70
+ switch (node.data.nodeType) {
71
+ case 'service':
72
+ return '#90caf9';
73
+ case 'database':
74
+ return '#ffb74d';
75
+ case 'external_api':
76
+ return '#f48fb1';
77
+ case 'actor':
78
+ return '#81c784';
79
+ case 'module':
80
+ return '#ce93d8';
81
+ case 'group':
82
+ return '#bdbdbd';
83
+ default:
84
+ return '#90caf9';
85
+ }
86
+ }, []);
87
+ return (_jsx("div", { className: `coral-editor ${className || ''}`, style: {
88
+ width: '100%',
89
+ height: '100%',
90
+ minHeight: '400px',
91
+ ...style,
92
+ }, children: _jsxs(ReactFlow, { nodes: nodes, edges: edges, onNodesChange: handleNodesChange, onEdgesChange: handleEdgesChange, onSelectionChange: handleSelectionChange, onNodeDoubleClick: handleNodeDoubleClick, nodeTypes: nodeTypes, nodesDraggable: config.draggable, nodesConnectable: config.connectable, elementsSelectable: config.selectable, zoomOnScroll: config.zoomable, panOnScroll: config.pannable, fitView: config.fitViewOnLoad, fitViewOptions: { padding: 0.2 }, defaultEdgeOptions: {
93
+ type: 'smoothstep',
94
+ animated: false,
95
+ }, children: [_jsx(Background, { variant: BackgroundVariant.Dots, gap: 20, size: 1 }), config.showControls && _jsx(Controls, {}), config.showMinimap && (_jsx(MiniMap, { nodeColor: getMinimapNodeColor, nodeStrokeWidth: 3, zoomable: true, pannable: true }))] }) }));
96
+ };
97
+ /**
98
+ * Hook to get Graph-IR from current editor state
99
+ */
100
+ export function useGraphIR(nodes, edges, originalGraph) {
101
+ return useMemo(() => {
102
+ const graphNodes = convertFlowToGraphNodes(nodes, originalGraph.nodes);
103
+ const graphEdges = convertFlowToGraphEdges(edges);
104
+ return {
105
+ ...originalGraph,
106
+ nodes: graphNodes,
107
+ edges: graphEdges,
108
+ };
109
+ }, [nodes, edges, originalGraph]);
110
+ }
111
+ export default CoralEditor;
112
+ //# sourceMappingURL=CoralEditor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CoralEditor.js","sourceRoot":"","sources":["../../src/editor/CoralEditor.tsx"],"names":[],"mappings":";AAAA;;;;GAIG;AAEH,OAAc,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC9D,OAAO,EACL,SAAS,EACT,UAAU,EACV,QAAQ,EACR,OAAO,EACP,aAAa,EACb,aAAa,EAKb,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAwBtG,MAAM,aAAa,GAAiB;IAClC,SAAS,EAAE,IAAI;IACf,WAAW,EAAE,KAAK;IAClB,UAAU,EAAE,IAAI;IAChB,QAAQ,EAAE,IAAI;IACd,QAAQ,EAAE,IAAI;IACd,WAAW,EAAE,IAAI;IACjB,YAAY,EAAE,IAAI;IAClB,aAAa,EAAE,IAAI;CACpB,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAA+B,CAAC,EACtD,KAAK,EACL,MAAM,EAAE,UAAU,EAClB,SAAS,EACT,SAAS,EACT,KAAK,GACN,EAAE,EAAE;IACH,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,aAAa,EAAE,GAAG,UAAU,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAElF,wCAAwC;IACxC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEtE,mBAAmB;IACnB,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,aAAa,CAAC,GAAG,aAAa,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAC1E,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,aAAa,CAAC,GAAG,aAAa,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAC1E,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAW,EAAE,CAAC,CAAC;IACjE,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAW,EAAE,CAAC,CAAC;IAEjE,wCAAwC;IACxC,MAAM,iBAAiB,GAA6B,WAAW,CAC7D,CAAC,OAAO,EAAE,EAAE;QACV,aAAa,CAAC,OAAO,CAAC,CAAC;QAEvB,2BAA2B;QAC3B,IAAI,SAAS,EAAE,aAAa,EAAE,CAAC;YAC7B,iCAAiC;YACjC,QAAQ,CAAC,CAAC,YAAY,EAAE,EAAE;gBACxB,SAAS,CAAC,aAAa,EAAE,CAAC,YAAY,CAAC,CAAC;gBACxC,OAAO,YAAY,CAAC;YACtB,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,EACD,CAAC,aAAa,EAAE,SAAS,EAAE,QAAQ,CAAC,CACrC,CAAC;IAEF,wCAAwC;IACxC,MAAM,iBAAiB,GAA6B,WAAW,CAC7D,CAAC,OAAO,EAAE,EAAE;QACV,aAAa,CAAC,OAAO,CAAC,CAAC;QAEvB,IAAI,SAAS,EAAE,aAAa,EAAE,CAAC;YAC7B,QAAQ,CAAC,CAAC,YAAY,EAAE,EAAE;gBACxB,SAAS,CAAC,aAAa,EAAE,CAAC,YAAY,CAAC,CAAC;gBACxC,OAAO,YAAY,CAAC;YACtB,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,EACD,CAAC,aAAa,EAAE,SAAS,EAAE,QAAQ,CAAC,CACrC,CAAC;IAEF,2BAA2B;IAC3B,MAAM,qBAAqB,GAA0B,WAAW,CAC9D,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAAE,EAAE;QACvD,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAElD,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC1B,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAE1B,SAAS,EAAE,YAAY,EAAE,CAAC,OAAO,CAAC,CAAC;QACnC,SAAS,EAAE,YAAY,EAAE,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC,EACD,CAAC,SAAS,CAAC,CACZ,CAAC;IAEF,2BAA2B;IAC3B,MAAM,qBAAqB,GAAgC,WAAW,CACpE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;QACf,SAAS,EAAE,iBAAiB,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1C,CAAC,EACD,CAAC,SAAS,CAAC,CACZ,CAAC;IAEF,mCAAmC;IACnC,MAAM,mBAAmB,GAAG,WAAW,CAAC,CAAC,IAAe,EAAE,EAAE;QAC1D,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC3B,KAAK,SAAS;gBACZ,OAAO,SAAS,CAAC;YACnB,KAAK,UAAU;gBACb,OAAO,SAAS,CAAC;YACnB,KAAK,cAAc;gBACjB,OAAO,SAAS,CAAC;YACnB,KAAK,OAAO;gBACV,OAAO,SAAS,CAAC;YACnB,KAAK,QAAQ;gBACX,OAAO,SAAS,CAAC;YACnB,KAAK,OAAO;gBACV,OAAO,SAAS,CAAC;YACnB;gBACE,OAAO,SAAS,CAAC;QACrB,CAAC;IACH,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACL,cACE,SAAS,EAAE,gBAAgB,SAAS,IAAI,EAAE,EAAE,EAC5C,KAAK,EAAE;YACL,KAAK,EAAE,MAAM;YACb,MAAM,EAAE,MAAM;YACd,SAAS,EAAE,OAAO;YAClB,GAAG,KAAK;SACT,YAED,MAAC,SAAS,IACR,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,KAAK,EACZ,aAAa,EAAE,iBAAiB,EAChC,aAAa,EAAE,iBAAiB,EAChC,iBAAiB,EAAE,qBAAqB,EACxC,iBAAiB,EAAE,qBAAqB,EACxC,SAAS,EAAE,SAAS,EACpB,cAAc,EAAE,MAAM,CAAC,SAAS,EAChC,gBAAgB,EAAE,MAAM,CAAC,WAAW,EACpC,kBAAkB,EAAE,MAAM,CAAC,UAAU,EACrC,YAAY,EAAE,MAAM,CAAC,QAAQ,EAC7B,WAAW,EAAE,MAAM,CAAC,QAAQ,EAC5B,OAAO,EAAE,MAAM,CAAC,aAAa,EAC7B,cAAc,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAChC,kBAAkB,EAAE;gBAClB,IAAI,EAAE,YAAY;gBAClB,QAAQ,EAAE,KAAK;aAChB,aAED,KAAC,UAAU,IAAC,OAAO,EAAE,iBAAiB,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,GAAI,EAEhE,MAAM,CAAC,YAAY,IAAI,KAAC,QAAQ,KAAG,EAEnC,MAAM,CAAC,WAAW,IAAI,CACrB,KAAC,OAAO,IACN,SAAS,EAAE,mBAAmB,EAC9B,eAAe,EAAE,CAAC,EAClB,QAAQ,QACR,QAAQ,SACR,CACH,IACS,GACR,CACP,CAAC;AACJ,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,UAAU,CACxB,KAAkB,EAClB,KAAkB,EAClB,aAAsB;IAEtB,OAAO,OAAO,CAAC,GAAG,EAAE;QAClB,MAAM,UAAU,GAAG,uBAAuB,CAAC,KAAK,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;QACvE,MAAM,UAAU,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;QAElD,OAAO;YACL,GAAG,aAAa;YAChB,KAAK,EAAE,UAAU;YACjB,KAAK,EAAE,UAAU;SAClB,CAAC;IACJ,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC;AACpC,CAAC;AAED,eAAe,WAAW,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * FileControls - UI component for file operations (CORAL-REQ-008)
3
+ *
4
+ * Provides buttons for:
5
+ * - Save: Download diagram as .coral.json file
6
+ * - Load: Open file picker to load .coral.json file
7
+ * - Export: Export Graph-IR as JSON
8
+ */
9
+ import { type CSSProperties } from 'react';
10
+ import type { CoralDocument } from '../file/index.js';
11
+ /** Props for the FileControls component */
12
+ export interface FileControlsProps {
13
+ /** Current document to save */
14
+ document: CoralDocument | null;
15
+ /** Callback when a document is loaded */
16
+ onLoad: (document: CoralDocument) => void;
17
+ /** Callback to get current state as document (for saving) */
18
+ onGetDocument?: () => CoralDocument;
19
+ /** Custom styles for the container */
20
+ style?: CSSProperties;
21
+ /** Custom class name for the container */
22
+ className?: string;
23
+ /** Whether to show keyboard shortcut hints in tooltips */
24
+ showShortcutHints?: boolean;
25
+ /** Disable all controls */
26
+ disabled?: boolean;
27
+ /** Show export button */
28
+ showExport?: boolean;
29
+ }
30
+ /**
31
+ * FileControls component
32
+ */
33
+ export declare function FileControls({ document, onLoad, onGetDocument, style, className, showShortcutHints, disabled, showExport, }: FileControlsProps): import("react").JSX.Element;
34
+ //# sourceMappingURL=FileControls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileControls.d.ts","sourceRoot":"","sources":["../../src/editor/FileControls.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAuB,KAAK,aAAa,EAAoB,MAAM,OAAO,CAAC;AAClF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,2CAA2C;AAC3C,MAAM,WAAW,iBAAiB;IAChC,+BAA+B;IAC/B,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;IAC/B,yCAAyC;IACzC,MAAM,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;IAC1C,6DAA6D;IAC7D,aAAa,CAAC,EAAE,MAAM,aAAa,CAAC;IACpC,sCAAsC;IACtC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yBAAyB;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AA8DD;;GAEG;AACH,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,MAAM,EACN,aAAa,EACb,KAAK,EACL,SAAS,EACT,iBAAwB,EACxB,QAAgB,EAChB,UAAiB,GAClB,EAAE,iBAAiB,+BAgJnB"}
@@ -0,0 +1,139 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ /**
3
+ * FileControls - UI component for file operations (CORAL-REQ-008)
4
+ *
5
+ * Provides buttons for:
6
+ * - Save: Download diagram as .coral.json file
7
+ * - Load: Open file picker to load .coral.json file
8
+ * - Export: Export Graph-IR as JSON
9
+ */
10
+ import { useRef, useCallback } from 'react';
11
+ /** Default button styles */
12
+ const buttonStyle = {
13
+ padding: '6px 12px',
14
+ fontSize: '13px',
15
+ fontWeight: 500,
16
+ borderRadius: '4px',
17
+ border: '1px solid #ccc',
18
+ background: '#fff',
19
+ cursor: 'pointer',
20
+ display: 'inline-flex',
21
+ alignItems: 'center',
22
+ gap: '4px',
23
+ transition: 'all 0.15s ease',
24
+ };
25
+ const buttonStyleDisabled = {
26
+ ...buttonStyle,
27
+ opacity: 0.5,
28
+ cursor: 'not-allowed',
29
+ };
30
+ const buttonStylePrimary = {
31
+ ...buttonStyle,
32
+ background: '#2e7d32',
33
+ borderColor: '#2e7d32',
34
+ color: '#fff',
35
+ };
36
+ const containerStyle = {
37
+ display: 'flex',
38
+ alignItems: 'center',
39
+ gap: '8px',
40
+ };
41
+ /**
42
+ * Download a file with the given content
43
+ */
44
+ function downloadFile(content, filename, mimeType) {
45
+ const blob = new Blob([content], { type: mimeType });
46
+ const url = URL.createObjectURL(blob);
47
+ const link = document.createElement('a');
48
+ link.href = url;
49
+ link.download = filename;
50
+ document.body.appendChild(link);
51
+ link.click();
52
+ document.body.removeChild(link);
53
+ URL.revokeObjectURL(url);
54
+ }
55
+ /**
56
+ * Generate filename from document name
57
+ */
58
+ function generateFilename(name) {
59
+ const sanitized = name
60
+ .toLowerCase()
61
+ .replace(/[^a-z0-9]+/g, '-')
62
+ .replace(/^-+|-+$/g, '');
63
+ return `${sanitized || 'diagram'}.coral.json`;
64
+ }
65
+ /**
66
+ * FileControls component
67
+ */
68
+ export function FileControls({ document, onLoad, onGetDocument, style, className, showShortcutHints = true, disabled = false, showExport = true, }) {
69
+ const fileInputRef = useRef(null);
70
+ /**
71
+ * Handle save button click
72
+ */
73
+ const handleSave = useCallback(() => {
74
+ const doc = onGetDocument ? onGetDocument() : document;
75
+ if (!doc)
76
+ return;
77
+ const json = JSON.stringify(doc, null, 2);
78
+ const filename = generateFilename(doc.metadata.name);
79
+ downloadFile(json, filename, 'application/json');
80
+ }, [document, onGetDocument]);
81
+ /**
82
+ * Handle load button click
83
+ */
84
+ const handleLoadClick = useCallback(() => {
85
+ fileInputRef.current?.click();
86
+ }, []);
87
+ /**
88
+ * Handle file input change
89
+ */
90
+ const handleFileChange = useCallback((event) => {
91
+ const file = event.target.files?.[0];
92
+ if (!file)
93
+ return;
94
+ const reader = new FileReader();
95
+ reader.onload = (e) => {
96
+ try {
97
+ const content = e.target?.result;
98
+ const doc = JSON.parse(content);
99
+ onLoad(doc);
100
+ }
101
+ catch (error) {
102
+ console.error('Failed to parse file:', error);
103
+ alert(`Failed to load file: ${error instanceof Error ? error.message : 'Unknown error'}`);
104
+ }
105
+ };
106
+ reader.readAsText(file);
107
+ // Reset input so same file can be loaded again
108
+ event.target.value = '';
109
+ }, [onLoad]);
110
+ /**
111
+ * Handle export Graph-IR button click
112
+ */
113
+ const handleExport = useCallback(() => {
114
+ const doc = onGetDocument ? onGetDocument() : document;
115
+ if (!doc?.content.graphIR)
116
+ return;
117
+ const json = JSON.stringify(doc.content.graphIR, null, 2);
118
+ const filename = `${doc.metadata.name.toLowerCase().replace(/\s+/g, '-')}-graph-ir.json`;
119
+ downloadFile(json, filename, 'application/json');
120
+ }, [document, onGetDocument]);
121
+ const getSaveTitle = () => {
122
+ let title = 'Save diagram as .coral.json file';
123
+ if (showShortcutHints) {
124
+ title += ' (Ctrl+S)';
125
+ }
126
+ return title;
127
+ };
128
+ const getLoadTitle = () => {
129
+ let title = 'Load diagram from .coral.json file';
130
+ if (showShortcutHints) {
131
+ title += ' (Ctrl+O)';
132
+ }
133
+ return title;
134
+ };
135
+ const canSave = Boolean(document || onGetDocument);
136
+ const canExport = Boolean(document?.content.graphIR || onGetDocument);
137
+ return (_jsxs("div", { style: { ...containerStyle, ...style }, className: className, children: [_jsx("input", { ref: fileInputRef, type: "file", accept: ".coral.json,.json", style: { display: 'none' }, onChange: handleFileChange }), _jsxs("button", { onClick: handleSave, disabled: disabled || !canSave, title: getSaveTitle(), style: disabled || !canSave ? buttonStyleDisabled : buttonStylePrimary, children: [_jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("path", { d: "M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z" }), _jsx("polyline", { points: "17 21 17 13 7 13 7 21" }), _jsx("polyline", { points: "7 3 7 8 15 8" })] }), "Save"] }), _jsxs("button", { onClick: handleLoadClick, disabled: disabled, title: getLoadTitle(), style: disabled ? buttonStyleDisabled : buttonStyle, children: [_jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("path", { d: "M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z" }), _jsx("line", { x1: "12", y1: "11", x2: "12", y2: "17" }), _jsx("polyline", { points: "9 14 12 11 15 14" })] }), "Load"] }), showExport && (_jsxs(_Fragment, { children: [_jsx("div", { style: { width: '1px', height: '20px', background: '#ddd' } }), _jsxs("button", { onClick: handleExport, disabled: disabled || !canExport, title: "Export Graph-IR as JSON", style: disabled || !canExport ? buttonStyleDisabled : buttonStyle, children: [_jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }), _jsx("polyline", { points: "7 10 12 15 17 10" }), _jsx("line", { x1: "12", y1: "15", x2: "12", y2: "3" })] }), "Export IR"] })] }))] }));
138
+ }
139
+ //# sourceMappingURL=FileControls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileControls.js","sourceRoot":"","sources":["../../src/editor/FileControls.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * LayoutControls - UI component for diagram reflow and undo/redo
3
+ *
4
+ * Provides buttons and keyboard shortcuts for:
5
+ * - Reflow: Re-run automatic layout (ELK)
6
+ * - Undo: Restore previous node positions
7
+ * - Redo: Re-apply undone changes
8
+ */
9
+ import { type CSSProperties } from 'react';
10
+ /** Props for the LayoutControls component */
11
+ export interface LayoutControlsProps {
12
+ /** Callback to trigger reflow/re-layout */
13
+ onReflow: () => void;
14
+ /** Callback to undo last layout change */
15
+ onUndo: () => void;
16
+ /** Callback to redo undone change */
17
+ onRedo: () => void;
18
+ /** Whether undo is available */
19
+ canUndo: boolean;
20
+ /** Whether redo is available */
21
+ canRedo: boolean;
22
+ /** Number of undo steps available */
23
+ undoCount?: number;
24
+ /** Number of redo steps available */
25
+ redoCount?: number;
26
+ /** Whether a reflow is currently in progress */
27
+ isReflowing?: boolean;
28
+ /** Custom styles for the container */
29
+ style?: CSSProperties;
30
+ /** Custom class name for the container */
31
+ className?: string;
32
+ /** Whether to show keyboard shortcut hints in tooltips */
33
+ showShortcutHints?: boolean;
34
+ /** Disable all controls */
35
+ disabled?: boolean;
36
+ }
37
+ /**
38
+ * LayoutControls component
39
+ */
40
+ export declare function LayoutControls({ onReflow, onUndo, onRedo, canUndo, canRedo, undoCount, redoCount, isReflowing, style, className, showShortcutHints, disabled, }: LayoutControlsProps): import("react").JSX.Element;
41
+ //# sourceMappingURL=LayoutControls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LayoutControls.d.ts","sourceRoot":"","sources":["../../src/editor/LayoutControls.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAA0B,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAEnE,6CAA6C;AAC7C,MAAM,WAAW,mBAAmB;IAClC,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,0CAA0C;IAC1C,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,qCAAqC;IACrC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,gCAAgC;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,gCAAgC;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,sCAAsC;IACtC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAoCD;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,MAAM,EACN,MAAM,EACN,OAAO,EACP,OAAO,EACP,SAAa,EACb,SAAa,EACb,WAAmB,EACnB,KAAK,EACL,SAAS,EACT,iBAAwB,EACxB,QAAgB,GACjB,EAAE,mBAAmB,+BAuJrB"}
@@ -0,0 +1,124 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * LayoutControls - UI component for diagram reflow and undo/redo
4
+ *
5
+ * Provides buttons and keyboard shortcuts for:
6
+ * - Reflow: Re-run automatic layout (ELK)
7
+ * - Undo: Restore previous node positions
8
+ * - Redo: Re-apply undone changes
9
+ */
10
+ import { useEffect, useCallback } from 'react';
11
+ /** Default button styles */
12
+ const buttonStyle = {
13
+ padding: '6px 12px',
14
+ fontSize: '13px',
15
+ fontWeight: 500,
16
+ borderRadius: '4px',
17
+ border: '1px solid #ccc',
18
+ background: '#fff',
19
+ cursor: 'pointer',
20
+ display: 'inline-flex',
21
+ alignItems: 'center',
22
+ gap: '4px',
23
+ transition: 'all 0.15s ease',
24
+ };
25
+ const buttonStyleDisabled = {
26
+ ...buttonStyle,
27
+ opacity: 0.5,
28
+ cursor: 'not-allowed',
29
+ };
30
+ const buttonStylePrimary = {
31
+ ...buttonStyle,
32
+ background: '#1976d2',
33
+ borderColor: '#1976d2',
34
+ color: '#fff',
35
+ };
36
+ const containerStyle = {
37
+ display: 'flex',
38
+ alignItems: 'center',
39
+ gap: '8px',
40
+ };
41
+ /**
42
+ * LayoutControls component
43
+ */
44
+ export function LayoutControls({ onReflow, onUndo, onRedo, canUndo, canRedo, undoCount = 0, redoCount = 0, isReflowing = false, style, className, showShortcutHints = true, disabled = false, }) {
45
+ /**
46
+ * Handle keyboard shortcuts
47
+ */
48
+ const handleKeyDown = useCallback((e) => {
49
+ if (disabled)
50
+ return;
51
+ // Ctrl+Shift+L or Cmd+Shift+L for reflow
52
+ if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key === 'L') {
53
+ e.preventDefault();
54
+ if (!isReflowing) {
55
+ onReflow();
56
+ }
57
+ return;
58
+ }
59
+ // Ctrl+Z or Cmd+Z for undo (without shift)
60
+ if ((e.ctrlKey || e.metaKey) && !e.shiftKey && e.key === 'z') {
61
+ e.preventDefault();
62
+ if (canUndo) {
63
+ onUndo();
64
+ }
65
+ return;
66
+ }
67
+ // Ctrl+Shift+Z or Cmd+Shift+Z for redo
68
+ if ((e.ctrlKey || e.metaKey) && e.shiftKey && (e.key === 'z' || e.key === 'Z')) {
69
+ e.preventDefault();
70
+ if (canRedo) {
71
+ onRedo();
72
+ }
73
+ return;
74
+ }
75
+ // Ctrl+Y or Cmd+Y for redo (alternative)
76
+ if ((e.ctrlKey || e.metaKey) && e.key === 'y') {
77
+ e.preventDefault();
78
+ if (canRedo) {
79
+ onRedo();
80
+ }
81
+ return;
82
+ }
83
+ }, [disabled, isReflowing, canUndo, canRedo, onReflow, onUndo, onRedo]);
84
+ // Attach keyboard listener
85
+ useEffect(() => {
86
+ window.addEventListener('keydown', handleKeyDown);
87
+ return () => window.removeEventListener('keydown', handleKeyDown);
88
+ }, [handleKeyDown]);
89
+ const getReflowTitle = () => {
90
+ let title = 'Re-apply automatic layout';
91
+ if (showShortcutHints) {
92
+ title += ' (Ctrl+Shift+L)';
93
+ }
94
+ return title;
95
+ };
96
+ const getUndoTitle = () => {
97
+ let title = `Undo${undoCount > 0 ? ` (${undoCount} step${undoCount > 1 ? 's' : ''} available)` : ''}`;
98
+ if (showShortcutHints) {
99
+ title += ' (Ctrl+Z)';
100
+ }
101
+ return title;
102
+ };
103
+ const getRedoTitle = () => {
104
+ let title = `Redo${redoCount > 0 ? ` (${redoCount} step${redoCount > 1 ? 's' : ''} available)` : ''}`;
105
+ if (showShortcutHints) {
106
+ title += ' (Ctrl+Shift+Z)';
107
+ }
108
+ return title;
109
+ };
110
+ return (_jsxs("div", { style: { ...containerStyle, ...style }, className: className, children: [_jsx("button", { onClick: onReflow, disabled: disabled || isReflowing, title: getReflowTitle(), style: disabled || isReflowing ? buttonStyleDisabled : buttonStylePrimary, children: isReflowing ? (_jsxs(_Fragment, { children: [_jsx("span", { style: {
111
+ display: 'inline-block',
112
+ width: '12px',
113
+ height: '12px',
114
+ border: '2px solid #fff',
115
+ borderTopColor: 'transparent',
116
+ borderRadius: '50%',
117
+ animation: 'spin 1s linear infinite',
118
+ } }), "Reflowing..."] })) : (_jsxs(_Fragment, { children: [_jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("path", { d: "M23 4v6h-6M1 20v-6h6" }), _jsx("path", { d: "M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15" })] }), "Reflow"] })) }), _jsx("div", { style: { width: '1px', height: '20px', background: '#ddd' } }), _jsxs("button", { onClick: onUndo, disabled: disabled || !canUndo, title: getUndoTitle(), style: disabled || !canUndo ? buttonStyleDisabled : buttonStyle, children: [_jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("path", { d: "M3 7v6h6" }), _jsx("path", { d: "M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13" })] }), "Undo"] }), _jsxs("button", { onClick: onRedo, disabled: disabled || !canRedo, title: getRedoTitle(), style: disabled || !canRedo ? buttonStyleDisabled : buttonStyle, children: [_jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("path", { d: "M21 7v6h-6" }), _jsx("path", { d: "M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3L21 13" })] }), "Redo"] }), _jsx("style", { children: `
119
+ @keyframes spin {
120
+ to { transform: rotate(360deg); }
121
+ }
122
+ ` })] }));
123
+ }
124
+ //# sourceMappingURL=LayoutControls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LayoutControls.js","sourceRoot":"","sources":["../../src/editor/LayoutControls.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Graph-IR to React Flow Converter
3
+ *
4
+ * Transforms Graph-IR nodes and edges to React Flow format.
5
+ */
6
+ import type { GraphIR, GraphNode, GraphEdge, CoralNode, CoralEdge } from '../types.js';
7
+ /**
8
+ * Convert a Graph-IR node to React Flow node
9
+ */
10
+ export declare function convertNode(node: GraphNode, index: number, parentId?: string): CoralNode;
11
+ /**
12
+ * Flatten nested nodes for React Flow
13
+ * React Flow doesn't support deeply nested nodes well, so we flatten
14
+ * and use parentId for grouping
15
+ */
16
+ export declare function flattenNodes(nodes: GraphNode[]): CoralNode[];
17
+ /**
18
+ * Convert a Graph-IR edge to React Flow edge
19
+ */
20
+ export declare function convertEdge(edge: GraphEdge): CoralEdge;
21
+ /**
22
+ * Convert entire Graph-IR to React Flow format
23
+ */
24
+ export declare function convertGraphToFlow(graph: GraphIR): {
25
+ nodes: CoralNode[];
26
+ edges: CoralEdge[];
27
+ };
28
+ /**
29
+ * Convert React Flow nodes back to Graph-IR nodes
30
+ * Used for bidirectional sync
31
+ */
32
+ export declare function convertFlowToGraphNodes(flowNodes: CoralNode[], originalNodes: GraphNode[]): GraphNode[];
33
+ /**
34
+ * Convert React Flow edges back to Graph-IR edges
35
+ */
36
+ export declare function convertFlowToGraphEdges(flowEdges: CoralEdge[]): GraphEdge[];
37
+ //# sourceMappingURL=converter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"converter.d.ts","sourceRoot":"","sources":["../../src/editor/converter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,OAAO,EACP,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EAGV,MAAM,aAAa,CAAC;AAoCrB;;GAEG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,GAChB,SAAS,CAqDX;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,SAAS,EAAE,CAmB5D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,CA8CtD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG;IAClD,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB,CAKA;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,SAAS,EAAE,EACtB,aAAa,EAAE,SAAS,EAAE,GACzB,SAAS,EAAE,CA4Db;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,SAAS,EAAE,GAAG,SAAS,EAAE,CA+B3E"}