@pixerate/editor-svelte 0.15.3 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/README.md +83 -0
  2. package/dist/BubbleMenu.svelte.d.ts +14 -0
  3. package/dist/BubbleMenu.svelte.d.ts.map +1 -0
  4. package/{src → dist}/EditableTextNodeEditor.svelte +1 -1
  5. package/dist/EditableTextNodeEditor.svelte.d.ts +26 -0
  6. package/dist/EditableTextNodeEditor.svelte.d.ts.map +1 -0
  7. package/dist/TemplateRenderer.svelte.d.ts +14 -0
  8. package/dist/TemplateRenderer.svelte.d.ts.map +1 -0
  9. package/dist/canvas/AgentPresenceLayer.svelte.d.ts +9 -0
  10. package/dist/canvas/AgentPresenceLayer.svelte.d.ts.map +1 -0
  11. package/dist/canvas/FloatingHorizontalScrollbar.svelte.d.ts +9 -0
  12. package/dist/canvas/FloatingHorizontalScrollbar.svelte.d.ts.map +1 -0
  13. package/dist/canvas/createCanvasClipboard.svelte.d.ts +32 -0
  14. package/dist/canvas/createCanvasClipboard.svelte.d.ts.map +1 -0
  15. package/dist/canvas/createCanvasClipboard.svelte.js +171 -0
  16. package/dist/canvas/createCanvasDisplacement.d.ts +32 -0
  17. package/dist/canvas/createCanvasDisplacement.d.ts.map +1 -0
  18. package/dist/canvas/createCanvasDisplacement.js +170 -0
  19. package/dist/canvas/createCanvasDocking.svelte.d.ts +56 -0
  20. package/dist/canvas/createCanvasDocking.svelte.d.ts.map +1 -0
  21. package/dist/canvas/createCanvasDocking.svelte.js +227 -0
  22. package/dist/canvas/createCanvasExplosion.svelte.d.ts +31 -0
  23. package/dist/canvas/createCanvasExplosion.svelte.d.ts.map +1 -0
  24. package/dist/canvas/createCanvasExplosion.svelte.js +346 -0
  25. package/dist/canvas/createCanvasGraph.svelte.d.ts +62 -0
  26. package/dist/canvas/createCanvasGraph.svelte.d.ts.map +1 -0
  27. package/dist/canvas/createCanvasGraph.svelte.js +223 -0
  28. package/dist/canvas/createCanvasInteractions.svelte.d.ts +28 -0
  29. package/dist/canvas/createCanvasInteractions.svelte.d.ts.map +1 -0
  30. package/dist/canvas/createCanvasInteractions.svelte.js +95 -0
  31. package/dist/canvas/createCanvasLayout.d.ts +22 -0
  32. package/dist/canvas/createCanvasLayout.d.ts.map +1 -0
  33. package/dist/canvas/createCanvasLayout.js +76 -0
  34. package/dist/canvas/createCanvasMultiDrag.svelte.d.ts +61 -0
  35. package/dist/canvas/createCanvasMultiDrag.svelte.d.ts.map +1 -0
  36. package/dist/canvas/createCanvasMultiDrag.svelte.js +105 -0
  37. package/dist/canvas/createCanvasNodeSync.svelte.d.ts +58 -0
  38. package/dist/canvas/createCanvasNodeSync.svelte.d.ts.map +1 -0
  39. package/dist/canvas/createCanvasNodeSync.svelte.js +82 -0
  40. package/dist/canvas/createCanvasSelection.svelte.d.ts +26 -0
  41. package/dist/canvas/createCanvasSelection.svelte.d.ts.map +1 -0
  42. package/dist/canvas/createCanvasSelection.svelte.js +26 -0
  43. package/dist/canvas/createCanvasShortcuts.d.ts +9 -0
  44. package/dist/canvas/createCanvasShortcuts.d.ts.map +1 -0
  45. package/dist/canvas/createCanvasShortcuts.js +97 -0
  46. package/dist/canvas/createCanvasTrajectory.d.ts +31 -0
  47. package/dist/canvas/createCanvasTrajectory.d.ts.map +1 -0
  48. package/dist/canvas/createCanvasTrajectory.js +141 -0
  49. package/dist/canvas/createStreamingCanvas.svelte.d.ts +19 -0
  50. package/dist/canvas/createStreamingCanvas.svelte.d.ts.map +1 -0
  51. package/dist/canvas/createStreamingCanvas.svelte.js +32 -0
  52. package/dist/canvas/index.d.ts +18 -688
  53. package/dist/canvas/index.d.ts.map +1 -0
  54. package/dist/canvas/index.js +34 -1839
  55. package/dist/canvas/types.d.ts +183 -0
  56. package/dist/canvas/types.d.ts.map +1 -0
  57. package/dist/canvas/types.js +1 -0
  58. package/dist/createNavigationGuard.svelte.d.ts +24 -0
  59. package/dist/createNavigationGuard.svelte.d.ts.map +1 -0
  60. package/dist/createNavigationGuard.svelte.js +65 -0
  61. package/dist/editor.svelte.d.ts +23 -0
  62. package/dist/editor.svelte.d.ts.map +1 -0
  63. package/dist/editor.svelte.js +41 -0
  64. package/dist/history/createHistoryShortcuts.d.ts +24 -0
  65. package/dist/history/createHistoryShortcuts.d.ts.map +1 -0
  66. package/dist/history/createHistoryShortcuts.js +57 -0
  67. package/dist/history/history.svelte.d.ts +18 -0
  68. package/dist/history/history.svelte.d.ts.map +1 -0
  69. package/dist/history/history.svelte.js +43 -0
  70. package/dist/history/index.d.ts +3 -0
  71. package/dist/history/index.d.ts.map +1 -0
  72. package/dist/history/index.js +2 -0
  73. package/{src → dist}/image-editor/ImageEditor.svelte +1 -1
  74. package/dist/image-editor/ImageEditor.svelte.d.ts +17 -0
  75. package/dist/image-editor/ImageEditor.svelte.d.ts.map +1 -0
  76. package/dist/image-editor/imageEditorState.svelte.d.ts +50 -0
  77. package/dist/image-editor/imageEditorState.svelte.d.ts.map +1 -0
  78. package/dist/image-editor/imageEditorState.svelte.js +132 -0
  79. package/dist/image-editor/index.d.ts +6 -16
  80. package/dist/image-editor/index.d.ts.map +1 -0
  81. package/dist/image-editor/index.js +2 -9
  82. package/dist/index.d.ts +20 -249
  83. package/dist/index.d.ts.map +1 -0
  84. package/dist/index.js +10 -1119
  85. package/dist/navigationGuard.d.ts +21 -0
  86. package/dist/navigationGuard.d.ts.map +1 -0
  87. package/dist/navigationGuard.js +59 -0
  88. package/{src → dist}/spreadsheet/FormulaBar.svelte +1 -1
  89. package/dist/spreadsheet/FormulaBar.svelte.d.ts +17 -0
  90. package/dist/spreadsheet/FormulaBar.svelte.d.ts.map +1 -0
  91. package/{src → dist}/spreadsheet/SpreadsheetEditor.svelte +1 -1
  92. package/dist/spreadsheet/SpreadsheetEditor.svelte.d.ts +22 -0
  93. package/dist/spreadsheet/SpreadsheetEditor.svelte.d.ts.map +1 -0
  94. package/dist/spreadsheet/index.d.ts +9 -0
  95. package/dist/spreadsheet/index.d.ts.map +1 -0
  96. package/{src/spreadsheet/index.ts → dist/spreadsheet/index.js} +1 -1
  97. package/dist/spreadsheet/spreadsheet.svelte.d.ts +33 -0
  98. package/dist/spreadsheet/spreadsheet.svelte.d.ts.map +1 -0
  99. package/dist/spreadsheet/spreadsheet.svelte.js +160 -0
  100. package/package.json +14 -16
  101. package/dist/canvas/index.js.map +0 -1
  102. package/dist/chunk-HEOI4UNF.js +0 -1191
  103. package/dist/chunk-HEOI4UNF.js.map +0 -1
  104. package/dist/image-editor/index.js.map +0 -1
  105. package/dist/index.css +0 -50
  106. package/dist/index.css.map +0 -1
  107. package/dist/index.js.map +0 -1
  108. package/src/canvas/__tests__/canvas-clipboard.test.ts +0 -154
  109. package/src/canvas/__tests__/canvas-docking.test.ts +0 -288
  110. package/src/canvas/__tests__/canvas-explosion.test.ts +0 -634
  111. package/src/canvas/__tests__/canvas-graph.test.ts +0 -159
  112. package/src/canvas/__tests__/canvas-interactions.test.ts +0 -86
  113. package/src/canvas/__tests__/canvas-layout.test.ts +0 -75
  114. package/src/canvas/__tests__/canvas-multi-drag.test.ts +0 -112
  115. package/src/canvas/__tests__/canvas-node-sync.svelte.test.ts +0 -104
  116. package/src/canvas/__tests__/canvas-shortcuts.test.ts +0 -59
  117. package/src/canvas/createCanvasClipboard.svelte.ts +0 -219
  118. package/src/canvas/createCanvasDisplacement.ts +0 -253
  119. package/src/canvas/createCanvasDocking.svelte.ts +0 -355
  120. package/src/canvas/createCanvasExplosion.svelte.ts +0 -457
  121. package/src/canvas/createCanvasGraph.svelte.ts +0 -330
  122. package/src/canvas/createCanvasInteractions.svelte.ts +0 -112
  123. package/src/canvas/createCanvasLayout.ts +0 -129
  124. package/src/canvas/createCanvasMultiDrag.svelte.ts +0 -175
  125. package/src/canvas/createCanvasNodeSync.svelte.ts +0 -150
  126. package/src/canvas/createCanvasSelection.svelte.ts +0 -51
  127. package/src/canvas/createCanvasShortcuts.ts +0 -99
  128. package/src/canvas/createCanvasTrajectory.ts +0 -207
  129. package/src/canvas/createStreamingCanvas.svelte.ts +0 -56
  130. package/src/canvas/index.d.ts +0 -688
  131. package/src/canvas/index.ts +0 -126
  132. package/src/canvas/types.ts +0 -223
  133. package/src/createNavigationGuard.svelte.ts +0 -97
  134. package/src/editor.svelte.ts +0 -65
  135. package/src/history/createHistoryShortcuts.ts +0 -95
  136. package/src/history/history.svelte.ts +0 -68
  137. package/src/history/index.ts +0 -2
  138. package/src/image-editor/imageEditorState.svelte.ts +0 -151
  139. package/src/image-editor/index.d.ts +0 -16
  140. package/src/image-editor/index.ts +0 -2
  141. package/src/index.d.ts +0 -249
  142. package/src/index.ts +0 -89
  143. package/src/navigationGuard.ts +0 -82
  144. package/src/spreadsheet/spreadsheet.svelte.ts +0 -176
  145. package/src/svelte.d.ts +0 -5
  146. /package/{src → dist}/BubbleMenu.svelte +0 -0
  147. /package/{src → dist}/TemplateRenderer.svelte +0 -0
  148. /package/{src → dist}/canvas/AgentPresenceLayer.svelte +0 -0
  149. /package/{src → dist}/canvas/FloatingHorizontalScrollbar.svelte +0 -0
  150. /package/{src → dist}/canvas/README.md +0 -0
@@ -0,0 +1,62 @@
1
+ import { type XYPosition } from '@xyflow/svelte';
2
+ import type { CanvasNode, CanvasEdge, GraphDifferences } from './types.js';
3
+ /**
4
+ * Pure calculation of graph differences between a current state and a baseline state.
5
+ */
6
+ export declare function calculateGraphDifferences<TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge>(currentState: {
7
+ nodes?: TNode[];
8
+ edges?: TEdge[];
9
+ }, baselineState: {
10
+ nodes?: TNode[];
11
+ edges?: TEdge[];
12
+ }): GraphDifferences<TNode, TEdge>;
13
+ /**
14
+ * Pure function to replace a node in a graph, optionally preserving its connected edges.
15
+ */
16
+ export declare function replaceNodeInGraph<TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge>(nodes: TNode[], edges: TEdge[], oldNode: TNode, newNode: TNode, keepEdges?: boolean): {
17
+ nodes: TNode[];
18
+ edges: TEdge[];
19
+ };
20
+ export interface CreateCanvasGraphOptions<TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge> {
21
+ initialNodes?: TNode[];
22
+ initialEdges?: TEdge[];
23
+ onNodesChange?: (nodes: TNode[]) => void;
24
+ onEdgesChange?: (edges: TEdge[]) => void;
25
+ onSave?: () => void;
26
+ createEdge?: (sourceId: string, targetId: string, options?: {
27
+ label?: string;
28
+ animated?: boolean;
29
+ data?: any;
30
+ }) => TEdge;
31
+ }
32
+ /**
33
+ * Headless Svelte 5 rune managing canvas graph state and operations.
34
+ */
35
+ export declare function createCanvasGraph<TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge>(options?: CreateCanvasGraphOptions<TNode, TEdge>): {
36
+ nodes: TNode[];
37
+ edges: TEdge[];
38
+ setNodes: (newNodes: TNode[], triggerCallback?: boolean) => void;
39
+ setEdges: (newEdges: TEdge[], triggerCallback?: boolean) => void;
40
+ addNodeOrNodes: (nodeOrNodesToAdd: TNode | TNode[], animateFromPosition?: XYPosition, save?: boolean) => void;
41
+ addEdge: (edgeToAdd: TEdge, save?: boolean) => void;
42
+ addEdges: (edgesToAdd: TEdge[], save?: boolean) => void;
43
+ removeNodes: (nodesToRemove: TNode[], save?: boolean) => void;
44
+ removeEdges: (edgesToRemove: TEdge[], save?: boolean) => void;
45
+ replaceNode: (oldNode: TNode, newNode: TNode, save?: boolean, keepEdges?: boolean) => void;
46
+ addConnectedNodes: (params: {
47
+ nodesToAdd: TNode[];
48
+ inboundNodes?: TNode[];
49
+ outboundNodes?: TNode[];
50
+ animatedEdges?: boolean;
51
+ animateFromPosition?: XYPosition;
52
+ inboundEdgeData?: any;
53
+ outboundEdgeData?: any;
54
+ getEdgeLabel?: (source: TNode, target: TNode) => string;
55
+ }) => void;
56
+ animateNodePosition: (node: TNode, targetPosition: XYPosition, duration?: number, easing?: (t: number) => number) => void;
57
+ getDifferences: (baseline: {
58
+ nodes?: TNode[];
59
+ edges?: TEdge[];
60
+ }) => GraphDifferences<TNode, TEdge>;
61
+ };
62
+ //# sourceMappingURL=createCanvasGraph.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createCanvasGraph.svelte.d.ts","sourceRoot":"","sources":["../../src/canvas/createCanvasGraph.svelte.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,223 @@
1
+ import { cubicOut } from 'svelte/easing';
2
+ /**
3
+ * Pure calculation of graph differences between a current state and a baseline state.
4
+ */
5
+ export function calculateGraphDifferences(currentState, baselineState) {
6
+ const currentNodes = currentState.nodes ?? [];
7
+ const currentEdges = currentState.edges ?? [];
8
+ const baselineNodes = baselineState.nodes ?? [];
9
+ const baselineEdges = baselineState.edges ?? [];
10
+ // Map baseline for fast O(1) lookup
11
+ const baselineNodeMap = new Map(baselineNodes.map((n) => [n.id, n]));
12
+ const baselineEdgeMap = new Map(baselineEdges.map((e) => [e.id, e]));
13
+ const currentNodeMap = new Map(currentNodes.map((n) => [n.id, n]));
14
+ const currentEdgeMap = new Map(currentEdges.map((e) => [e.id, e]));
15
+ const removedNodes = baselineNodes.filter((oldNode) => !currentNodeMap.has(oldNode.id));
16
+ const removedEdges = baselineEdges.filter((oldEdge) => !currentEdgeMap.has(oldEdge.id));
17
+ const changedNodes = currentNodes.filter((newNode) => {
18
+ const oldNode = baselineNodeMap.get(newNode.id);
19
+ if (!oldNode)
20
+ return true;
21
+ return JSON.stringify(newNode) !== JSON.stringify(oldNode);
22
+ });
23
+ const changedEdges = currentEdges.filter((newEdge) => {
24
+ const oldEdge = baselineEdgeMap.get(newEdge.id);
25
+ if (!oldEdge)
26
+ return true;
27
+ return JSON.stringify(newEdge) !== JSON.stringify(oldEdge);
28
+ });
29
+ return { changedNodes, changedEdges, removedNodes, removedEdges };
30
+ }
31
+ /**
32
+ * Pure function to replace a node in a graph, optionally preserving its connected edges.
33
+ */
34
+ export function replaceNodeInGraph(nodes, edges, oldNode, newNode, keepEdges = false) {
35
+ const updatedNodes = nodes.map((n) => (n.id === oldNode.id ? newNode : n));
36
+ if (!keepEdges) {
37
+ return { nodes: updatedNodes, edges };
38
+ }
39
+ const updatedEdges = edges.map((edge) => {
40
+ if (edge.source === oldNode.id || edge.target === oldNode.id) {
41
+ return {
42
+ ...edge,
43
+ id: crypto.randomUUID(),
44
+ source: edge.source === oldNode.id ? newNode.id : edge.source,
45
+ target: edge.target === oldNode.id ? newNode.id : edge.target
46
+ };
47
+ }
48
+ return edge;
49
+ });
50
+ return {
51
+ nodes: updatedNodes,
52
+ edges: updatedEdges
53
+ };
54
+ }
55
+ /**
56
+ * Headless Svelte 5 rune managing canvas graph state and operations.
57
+ */
58
+ export function createCanvasGraph(options = {}) {
59
+ let nodes = $state.raw(options.initialNodes ?? []);
60
+ let edges = $state.raw(options.initialEdges ?? []);
61
+ function setNodes(newNodes, triggerCallback = true) {
62
+ nodes = newNodes;
63
+ if (triggerCallback) {
64
+ options.onNodesChange?.(nodes);
65
+ }
66
+ }
67
+ function setEdges(newEdges, triggerCallback = true) {
68
+ edges = newEdges;
69
+ if (triggerCallback) {
70
+ options.onEdgesChange?.(edges);
71
+ }
72
+ }
73
+ function animateNodePosition(node, targetPosition, duration = 400, easing = cubicOut) {
74
+ const delay = node.data?.animationDelay ?? 0;
75
+ const startPosition = { ...node.position };
76
+ const startTime = Date.now() + delay;
77
+ function step() {
78
+ const currentTime = Date.now();
79
+ if (currentTime < startTime) {
80
+ if (typeof requestAnimationFrame !== 'undefined') {
81
+ requestAnimationFrame(step);
82
+ }
83
+ return;
84
+ }
85
+ const progress = Math.min((currentTime - startTime) / duration, 1);
86
+ const eased = easing(progress);
87
+ const currentPos = {
88
+ x: startPosition.x + (targetPosition.x - startPosition.x) * eased,
89
+ y: startPosition.y + (targetPosition.y - startPosition.y) * eased
90
+ };
91
+ // Mutate position in place without recreating the entire array every frame
92
+ const targetNode = nodes.find((n) => n.id === node.id);
93
+ if (targetNode) {
94
+ targetNode.position = currentPos;
95
+ }
96
+ if (progress < 1) {
97
+ if (typeof requestAnimationFrame !== 'undefined') {
98
+ requestAnimationFrame(step);
99
+ }
100
+ }
101
+ else {
102
+ // Animation completed: trigger final reactive update and change event
103
+ setNodes([...nodes]);
104
+ }
105
+ }
106
+ step();
107
+ }
108
+ function addNodeOrNodes(nodeOrNodesToAdd, animateFromPosition, save = true) {
109
+ const toAdd = Array.isArray(nodeOrNodesToAdd) ? nodeOrNodesToAdd : [nodeOrNodesToAdd];
110
+ const existingMap = new Map(nodes.map((n) => [n.id, n]));
111
+ toAdd.forEach((node) => {
112
+ if (!existingMap.has(node.id)) {
113
+ existingMap.set(node.id, node);
114
+ }
115
+ });
116
+ setNodes(Array.from(existingMap.values()));
117
+ if (animateFromPosition) {
118
+ toAdd.forEach((node) => {
119
+ const target = { ...node.position };
120
+ node.position = { ...animateFromPosition };
121
+ animateNodePosition(node, target);
122
+ });
123
+ }
124
+ if (save)
125
+ options.onSave?.();
126
+ }
127
+ function addEdge(edgeToAdd, save = true) {
128
+ setEdges([...edges, edgeToAdd]);
129
+ if (save)
130
+ options.onSave?.();
131
+ }
132
+ function addEdges(edgesToAdd, save = true) {
133
+ setEdges([...edges, ...edgesToAdd]);
134
+ if (save)
135
+ options.onSave?.();
136
+ }
137
+ function removeNodes(nodesToRemove, save = true) {
138
+ const idsToRemove = new Set(nodesToRemove.map((n) => n.id));
139
+ setNodes(nodes.filter((n) => !idsToRemove.has(n.id)));
140
+ if (save)
141
+ options.onSave?.();
142
+ }
143
+ function removeEdges(edgesToRemove, save = true) {
144
+ const idsToRemove = new Set(edgesToRemove.map((e) => e.id));
145
+ setEdges(edges.filter((e) => !idsToRemove.has(e.id)));
146
+ if (save)
147
+ options.onSave?.();
148
+ }
149
+ function replaceNode(oldNode, newNode, save = true, keepEdges = false) {
150
+ const result = replaceNodeInGraph(nodes, edges, oldNode, newNode, keepEdges);
151
+ setNodes(result.nodes);
152
+ if (result.edges !== edges) {
153
+ setEdges(result.edges);
154
+ }
155
+ if (save)
156
+ options.onSave?.();
157
+ }
158
+ function addConnectedNodes(params) {
159
+ const { nodesToAdd, inboundNodes = [], outboundNodes = [], animatedEdges = false, animateFromPosition, inboundEdgeData = {}, outboundEdgeData = {}, getEdgeLabel } = params;
160
+ const defaultCreateEdge = (sourceId, targetId, opt) => {
161
+ if (options.createEdge) {
162
+ return options.createEdge(sourceId, targetId, opt);
163
+ }
164
+ return {
165
+ id: crypto.randomUUID(),
166
+ type: 'default',
167
+ source: sourceId,
168
+ target: targetId,
169
+ label: opt?.label ?? '',
170
+ animated: opt?.animated ?? false,
171
+ data: opt?.data ?? {}
172
+ };
173
+ };
174
+ nodesToAdd.forEach((addedNode) => {
175
+ addNodeOrNodes(addedNode, animateFromPosition, false);
176
+ inboundNodes.forEach((sourceNode) => {
177
+ const label = getEdgeLabel ? getEdgeLabel(sourceNode, addedNode) : '';
178
+ addEdge(defaultCreateEdge(sourceNode.id, addedNode.id, {
179
+ label,
180
+ animated: animatedEdges,
181
+ data: inboundEdgeData
182
+ }), false);
183
+ });
184
+ outboundNodes.forEach((targetNode) => {
185
+ const label = getEdgeLabel ? getEdgeLabel(addedNode, targetNode) : '';
186
+ addEdge(defaultCreateEdge(addedNode.id, targetNode.id, {
187
+ label,
188
+ animated: animatedEdges,
189
+ data: outboundEdgeData
190
+ }), false);
191
+ });
192
+ });
193
+ options.onSave?.();
194
+ }
195
+ function getDifferences(baseline) {
196
+ return calculateGraphDifferences({ nodes, edges }, baseline);
197
+ }
198
+ return {
199
+ get nodes() {
200
+ return nodes;
201
+ },
202
+ set nodes(val) {
203
+ setNodes(val);
204
+ },
205
+ get edges() {
206
+ return edges;
207
+ },
208
+ set edges(val) {
209
+ setEdges(val);
210
+ },
211
+ setNodes,
212
+ setEdges,
213
+ addNodeOrNodes,
214
+ addEdge,
215
+ addEdges,
216
+ removeNodes,
217
+ removeEdges,
218
+ replaceNode,
219
+ addConnectedNodes,
220
+ animateNodePosition,
221
+ getDifferences
222
+ };
223
+ }
@@ -0,0 +1,28 @@
1
+ import type { CanvasInteractionPresetConfig } from './types.js';
2
+ export interface CreateCanvasInteractionsOptions {
3
+ targetElement?: HTMLElement | Window;
4
+ onPanModeChange?: (active: boolean) => void;
5
+ onTrackpadDetected?: () => void;
6
+ }
7
+ /**
8
+ * Headless Svelte 5 rune managing canvas pan interactions (spacebar panning, trackpad pinch detection).
9
+ */
10
+ export declare function createCanvasInteractions(options?: CreateCanvasInteractionsOptions): {
11
+ readonly isSpacebarPanning: boolean;
12
+ readonly trackpadDetected: boolean;
13
+ attachListeners: (target?: HTMLElement | Window) => () => void;
14
+ destroy: () => void;
15
+ };
16
+ /**
17
+ * Default interaction configuration presets for SvelteFlow.
18
+ */
19
+ export declare const defaultSvelteFlowPreset: CanvasInteractionPresetConfig;
20
+ /**
21
+ * Miro-compatible interaction preset (middle/right drag to pan, left drag to select).
22
+ */
23
+ export declare const miroCompatiblePreset: CanvasInteractionPresetConfig;
24
+ /**
25
+ * Helper to ensure panels restore pointer events after selection rectangle releases.
26
+ */
27
+ export declare function restorePanelPointerEvents(panelSelector?: string): void;
28
+ //# sourceMappingURL=createCanvasInteractions.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createCanvasInteractions.svelte.d.ts","sourceRoot":"","sources":["../../src/canvas/createCanvasInteractions.svelte.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAC;AAEhE,MAAM,WAAW,+BAA+B;IAC/C,aAAa,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IACrC,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;CAChC;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,GAAE,+BAAoC;;;+BAsCnD,WAAW,GAAG,MAAM,KAAG,MAAM,IAAI;mBAAJ,IAAI;EA4BnE;AAED;;GAEG;AACH,eAAO,MAAM,uBAAuB,EAAE,6BAOrC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,6BAIlC,CAAC;AAEF;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,aAAa,SAAwB,GAAG,IAAI,CAMrF"}
@@ -0,0 +1,95 @@
1
+ import { isEventFromTextInput } from './createCanvasClipboard.svelte.js';
2
+ /**
3
+ * Headless Svelte 5 rune managing canvas pan interactions (spacebar panning, trackpad pinch detection).
4
+ */
5
+ export function createCanvasInteractions(options = {}) {
6
+ let isSpacebarPanning = $state.raw(false);
7
+ let trackpadDetected = $state.raw(false);
8
+ let toggledPanMode = false;
9
+ function handleKeyDown(event) {
10
+ if (event.key === ' ' || event.code === 'Space') {
11
+ if (isSpacebarPanning || isEventFromTextInput(event))
12
+ return;
13
+ isSpacebarPanning = true;
14
+ toggledPanMode = true;
15
+ options.onPanModeChange?.(true);
16
+ if (typeof document !== 'undefined') {
17
+ document.body.classList.add('cursor-grab');
18
+ }
19
+ }
20
+ }
21
+ function handleKeyUp(event) {
22
+ if (event.key === ' ' || event.code === 'Space') {
23
+ if (!isSpacebarPanning && !toggledPanMode)
24
+ return;
25
+ isSpacebarPanning = false;
26
+ toggledPanMode = false;
27
+ options.onPanModeChange?.(false);
28
+ if (typeof document !== 'undefined') {
29
+ document.body.classList.remove('cursor-grab');
30
+ }
31
+ }
32
+ }
33
+ function handleWheel(event) {
34
+ if (event.ctrlKey && !trackpadDetected) {
35
+ trackpadDetected = true;
36
+ options.onTrackpadDetected?.();
37
+ }
38
+ }
39
+ function attachListeners(target) {
40
+ const el = target ?? options.targetElement ?? (typeof window !== 'undefined' ? window : null);
41
+ if (!el)
42
+ return () => { };
43
+ el.addEventListener('keydown', handleKeyDown);
44
+ el.addEventListener('keyup', handleKeyUp);
45
+ el.addEventListener('wheel', handleWheel, { passive: true });
46
+ return () => {
47
+ el.removeEventListener('keydown', handleKeyDown);
48
+ el.removeEventListener('keyup', handleKeyUp);
49
+ el.removeEventListener('wheel', handleWheel);
50
+ if (typeof document !== 'undefined') {
51
+ document.body.classList.remove('cursor-grab');
52
+ }
53
+ };
54
+ }
55
+ return {
56
+ get isSpacebarPanning() {
57
+ return isSpacebarPanning;
58
+ },
59
+ get trackpadDetected() {
60
+ return trackpadDetected;
61
+ },
62
+ attachListeners,
63
+ destroy: attachListeners()
64
+ };
65
+ }
66
+ /**
67
+ * Default interaction configuration presets for SvelteFlow.
68
+ */
69
+ export const defaultSvelteFlowPreset = {
70
+ snapGrid: [25, 25],
71
+ panOnDrag: [0, 1, 2, 3, 4],
72
+ panOnScroll: false,
73
+ selectionOnDrag: false,
74
+ colorMode: 'system',
75
+ multiSelectionKey: ['Shift', 'Meta']
76
+ };
77
+ /**
78
+ * Miro-compatible interaction preset (middle/right drag to pan, left drag to select).
79
+ */
80
+ export const miroCompatiblePreset = {
81
+ ...defaultSvelteFlowPreset,
82
+ panOnDrag: [1, 2],
83
+ selectionOnDrag: true
84
+ };
85
+ /**
86
+ * Helper to ensure panels restore pointer events after selection rectangle releases.
87
+ */
88
+ export function restorePanelPointerEvents(panelSelector = '.svelte-flow__panel') {
89
+ if (typeof document === 'undefined')
90
+ return;
91
+ const panels = document.querySelectorAll(panelSelector);
92
+ panels.forEach((panel) => {
93
+ panel.style.pointerEvents = 'auto';
94
+ });
95
+ }
@@ -0,0 +1,22 @@
1
+ import { type XYPosition, type Rect } from '@xyflow/svelte';
2
+ import type { CanvasNode, CanvasEdge, CanvasLayoutOptions } from './types.js';
3
+ /**
4
+ * Calculates upper-left flow coordinate for an element to be centered in the viewport.
5
+ */
6
+ export declare function getCenteredNodePosition(width: number | undefined, height: number | undefined, screenToFlowPosition: (position: XYPosition) => XYPosition, screenDimensions?: {
7
+ width: number;
8
+ height: number;
9
+ }): XYPosition;
10
+ /**
11
+ * Updates positions of nodes so their collective bounding box is centered in the current viewport.
12
+ */
13
+ export declare function centerNodes<TNode extends CanvasNode = CanvasNode>(nodes: TNode[], screenToFlowPosition: (position: XYPosition) => XYPosition, getNodesBounds: (nodes: TNode[]) => Rect, screenDimensions?: {
14
+ width: number;
15
+ height: number;
16
+ }): TNode[];
17
+ /**
18
+ * Automatically calculates directed hierarchical layout of nodes and edges using Dagre.
19
+ */
20
+ export declare function getLayoutedNodes<TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge>(nodes: TNode[], edges: TEdge[], getNodesBounds: (nodes: TNode[]) => Rect, options?: CanvasLayoutOptions): TNode[];
21
+ export { ensureLayout, placeBeside, estimateNodeSize, flowSide } from '@pixerate/editor/canvas';
22
+ //# sourceMappingURL=createCanvasLayout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createCanvasLayout.d.ts","sourceRoot":"","sources":["../../src/canvas/createCanvasLayout.ts"],"names":[],"mappings":"AACA,OAAO,EAAY,KAAK,UAAU,EAAE,KAAK,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAE9E;;GAEG;AACH,wBAAgB,uBAAuB,CACtC,KAAK,oBAAI,EACT,MAAM,oBAAI,EACV,oBAAoB,EAAE,CAAC,QAAQ,EAAE,UAAU,KAAK,UAAU,EAC1D,gBAAgB,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClD,UAAU,CAUZ;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,EAChE,KAAK,EAAE,KAAK,EAAE,EACd,oBAAoB,EAAE,CAAC,QAAQ,EAAE,UAAU,KAAK,UAAU,EAC1D,cAAc,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,EACxC,gBAAgB,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClD,KAAK,EAAE,CAyBT;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC/B,KAAK,SAAS,UAAU,GAAG,UAAU,EACrC,KAAK,SAAS,UAAU,GAAG,UAAU,EAErC,KAAK,EAAE,KAAK,EAAE,EACd,KAAK,EAAE,KAAK,EAAE,EACd,cAAc,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,EACxC,OAAO,GAAE,mBAAwB,GAC/B,KAAK,EAAE,CAiDT;AAGD,OAAO,EACN,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,QAAQ,EACR,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,76 @@
1
+ import dagre from '@dagrejs/dagre';
2
+ import { Position } from '@xyflow/svelte';
3
+ /**
4
+ * Calculates upper-left flow coordinate for an element to be centered in the viewport.
5
+ */
6
+ export function getCenteredNodePosition(width = 0, height = 0, screenToFlowPosition, screenDimensions) {
7
+ const rect = screenDimensions ?? (typeof document !== 'undefined'
8
+ ? { width: document.documentElement.clientWidth, height: document.documentElement.clientHeight }
9
+ : { width: 1920, height: 1080 });
10
+ const flowPos = screenToFlowPosition({ x: rect.width / 2, y: rect.height / 2 });
11
+ return {
12
+ x: flowPos.x - width / 2,
13
+ y: flowPos.y - height / 2
14
+ };
15
+ }
16
+ /**
17
+ * Updates positions of nodes so their collective bounding box is centered in the current viewport.
18
+ */
19
+ export function centerNodes(nodes, screenToFlowPosition, getNodesBounds, screenDimensions) {
20
+ if (nodes.length === 0) {
21
+ return [];
22
+ }
23
+ const bounds = getNodesBounds(nodes);
24
+ const boundingBoxOrigin = { x: bounds.x, y: bounds.y };
25
+ const centeredPosition = getCenteredNodePosition(bounds.width, bounds.height, screenToFlowPosition, screenDimensions);
26
+ const deltaX = centeredPosition.x - boundingBoxOrigin.x;
27
+ const deltaY = centeredPosition.y - boundingBoxOrigin.y;
28
+ return nodes.map((node) => ({
29
+ ...node,
30
+ position: {
31
+ x: node.position.x + deltaX,
32
+ y: node.position.y + deltaY
33
+ }
34
+ }));
35
+ }
36
+ /**
37
+ * Automatically calculates directed hierarchical layout of nodes and edges using Dagre.
38
+ */
39
+ export function getLayoutedNodes(nodes, edges, getNodesBounds, options = {}) {
40
+ if (nodes.length === 0)
41
+ return [];
42
+ const { direction = 'LR', ranksep = 100, nodesep = 25, defaultNodeWidth = 200, defaultNodeHeight = 200 } = options;
43
+ const isHorizontal = direction === 'LR' || direction === 'RL';
44
+ const bounds = getNodesBounds(nodes);
45
+ const dagreGraph = new dagre.graphlib.Graph();
46
+ dagreGraph.setDefaultEdgeLabel(() => ({}));
47
+ dagreGraph.setGraph({ rankdir: direction, ranksep, nodesep });
48
+ const nodeIds = new Set(nodes.map((node) => node.id));
49
+ nodes.forEach((node) => {
50
+ const nodeWidth = node.measured?.width ?? node.width ?? defaultNodeWidth;
51
+ const nodeHeight = node.measured?.height ?? node.height ?? defaultNodeHeight;
52
+ dagreGraph.setNode(node.id, { width: nodeWidth, height: nodeHeight });
53
+ });
54
+ edges.forEach((edge) => {
55
+ if (nodeIds.has(edge.source) && nodeIds.has(edge.target)) {
56
+ dagreGraph.setEdge(edge.source, edge.target);
57
+ }
58
+ });
59
+ dagre.layout(dagreGraph);
60
+ return nodes.map((node) => {
61
+ const nodeWithPosition = dagreGraph.node(node.id);
62
+ const nodeWidth = node.measured?.width ?? node.width ?? defaultNodeWidth;
63
+ const nodeHeight = node.measured?.height ?? node.height ?? defaultNodeHeight;
64
+ return {
65
+ ...node,
66
+ targetPosition: isHorizontal ? Position.Left : Position.Top,
67
+ sourcePosition: isHorizontal ? Position.Right : Position.Bottom,
68
+ position: {
69
+ x: bounds.x + (nodeWithPosition?.x ?? 0) - nodeWidth / 2,
70
+ y: bounds.y + (nodeWithPosition?.y ?? 0) - nodeHeight / 2
71
+ }
72
+ };
73
+ });
74
+ }
75
+ // Re-export incremental layout and collision-aware placement from core
76
+ export { ensureLayout, placeBeside, estimateNodeSize, flowSide } from '@pixerate/editor/canvas';
@@ -0,0 +1,61 @@
1
+ import type { XYPosition } from '@xyflow/svelte';
2
+ import type { CanvasNode } from './types.js';
3
+ export interface MultiDragFollowerOffset {
4
+ deltaX: number;
5
+ deltaY: number;
6
+ originalPosition: XYPosition;
7
+ stackOffsetX: number;
8
+ stackOffsetY: number;
9
+ rotationDeg: number;
10
+ }
11
+ export interface MultiDragState {
12
+ leadId: string;
13
+ offsets: Record<string, MultiDragFollowerOffset>;
14
+ count: number;
15
+ }
16
+ export interface CreateCanvasMultiDragOptions {
17
+ /**
18
+ * Base horizontal fan-out offset per stacked follower card (default: 4px).
19
+ */
20
+ stackOffsetStepX?: number;
21
+ /**
22
+ * Base vertical fan-out offset per stacked follower card (default: 4px).
23
+ */
24
+ stackOffsetStepY?: number;
25
+ /**
26
+ * Alternating angular tilt in degrees for follower cards (default: [-2, 2.5, -3, 3]).
27
+ */
28
+ rotationAngles?: number[];
29
+ /**
30
+ * Base z-index for stacked cards during active dragging (default: 50).
31
+ */
32
+ baseZIndex?: number;
33
+ }
34
+ export interface FollowerTransform {
35
+ isFollower: boolean;
36
+ stackOffsetX: number;
37
+ stackOffsetY: number;
38
+ rotationDeg: number;
39
+ zIndex: number;
40
+ }
41
+ /**
42
+ * Headless Svelte 5 rune orchestrating multi-node drag operations with stacked visual fanning,
43
+ * dynamic z-index layering, and position restoration.
44
+ */
45
+ export declare function createCanvasMultiDrag(options?: CreateCanvasMultiDragOptions): {
46
+ readonly dragState: MultiDragState | null;
47
+ readonly isMultiDrag: boolean;
48
+ readonly count: number;
49
+ readonly leadId: string | null;
50
+ startMultiDrag: (leadNodeId: string, selectedNodeIds: string[] | Set<string>, nodes: CanvasNode[] | Map<string, CanvasNode>) => MultiDragState | null;
51
+ getFollowerTransform: (nodeId: string) => FollowerTransform;
52
+ cancelMultiDrag: (applyRestore?: (restores: {
53
+ id: string;
54
+ originalPosition: XYPosition;
55
+ }[]) => void) => {
56
+ id: string;
57
+ originalPosition: XYPosition;
58
+ }[];
59
+ commitMultiDrag: () => void;
60
+ };
61
+ //# sourceMappingURL=createCanvasMultiDrag.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createCanvasMultiDrag.svelte.d.ts","sourceRoot":"","sources":["../../src/canvas/createCanvasMultiDrag.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,uBAAuB;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,UAAU,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;IACjD,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,4BAA4B;IAC5C;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IACjC,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,4BAAiC;;;;;iCASlE,MAAM,mBACD,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,SAChC,UAAU,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,KAC3C,cAAc,GAAG,IAAI;mCAiDc,MAAM,KAAG,iBAAiB;qCAyBhD,CAAC,QAAQ,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,UAAU,CAAA;KAAE,EAAE,KAAK,IAAI,KAC/E;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,UAAU,CAAA;KAAE,EAAE;2BAgBrB,IAAI;EAsBhC"}