@pixerate/editor-svelte 0.15.2 → 0.16.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 (149) hide show
  1. package/dist/BubbleMenu.svelte.d.ts +14 -0
  2. package/dist/BubbleMenu.svelte.d.ts.map +1 -0
  3. package/{src → dist}/EditableTextNodeEditor.svelte +1 -1
  4. package/dist/EditableTextNodeEditor.svelte.d.ts +26 -0
  5. package/dist/EditableTextNodeEditor.svelte.d.ts.map +1 -0
  6. package/dist/TemplateRenderer.svelte.d.ts +14 -0
  7. package/dist/TemplateRenderer.svelte.d.ts.map +1 -0
  8. package/dist/canvas/AgentPresenceLayer.svelte.d.ts +9 -0
  9. package/dist/canvas/AgentPresenceLayer.svelte.d.ts.map +1 -0
  10. package/dist/canvas/FloatingHorizontalScrollbar.svelte.d.ts +9 -0
  11. package/dist/canvas/FloatingHorizontalScrollbar.svelte.d.ts.map +1 -0
  12. package/dist/canvas/createCanvasClipboard.svelte.d.ts +32 -0
  13. package/dist/canvas/createCanvasClipboard.svelte.d.ts.map +1 -0
  14. package/dist/canvas/createCanvasClipboard.svelte.js +171 -0
  15. package/dist/canvas/createCanvasDisplacement.d.ts +32 -0
  16. package/dist/canvas/createCanvasDisplacement.d.ts.map +1 -0
  17. package/dist/canvas/createCanvasDisplacement.js +170 -0
  18. package/dist/canvas/createCanvasDocking.svelte.d.ts +56 -0
  19. package/dist/canvas/createCanvasDocking.svelte.d.ts.map +1 -0
  20. package/dist/canvas/createCanvasDocking.svelte.js +227 -0
  21. package/dist/canvas/createCanvasExplosion.svelte.d.ts +31 -0
  22. package/dist/canvas/createCanvasExplosion.svelte.d.ts.map +1 -0
  23. package/dist/canvas/createCanvasExplosion.svelte.js +346 -0
  24. package/dist/canvas/createCanvasGraph.svelte.d.ts +62 -0
  25. package/dist/canvas/createCanvasGraph.svelte.d.ts.map +1 -0
  26. package/dist/canvas/createCanvasGraph.svelte.js +223 -0
  27. package/dist/canvas/createCanvasInteractions.svelte.d.ts +28 -0
  28. package/dist/canvas/createCanvasInteractions.svelte.d.ts.map +1 -0
  29. package/dist/canvas/createCanvasInteractions.svelte.js +95 -0
  30. package/dist/canvas/createCanvasLayout.d.ts +22 -0
  31. package/dist/canvas/createCanvasLayout.d.ts.map +1 -0
  32. package/dist/canvas/createCanvasLayout.js +76 -0
  33. package/dist/canvas/createCanvasMultiDrag.svelte.d.ts +61 -0
  34. package/dist/canvas/createCanvasMultiDrag.svelte.d.ts.map +1 -0
  35. package/dist/canvas/createCanvasMultiDrag.svelte.js +105 -0
  36. package/dist/canvas/createCanvasNodeSync.svelte.d.ts +58 -0
  37. package/dist/canvas/createCanvasNodeSync.svelte.d.ts.map +1 -0
  38. package/dist/canvas/createCanvasNodeSync.svelte.js +82 -0
  39. package/dist/canvas/createCanvasSelection.svelte.d.ts +26 -0
  40. package/dist/canvas/createCanvasSelection.svelte.d.ts.map +1 -0
  41. package/dist/canvas/createCanvasSelection.svelte.js +26 -0
  42. package/dist/canvas/createCanvasShortcuts.d.ts +9 -0
  43. package/dist/canvas/createCanvasShortcuts.d.ts.map +1 -0
  44. package/dist/canvas/createCanvasShortcuts.js +97 -0
  45. package/dist/canvas/createCanvasTrajectory.d.ts +31 -0
  46. package/dist/canvas/createCanvasTrajectory.d.ts.map +1 -0
  47. package/dist/canvas/createCanvasTrajectory.js +141 -0
  48. package/dist/canvas/createStreamingCanvas.svelte.d.ts +19 -0
  49. package/dist/canvas/createStreamingCanvas.svelte.d.ts.map +1 -0
  50. package/dist/canvas/createStreamingCanvas.svelte.js +32 -0
  51. package/dist/canvas/index.d.ts +18 -688
  52. package/dist/canvas/index.d.ts.map +1 -0
  53. package/dist/canvas/index.js +34 -1839
  54. package/dist/canvas/types.d.ts +183 -0
  55. package/dist/canvas/types.d.ts.map +1 -0
  56. package/dist/canvas/types.js +1 -0
  57. package/dist/createNavigationGuard.svelte.d.ts +24 -0
  58. package/dist/createNavigationGuard.svelte.d.ts.map +1 -0
  59. package/dist/createNavigationGuard.svelte.js +65 -0
  60. package/dist/editor.svelte.d.ts +23 -0
  61. package/dist/editor.svelte.d.ts.map +1 -0
  62. package/dist/editor.svelte.js +41 -0
  63. package/dist/history/createHistoryShortcuts.d.ts +24 -0
  64. package/dist/history/createHistoryShortcuts.d.ts.map +1 -0
  65. package/dist/history/createHistoryShortcuts.js +57 -0
  66. package/dist/history/history.svelte.d.ts +18 -0
  67. package/dist/history/history.svelte.d.ts.map +1 -0
  68. package/dist/history/history.svelte.js +43 -0
  69. package/dist/history/index.d.ts +3 -0
  70. package/dist/history/index.d.ts.map +1 -0
  71. package/dist/history/index.js +2 -0
  72. package/{src → dist}/image-editor/ImageEditor.svelte +1 -1
  73. package/dist/image-editor/ImageEditor.svelte.d.ts +17 -0
  74. package/dist/image-editor/ImageEditor.svelte.d.ts.map +1 -0
  75. package/dist/image-editor/imageEditorState.svelte.d.ts +50 -0
  76. package/dist/image-editor/imageEditorState.svelte.d.ts.map +1 -0
  77. package/dist/image-editor/imageEditorState.svelte.js +132 -0
  78. package/dist/image-editor/index.d.ts +6 -16
  79. package/dist/image-editor/index.d.ts.map +1 -0
  80. package/dist/image-editor/index.js +2 -9
  81. package/dist/index.d.ts +20 -249
  82. package/dist/index.d.ts.map +1 -0
  83. package/dist/index.js +10 -1119
  84. package/dist/navigationGuard.d.ts +21 -0
  85. package/dist/navigationGuard.d.ts.map +1 -0
  86. package/dist/navigationGuard.js +59 -0
  87. package/{src → dist}/spreadsheet/FormulaBar.svelte +1 -1
  88. package/dist/spreadsheet/FormulaBar.svelte.d.ts +17 -0
  89. package/dist/spreadsheet/FormulaBar.svelte.d.ts.map +1 -0
  90. package/{src → dist}/spreadsheet/SpreadsheetEditor.svelte +1 -1
  91. package/dist/spreadsheet/SpreadsheetEditor.svelte.d.ts +22 -0
  92. package/dist/spreadsheet/SpreadsheetEditor.svelte.d.ts.map +1 -0
  93. package/dist/spreadsheet/index.d.ts +9 -0
  94. package/dist/spreadsheet/index.d.ts.map +1 -0
  95. package/{src/spreadsheet/index.ts → dist/spreadsheet/index.js} +1 -1
  96. package/dist/spreadsheet/spreadsheet.svelte.d.ts +33 -0
  97. package/dist/spreadsheet/spreadsheet.svelte.d.ts.map +1 -0
  98. package/dist/spreadsheet/spreadsheet.svelte.js +160 -0
  99. package/package.json +14 -16
  100. package/dist/canvas/index.js.map +0 -1
  101. package/dist/chunk-HEOI4UNF.js +0 -1191
  102. package/dist/chunk-HEOI4UNF.js.map +0 -1
  103. package/dist/image-editor/index.js.map +0 -1
  104. package/dist/index.css +0 -50
  105. package/dist/index.css.map +0 -1
  106. package/dist/index.js.map +0 -1
  107. package/src/canvas/__tests__/canvas-clipboard.test.ts +0 -154
  108. package/src/canvas/__tests__/canvas-docking.test.ts +0 -288
  109. package/src/canvas/__tests__/canvas-explosion.test.ts +0 -634
  110. package/src/canvas/__tests__/canvas-graph.test.ts +0 -159
  111. package/src/canvas/__tests__/canvas-interactions.test.ts +0 -86
  112. package/src/canvas/__tests__/canvas-layout.test.ts +0 -75
  113. package/src/canvas/__tests__/canvas-multi-drag.test.ts +0 -112
  114. package/src/canvas/__tests__/canvas-node-sync.svelte.test.ts +0 -104
  115. package/src/canvas/__tests__/canvas-shortcuts.test.ts +0 -59
  116. package/src/canvas/createCanvasClipboard.svelte.ts +0 -219
  117. package/src/canvas/createCanvasDisplacement.ts +0 -253
  118. package/src/canvas/createCanvasDocking.svelte.ts +0 -355
  119. package/src/canvas/createCanvasExplosion.svelte.ts +0 -457
  120. package/src/canvas/createCanvasGraph.svelte.ts +0 -330
  121. package/src/canvas/createCanvasInteractions.svelte.ts +0 -112
  122. package/src/canvas/createCanvasLayout.ts +0 -129
  123. package/src/canvas/createCanvasMultiDrag.svelte.ts +0 -175
  124. package/src/canvas/createCanvasNodeSync.svelte.ts +0 -150
  125. package/src/canvas/createCanvasSelection.svelte.ts +0 -51
  126. package/src/canvas/createCanvasShortcuts.ts +0 -99
  127. package/src/canvas/createCanvasTrajectory.ts +0 -207
  128. package/src/canvas/createStreamingCanvas.svelte.ts +0 -56
  129. package/src/canvas/index.d.ts +0 -688
  130. package/src/canvas/index.ts +0 -126
  131. package/src/canvas/types.ts +0 -223
  132. package/src/createNavigationGuard.svelte.ts +0 -97
  133. package/src/editor.svelte.ts +0 -65
  134. package/src/history/createHistoryShortcuts.ts +0 -95
  135. package/src/history/history.svelte.ts +0 -68
  136. package/src/history/index.ts +0 -2
  137. package/src/image-editor/imageEditorState.svelte.ts +0 -151
  138. package/src/image-editor/index.d.ts +0 -16
  139. package/src/image-editor/index.ts +0 -2
  140. package/src/index.d.ts +0 -249
  141. package/src/index.ts +0 -89
  142. package/src/navigationGuard.ts +0 -82
  143. package/src/spreadsheet/spreadsheet.svelte.ts +0 -176
  144. package/src/svelte.d.ts +0 -5
  145. /package/{src → dist}/BubbleMenu.svelte +0 -0
  146. /package/{src → dist}/TemplateRenderer.svelte +0 -0
  147. /package/{src → dist}/canvas/AgentPresenceLayer.svelte +0 -0
  148. /package/{src → dist}/canvas/FloatingHorizontalScrollbar.svelte +0 -0
  149. /package/{src → dist}/canvas/README.md +0 -0
@@ -0,0 +1,58 @@
1
+ import type { Position } from '@xyflow/svelte';
2
+ import type { CanvasNode, CanvasEdge } from './types.js';
3
+ export interface HandleConfig {
4
+ id?: string | null;
5
+ type: 'source' | 'target';
6
+ position: Position;
7
+ x?: number;
8
+ y?: number;
9
+ width?: number;
10
+ height?: number;
11
+ }
12
+ export interface NodeMeasurement {
13
+ width: number;
14
+ height: number;
15
+ }
16
+ /**
17
+ * Preserves cached .measured dimensions from existing nodes to newly constructed nodes.
18
+ * Resolves measurements without subscribing to reactive updates on the existing collection.
19
+ */
20
+ export declare function preserveNodeMeasurements<TNode extends CanvasNode = CanvasNode>(newNodes: TNode[], existingNodes: TNode[] | Map<string, TNode>): TNode[];
21
+ /**
22
+ * Pre-populates handle geometry on a node to prevent @xyflow/system's getNodesInside
23
+ * from evaluating `forceInitialRender = !node.internals.handleBounds` and triggering
24
+ * a false full-canvas selection on the first frame of marquee drag-selection.
25
+ */
26
+ export declare function normalizeNodeHandles<TNode extends CanvasNode = CanvasNode>(node: TNode, handles?: HandleConfig[]): TNode;
27
+ export interface CreateCanvasNodeSyncOptions<TItem, TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge> {
28
+ /**
29
+ * Reactive getter returning raw domain items.
30
+ */
31
+ items: () => TItem[];
32
+ /**
33
+ * Factory function converting a domain item into a CanvasNode.
34
+ */
35
+ toNode: (item: TItem, index: number, context: {
36
+ existingNode?: TNode;
37
+ prevNodesMap: Map<string, TNode>;
38
+ }) => TNode;
39
+ /**
40
+ * Optional factory function converting domain items and generated nodes into CanvasEdges.
41
+ */
42
+ toEdges?: (items: TItem[], nodes: TNode[]) => TEdge[];
43
+ /**
44
+ * Optional default handle configuration provider for connectable nodes.
45
+ */
46
+ defaultHandles?: (node: TNode) => HandleConfig[] | undefined;
47
+ }
48
+ /**
49
+ * Headless Svelte 5 rune that synchronizes reactive domain items with SvelteFlow nodes/edges,
50
+ * automatically untracking previous node reads, caching .measured dimensions, and normalizing
51
+ * handle bounds to prevent Svelte 5 effect_update_depth_exceeded and marquee drag flashes.
52
+ */
53
+ export declare function createCanvasNodeSync<TItem, TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge>(options: CreateCanvasNodeSyncOptions<TItem, TNode, TEdge>): {
54
+ nodes: TNode[];
55
+ edges: TEdge[];
56
+ updateNodeMeasurements(id: string, width: number, height: number): void;
57
+ };
58
+ //# sourceMappingURL=createCanvasNodeSync.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createCanvasNodeSync.svelte.d.ts","sourceRoot":"","sources":["../../src/canvas/createCanvasNodeSync.svelte.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEzD,MAAM,WAAW,YAAY;IAC5B,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,QAAQ,EAAE,QAAQ,CAAC;IACnB,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,EAC7E,QAAQ,EAAE,KAAK,EAAE,EACjB,aAAa,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,GACzC,KAAK,EAAE,CAaT;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,EACzE,IAAI,EAAE,KAAK,EACX,OAAO,GAAE,YAAY,EAAO,GAC1B,KAAK,CAGP;AAED,MAAM,WAAW,2BAA2B,CAC3C,KAAK,EACL,KAAK,SAAS,UAAU,GAAG,UAAU,EACrC,KAAK,SAAS,UAAU,GAAG,UAAU;IAErC;;OAEG;IACH,KAAK,EAAE,MAAM,KAAK,EAAE,CAAC;IACrB;;OAEG;IACH,MAAM,EAAE,CACP,IAAI,EAAE,KAAK,EACX,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;QAAE,YAAY,CAAC,EAAE,KAAK,CAAC;QAAC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;KAAE,KAC/D,KAAK,CAAC;IACX;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,KAAK,EAAE,CAAC;IACtD;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,YAAY,EAAE,GAAG,SAAS,CAAC;CAC7D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CACnC,KAAK,EACL,KAAK,SAAS,UAAU,GAAG,UAAU,EACrC,KAAK,SAAS,UAAU,GAAG,UAAU,EACpC,OAAO,EAAE,2BAA2B,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;WA2CxC,KAAK,EAAE;WAMP,KAAK,EAAE;+BAGG,MAAM,SAAS,MAAM,UAAU,MAAM;EAOjE"}
@@ -0,0 +1,82 @@
1
+ import { untrack } from 'svelte';
2
+ /**
3
+ * Preserves cached .measured dimensions from existing nodes to newly constructed nodes.
4
+ * Resolves measurements without subscribing to reactive updates on the existing collection.
5
+ */
6
+ export function preserveNodeMeasurements(newNodes, existingNodes) {
7
+ const map = existingNodes instanceof Map
8
+ ? existingNodes
9
+ : new Map(existingNodes.map((n) => [n.id, n]));
10
+ for (const node of newNodes) {
11
+ const prev = map.get(node.id);
12
+ if (prev && prev.measured) {
13
+ node.measured = { ...prev.measured };
14
+ }
15
+ }
16
+ return newNodes;
17
+ }
18
+ /**
19
+ * Pre-populates handle geometry on a node to prevent @xyflow/system's getNodesInside
20
+ * from evaluating `forceInitialRender = !node.internals.handleBounds` and triggering
21
+ * a false full-canvas selection on the first frame of marquee drag-selection.
22
+ */
23
+ export function normalizeNodeHandles(node, handles = []) {
24
+ node.handles = handles;
25
+ return node;
26
+ }
27
+ /**
28
+ * Headless Svelte 5 rune that synchronizes reactive domain items with SvelteFlow nodes/edges,
29
+ * automatically untracking previous node reads, caching .measured dimensions, and normalizing
30
+ * handle bounds to prevent Svelte 5 effect_update_depth_exceeded and marquee drag flashes.
31
+ */
32
+ export function createCanvasNodeSync(options) {
33
+ let nodes = $state([]);
34
+ let edges = $state([]);
35
+ $effect.pre(() => {
36
+ const rawItems = options.items();
37
+ // Untrack the read of current nodes to avoid recursive effect loops
38
+ const existingNodesMap = untrack(() => new Map(nodes.map((n) => [n.id, n])));
39
+ const newNodes = rawItems.map((item, index) => {
40
+ const existing = existingNodesMap.get(item?.id);
41
+ const node = options.toNode(item, index, {
42
+ existingNode: existing,
43
+ prevNodesMap: existingNodesMap
44
+ });
45
+ // Automatically preserve measured dimensions if available
46
+ if (existing && existing.measured && !node.measured) {
47
+ node.measured = { ...existing.measured };
48
+ }
49
+ // Pre-populate handles if provided
50
+ if (options.defaultHandles && !node.handles) {
51
+ const handles = options.defaultHandles(node);
52
+ if (handles) {
53
+ node.handles = handles;
54
+ }
55
+ }
56
+ return node;
57
+ });
58
+ const newEdges = options.toEdges ? options.toEdges(rawItems, newNodes) : [];
59
+ nodes = newNodes;
60
+ edges = newEdges;
61
+ });
62
+ return {
63
+ get nodes() {
64
+ return nodes;
65
+ },
66
+ set nodes(value) {
67
+ nodes = value;
68
+ },
69
+ get edges() {
70
+ return edges;
71
+ },
72
+ set edges(value) {
73
+ edges = value;
74
+ },
75
+ updateNodeMeasurements(id, width, height) {
76
+ const node = nodes.find((n) => n.id === id);
77
+ if (node) {
78
+ node.measured = { width, height };
79
+ }
80
+ }
81
+ };
82
+ }
@@ -0,0 +1,26 @@
1
+ import type { CanvasInteractionPresetConfig } from './types.js';
2
+ export interface CanvasSelectionOptions {
3
+ /**
4
+ * Whether spacebar panning is currently active (suspends marquee selection).
5
+ */
6
+ isSpacebarPanning?: boolean;
7
+ /**
8
+ * Selection mode: 'partial' (default) selects nodes intersected by selection box,
9
+ * 'full' requires nodes to be fully enclosed.
10
+ */
11
+ selectionMode?: 'partial' | 'full';
12
+ /**
13
+ * Additional keys that trigger multi-selection (default: ['Shift', 'Meta']).
14
+ */
15
+ multiSelectionKey?: string[];
16
+ }
17
+ /**
18
+ * Generates an interaction preset configured for left-click marquee drag-selection
19
+ * while preserving middle-mouse and spacebar panning.
20
+ */
21
+ export declare function getMarqueeSelectionPreset(options?: CanvasSelectionOptions): CanvasInteractionPresetConfig;
22
+ /**
23
+ * Keyboard listener helper to deselect nodes on Escape.
24
+ */
25
+ export declare function handleDeselectOnEscape(event: KeyboardEvent, onDeselect: () => void): boolean;
26
+ //# sourceMappingURL=createCanvasSelection.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createCanvasSelection.svelte.d.ts","sourceRoot":"","sources":["../../src/canvas/createCanvasSelection.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAC;AAEhE,MAAM,WAAW,sBAAsB;IACtC;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;OAGG;IACH,aAAa,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IACnC;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACxC,OAAO,GAAE,sBAA2B,GAClC,6BAA6B,CAY/B;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACrC,KAAK,EAAE,aAAa,EACpB,UAAU,EAAE,MAAM,IAAI,GACpB,OAAO,CAMT"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Generates an interaction preset configured for left-click marquee drag-selection
3
+ * while preserving middle-mouse and spacebar panning.
4
+ */
5
+ export function getMarqueeSelectionPreset(options = {}) {
6
+ const isSpacebarPanning = options.isSpacebarPanning ?? false;
7
+ return {
8
+ snapGrid: [25, 25],
9
+ panOnDrag: isSpacebarPanning ? [0, 1, 2] : [1, 2],
10
+ panOnScroll: false,
11
+ selectionOnDrag: !isSpacebarPanning,
12
+ colorMode: 'system',
13
+ multiSelectionKey: options.multiSelectionKey ?? ['Shift', 'Meta'],
14
+ selectionMode: (options.selectionMode ?? 'partial')
15
+ };
16
+ }
17
+ /**
18
+ * Keyboard listener helper to deselect nodes on Escape.
19
+ */
20
+ export function handleDeselectOnEscape(event, onDeselect) {
21
+ if (event.key === 'Escape' || event.code === 'Escape') {
22
+ onDeselect();
23
+ return true;
24
+ }
25
+ return false;
26
+ }
@@ -0,0 +1,9 @@
1
+ import type { CanvasNode, CanvasShortcutsOptions } from './types.js';
2
+ /**
3
+ * Attaches keyboard shortcut handlers for canvas interaction.
4
+ * Automatically ignores shortcuts when the user is typing into text inputs, textareas, or rich editors.
5
+ *
6
+ * @returns A cleanup function to remove event listeners.
7
+ */
8
+ export declare function createCanvasShortcuts<TNode extends CanvasNode = CanvasNode>(options: CanvasShortcutsOptions<TNode>): () => void;
9
+ //# sourceMappingURL=createCanvasShortcuts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createCanvasShortcuts.d.ts","sourceRoot":"","sources":["../../src/canvas/createCanvasShortcuts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAErE;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,EAC1E,OAAO,EAAE,sBAAsB,CAAC,KAAK,CAAC,GACpC,MAAM,IAAI,CAuFZ"}
@@ -0,0 +1,97 @@
1
+ import { isEventFromTextInput } from './createCanvasClipboard.svelte.js';
2
+ /**
3
+ * Attaches keyboard shortcut handlers for canvas interaction.
4
+ * Automatically ignores shortcuts when the user is typing into text inputs, textareas, or rich editors.
5
+ *
6
+ * @returns A cleanup function to remove event listeners.
7
+ */
8
+ export function createCanvasShortcuts(options) {
9
+ const target = options.targetElement ?? (typeof window !== 'undefined' ? window : null);
10
+ if (!target)
11
+ return () => { };
12
+ function handleKeyDown(event) {
13
+ const keyboardEvent = event;
14
+ if (isEventFromTextInput(keyboardEvent)) {
15
+ return;
16
+ }
17
+ const isMod = keyboardEvent.metaKey || keyboardEvent.ctrlKey;
18
+ const isShift = keyboardEvent.shiftKey;
19
+ const key = keyboardEvent.key;
20
+ const selectedNodes = options.getSelectedNodes ? options.getSelectedNodes() : [];
21
+ if (key === 'Backspace' || key === 'Delete') {
22
+ if (options.onDelete && selectedNodes.length > 0) {
23
+ keyboardEvent.preventDefault();
24
+ options.onDelete(selectedNodes);
25
+ }
26
+ return;
27
+ }
28
+ if (isMod) {
29
+ const lowerKey = key.toLowerCase();
30
+ if (lowerKey === 'c' && !isShift) {
31
+ if (options.onCopy) {
32
+ // We let the native copy event fire or call onCopy
33
+ options.onCopy();
34
+ }
35
+ }
36
+ else if (lowerKey === 'x' && !isShift) {
37
+ if (options.onCut) {
38
+ options.onCut();
39
+ }
40
+ }
41
+ else if (lowerKey === 'd' && !isShift) {
42
+ if (options.onDuplicate && selectedNodes.length > 0) {
43
+ keyboardEvent.preventDefault();
44
+ options.onDuplicate(selectedNodes);
45
+ }
46
+ }
47
+ else if (lowerKey === 'a' && !isShift) {
48
+ if (options.onSelectAll) {
49
+ keyboardEvent.preventDefault();
50
+ options.onSelectAll();
51
+ }
52
+ }
53
+ else if (lowerKey === 'g') {
54
+ if (isShift) {
55
+ if (options.onUngroup && selectedNodes.length > 0) {
56
+ keyboardEvent.preventDefault();
57
+ options.onUngroup(selectedNodes);
58
+ }
59
+ }
60
+ else {
61
+ if (options.onGroup && selectedNodes.length > 0) {
62
+ keyboardEvent.preventDefault();
63
+ options.onGroup(selectedNodes);
64
+ }
65
+ }
66
+ }
67
+ else if (key === '=' || key === '+') {
68
+ if (options.onZoomIn) {
69
+ keyboardEvent.preventDefault();
70
+ options.onZoomIn();
71
+ }
72
+ }
73
+ else if (key === '-') {
74
+ if (options.onZoomOut) {
75
+ keyboardEvent.preventDefault();
76
+ options.onZoomOut();
77
+ }
78
+ }
79
+ else if (key === '0') {
80
+ if (options.onFitView) {
81
+ keyboardEvent.preventDefault();
82
+ options.onFitView();
83
+ }
84
+ }
85
+ else if (lowerKey === 'f') {
86
+ if (options.onSearch) {
87
+ keyboardEvent.preventDefault();
88
+ options.onSearch();
89
+ }
90
+ }
91
+ }
92
+ }
93
+ target.addEventListener('keydown', handleKeyDown);
94
+ return () => {
95
+ target.removeEventListener('keydown', handleKeyDown);
96
+ };
97
+ }
@@ -0,0 +1,31 @@
1
+ import type { XYPosition } from '@xyflow/svelte';
2
+ import type { CanvasNode, FanOutTrajectoryOptions, NodeTransition, TrajectoryFunction } from './types.js';
3
+ /**
4
+ * Standard linear trajectory: straight line interpolation with linear scale & opacity progression.
5
+ */
6
+ export declare const linearTrajectory: TrajectoryFunction;
7
+ /**
8
+ * Linear position trajectory: pure position interpolation without altering scale or opacity.
9
+ * Used for displaced sibling nodes to ensure their visibility remains unaltered.
10
+ */
11
+ export declare const linearPositionTrajectory: TrajectoryFunction;
12
+ /**
13
+ * Creates a fan-out trajectory where nodes arc outward from origin to target.
14
+ * Matches the curved distribution shown in multi-node branching diagrams.
15
+ */
16
+ export declare function createFanOutTrajectory(options?: FanOutTrajectoryOptions): TrajectoryFunction;
17
+ /**
18
+ * Creates a custom quadratic Bezier trajectory with a specified or dynamically calculated control point.
19
+ */
20
+ export declare function createBezierTrajectory(getControlPoint: (origin: XYPosition, target: XYPosition) => XYPosition): TrajectoryFunction;
21
+ /**
22
+ * Coordinates and animates multiple node transitions simultaneously with zero per-frame array allocations.
23
+ * Directly mutates node positions and data (scale, opacity) in-place during the animation loop.
24
+ */
25
+ export declare function runMultiNodeTransition<TNode extends CanvasNode = CanvasNode>(transitions: NodeTransition<TNode>[], options?: {
26
+ defaultDuration?: number;
27
+ defaultEasing?: (t: number) => number;
28
+ onUpdate?: () => void;
29
+ onComplete?: () => void;
30
+ }): () => void;
31
+ //# sourceMappingURL=createCanvasTrajectory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createCanvasTrajectory.d.ts","sourceRoot":"","sources":["../../src/canvas/createCanvasTrajectory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EACX,UAAU,EACV,uBAAuB,EACvB,cAAc,EACd,kBAAkB,EAElB,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,kBAa9B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,EAAE,kBAWtC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,uBAA4B,GAAG,kBAAkB,CA0ChG;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACrC,eAAe,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,KAAK,UAAU,GACrE,kBAAkB,CAepB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,EAC3E,WAAW,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,EACpC,OAAO,GAAE;IACR,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACnB,GACJ,MAAM,IAAI,CA+EZ"}
@@ -0,0 +1,141 @@
1
+ import { cubicOut } from 'svelte/easing';
2
+ /**
3
+ * Standard linear trajectory: straight line interpolation with linear scale & opacity progression.
4
+ */
5
+ export const linearTrajectory = (origin, target, progress) => {
6
+ return {
7
+ position: {
8
+ x: origin.x + (target.x - origin.x) * progress,
9
+ y: origin.y + (target.y - origin.y) * progress
10
+ },
11
+ scale: progress,
12
+ opacity: Math.min(1, progress * 1.5)
13
+ };
14
+ };
15
+ /**
16
+ * Linear position trajectory: pure position interpolation without altering scale or opacity.
17
+ * Used for displaced sibling nodes to ensure their visibility remains unaltered.
18
+ */
19
+ export const linearPositionTrajectory = (origin, target, progress) => {
20
+ return {
21
+ position: {
22
+ x: origin.x + (target.x - origin.x) * progress,
23
+ y: origin.y + (target.y - origin.y) * progress
24
+ }
25
+ };
26
+ };
27
+ /**
28
+ * Creates a fan-out trajectory where nodes arc outward from origin to target.
29
+ * Matches the curved distribution shown in multi-node branching diagrams.
30
+ */
31
+ export function createFanOutTrajectory(options = {}) {
32
+ const { curvature = 0.4, startScale = 0, endScale = 1, startOpacity = 0, endOpacity = 1 } = options;
33
+ return (origin, target, progress, index, total) => {
34
+ const dx = target.x - origin.x;
35
+ const dy = target.y - origin.y;
36
+ // Normalized index from -1 (top) to +1 (bottom)
37
+ const normIndex = total > 1 ? (index - (total - 1) / 2) / ((total - 1) / 2) : 0;
38
+ // Perpendicular control point offset to create smooth fan arc
39
+ const midX = origin.x + dx * 0.4;
40
+ const midY = origin.y + dy * 0.1 - normIndex * Math.abs(dx) * 0.15 * curvature;
41
+ // Quadratic Bezier interpolation: B(t) = (1-t)^2 * P0 + 2(1-t)t * P1 + t^2 * P2
42
+ const t = progress;
43
+ const oneMinusT = 1 - t;
44
+ const x = oneMinusT * oneMinusT * origin.x + 2 * oneMinusT * t * midX + t * t * target.x;
45
+ const y = oneMinusT * oneMinusT * origin.y + 2 * oneMinusT * t * midY + t * t * target.y;
46
+ const scale = startScale + (endScale - startScale) * progress;
47
+ const opacity = startOpacity + (endOpacity - startOpacity) * progress;
48
+ return {
49
+ position: { x, y },
50
+ scale,
51
+ opacity
52
+ };
53
+ };
54
+ }
55
+ /**
56
+ * Creates a custom quadratic Bezier trajectory with a specified or dynamically calculated control point.
57
+ */
58
+ export function createBezierTrajectory(getControlPoint) {
59
+ return (origin, target, progress) => {
60
+ const cp = getControlPoint(origin, target);
61
+ const t = progress;
62
+ const oneMinusT = 1 - t;
63
+ const x = oneMinusT * oneMinusT * origin.x + 2 * oneMinusT * t * cp.x + t * t * target.x;
64
+ const y = oneMinusT * oneMinusT * origin.y + 2 * oneMinusT * t * cp.y + t * t * target.y;
65
+ return {
66
+ position: { x, y },
67
+ scale: progress,
68
+ opacity: progress
69
+ };
70
+ };
71
+ }
72
+ /**
73
+ * Coordinates and animates multiple node transitions simultaneously with zero per-frame array allocations.
74
+ * Directly mutates node positions and data (scale, opacity) in-place during the animation loop.
75
+ */
76
+ export function runMultiNodeTransition(transitions, options = {}) {
77
+ if (transitions.length === 0) {
78
+ options.onComplete?.();
79
+ return () => { };
80
+ }
81
+ const { defaultDuration = 400, defaultEasing = cubicOut, onUpdate, onComplete } = options;
82
+ let isCancelled = false;
83
+ const startTime = Date.now();
84
+ const items = transitions.map((tr, i) => ({
85
+ ...tr,
86
+ index: tr.index ?? i,
87
+ total: tr.total ?? transitions.length,
88
+ duration: tr.duration ?? defaultDuration,
89
+ easing: tr.easing ?? defaultEasing,
90
+ delay: tr.delay ?? 0,
91
+ trajectory: tr.trajectory ?? linearTrajectory
92
+ }));
93
+ function frame() {
94
+ if (isCancelled)
95
+ return;
96
+ const now = Date.now();
97
+ let allCompleted = true;
98
+ for (let i = 0; i < items.length; i++) {
99
+ const item = items[i];
100
+ const elapsed = now - (startTime + item.delay);
101
+ if (elapsed < 0) {
102
+ allCompleted = false;
103
+ continue;
104
+ }
105
+ const rawProgress = item.duration <= 0 ? 1 : Math.min(elapsed / item.duration, 1);
106
+ const progress = item.duration <= 0 ? 1 : item.easing(rawProgress);
107
+ const point = item.trajectory(item.from, item.to, progress, item.index, item.total);
108
+ // Direct in-place mutation avoids array reconstruction during RAF
109
+ item.node.position = { ...point.position };
110
+ if (point.scale !== undefined || point.opacity !== undefined) {
111
+ if (!item.node.data) {
112
+ item.node.data = {};
113
+ }
114
+ if (point.scale !== undefined) {
115
+ item.node.data.scale = point.scale;
116
+ }
117
+ if (point.opacity !== undefined) {
118
+ item.node.data.opacity = point.opacity;
119
+ const currentStyle = (item.node.style || '').replace(/opacity:\s*[^;]+;?/g, '').trim();
120
+ item.node.style = `${currentStyle ? currentStyle + '; ' : ''}opacity: ${point.opacity};`;
121
+ }
122
+ }
123
+ if (rawProgress < 1) {
124
+ allCompleted = false;
125
+ }
126
+ }
127
+ onUpdate?.();
128
+ if (!allCompleted) {
129
+ if (typeof requestAnimationFrame !== 'undefined') {
130
+ requestAnimationFrame(frame);
131
+ }
132
+ }
133
+ else {
134
+ onComplete?.();
135
+ }
136
+ }
137
+ frame();
138
+ return () => {
139
+ isCancelled = true;
140
+ };
141
+ }
@@ -0,0 +1,19 @@
1
+ import { type CanvasEdge, type CanvasNode, type IncrementalLayoutOptions, type XYPosition } from '@pixerate/editor/canvas';
2
+ export interface CreateStreamingCanvasOptions<TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge> {
3
+ throttleMs?: number;
4
+ glideDurationMs?: number;
5
+ connectedOnly?: boolean;
6
+ clock?: any;
7
+ layoutOptions?: IncrementalLayoutOptions;
8
+ onPositionsChange?: (positions: Map<string, XYPosition>) => void;
9
+ }
10
+ /**
11
+ * Svelte 5 rune managing throttled graph streaming and fluid node glide animations.
12
+ */
13
+ export declare function createStreamingCanvas<TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge>(options?: CreateStreamingCanvasOptions<TNode, TEdge>): {
14
+ readonly positions: Map<string, XYPosition>;
15
+ pushStreamUpdate(nodes: TNode[], edges: TEdge[], currentPositions: Map<string, XYPosition>): void;
16
+ flush(nodes: TNode[], edges: TEdge[], currentPositions: Map<string, XYPosition>): void;
17
+ destroy(): void;
18
+ };
19
+ //# sourceMappingURL=createStreamingCanvas.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createStreamingCanvas.svelte.d.ts","sourceRoot":"","sources":["../../src/canvas/createStreamingCanvas.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,wBAAwB,EAC7B,KAAK,UAAU,EACf,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,4BAA4B,CAC5C,KAAK,SAAS,UAAU,GAAG,UAAU,EACrC,KAAK,SAAS,UAAU,GAAG,UAAU;IAErC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,aAAa,CAAC,EAAE,wBAAwB,CAAC;IACzC,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,IAAI,CAAC;CACjE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACpC,KAAK,SAAS,UAAU,GAAG,UAAU,EACrC,KAAK,SAAS,UAAU,GAAG,UAAU,EACpC,OAAO,GAAE,4BAA4B,CAAC,KAAK,EAAE,KAAK,CAAM;;4BAmBhC,KAAK,EAAE,SAAS,KAAK,EAAE,oBAAoB,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC;iBAG7E,KAAK,EAAE,SAAS,KAAK,EAAE,oBAAoB,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC;;EAOhF"}
@@ -0,0 +1,32 @@
1
+ import { StreamingLayoutManager } from '@pixerate/editor/canvas';
2
+ /**
3
+ * Svelte 5 rune managing throttled graph streaming and fluid node glide animations.
4
+ */
5
+ export function createStreamingCanvas(options = {}) {
6
+ let positions = $state(new Map());
7
+ const manager = new StreamingLayoutManager({
8
+ throttleMs: options.throttleMs,
9
+ glideDurationMs: options.glideDurationMs,
10
+ connectedOnly: options.connectedOnly,
11
+ clock: options.clock,
12
+ layoutOptions: options.layoutOptions,
13
+ onLayoutUpdated: (updated) => {
14
+ positions = updated;
15
+ options.onPositionsChange?.(updated);
16
+ }
17
+ });
18
+ return {
19
+ get positions() {
20
+ return positions;
21
+ },
22
+ pushStreamUpdate(nodes, edges, currentPositions) {
23
+ manager.pushStreamUpdate(nodes, edges, currentPositions);
24
+ },
25
+ flush(nodes, edges, currentPositions) {
26
+ manager.flush(nodes, edges, currentPositions);
27
+ },
28
+ destroy() {
29
+ manager.destroy();
30
+ }
31
+ };
32
+ }