@bian-womp/spark-workbench 0.3.3 → 0.3.4

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.
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import { ReactFlowInstance, Node, Edge } from "@xyflow/react";
3
+ export declare const SelectionBoundOverlay: React.FC<{
4
+ selection: {
5
+ nodes: string[];
6
+ edges: string[];
7
+ };
8
+ rfInstance: ReactFlowInstance<Node, Edge> | null;
9
+ }>;
10
+ //# sourceMappingURL=SelectionBoundOverlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectionBoundOverlay.d.ts","sourceRoot":"","sources":["../../../../src/misc/SelectionBoundOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE9D,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC;IAC3C,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAChD,UAAU,EAAE,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC;CAClD,CAgEA,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import React from "react";
2
+ import { ReactFlowInstance, Node, Edge, type ReactFlowProps } from "@xyflow/react";
2
3
  import type { Viewport } from "@bian-womp/spark-protocol";
3
4
  export type WorkbenchCanvasHandle = {
4
5
  fitView: () => void;
@@ -12,5 +13,8 @@ export declare const WorkbenchCanvas: React.ForwardRefExoticComponent<{
12
13
  width: number;
13
14
  height: number;
14
15
  } | undefined;
16
+ reactFlowProps?: Partial<Omit<ReactFlowProps<Node, Edge>, "nodes" | "edges" | "nodeTypes" | "edgeTypes" | "connectionLineComponent" | "onInit" | "onConnect" | "onEdgesChange" | "onEdgesDelete" | "onNodesDelete" | "onNodesChange" | "onMoveEnd">> & {
17
+ onInit?: (instance: ReactFlowInstance<Node, Edge>) => void;
18
+ };
15
19
  } & React.RefAttributes<WorkbenchCanvasHandle>>;
16
20
  //# sourceMappingURL=WorkbenchCanvas.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"WorkbenchCanvas.d.ts","sourceRoot":"","sources":["../../../../src/misc/WorkbenchCanvas.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AAYf,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAsB1D,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,WAAW,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;CAC3C,CAAC;AAEF,eAAO,MAAM,eAAe;iBAGX,OAAO;cACV,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,MAAM;eAC3C,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,GAAG,CAAC,OAAO;yBACvC,CACnB,MAAM,EAAE,MAAM,KACX;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS;+CAq9BpD,CAAC"}
1
+ {"version":3,"file":"WorkbenchCanvas.d.ts","sourceRoot":"","sources":["../../../../src/misc/WorkbenchCanvas.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AACf,OAAO,EAOL,iBAAiB,EACjB,IAAI,EACJ,IAAI,EACJ,KAAK,cAAc,EACpB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAuB1D,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,WAAW,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;CAC3C,CAAC;AAEF,eAAO,MAAM,eAAe;iBAGX,OAAO;cACV,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,MAAM;eAC3C,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,GAAG,CAAC,OAAO;yBACvC,CACnB,MAAM,EAAE,MAAM,KACX;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS;qBACjC,OAAO,CACtB,IAAI,CACF,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,EACxB,OAAO,GACP,OAAO,GACP,WAAW,GACX,WAAW,GACX,yBAAyB,GACzB,QAAQ,GACR,WAAW,GACX,eAAe,GACf,eAAe,GACf,eAAe,GACf,eAAe,GACf,WAAW,CACd,CACF,GAAG;QACF,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,IAAI,CAAC;KAC5D;+CAs9BJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"WorkbenchStudio.d.ts","sourceRoot":"","sources":["../../../../src/misc/WorkbenchStudio.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAW,MAAM,2BAA2B,CAAC;AAgB1E,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAkBvE,OAAO,EAGL,kBAAkB,EACnB,MAAM,4BAA4B,CAAC;AAMpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAK9D,OAAO,EAEL,oBAAoB,EACpB,YAAY,EAGb,MAAM,yBAAyB,CAAC;AAIjC;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,cAAc,CAAC,EAAE,uBAAuB,CAAC;IACzC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;CACtC;AA2sBD,wBAAgB,eAAe,CAAC,EAC9B,OAAO,EACP,eAAe,EACf,WAAW,EACX,mBAAmB,EACnB,WAAW,EACX,mBAAmB,EACnB,KAAK,EACL,aAAa,EACb,KAAK,EACL,aAAa,EACb,UAAU,EACV,kBAAkB,EAClB,aAAa,EACb,qBAAqB,EACrB,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,SAAS,EACT,MAAM,EACN,QAAQ,GACT,EAAE;IACD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAClD,WAAW,EAAE,oBAAoB,CAAC;IAClC,mBAAmB,EAAE,CAAC,CAAC,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,aAAa,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACpC,UAAU,EAAE,OAAO,CAAC;IACpB,kBAAkB,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,aAAa,EAAE,OAAO,CAAC;IACvB,qBAAqB,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,UAAU,EAAE,OAAO,CAAC;IACpB,kBAAkB,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE;QACd,EAAE,EAAE,iBAAiB,CAAC;QACtB,MAAM,EAAE,YAAY,CAAC;QACrB,eAAe,EAAE,CACf,GAAG,EAAE,eAAe,EACpB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KAC7C,OAAO,CAAC,IAAI,CAAC,CAAC;KACpB,KAAK,IAAI,CAAC;IACX,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE;QAChB,GAAG,EAAE,eAAe,CAAC;QACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;KACjD,KAAK,IAAI,CAAC;CACZ,2CA8GA"}
1
+ {"version":3,"file":"WorkbenchStudio.d.ts","sourceRoot":"","sources":["../../../../src/misc/WorkbenchStudio.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAW,MAAM,2BAA2B,CAAC;AAgB1E,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAkBvE,OAAO,EAGL,kBAAkB,EACnB,MAAM,4BAA4B,CAAC;AAMpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAK9D,OAAO,EAEL,oBAAoB,EACpB,YAAY,EAGb,MAAM,yBAAyB,CAAC;AAIjC;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,cAAc,CAAC,EAAE,uBAAuB,CAAC;IACzC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;CACtC;AA+sBD,wBAAgB,eAAe,CAAC,EAC9B,OAAO,EACP,eAAe,EACf,WAAW,EACX,mBAAmB,EACnB,WAAW,EACX,mBAAmB,EACnB,KAAK,EACL,aAAa,EACb,KAAK,EACL,aAAa,EACb,UAAU,EACV,kBAAkB,EAClB,aAAa,EACb,qBAAqB,EACrB,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,SAAS,EACT,MAAM,EACN,QAAQ,GACT,EAAE;IACD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAClD,WAAW,EAAE,oBAAoB,CAAC;IAClC,mBAAmB,EAAE,CAAC,CAAC,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,aAAa,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACpC,UAAU,EAAE,OAAO,CAAC;IACpB,kBAAkB,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,aAAa,EAAE,OAAO,CAAC;IACvB,qBAAqB,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,UAAU,EAAE,OAAO,CAAC;IACpB,kBAAkB,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE;QACd,EAAE,EAAE,iBAAiB,CAAC;QACtB,MAAM,EAAE,YAAY,CAAC;QACrB,eAAe,EAAE,CACf,GAAG,EAAE,eAAe,EACpB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KAC7C,OAAO,CAAC,IAAI,CAAC,CAAC;KACpB,KAAK,IAAI,CAAC;IACX,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE;QAChB,GAAG,EAAE,eAAe,CAAC;QACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;KACjD,KAAK,IAAI,CAAC;CACZ,2CA8GA"}
@@ -1,3 +1,3 @@
1
1
  import type { NodeContextMenuProps } from "./ContextMenuHandlers";
2
- export declare function NodeContextMenu({ open, clientPos, nodeId, handlers, bakeableOutputs, runMode, enableKeyboardShortcuts, keyboardShortcuts, }: NodeContextMenuProps): import("react/jsx-runtime").JSX.Element | null;
2
+ export declare function NodeContextMenu({ open, clientPos, nodeId, handlers, bakeableOutputs, runMode, wb, enableKeyboardShortcuts, keyboardShortcuts, }: NodeContextMenuProps): import("react/jsx-runtime").JSX.Element | null;
3
3
  //# sourceMappingURL=NodeContextMenu.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"NodeContextMenu.d.ts","sourceRoot":"","sources":["../../../../../src/misc/context-menu/NodeContextMenu.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAGlE,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,SAAS,EACT,MAAM,EACN,QAAQ,EACR,eAAe,EACf,OAAO,EACP,uBAA8B,EAC9B,iBAKC,GACF,EAAE,oBAAoB,kDA6HtB"}
1
+ {"version":3,"file":"NodeContextMenu.d.ts","sourceRoot":"","sources":["../../../../../src/misc/context-menu/NodeContextMenu.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAGlE,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,SAAS,EACT,MAAM,EACN,QAAQ,EACR,eAAe,EACf,OAAO,EACP,EAAE,EACF,uBAA8B,EAC9B,iBAKC,GACF,EAAE,oBAAoB,kDAkItB"}
package/lib/esm/index.js CHANGED
@@ -5516,7 +5516,7 @@ function DefaultContextMenu({ open, clientPos, handlers, registry, nodeIds, enab
5516
5516
  !handlers.onRedo && jsx("div", { className: "h-px bg-gray-200 my-1" }), jsxs("div", { className: "px-2 py-1 font-semibold text-gray-700", children: ["Add Node", " ", jsxs("span", { className: "text-gray-500 font-normal", children: ["(", totalCount, ")"] })] }), jsx("div", { className: "px-2 pb-1", children: jsx("input", { ref: inputRef, type: "text", value: query, onChange: (e) => setQuery(e.target.value), placeholder: "Filter nodes...", className: "w-full border border-gray-300 rounded px-2 py-1 text-sm outline-none focus:border-gray-400 select-text", onClick: (e) => e.stopPropagation(), onMouseDown: (e) => e.stopPropagation(), onWheel: (e) => e.stopPropagation() }) }), jsx("div", { className: "max-h-60 overflow-auto", children: totalCount > 0 ? (renderTree(root)) : (jsx("div", { className: "px-3 py-2 text-gray-400", children: "No matches" })) })] }));
5517
5517
  }
5518
5518
 
5519
- function NodeContextMenu({ open, clientPos, nodeId, handlers, bakeableOutputs, runMode, enableKeyboardShortcuts = true, keyboardShortcuts = {
5519
+ function NodeContextMenu({ open, clientPos, nodeId, handlers, bakeableOutputs, runMode, wb, enableKeyboardShortcuts = true, keyboardShortcuts = {
5520
5520
  copy: "⌘/Ctrl + C",
5521
5521
  duplicate: "⌘/Ctrl + E",
5522
5522
  duplicateWithEdges: "⌘/Ctrl + Shift + E",
@@ -5550,6 +5550,10 @@ function NodeContextMenu({ open, clientPos, nodeId, handlers, bakeableOutputs, r
5550
5550
  }, [open]);
5551
5551
  if (!open || !clientPos || !nodeId)
5552
5552
  return null;
5553
+ // Determine if this is a start node (no inbound edges)
5554
+ const isStartNode = wb
5555
+ ? !wb.def.edges.some((e) => e.target.nodeId === nodeId)
5556
+ : false;
5553
5557
  // clamp
5554
5558
  const MENU_MIN_WIDTH = 180;
5555
5559
  const PADDING = 16;
@@ -5559,7 +5563,7 @@ function NodeContextMenu({ open, clientPos, nodeId, handlers, bakeableOutputs, r
5559
5563
  return (jsxs("div", { ref: ref, tabIndex: -1, className: "fixed z-[1000] bg-white border border-gray-300 rounded-lg shadow-lg p-1 min-w-[180px] text-sm text-gray-700 select-none", style: { left: x, top: y }, onClick: (e) => e.stopPropagation(), onMouseDown: (e) => e.stopPropagation(), onWheel: (e) => e.stopPropagation(), onContextMenu: (e) => {
5560
5564
  e.preventDefault();
5561
5565
  e.stopPropagation();
5562
- }, children: [jsxs("div", { className: "px-2 py-1 font-semibold text-gray-700", children: ["Node (", nodeId, ")"] }), jsx(ContextMenuButton, { label: "Delete", onClick: handlers.onDelete, shortcut: keyboardShortcuts.delete, enableKeyboardShortcuts: enableKeyboardShortcuts }), jsx(ContextMenuButton, { label: "Duplicate", onClick: handlers.onDuplicate, shortcut: keyboardShortcuts.duplicate, enableKeyboardShortcuts: enableKeyboardShortcuts }), jsx(ContextMenuButton, { label: "Duplicate with edges", onClick: handlers.onDuplicateWithEdges, shortcut: keyboardShortcuts.duplicateWithEdges, enableKeyboardShortcuts: enableKeyboardShortcuts }), runMode === "manual" && (jsxs(Fragment, { children: [handlers.onRunNode && (jsx("button", { className: "block w-full text-left px-2 py-1 hover:bg-gray-100", onClick: handlers.onRunNode, children: "Run node" })), handlers.onRunFromHere && (jsx("button", { className: "block w-full text-left px-2 py-1 hover:bg-gray-100", onClick: handlers.onRunFromHere, children: "Run from here" }))] })), jsx("div", { className: "h-px bg-gray-200 my-1" }), jsx(ContextMenuButton, { label: "Copy", onClick: handlers.onCopy, shortcut: keyboardShortcuts.copy, enableKeyboardShortcuts: enableKeyboardShortcuts }), jsx("button", { className: "block w-full text-left px-2 py-1 hover:bg-gray-100", onClick: handlers.onCopyId, children: "Copy Node ID" }), bakeableOutputs.length > 0 && (jsxs(Fragment, { children: [jsx("div", { className: "h-px bg-gray-200 my-1" }), jsx("div", { className: "px-2 py-1 font-semibold text-gray-700", children: "Bake" }), bakeableOutputs.map((h) => (jsxs("button", { className: "block w-full text-left px-2 py-1 hover:bg-gray-100", onClick: () => handlers.onBake(h), children: ["Bake: ", h] }, h)))] }))] }));
5566
+ }, children: [jsxs("div", { className: "px-2 py-1 font-semibold text-gray-700", children: ["Node (", nodeId, ")"] }), jsx(ContextMenuButton, { label: "Delete", onClick: handlers.onDelete, shortcut: keyboardShortcuts.delete, enableKeyboardShortcuts: enableKeyboardShortcuts }), jsx(ContextMenuButton, { label: "Duplicate", onClick: handlers.onDuplicate, shortcut: keyboardShortcuts.duplicate, enableKeyboardShortcuts: enableKeyboardShortcuts }), jsx(ContextMenuButton, { label: "Duplicate with edges", onClick: handlers.onDuplicateWithEdges, shortcut: keyboardShortcuts.duplicateWithEdges, enableKeyboardShortcuts: enableKeyboardShortcuts }), runMode === "manual" && (jsxs(Fragment, { children: [handlers.onRunNode && (jsx("button", { className: "block w-full text-left px-2 py-1 hover:bg-gray-100", onClick: handlers.onRunNode, children: "Run node" })), handlers.onRunFromHere && (jsx("button", { className: "block w-full text-left px-2 py-1 hover:bg-gray-100", onClick: handlers.onRunFromHere, children: isStartNode ? "Run workflow" : "Run from here" }))] })), jsx("div", { className: "h-px bg-gray-200 my-1" }), jsx(ContextMenuButton, { label: "Copy", onClick: handlers.onCopy, shortcut: keyboardShortcuts.copy, enableKeyboardShortcuts: enableKeyboardShortcuts }), jsx("button", { className: "block w-full text-left px-2 py-1 hover:bg-gray-100", onClick: handlers.onCopyId, children: "Copy Node ID" }), bakeableOutputs.length > 0 && (jsxs(Fragment, { children: [jsx("div", { className: "h-px bg-gray-200 my-1" }), jsx("div", { className: "px-2 py-1 font-semibold text-gray-700", children: "Bake" }), bakeableOutputs.map((h) => (jsxs("button", { className: "block w-full text-left px-2 py-1 hover:bg-gray-100", onClick: () => handlers.onBake(h), children: ["Bake: ", h] }, h)))] }))] }));
5563
5567
  }
5564
5568
 
5565
5569
  function SelectionContextMenu({ open, clientPos, handlers, enableKeyboardShortcuts = true, keyboardShortcuts = {
@@ -5645,7 +5649,56 @@ function useKeyboardShortcutToast() {
5645
5649
  return { toast, showToast, hideToast };
5646
5650
  }
5647
5651
 
5648
- const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, getDefaultNodeSize }, ref) => {
5652
+ const SelectionBoundOverlay = ({ selection, rfInstance }) => {
5653
+ const selectionBounds = useMemo(() => {
5654
+ if (typeof document === "undefined" ||
5655
+ !rfInstance ||
5656
+ selection.nodes.length < 2) {
5657
+ return null;
5658
+ }
5659
+ let bounds = null;
5660
+ for (const nodeId of selection.nodes) {
5661
+ const el = document.querySelector(`.react-flow__node[data-id="${nodeId}"]`);
5662
+ if (!el)
5663
+ continue;
5664
+ const rect = el.getBoundingClientRect();
5665
+ if (!bounds) {
5666
+ bounds = {
5667
+ left: rect.left,
5668
+ top: rect.top,
5669
+ right: rect.right,
5670
+ bottom: rect.bottom,
5671
+ };
5672
+ }
5673
+ else {
5674
+ bounds.left = Math.min(bounds.left, rect.left);
5675
+ bounds.top = Math.min(bounds.top, rect.top);
5676
+ bounds.right = Math.max(bounds.right, rect.right);
5677
+ bounds.bottom = Math.max(bounds.bottom, rect.bottom);
5678
+ }
5679
+ }
5680
+ return bounds;
5681
+ }, [selection.nodes, rfInstance]);
5682
+ if (!selectionBounds || selection.nodes.length < 2) {
5683
+ return null;
5684
+ }
5685
+ const { left, top, right, bottom } = selectionBounds;
5686
+ const width = right - left;
5687
+ const height = bottom - top;
5688
+ return (jsx("div", { style: {
5689
+ position: "fixed",
5690
+ left: `${left}px`,
5691
+ top: `${top}px`,
5692
+ width: `${width}px`,
5693
+ height: `${height}px`,
5694
+ border: "1px dashed #0ea5e9",
5695
+ pointerEvents: "none",
5696
+ zIndex: 4,
5697
+ boxSizing: "border-box",
5698
+ } }));
5699
+ };
5700
+
5701
+ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, getDefaultNodeSize, reactFlowProps }, ref) => {
5649
5702
  const { wb, inputsMap, inputDefaultsMap, outputsMap, outputTypesMap, valuesTick, nodeStatus, edgeStatus, validationByNode, validationByEdge, uiVersion, registryVersion, runner, overrides, runNode, runFromHere, runMode, } = useWorkbenchContext();
5650
5703
  const nodeValidation = validationByNode;
5651
5704
  const edgeValidation = validationByEdge.errors;
@@ -5760,27 +5813,9 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
5760
5813
  }, [uiVersion, ui]);
5761
5814
  const { nodes, edges } = useMemo(() => {
5762
5815
  const sel = wb.getSelection();
5763
- // Merge defaults with inputs for node display (defaults shown in lighter gray)
5764
- const inputsWithDefaults = {};
5765
- for (const n of wb.def.nodes) {
5766
- const nodeInputs = inputsMap[n.nodeId] ?? {};
5767
- const nodeDefaults = inputDefaultsMap[n.nodeId] ?? {};
5768
- const inbound = new Set(wb.def.edges
5769
- .filter((e) => e.target.nodeId === n.nodeId)
5770
- .map((e) => e.target.handle));
5771
- const merged = { ...nodeInputs };
5772
- for (const [h, v] of Object.entries(nodeDefaults)) {
5773
- if (!inbound.has(h) && merged[h] === undefined) {
5774
- merged[h] = v;
5775
- }
5776
- }
5777
- if (Object.keys(merged).length > 0) {
5778
- inputsWithDefaults[n.nodeId] = merged;
5779
- }
5780
- }
5781
5816
  const out = toReactFlow(wb.def, wb.getPositions(), wb.getSizes(), wb.registry, {
5782
5817
  showValues,
5783
- inputs: inputsWithDefaults,
5818
+ inputs: inputsMap,
5784
5819
  inputDefaults: inputDefaultsMap,
5785
5820
  outputs: outputsMap,
5786
5821
  resolveNodeType,
@@ -5899,13 +5934,7 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
5899
5934
  resolveNodeType,
5900
5935
  ]);
5901
5936
  const throttled = useThrottledValue({ nodes, edges }, 100);
5902
- const [menuOpen, setMenuOpen] = useState(false);
5903
- const [menuPos, setMenuPos] = useState(null);
5904
- const [nodeMenuOpen, setNodeMenuOpen] = useState(false);
5905
- const [nodeMenuPos, setNodeMenuPos] = useState(null);
5906
- const [nodeAtMenu, setNodeAtMenu] = useState(null);
5907
- const [selectionMenuPos, setSelectionMenuPos] = useState(null);
5908
- const [selectionMenuOpen, setSelectionMenuOpen] = useState(false);
5937
+ const [menuState, setMenuState] = useState(null);
5909
5938
  // Compute the rectangular screen-space bounds of the current selection
5910
5939
  const getSelectionScreenBounds = () => {
5911
5940
  if (typeof document === "undefined")
@@ -5946,31 +5975,24 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
5946
5975
  if (target) {
5947
5976
  // Resolve node id from data-id attribute React Flow sets
5948
5977
  const nodeId = target.getAttribute("data-id");
5949
- const isSelected = nodeId && selection.nodes.includes(nodeId);
5950
- if (isSelected && isSingleNodeSelected) {
5951
- // Right-clicked on the single selected node - show node menu
5952
- setNodeAtMenu(nodeId);
5953
- setNodeMenuPos({ x: e.clientX, y: e.clientY });
5954
- setNodeMenuOpen(true);
5955
- setMenuOpen(false);
5956
- setSelectionMenuOpen(false);
5978
+ if (!nodeId)
5957
5979
  return;
5958
- }
5959
- else if (isSelected) {
5980
+ const isSelected = selection.nodes.includes(nodeId);
5981
+ if (isSelected && !isSingleNodeSelected) {
5960
5982
  // Right-clicked on a node that's part of multi-selection - show selection menu
5961
- setSelectionMenuPos({ x: e.clientX, y: e.clientY });
5962
- setSelectionMenuOpen(true);
5963
- setMenuOpen(false);
5964
- setNodeMenuOpen(false);
5983
+ setMenuState({
5984
+ type: "selection",
5985
+ menuPos: { x: e.clientX, y: e.clientY },
5986
+ });
5965
5987
  return;
5966
5988
  }
5967
5989
  else {
5968
5990
  // Right-clicked on a non-selected node - show node menu
5969
- setNodeAtMenu(nodeId);
5970
- setNodeMenuPos({ x: e.clientX, y: e.clientY });
5971
- setNodeMenuOpen(true);
5972
- setMenuOpen(false);
5973
- setSelectionMenuOpen(false);
5991
+ setMenuState({
5992
+ type: "node",
5993
+ menuPos: { x: e.clientX, y: e.clientY },
5994
+ nodeId,
5995
+ });
5974
5996
  return;
5975
5997
  }
5976
5998
  }
@@ -5982,32 +6004,22 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
5982
6004
  if (isSelected && isSingleNodeSelected) {
5983
6005
  // Right-clicked on an edge, but only one node is selected - show node menu
5984
6006
  const nodeId = selection.nodes[0];
5985
- setNodeAtMenu(nodeId);
5986
- setNodeMenuPos({ x: e.clientX, y: e.clientY });
5987
- setNodeMenuOpen(true);
5988
- setMenuOpen(false);
5989
- setSelectionMenuOpen(false);
6007
+ setMenuState({
6008
+ type: "node",
6009
+ menuPos: { x: e.clientX, y: e.clientY },
6010
+ nodeId,
6011
+ });
5990
6012
  return;
5991
6013
  }
5992
6014
  else if (isSelected) {
5993
6015
  // Right-clicked on a selected edge with multiple nodes - show selection menu
5994
- setSelectionMenuPos({ x: e.clientX, y: e.clientY });
5995
- setSelectionMenuOpen(true);
5996
- setMenuOpen(false);
5997
- setNodeMenuOpen(false);
6016
+ setMenuState({
6017
+ type: "selection",
6018
+ menuPos: { x: e.clientX, y: e.clientY },
6019
+ });
5998
6020
  return;
5999
6021
  }
6000
6022
  }
6001
- // If only one node is selected (even with edges), show node menu for empty space clicks
6002
- if (isSingleNodeSelected) {
6003
- const nodeId = selection.nodes[0];
6004
- setNodeAtMenu(nodeId);
6005
- setNodeMenuPos({ x: e.clientX, y: e.clientY });
6006
- setNodeMenuOpen(true);
6007
- setMenuOpen(false);
6008
- setSelectionMenuOpen(false);
6009
- return;
6010
- }
6011
6023
  // Check if the cursor is inside the rectangular bounds of the current selection
6012
6024
  // (for multi-selection when right-clicking on empty space within selection bounds)
6013
6025
  const selectionBounds = getSelectionScreenBounds();
@@ -6017,28 +6029,38 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
6017
6029
  e.clientX <= right &&
6018
6030
  e.clientY >= top &&
6019
6031
  e.clientY <= bottom) {
6020
- setSelectionMenuPos({ x: e.clientX, y: e.clientY });
6021
- setSelectionMenuOpen(true);
6022
- setMenuOpen(false);
6023
- setNodeMenuOpen(false);
6032
+ // If only one node is selected (even with edges), show node menu for empty space clicks
6033
+ if (isSingleNodeSelected) {
6034
+ const nodeId = selection.nodes[0];
6035
+ setMenuState({
6036
+ type: "node",
6037
+ menuPos: { x: e.clientX, y: e.clientY },
6038
+ nodeId,
6039
+ });
6040
+ return;
6041
+ }
6042
+ setMenuState({
6043
+ type: "selection",
6044
+ menuPos: { x: e.clientX, y: e.clientY },
6045
+ });
6024
6046
  return;
6025
6047
  }
6026
6048
  }
6027
6049
  // Right-clicked on empty space with no selection - show default menu
6028
- setMenuPos({ x: e.clientX, y: e.clientY });
6029
- setMenuOpen(true);
6030
- setNodeMenuOpen(false);
6031
- setSelectionMenuOpen(false);
6050
+ setMenuState({
6051
+ type: "default",
6052
+ menuPos: { x: e.clientX, y: e.clientY },
6053
+ });
6032
6054
  };
6033
6055
  const addNodeAt = useCallback(async (typeId, opts) => wb.addNode({ typeId }, { inputs: opts.inputs, position: opts.position, commit: true }), [wb]);
6034
6056
  const onCloseMenu = useCallback(() => {
6035
- setMenuOpen(false);
6057
+ setMenuState(null);
6036
6058
  }, []);
6037
6059
  const onCloseNodeMenu = useCallback(() => {
6038
- setNodeMenuOpen(false);
6060
+ setMenuState(null);
6039
6061
  }, []);
6040
6062
  const onCloseSelectionMenu = useCallback(() => {
6041
- setSelectionMenuOpen(false);
6063
+ setMenuState(null);
6042
6064
  }, []);
6043
6065
  useEffect(() => {
6044
6066
  const off = wb.on("historyChanged", (event) => {
@@ -6085,8 +6107,9 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
6085
6107
  return baseHandlers;
6086
6108
  }, [wb, runner, overrides, onCloseSelectionMenu]);
6087
6109
  const nodeContextMenuHandlers = useMemo(() => {
6088
- if (!nodeAtMenu)
6110
+ if (menuState?.type !== "node")
6089
6111
  return null;
6112
+ const nodeAtMenu = menuState.nodeId;
6090
6113
  // Get storage from override or use workbench's internal storage
6091
6114
  const storage = overrides?.getCopiedDataStorage
6092
6115
  ? overrides.getCopiedDataStorage()
@@ -6102,7 +6125,7 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
6102
6125
  }
6103
6126
  return baseHandlers;
6104
6127
  }, [
6105
- nodeAtMenu,
6128
+ menuState,
6106
6129
  wb,
6107
6130
  runner,
6108
6131
  wb.registry,
@@ -6115,10 +6138,10 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
6115
6138
  overrides?.getCopiedDataStorage,
6116
6139
  ]);
6117
6140
  const bakeableOutputs = useMemo(() => {
6118
- if (!nodeAtMenu)
6141
+ if (menuState?.type !== "node")
6119
6142
  return [];
6120
- return getBakeableOutputs(nodeAtMenu, wb, wb.registry, outputTypesMap);
6121
- }, [nodeAtMenu, wb, wb.registry, registryVersion, outputTypesMap]);
6143
+ return getBakeableOutputs(menuState.nodeId, wb, wb.registry, outputTypesMap);
6144
+ }, [menuState, wb, wb.registry, registryVersion, outputTypesMap]);
6122
6145
  // Keyboard shortcuts configuration
6123
6146
  const enableKeyboardShortcuts = overrides?.enableKeyboardShortcuts !== false; // Default to true
6124
6147
  const keyboardShortcuts = overrides?.keyboardShortcuts || {
@@ -6188,7 +6211,8 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
6188
6211
  const modKeyLabel = isMac ? "⌘" : "Ctrl";
6189
6212
  showToast(`Copy (${modKeyLabel} + C)`);
6190
6213
  // If single node selected, use node context menu handler; otherwise use selection handler
6191
- if (selection.nodes.length === 1 && nodeContextMenuHandlers?.onCopy) {
6214
+ if (selection.nodes.length === 1 &&
6215
+ nodeContextMenuHandlers?.onCopy) {
6192
6216
  nodeContextMenuHandlers.onCopy();
6193
6217
  }
6194
6218
  else if (selectionContextMenuHandlers.onCopy) {
@@ -6308,21 +6332,25 @@ const WorkbenchCanvas = React.forwardRef(({ showValues, toString, toElement, get
6308
6332
  });
6309
6333
  return () => off();
6310
6334
  }, [wb]);
6311
- return (jsxs("div", { className: "w-full h-full", onContextMenu: onContextMenu, children: [jsx(ReactFlowProvider, { children: jsxs(ReactFlow, { nodes: throttled.nodes, edges: throttled.edges, nodeTypes: nodeTypes, edgeTypes: edgeTypes, connectionLineComponent: connectionLineRenderer, selectionOnDrag: true, onInit: (inst) => {
6312
- rfInstanceRef.current = inst;
6313
- const savedViewport = wb.getViewport();
6314
- if (savedViewport) {
6315
- inst.setViewport(lod.clone(savedViewport));
6316
- }
6317
- }, onConnect: onConnect, onEdgesChange: onEdgesChange, onEdgesDelete: onEdgesDelete, onNodesDelete: onNodesDelete, onNodesChange: onNodesChange, onMoveEnd: onMoveEnd, deleteKeyCode: ["Backspace", "Delete"], proOptions: { hideAttribution: true }, noDragClassName: "wb-nodrag", noWheelClassName: "wb-nowheel", noPanClassName: "wb-nopan", children: [BackgroundRenderer ? (jsx(BackgroundRenderer, {})) : (jsx(Background, { id: "workbench-canvas-background", variant: BackgroundVariant.Dots, gap: 12, size: 1 })), MinimapRenderer ? jsx(MinimapRenderer, {}) : jsx(MiniMap, {}), ControlsRenderer ? jsx(ControlsRenderer, {}) : jsx(Controls, {}), DefaultContextMenuRenderer ? (jsx(DefaultContextMenuRenderer, { open: menuOpen, clientPos: menuPos, handlers: defaultContextMenuHandlers, registry: wb.registry, nodeIds: nodeIds, ...(enableKeyboardShortcuts !== false
6318
- ? { enableKeyboardShortcuts, keyboardShortcuts }
6319
- : {}) })) : (jsx(DefaultContextMenu, { open: menuOpen, clientPos: menuPos, handlers: defaultContextMenuHandlers, registry: wb.registry, nodeIds: nodeIds, enableKeyboardShortcuts: enableKeyboardShortcuts, keyboardShortcuts: keyboardShortcuts })), !!nodeAtMenu &&
6320
- nodeContextMenuHandlers &&
6321
- (NodeContextMenuRenderer ? (jsx(NodeContextMenuRenderer, { open: nodeMenuOpen, clientPos: nodeMenuPos, nodeId: nodeAtMenu, handlers: nodeContextMenuHandlers, bakeableOutputs: bakeableOutputs, runMode: runMode, wb: wb, ...(enableKeyboardShortcuts !== false
6322
- ? { enableKeyboardShortcuts, keyboardShortcuts }
6323
- : {}) })) : (jsx(NodeContextMenu, { open: nodeMenuOpen, clientPos: nodeMenuPos, nodeId: nodeAtMenu, handlers: nodeContextMenuHandlers, bakeableOutputs: bakeableOutputs, runMode: runMode }))), selectionMenuOpen &&
6324
- selectionMenuPos &&
6325
- (SelectionContextMenuRenderer ? (jsx(SelectionContextMenuRenderer, { open: selectionMenuOpen, clientPos: selectionMenuPos, handlers: selectionContextMenuHandlers, enableKeyboardShortcuts: enableKeyboardShortcuts, keyboardShortcuts: keyboardShortcuts })) : (jsx(SelectionContextMenu, { open: selectionMenuOpen, clientPos: selectionMenuPos, handlers: selectionContextMenuHandlers, enableKeyboardShortcuts: enableKeyboardShortcuts, keyboardShortcuts: keyboardShortcuts })))] }) }), toast && (jsx(KeyboardShortcutToast, { message: toast.message, onClose: hideToast }, toast.id))] }));
6335
+ const { onInit: userOnInit, ...restReactFlowProps } = reactFlowProps || {};
6336
+ return (jsxs("div", { className: "w-full h-full", onContextMenu: onContextMenu, children: [jsxs(ReactFlowProvider, { children: [jsxs(ReactFlow, { ...restReactFlowProps, nodes: throttled.nodes, edges: throttled.edges, nodeTypes: nodeTypes, edgeTypes: edgeTypes, connectionLineComponent: connectionLineRenderer, selectionOnDrag: true, onInit: (inst) => {
6337
+ rfInstanceRef.current = inst;
6338
+ const savedViewport = wb.getViewport();
6339
+ if (savedViewport) {
6340
+ inst.setViewport(lod.clone(savedViewport));
6341
+ }
6342
+ if (userOnInit) {
6343
+ userOnInit(inst);
6344
+ }
6345
+ }, onConnect: onConnect, onEdgesChange: onEdgesChange, onEdgesDelete: onEdgesDelete, onNodesDelete: onNodesDelete, onNodesChange: onNodesChange, onMoveEnd: onMoveEnd, deleteKeyCode: ["Backspace", "Delete"], proOptions: { hideAttribution: true }, noDragClassName: "wb-nodrag", noWheelClassName: "wb-nowheel", noPanClassName: "wb-nopan", children: [BackgroundRenderer ? (jsx(BackgroundRenderer, {})) : (jsx(Background, { id: "workbench-canvas-background", variant: BackgroundVariant.Dots, gap: 12, size: 1 })), MinimapRenderer ? jsx(MinimapRenderer, {}) : jsx(MiniMap, {}), ControlsRenderer ? jsx(ControlsRenderer, {}) : jsx(Controls, {}), menuState?.type === "default" &&
6346
+ (DefaultContextMenuRenderer ? (jsx(DefaultContextMenuRenderer, { open: true, clientPos: menuState.menuPos, handlers: defaultContextMenuHandlers, registry: wb.registry, nodeIds: nodeIds, ...(enableKeyboardShortcuts !== false
6347
+ ? { enableKeyboardShortcuts, keyboardShortcuts }
6348
+ : {}) })) : (jsx(DefaultContextMenu, { open: true, clientPos: menuState.menuPos, handlers: defaultContextMenuHandlers, registry: wb.registry, nodeIds: nodeIds, enableKeyboardShortcuts: enableKeyboardShortcuts, keyboardShortcuts: keyboardShortcuts }))), menuState?.type === "node" &&
6349
+ nodeContextMenuHandlers &&
6350
+ (NodeContextMenuRenderer ? (jsx(NodeContextMenuRenderer, { open: true, clientPos: menuState.menuPos, nodeId: menuState.nodeId, handlers: nodeContextMenuHandlers, bakeableOutputs: bakeableOutputs, runMode: runMode, wb: wb, ...(enableKeyboardShortcuts !== false
6351
+ ? { enableKeyboardShortcuts, keyboardShortcuts }
6352
+ : {}) })) : (jsx(NodeContextMenu, { open: true, clientPos: menuState.menuPos, nodeId: menuState.nodeId, handlers: nodeContextMenuHandlers, bakeableOutputs: bakeableOutputs, runMode: runMode }))), menuState?.type === "selection" &&
6353
+ (SelectionContextMenuRenderer ? (jsx(SelectionContextMenuRenderer, { open: true, clientPos: menuState.menuPos, handlers: selectionContextMenuHandlers, enableKeyboardShortcuts: enableKeyboardShortcuts, keyboardShortcuts: keyboardShortcuts })) : (jsx(SelectionContextMenu, { open: true, clientPos: menuState.menuPos, handlers: selectionContextMenuHandlers, enableKeyboardShortcuts: enableKeyboardShortcuts, keyboardShortcuts: keyboardShortcuts })))] }), jsx(SelectionBoundOverlay, { selection: wb.getSelection(), rfInstance: rfInstanceRef.current })] }), toast && (jsx(KeyboardShortcutToast, { message: toast.message, onClose: hideToast }, toast.id))] }));
6326
6354
  });
6327
6355
 
6328
6356
  function WorkbenchStudioCanvas({ autoScroll, onAutoScrollChange, example, onExampleChange, backendKind, onBackendKindChange, httpBaseUrl, onHttpBaseUrlChange, wsUrl, onWsUrlChange, debug, onDebugChange, showValues, onShowValuesChange, hideWorkbench, onHideWorkbenchChange, overrides, onInit, onChange, }) {
@@ -6738,7 +6766,10 @@ function WorkbenchStudioCanvas({ autoScroll, onAutoScrollChange, example, onExam
6738
6766
  }
6739
6767
  }, title: "Select run mode", children: [jsx("option", { value: "manual", children: "Manual" }), jsx("option", { value: "auto", children: "Auto" })] }), renderStartStopButton(), jsx("button", { className: "border border-gray-300 rounded p-1", onClick: runAutoLayout, children: jsx(TreeStructureIcon, { size: 24 }) }), jsx("button", { className: "border border-gray-300 rounded p-1", onClick: () => canvasRef.current?.fitView?.(), title: "Fit View", children: jsx(CornersOutIcon, { size: 24 }) }), jsx("button", { className: "border border-gray-300 rounded p-1", onClick: download$1, children: jsx(DownloadIcon, { size: 24 }) }), jsx("input", { ref: uploadInputRef, type: "file", accept: "application/json,.json", className: "hidden", onChange: onUploadPicked }), jsx("button", { className: "border border-gray-300 rounded p-1", onClick: triggerUpload, children: jsx(UploadIcon, { size: 24 }) }), jsx("button", { className: "border border-gray-300 rounded p-1", onClick: async () => {
6740
6768
  await downloadCanvasThumbnail(canvasContainerRef.current);
6741
- }, title: "Download Flow Thumbnail (SVG)", children: jsx(ImageIcon, { size: 24 }) }), jsxs("label", { className: "flex items-center gap-1", children: [jsx("input", { type: "checkbox", checked: debug, onChange: (e) => onDebugChange(e.target.checked) }), jsx(BugBeetleIcon, { size: 24, weight: debug ? "fill" : undefined })] }), jsxs("label", { className: "flex items-center gap-1", children: [jsx("input", { type: "checkbox", checked: showValues, onChange: (e) => onShowValuesChange(e.target.checked) }), jsx(ListBulletsIcon, { size: 24, weight: showValues ? "fill" : undefined })] })] }), jsxs("div", { className: "flex flex-1 min-h-0", children: [jsx("div", { className: "flex-1 min-w-0", ref: canvasContainerRef, children: jsx(WorkbenchCanvas, { ref: canvasRef, showValues: showValues, toString: toString, toElement: toElement, getDefaultNodeSize: overrides?.getDefaultNodeSize }) }), jsx(Inspector, { setInput: setInput, debug: debug, autoScroll: autoScroll, hideWorkbench: hideWorkbench, onAutoScrollChange: onAutoScrollChange, onHideWorkbenchChange: onHideWorkbenchChange, toString: toString, contextPanel: overrides?.contextPanel })] })] }));
6769
+ }, title: "Download Flow Thumbnail (SVG)", children: jsx(ImageIcon, { size: 24 }) }), jsxs("label", { className: "flex items-center gap-1", children: [jsx("input", { type: "checkbox", checked: debug, onChange: (e) => onDebugChange(e.target.checked) }), jsx(BugBeetleIcon, { size: 24, weight: debug ? "fill" : undefined })] }), jsxs("label", { className: "flex items-center gap-1", children: [jsx("input", { type: "checkbox", checked: showValues, onChange: (e) => onShowValuesChange(e.target.checked) }), jsx(ListBulletsIcon, { size: 24, weight: showValues ? "fill" : undefined })] })] }), jsxs("div", { className: "flex flex-1 min-h-0", children: [jsx("div", { className: "flex-1 min-w-0", ref: canvasContainerRef, children: jsx(WorkbenchCanvas, { ref: canvasRef, showValues: showValues, toString: toString, toElement: toElement, getDefaultNodeSize: overrides?.getDefaultNodeSize, reactFlowProps: {
6770
+ minZoom: 0.1,
6771
+ maxZoom: 5,
6772
+ } }) }), jsx(Inspector, { setInput: setInput, debug: debug, autoScroll: autoScroll, hideWorkbench: hideWorkbench, onAutoScrollChange: onAutoScrollChange, onHideWorkbenchChange: onHideWorkbenchChange, toString: toString, contextPanel: overrides?.contextPanel })] })] }));
6742
6773
  }
6743
6774
  function WorkbenchStudio({ example, onExampleChange, backendKind, onBackendKindChange, httpBaseUrl, onHttpBaseUrlChange, wsUrl, onWsUrlChange, debug, onDebugChange, showValues, onShowValuesChange, hideWorkbench, onHideWorkbenchChange, autoScroll, onAutoScrollChange, backendOptions, overrides, onInit, onChange, }) {
6744
6775
  const [registry, setRegistry] = useState(createSimpleGraphRegistry());