@redvars/peacock 3.8.6 → 3.9.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 (85) hide show
  1. package/dist/code-highlighter.js +1 -4
  2. package/dist/code-highlighter.js.map +1 -1
  3. package/dist/custom-elements-jsdocs.json +93 -213
  4. package/dist/custom-elements.json +488 -2149
  5. package/dist/elevation.js +55 -2
  6. package/dist/elevation.js.map +1 -1
  7. package/dist/flow.js +762 -0
  8. package/dist/flow.js.map +1 -0
  9. package/dist/index.js +3 -3
  10. package/dist/loader.js +10 -9
  11. package/dist/loader.js.map +1 -1
  12. package/dist/menu-item.js +144 -63
  13. package/dist/menu-item.js.map +1 -1
  14. package/dist/menu.js +161 -73
  15. package/dist/menu.js.map +1 -1
  16. package/dist/src/flow/flow.d.ts +102 -0
  17. package/dist/src/flow/index.d.ts +2 -0
  18. package/dist/src/index.d.ts +3 -4
  19. package/dist/src/menu/menu/menu.d.ts +10 -9
  20. package/dist/src/menu/menu-item/menu-item.d.ts +1 -3
  21. package/dist/src/timeline/index.d.ts +2 -0
  22. package/dist/src/timeline/timeline-item.d.ts +23 -0
  23. package/dist/src/timeline/timeline.d.ts +26 -0
  24. package/dist/sub-menu.js +28 -1
  25. package/dist/sub-menu.js.map +1 -1
  26. package/dist/timeline-item.js +163 -0
  27. package/dist/timeline-item.js.map +1 -0
  28. package/dist/timeline.js +52 -0
  29. package/dist/timeline.js.map +1 -0
  30. package/dist/tsconfig.tsbuildinfo +1 -1
  31. package/package.json +3 -2
  32. package/readme.md +2 -2
  33. package/src/code-highlighter/code-highlighter.scss +1 -7
  34. package/src/elevation/demo/index.html +52 -0
  35. package/src/elevation/elevation.scss +52 -5
  36. package/src/elevation/elevation.ts +8 -1
  37. package/src/flow/flow.scss +195 -0
  38. package/src/flow/flow.ts +683 -0
  39. package/src/flow/index.ts +2 -0
  40. package/src/index.ts +3 -16
  41. package/src/loader.ts +10 -9
  42. package/src/menu/menu/copy-component-files.mjs +47 -0
  43. package/src/menu/menu/menu.scss +55 -17
  44. package/src/menu/menu/menu.ts +155 -84
  45. package/src/menu/menu-item/menu-item-colors.scss +3 -3
  46. package/src/menu/menu-item/menu-item.scss +118 -24
  47. package/src/menu/menu-item/menu-item.ts +61 -55
  48. package/src/menu/sub-menu/sub-menu.scss +30 -1
  49. package/src/timeline/index.ts +2 -0
  50. package/src/timeline/timeline-item.scss +98 -0
  51. package/src/timeline/timeline-item.ts +63 -0
  52. package/src/timeline/timeline.scss +11 -0
  53. package/src/timeline/timeline.ts +41 -0
  54. package/dist/canvas.js +0 -385
  55. package/dist/canvas.js.map +0 -1
  56. package/dist/flow-designer-node-CGSm6cUH.js +0 -553
  57. package/dist/flow-designer-node-CGSm6cUH.js.map +0 -1
  58. package/dist/flow-designer-node.js +0 -4
  59. package/dist/flow-designer-node.js.map +0 -1
  60. package/dist/flow-designer.js +0 -1417
  61. package/dist/flow-designer.js.map +0 -1
  62. package/dist/src/canvas/canvas.d.ts +0 -92
  63. package/dist/src/canvas/index.d.ts +0 -2
  64. package/dist/src/flow-designer/commands.d.ts +0 -66
  65. package/dist/src/flow-designer/flow-designer-node.d.ts +0 -46
  66. package/dist/src/flow-designer/flow-designer.d.ts +0 -133
  67. package/dist/src/flow-designer/index.d.ts +0 -7
  68. package/dist/src/flow-designer/layout.d.ts +0 -30
  69. package/dist/src/flow-designer/types.d.ts +0 -142
  70. package/dist/src/flow-designer/validation.d.ts +0 -43
  71. package/dist/src/flow-designer/workflow-utils.d.ts +0 -40
  72. package/src/canvas/canvas.scss +0 -72
  73. package/src/canvas/canvas.ts +0 -413
  74. package/src/canvas/index.ts +0 -2
  75. package/src/flow-designer/DEMO.md +0 -239
  76. package/src/flow-designer/commands.ts +0 -278
  77. package/src/flow-designer/flow-designer-node.ts +0 -172
  78. package/src/flow-designer/flow-designer.scss +0 -457
  79. package/src/flow-designer/flow-designer.ts +0 -611
  80. package/src/flow-designer/index.ts +0 -41
  81. package/src/flow-designer/layout.ts +0 -357
  82. package/src/flow-designer/types.ts +0 -166
  83. package/src/flow-designer/validation.ts +0 -284
  84. package/src/flow-designer/workflow-utils.ts +0 -282
  85. /package/dist/test/{flow-designer.test.d.ts → elevation.test.d.ts} +0 -0
package/dist/flow.js ADDED
@@ -0,0 +1,762 @@
1
+ import { i, _ as __decorate, I as IndividualComponent, a as i$1, b, A, w } from './IndividualComponent-Bdwyrvd6.js';
2
+ import { n } from './property-B49QQ8pS.js';
3
+ import { r } from './state-DkTK9EGF.js';
4
+ import { e } from './class-map-DG7CA1et.js';
5
+ import './directive-ZPhl09Yt.js';
6
+
7
+ var css_248z = i`* {
8
+ box-sizing: border-box;
9
+ -webkit-tap-highlight-color: transparent;
10
+ }
11
+
12
+ .screen-reader-only {
13
+ display: none !important;
14
+ }
15
+
16
+ [hidden] {
17
+ display: none !important;
18
+ }
19
+
20
+ :host {
21
+ display: block;
22
+ width: 100%;
23
+ height: 100%;
24
+ overflow: hidden;
25
+ --flow-background: var(--color-surface-container-lowest, #f4f5f8);
26
+ --flow-dot-color: var(--color-outline-variant, #e1e3e8);
27
+ --flow-line-color: var(--color-outline, #75777c);
28
+ --flow-hover-color: var(--color-primary, #005FAF);
29
+ --flow-node-bg: var(--color-surface-container-low, #f8f9fc);
30
+ --flow-node-border: var(--color-outline-variant, #c5c6cb);
31
+ --flow-node-shadow: 0 4px 12px rgba(0, 0, 0, 0.08), 0 1px 3px rgba(0, 0, 0, 0.05);
32
+ --flow-node-active-shadow: 0 8px 24px rgba(0, 0, 0, 0.12), 0 2px 6px rgba(0, 0, 0, 0.08);
33
+ }
34
+
35
+ .flow-container {
36
+ position: relative;
37
+ width: 100%;
38
+ height: 100%;
39
+ background: var(--flow-background);
40
+ border: 1px solid var(--color-outline-variant);
41
+ border-radius: 16px;
42
+ overflow: auto;
43
+ }
44
+
45
+ .flow-workspace {
46
+ position: relative;
47
+ }
48
+
49
+ .flow-svg {
50
+ position: absolute;
51
+ inset: 0;
52
+ width: 100%;
53
+ height: 100%;
54
+ pointer-events: auto;
55
+ }
56
+
57
+ #dot-grid circle {
58
+ fill: var(--flow-dot-color);
59
+ }
60
+
61
+ .flow-edge {
62
+ transition: stroke 150ms ease, stroke-width 150ms ease;
63
+ pointer-events: stroke;
64
+ cursor: pointer;
65
+ }
66
+ .flow-edge:hover {
67
+ stroke: var(--flow-hover-color);
68
+ stroke-width: 3;
69
+ }
70
+ .flow-edge.variant-dashed {
71
+ stroke-dasharray: 5 5;
72
+ }
73
+ .flow-edge.variant-animated-dashed {
74
+ stroke-dasharray: 5 5;
75
+ animation: flow-dash-flow 1s linear infinite;
76
+ }
77
+
78
+ .flow-edge-preview {
79
+ stroke-dasharray: 5 5;
80
+ animation: flow-dash-flow 1s linear infinite;
81
+ pointer-events: none;
82
+ }
83
+
84
+ .flow-nodes {
85
+ pointer-events: none;
86
+ }
87
+ .flow-nodes > * {
88
+ pointer-events: auto;
89
+ }
90
+
91
+ .flow-node {
92
+ display: inline-flex;
93
+ align-items: center;
94
+ justify-content: center;
95
+ background: var(--flow-node-bg);
96
+ border: 1px solid var(--flow-node-border);
97
+ box-shadow: var(--flow-node-shadow);
98
+ border-radius: 12px;
99
+ min-width: 150px;
100
+ min-height: 70px;
101
+ cursor: grab;
102
+ user-select: none;
103
+ z-index: 5;
104
+ transition: box-shadow 150ms ease, border-color 150ms ease, transform 150ms ease;
105
+ }
106
+ .flow-node:active {
107
+ cursor: grabbing;
108
+ box-shadow: var(--flow-node-active-shadow);
109
+ border-color: var(--flow-hover-color);
110
+ transform: translateY(-1px);
111
+ }
112
+
113
+ .flow-node-content {
114
+ width: 100%;
115
+ height: 100%;
116
+ padding: 12px 16px;
117
+ }
118
+
119
+ .flow-node-default-card {
120
+ display: flex;
121
+ flex-direction: column;
122
+ justify-content: center;
123
+ align-items: center;
124
+ text-align: center;
125
+ width: 100%;
126
+ height: 100%;
127
+ }
128
+
129
+ .flow-node-title {
130
+ font-family: inherit;
131
+ font-size: 14px;
132
+ font-weight: 500;
133
+ color: var(--color-on-surface);
134
+ }
135
+
136
+ .handle {
137
+ position: absolute;
138
+ width: 12px;
139
+ height: 12px;
140
+ border-radius: 50%;
141
+ background: var(--color-surface, #ffffff);
142
+ border: 2px solid var(--color-outline, #75777c);
143
+ z-index: 10;
144
+ cursor: crosshair;
145
+ transition: transform 150ms cubic-bezier(0.4, 0, 0.2, 1), background-color 150ms ease, border-color 150ms ease, box-shadow 150ms ease;
146
+ }
147
+ .handle:hover {
148
+ transform: scale(1.4);
149
+ background-color: var(--flow-hover-color);
150
+ border-color: var(--flow-hover-color);
151
+ box-shadow: 0 0 8px rgba(0, 95, 175, 0.5);
152
+ }
153
+ .handle:active {
154
+ transform: scale(1.2);
155
+ background-color: var(--flow-hover-color);
156
+ border-color: var(--flow-hover-color);
157
+ }
158
+
159
+ .handle-position-left {
160
+ left: -7px;
161
+ top: calc(50% - 6px);
162
+ }
163
+
164
+ .handle-position-right {
165
+ right: -7px;
166
+ top: calc(50% - 6px);
167
+ }
168
+
169
+ .handle-position-top {
170
+ top: -7px;
171
+ left: calc(50% - 6px);
172
+ }
173
+
174
+ .handle-position-bottom {
175
+ bottom: -7px;
176
+ left: calc(50% - 6px);
177
+ }
178
+
179
+ @keyframes flow-dash-flow {
180
+ to {
181
+ stroke-dashoffset: -20;
182
+ }
183
+ }
184
+ .flow-node-custom {
185
+ background: transparent !important;
186
+ border-color: transparent !important;
187
+ box-shadow: none !important;
188
+ min-width: 0 !important;
189
+ min-height: 0 !important;
190
+ }
191
+ .flow-node-custom .flow-node-content {
192
+ padding: 0 !important;
193
+ }`;
194
+
195
+ /**
196
+ * @label Flow
197
+ * @tag wc-flow
198
+ * @rawTag flow
199
+ * @summary An interactive node editor canvas with draggable nodes, custom HTML element rendering, and mouse-based edge connection creation on a dotted grid.
200
+ *
201
+ * @example
202
+ * ```html
203
+ * <wc-flow id="my-flow"></wc-flow>
204
+ * <script>
205
+ * const flow = document.getElementById('my-flow');
206
+ * flow.nodes = [
207
+ * { id: '1', position: { x: 50, y: 50 }, data: { label: 'Node 1' } },
208
+ * { id: '2', position: { x: 250, y: 50 }, data: { label: 'Node 2' } }
209
+ * ];
210
+ * flow.edges = [
211
+ * { id: 'e1-2', source: '1', target: '2' }
212
+ * ];
213
+ * </script>
214
+ * ```
215
+ *
216
+ * @cssprop --flow-background - Background color for the canvas wrapper. Defaults to surface-container-low.
217
+ * @cssprop --flow-dot-color - Color of the background grid dots. Defaults to outline-variant.
218
+ * @cssprop --flow-line-color - Default stroke color for lines and connectors. Defaults to on-surface.
219
+ * @cssprop --flow-hover-color - Stroke color on hover for clickable shapes. Defaults to primary.
220
+ * @cssprop --flow-arrow-color - Stroke color for arrow markers. Defaults to on-surface.
221
+ */
222
+ let Flow = class Flow extends i$1 {
223
+ constructor() {
224
+ super(...arguments);
225
+ this.nodes = [];
226
+ this.edges = [];
227
+ this.zoom = 1;
228
+ this.padding = 50;
229
+ // Node dimensions tracking
230
+ this.nodeDimensions = new Map();
231
+ // Drag node state
232
+ this.draggingNodeId = null;
233
+ this.dragStartMouseX = 0;
234
+ this.dragStartMouseY = 0;
235
+ this.dragStartNodeX = 0;
236
+ this.dragStartNodeY = 0;
237
+ // Connection drag state
238
+ this.isDrawingConnection = false;
239
+ this.draggingSourceId = null;
240
+ this.draggingSourceHandle = null;
241
+ this.connectionStartX = 0;
242
+ this.connectionStartY = 0;
243
+ this.currentMouseX = 0;
244
+ this.currentMouseY = 0;
245
+ this.onNodeMouseMove = (event) => {
246
+ if (!this.draggingNodeId)
247
+ return;
248
+ const deltaX = (event.clientX - this.dragStartMouseX) / this.zoom;
249
+ const deltaY = (event.clientY - this.dragStartMouseY) / this.zoom;
250
+ const node = this.nodes.find((n) => n.id === this.draggingNodeId);
251
+ if (node) {
252
+ node.position = {
253
+ x: this.dragStartNodeX + deltaX,
254
+ y: this.dragStartNodeY + deltaY,
255
+ };
256
+ this.dispatchEvent(new CustomEvent("node-drag", {
257
+ detail: { id: node.id, position: node.position },
258
+ bubbles: true,
259
+ composed: true,
260
+ }));
261
+ this.requestUpdate();
262
+ }
263
+ };
264
+ this.onNodeMouseUp = () => {
265
+ this.draggingNodeId = null;
266
+ window.removeEventListener("mousemove", this.onNodeMouseMove);
267
+ window.removeEventListener("mouseup", this.onNodeMouseUp);
268
+ };
269
+ this.onConnectionMouseMove = (event) => {
270
+ if (!this.isDrawingConnection)
271
+ return;
272
+ const workspaceEl = this.shadowRoot?.querySelector(".flow-workspace");
273
+ if (workspaceEl) {
274
+ const rect = workspaceEl.getBoundingClientRect();
275
+ const bounds = this.getBounds();
276
+ const viewBoxX = bounds.minX - this.padding;
277
+ const viewBoxY = bounds.minY - this.padding;
278
+ this.currentMouseX = viewBoxX + (event.clientX - rect.left) / this.zoom;
279
+ this.currentMouseY = viewBoxY + (event.clientY - rect.top) / this.zoom;
280
+ this.requestUpdate();
281
+ }
282
+ };
283
+ this.onConnectionMouseUp = (event) => {
284
+ if (!this.isDrawingConnection)
285
+ return;
286
+ this.isDrawingConnection = false;
287
+ window.removeEventListener("mousemove", this.onConnectionMouseMove);
288
+ window.removeEventListener("mouseup", this.onConnectionMouseUp);
289
+ const target = this.shadowRoot?.elementFromPoint(event.clientX, event.clientY);
290
+ const inputHandle = target?.closest(".handle-input");
291
+ if (inputHandle) {
292
+ const targetNodeId = inputHandle.getAttribute("data-node-id");
293
+ const targetHandle = inputHandle.getAttribute("data-position");
294
+ if (targetNodeId && targetNodeId !== this.draggingSourceId) {
295
+ this.dispatchEvent(new CustomEvent("connect", {
296
+ detail: {
297
+ source: this.draggingSourceId,
298
+ target: targetNodeId,
299
+ sourceHandle: this.draggingSourceHandle,
300
+ targetHandle: targetHandle,
301
+ },
302
+ bubbles: true,
303
+ composed: true,
304
+ }));
305
+ }
306
+ }
307
+ this.draggingSourceId = null;
308
+ this.draggingSourceHandle = null;
309
+ this.requestUpdate();
310
+ };
311
+ }
312
+ updated() {
313
+ let dimensionsChanged = false;
314
+ this.shadowRoot?.querySelectorAll(".flow-node").forEach((el) => {
315
+ const id = el.getAttribute("data-id");
316
+ if (id) {
317
+ const current = this.nodeDimensions.get(id);
318
+ const w = el.offsetWidth || 150;
319
+ const h = el.offsetHeight || 70;
320
+ if (!current || current.width !== w || current.height !== h) {
321
+ this.nodeDimensions.set(id, { width: w, height: h });
322
+ dimensionsChanged = true;
323
+ }
324
+ }
325
+ });
326
+ if (dimensionsChanged) {
327
+ this.requestUpdate();
328
+ }
329
+ }
330
+ // --- Node Dragging Handlers ---
331
+ onNodeMouseDown(event, node) {
332
+ const target = event.target;
333
+ if (target.closest(".handle") ||
334
+ target.closest("button") ||
335
+ target.closest("input") ||
336
+ target.closest("a")) {
337
+ return;
338
+ }
339
+ event.preventDefault();
340
+ this.draggingNodeId = node.id;
341
+ this.dragStartMouseX = event.clientX;
342
+ this.dragStartMouseY = event.clientY;
343
+ this.dragStartNodeX = node.position.x;
344
+ this.dragStartNodeY = node.position.y;
345
+ window.addEventListener("mousemove", this.onNodeMouseMove);
346
+ window.addEventListener("mouseup", this.onNodeMouseUp);
347
+ }
348
+ // --- Handle Helpers ---
349
+ getNodeInputs(node) {
350
+ if (node.inputs && Array.isArray(node.inputs)) {
351
+ return node.inputs;
352
+ }
353
+ if (node.data && typeof node.data === "object" && Array.isArray(node.data.inputs)) {
354
+ return node.data.inputs;
355
+ }
356
+ return ["left"];
357
+ }
358
+ getNodeOutputs(node) {
359
+ if (node.outputs && Array.isArray(node.outputs)) {
360
+ return node.outputs;
361
+ }
362
+ if (node.data && typeof node.data === "object" && Array.isArray(node.data.outputs)) {
363
+ return node.data.outputs;
364
+ }
365
+ return ["right"];
366
+ }
367
+ getHandleCoordinates(node, position, dim) {
368
+ const x = node.position.x;
369
+ const y = node.position.y;
370
+ const w = dim.width;
371
+ const h = dim.height;
372
+ switch (position) {
373
+ case "top":
374
+ return { x: x + w / 2, y };
375
+ case "bottom":
376
+ return { x: x + w / 2, y: y + h };
377
+ case "left":
378
+ return { x, y: y + h / 2 };
379
+ case "right":
380
+ default:
381
+ return { x: x + w, y: y + h / 2 };
382
+ }
383
+ }
384
+ // --- Connection Dragging Handlers ---
385
+ onHandleMouseDown(event, node, position) {
386
+ event.stopPropagation();
387
+ event.preventDefault();
388
+ const dim = this.nodeDimensions.get(node.id) || { width: 150, height: 70 };
389
+ this.draggingSourceId = node.id;
390
+ this.draggingSourceHandle = position;
391
+ const coords = this.getHandleCoordinates(node, position, dim);
392
+ this.connectionStartX = coords.x;
393
+ this.connectionStartY = coords.y;
394
+ this.isDrawingConnection = true;
395
+ this.currentMouseX = this.connectionStartX;
396
+ this.currentMouseY = this.connectionStartY;
397
+ window.addEventListener("mousemove", this.onConnectionMouseMove);
398
+ window.addEventListener("mouseup", this.onConnectionMouseUp);
399
+ }
400
+ // --- Path Builders ---
401
+ getRoundedPath(points, radius = 12) {
402
+ if (points.length < 3) {
403
+ return points.map((p, i) => (i === 0 ? `M ${p.x} ${p.y}` : `L ${p.x} ${p.y}`)).join(" ");
404
+ }
405
+ let path = `M ${points[0].x} ${points[0].y}`;
406
+ for (let i = 1; i < points.length - 1; i++) {
407
+ const prev = points[i - 1];
408
+ const curr = points[i];
409
+ const next = points[i + 1];
410
+ const dxp = prev.x - curr.x;
411
+ const dyp = prev.y - curr.y;
412
+ const lenp = Math.hypot(dxp, dyp);
413
+ const dxn = next.x - curr.x;
414
+ const dyn = next.y - curr.y;
415
+ const lenn = Math.hypot(dxn, dyn);
416
+ if (lenp === 0 || lenn === 0) {
417
+ path += ` L ${curr.x} ${curr.y}`;
418
+ continue;
419
+ }
420
+ const r = Math.min(radius, lenp / 2, lenn / 2);
421
+ if (r > 0) {
422
+ const x1 = curr.x + (dxp / lenp) * r;
423
+ const y1 = curr.y + (dyp / lenp) * r;
424
+ const x2 = curr.x + (dxn / lenn) * r;
425
+ const y2 = curr.y + (dyn / lenn) * r;
426
+ path += ` L ${x1} ${y1} Q ${curr.x} ${curr.y} ${x2} ${y2}`;
427
+ }
428
+ else {
429
+ path += ` L ${curr.x} ${curr.y}`;
430
+ }
431
+ }
432
+ const last = points[points.length - 1];
433
+ path += ` L ${last.x} ${last.y}`;
434
+ return path;
435
+ }
436
+ getSmoothStepPath(x1, y1, x2, y2, sourceHandle = "right", targetHandle = "left") {
437
+ const isSourceHorizontal = sourceHandle === "left" || sourceHandle === "right";
438
+ const isTargetHorizontal = targetHandle === "left" || targetHandle === "right";
439
+ let points = [];
440
+ if (isSourceHorizontal && isTargetHorizontal) {
441
+ const midX = x1 + (x2 - x1) / 2;
442
+ points = [
443
+ { x: x1, y: y1 },
444
+ { x: midX, y: y1 },
445
+ { x: midX, y: y2 },
446
+ { x: x2, y: y2 },
447
+ ];
448
+ }
449
+ else if (!isSourceHorizontal && !isTargetHorizontal) {
450
+ const midY = y1 + (y2 - y1) / 2;
451
+ points = [
452
+ { x: x1, y: y1 },
453
+ { x: x1, y: midY },
454
+ { x: x2, y: midY },
455
+ { x: x2, y: y2 },
456
+ ];
457
+ }
458
+ else if (isSourceHorizontal && !isTargetHorizontal) {
459
+ points = [
460
+ { x: x1, y: y1 },
461
+ { x: x2, y: y1 },
462
+ { x: x2, y: y2 },
463
+ ];
464
+ }
465
+ else {
466
+ points = [
467
+ { x: x1, y: y1 },
468
+ { x: x1, y: y2 },
469
+ { x: x2, y: y2 },
470
+ ];
471
+ }
472
+ return this.getRoundedPath(points, 12);
473
+ }
474
+ getBezierPath(x1, y1, x2, y2, sourceHandle = "right", targetHandle = "left") {
475
+ const normals = {
476
+ left: { x: -1, y: 0 },
477
+ right: { x: 1, y: 0 },
478
+ top: { x: 0, y: -1 },
479
+ bottom: { x: 0, y: 1 },
480
+ };
481
+ const sNormal = normals[sourceHandle] || { x: 1, y: 0 };
482
+ const tNormal = normals[targetHandle] || { x: -1, y: 0 };
483
+ const dx = x2 - x1;
484
+ const dy = y2 - y1;
485
+ const dist = Math.hypot(dx, dy);
486
+ const offset = Math.max(dist / 2, 50);
487
+ const cx1 = x1 + sNormal.x * offset;
488
+ const cy1 = y1 + sNormal.y * offset;
489
+ const cx2 = x2 + tNormal.x * offset;
490
+ const cy2 = y2 + tNormal.y * offset;
491
+ return `M ${x1} ${y1} C ${cx1} ${cy1}, ${cx2} ${cy2}, ${x2} ${y2}`;
492
+ }
493
+ getStraightPath(x1, y1, x2, y2) {
494
+ return `M ${x1} ${y1} L ${x2} ${y2}`;
495
+ }
496
+ drawPath(sourceId, targetId, type, sourceHandle, targetHandle) {
497
+ const sourceNode = this.nodes.find((n) => n.id === sourceId);
498
+ const targetNode = this.nodes.find((n) => n.id === targetId);
499
+ if (!sourceNode || !targetNode)
500
+ return "";
501
+ const sDim = this.nodeDimensions.get(sourceId) || { width: 150, height: 70 };
502
+ const tDim = this.nodeDimensions.get(targetId) || { width: 150, height: 70 };
503
+ const sHandle = sourceHandle || this.getNodeOutputs(sourceNode)[0] || "right";
504
+ const tHandle = targetHandle || this.getNodeInputs(targetNode)[0] || "left";
505
+ const startCoords = this.getHandleCoordinates(sourceNode, sHandle, sDim);
506
+ const endCoords = this.getHandleCoordinates(targetNode, tHandle, tDim);
507
+ const edgeType = type || "smoothstep";
508
+ if (edgeType === "bezier") {
509
+ return this.getBezierPath(startCoords.x, startCoords.y, endCoords.x, endCoords.y, sHandle, tHandle);
510
+ }
511
+ if (edgeType === "straight") {
512
+ return this.getStraightPath(startCoords.x, startCoords.y, endCoords.x, endCoords.y);
513
+ }
514
+ return this.getSmoothStepPath(startCoords.x, startCoords.y, endCoords.x, endCoords.y, sHandle, tHandle);
515
+ }
516
+ // --- Auto viewbox math ---
517
+ getBounds() {
518
+ if (this.nodes.length === 0) {
519
+ return { minX: 0, minY: 0, maxX: 400, maxY: 300 };
520
+ }
521
+ let minX = Infinity;
522
+ let minY = Infinity;
523
+ let maxX = -Infinity;
524
+ let maxY = -Infinity;
525
+ this.nodes.forEach((node) => {
526
+ const dim = this.nodeDimensions.get(node.id) ||
527
+ { width: 150, height: 70 };
528
+ const x = node.position.x;
529
+ const y = node.position.y;
530
+ if (x < minX)
531
+ minX = x;
532
+ if (y < minY)
533
+ minY = y;
534
+ if (x + dim.width > maxX)
535
+ maxX = x + dim.width;
536
+ if (y + dim.height > maxY)
537
+ maxY = y + dim.height;
538
+ });
539
+ return { minX, minY, maxX, maxY };
540
+ }
541
+ // --- Content Renderers ---
542
+ isCustomNode(node) {
543
+ if (node.data instanceof HTMLElement) {
544
+ return true;
545
+ }
546
+ if (node.data &&
547
+ typeof node.data === "object" &&
548
+ node.data.element instanceof HTMLElement) {
549
+ return true;
550
+ }
551
+ return false;
552
+ }
553
+ renderNodeContent(node) {
554
+ if (node.data instanceof HTMLElement) {
555
+ return node.data;
556
+ }
557
+ if (node.data &&
558
+ typeof node.data === "object" &&
559
+ node.data.element instanceof HTMLElement) {
560
+ return node.data.element;
561
+ }
562
+ const label = node.data && typeof node.data === "object"
563
+ ? node.data.label || node.id
564
+ : String(node.data);
565
+ return b `
566
+ <div class="flow-node-default-card">
567
+ <div class="flow-node-title">${label}</div>
568
+ </div>
569
+ `;
570
+ }
571
+ render() {
572
+ const bounds = this.getBounds();
573
+ const viewBoxX = bounds.minX - this.padding;
574
+ const viewBoxY = bounds.minY - this.padding;
575
+ const viewBoxWidth = bounds.maxX - bounds.minX + 2 * this.padding;
576
+ const viewBoxHeight = bounds.maxY - bounds.minY + 2 * this.padding;
577
+ const svgViewBox = `${viewBoxX} ${viewBoxY} ${viewBoxWidth} ${viewBoxHeight}`;
578
+ return b `
579
+ <div class="flow-container">
580
+ <div
581
+ class="flow-scroller"
582
+ style="width: ${viewBoxWidth * this.zoom}px; height: ${viewBoxHeight * this.zoom}px; position: relative;"
583
+ >
584
+ <div
585
+ class="flow-workspace"
586
+ style="transform: scale(${this.zoom}); transform-origin: top left; width: ${viewBoxWidth}px; height: ${viewBoxHeight}px; position: absolute; left: 0; top: 0;"
587
+ >
588
+ <!-- SVG canvas for rendering grid and paths -->
589
+ <svg class="flow-svg" viewBox="${svgViewBox}">
590
+ <defs>
591
+ <pattern
592
+ id="dot-grid"
593
+ width="20"
594
+ height="20"
595
+ patternUnits="userSpaceOnUse"
596
+ >
597
+ <circle cx="1" cy="1" r="1" />
598
+ </pattern>
599
+ <marker
600
+ id="arrowhead"
601
+ markerWidth="8"
602
+ markerHeight="8"
603
+ refX="7"
604
+ refY="4"
605
+ orient="auto"
606
+ >
607
+ <polygon
608
+ points="0 0, 8 4, 0 8"
609
+ fill="var(--flow-line-color, var(--color-outline))"
610
+ />
611
+ </marker>
612
+ </defs>
613
+
614
+ <!-- Background Grid -->
615
+ <rect
616
+ x="${viewBoxX}"
617
+ y="${viewBoxY}"
618
+ width="${viewBoxWidth}"
619
+ height="${viewBoxHeight}"
620
+ fill="url(#dot-grid)"
621
+ />
622
+
623
+ <!-- Connection Edges -->
624
+ ${this.edges.map((edge) => {
625
+ const pathString = this.drawPath(edge.source, edge.target, edge.type, edge.sourceHandle, edge.targetHandle);
626
+ const color = edge.color ||
627
+ "var(--flow-line-color, var(--color-outline))";
628
+ const variant = edge.variant || "solid";
629
+ return w `
630
+ <path
631
+ class="${e({
632
+ "flow-edge": true,
633
+ "variant-dashed": variant === "dashed" ||
634
+ variant === "animated-dashed",
635
+ "variant-animated-dashed": variant === "animated-dashed",
636
+ })}"
637
+ d="${pathString}"
638
+ stroke="${color}"
639
+ fill="none"
640
+ stroke-width="2"
641
+ marker-end="url(#arrowhead)"
642
+ />
643
+ `;
644
+ })}
645
+
646
+ <!-- Connection Draft line preview -->
647
+ ${this.isDrawingConnection && this.draggingSourceHandle
648
+ ? w `
649
+ <path
650
+ class="flow-edge-preview"
651
+ d="${this.getBezierPath(this.connectionStartX, this.connectionStartY, this.currentMouseX, this.currentMouseY, this.draggingSourceHandle, ({
652
+ left: "right",
653
+ right: "left",
654
+ top: "bottom",
655
+ bottom: "top",
656
+ })[this.draggingSourceHandle])}"
657
+ stroke="var(--flow-hover-color, var(--color-primary))"
658
+ fill="none"
659
+ stroke-width="2"
660
+ stroke-dasharray="4 4"
661
+ />
662
+ `
663
+ : A}
664
+ </svg>
665
+
666
+ <!-- Nodes Workspace -->
667
+ <div
668
+ class="flow-nodes"
669
+ style="position: absolute; left: ${-viewBoxX}px; top: ${-viewBoxY}px;"
670
+ >
671
+ ${this.nodes.map((node) => {
672
+ const inputs = this.getNodeInputs(node);
673
+ const outputs = this.getNodeOutputs(node);
674
+ return b `
675
+ <div
676
+ class="${e({
677
+ "flow-node": true,
678
+ "flow-node-custom": this.isCustomNode(node),
679
+ })}"
680
+ data-id="${node.id}"
681
+ style="position: absolute; left: ${node.position
682
+ .x}px; top: ${node.position.y}px;"
683
+ @mousedown="${(e) => this.onNodeMouseDown(e, node)}"
684
+ >
685
+ <!-- Input connection handles -->
686
+ ${inputs.map((pos) => b `
687
+ <div
688
+ class="handle handle-input handle-position-${pos}"
689
+ data-node-id="${node.id}"
690
+ data-position="${pos}"
691
+ >
692
+ </div>
693
+ `)}
694
+
695
+ <!-- Node Inner Content -->
696
+ <div class="flow-node-content">
697
+ ${this.renderNodeContent(node)}
698
+ </div>
699
+
700
+ <!-- Output connection handles -->
701
+ ${outputs.map((pos) => b `
702
+ <div
703
+ class="handle handle-output handle-position-${pos}"
704
+ data-node-id="${node.id}"
705
+ data-position="${pos}"
706
+ @mousedown="${(e) => this.onHandleMouseDown(e, node, pos)}"
707
+ >
708
+ </div>
709
+ `)}
710
+ </div>
711
+ `;
712
+ })}
713
+ </div>
714
+ </div>
715
+ </div>
716
+ </div>
717
+ `;
718
+ }
719
+ };
720
+ Flow.styles = [css_248z];
721
+ __decorate([
722
+ n({ type: Array })
723
+ ], Flow.prototype, "nodes", void 0);
724
+ __decorate([
725
+ n({ type: Array })
726
+ ], Flow.prototype, "edges", void 0);
727
+ __decorate([
728
+ n({ type: Number, reflect: true })
729
+ ], Flow.prototype, "zoom", void 0);
730
+ __decorate([
731
+ n({ type: Number, reflect: true })
732
+ ], Flow.prototype, "padding", void 0);
733
+ __decorate([
734
+ r()
735
+ ], Flow.prototype, "draggingNodeId", void 0);
736
+ __decorate([
737
+ r()
738
+ ], Flow.prototype, "isDrawingConnection", void 0);
739
+ __decorate([
740
+ r()
741
+ ], Flow.prototype, "draggingSourceId", void 0);
742
+ __decorate([
743
+ r()
744
+ ], Flow.prototype, "draggingSourceHandle", void 0);
745
+ __decorate([
746
+ r()
747
+ ], Flow.prototype, "connectionStartX", void 0);
748
+ __decorate([
749
+ r()
750
+ ], Flow.prototype, "connectionStartY", void 0);
751
+ __decorate([
752
+ r()
753
+ ], Flow.prototype, "currentMouseX", void 0);
754
+ __decorate([
755
+ r()
756
+ ], Flow.prototype, "currentMouseY", void 0);
757
+ Flow = __decorate([
758
+ IndividualComponent
759
+ ], Flow);
760
+
761
+ export { Flow };
762
+ //# sourceMappingURL=flow.js.map