@octaviaflow/core 3.0.18-beta.8 → 3.0.18-beta.9

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 (37) hide show
  1. package/dist/chunk-CEUP4NK2.js +2850 -0
  2. package/dist/chunk-CEUP4NK2.js.map +1 -0
  3. package/dist/chunk-EERNYLFL.js +2860 -0
  4. package/dist/chunk-EERNYLFL.js.map +1 -0
  5. package/dist/chunk-EKFDJX4G.js +2872 -0
  6. package/dist/chunk-EKFDJX4G.js.map +1 -0
  7. package/dist/chunk-GJA3GJUZ.js +2844 -0
  8. package/dist/chunk-GJA3GJUZ.js.map +1 -0
  9. package/dist/chunk-J7YASALS.js +2859 -0
  10. package/dist/chunk-J7YASALS.js.map +1 -0
  11. package/dist/chunk-JIEUYBQT.js +2658 -0
  12. package/dist/chunk-JIEUYBQT.js.map +1 -0
  13. package/dist/chunk-S2SSBMWJ.js +2658 -0
  14. package/dist/chunk-S2SSBMWJ.js.map +1 -0
  15. package/dist/chunk-WEPTBLWX.js +2847 -0
  16. package/dist/chunk-WEPTBLWX.js.map +1 -0
  17. package/dist/chunk-WG4ZQMPS.js +2844 -0
  18. package/dist/chunk-WG4ZQMPS.js.map +1 -0
  19. package/dist/chunk-XEPEBHAW.js +2808 -0
  20. package/dist/chunk-XEPEBHAW.js.map +1 -0
  21. package/dist/chunk-XG2OYFX6.js +2925 -0
  22. package/dist/chunk-XG2OYFX6.js.map +1 -0
  23. package/dist/components/WorkflowHeader/WorkflowHeader.d.ts.map +1 -1
  24. package/dist/index.cjs +736 -441
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.js +6 -5
  27. package/dist/index.js.map +1 -1
  28. package/dist/styles.css +1 -1
  29. package/dist/workflow/components/FlowCanvas/FlowCanvas.d.ts +27 -0
  30. package/dist/workflow/components/FlowCanvas/FlowCanvas.d.ts.map +1 -1
  31. package/dist/workflow/components/kinds/index.d.ts +4 -0
  32. package/dist/workflow/components/kinds/index.d.ts.map +1 -1
  33. package/dist/workflow.cjs +433 -312
  34. package/dist/workflow.cjs.map +1 -1
  35. package/dist/workflow.js +5 -149
  36. package/dist/workflow.js.map +1 -1
  37. package/package.json +1 -1
package/dist/workflow.cjs CHANGED
@@ -961,7 +961,7 @@ function ConfigPanel({
961
961
  }
962
962
 
963
963
  // src/workflow/components/FlowCanvas/FlowCanvas.tsx
964
- var import_react14 = require("react");
964
+ var import_react15 = require("react");
965
965
 
966
966
  // src/workflow/store/createFlowStore.ts
967
967
  var DEFAULT_VIEWPORT = { x: 0, y: 0, zoom: 1 };
@@ -1809,10 +1809,155 @@ function handleSideStyle(side, index, total) {
1809
1809
  }
1810
1810
  }
1811
1811
 
1812
- // src/workflow/components/kinds/BaseNode.tsx
1813
- var import_icons = require("@octaviaflow/icons");
1812
+ // src/workflow/components/NodeResizer/NodeResizer.tsx
1814
1813
  var import_react13 = require("react");
1815
1814
  var import_jsx_runtime5 = require("react/jsx-runtime");
1815
+ function NodeResizer({
1816
+ isVisible,
1817
+ minWidth = 80,
1818
+ minHeight = 60,
1819
+ maxWidth,
1820
+ maxHeight,
1821
+ keepAspectRatio = false,
1822
+ onResize,
1823
+ onResizeEnd,
1824
+ color
1825
+ }) {
1826
+ const { node, selected } = useFlowNodeContext();
1827
+ const viewport = useViewport();
1828
+ const flow = useFlow();
1829
+ const dragRef = (0, import_react13.useRef)(null);
1830
+ const show = isVisible ?? selected;
1831
+ if (!show) return null;
1832
+ const beginResize = (e, corner) => {
1833
+ e.preventDefault();
1834
+ e.stopPropagation();
1835
+ e.target.setPointerCapture(e.pointerId);
1836
+ const w = node.width ?? DEFAULT_NODE_WIDTH;
1837
+ const h = node.height ?? DEFAULT_NODE_HEIGHT;
1838
+ dragRef.current = {
1839
+ pointerId: e.pointerId,
1840
+ corner,
1841
+ startClientX: e.clientX,
1842
+ startClientY: e.clientY,
1843
+ startWidth: w,
1844
+ startHeight: h,
1845
+ startX: node.position.x,
1846
+ startY: node.position.y,
1847
+ aspect: w / Math.max(1, h)
1848
+ };
1849
+ };
1850
+ const onMove = (e) => {
1851
+ const drag = dragRef.current;
1852
+ if (!drag || drag.pointerId !== e.pointerId) return;
1853
+ const dx = (e.clientX - drag.startClientX) / viewport.zoom;
1854
+ const dy = (e.clientY - drag.startClientY) / viewport.zoom;
1855
+ let nextW = drag.startWidth;
1856
+ let nextH = drag.startHeight;
1857
+ let nextX = drag.startX;
1858
+ let nextY = drag.startY;
1859
+ switch (drag.corner) {
1860
+ case "se":
1861
+ nextW = drag.startWidth + dx;
1862
+ nextH = drag.startHeight + dy;
1863
+ break;
1864
+ case "sw":
1865
+ nextW = drag.startWidth - dx;
1866
+ nextH = drag.startHeight + dy;
1867
+ nextX = drag.startX + dx;
1868
+ break;
1869
+ case "ne":
1870
+ nextW = drag.startWidth + dx;
1871
+ nextH = drag.startHeight - dy;
1872
+ nextY = drag.startY + dy;
1873
+ break;
1874
+ case "nw":
1875
+ nextW = drag.startWidth - dx;
1876
+ nextH = drag.startHeight - dy;
1877
+ nextX = drag.startX + dx;
1878
+ nextY = drag.startY + dy;
1879
+ break;
1880
+ }
1881
+ if (keepAspectRatio) {
1882
+ nextH = nextW / drag.aspect;
1883
+ if (drag.corner === "nw" || drag.corner === "ne") {
1884
+ nextY = drag.startY + (drag.startHeight - nextH);
1885
+ }
1886
+ }
1887
+ nextW = Math.max(minWidth, maxWidth ? Math.min(maxWidth, nextW) : nextW);
1888
+ nextH = Math.max(minHeight, maxHeight ? Math.min(maxHeight, nextH) : nextH);
1889
+ flow.updateNode(node.id, {
1890
+ width: nextW,
1891
+ height: nextH,
1892
+ position: { x: nextX, y: nextY }
1893
+ });
1894
+ onResize?.({ width: nextW, height: nextH });
1895
+ };
1896
+ const onUp = (e) => {
1897
+ if (dragRef.current?.pointerId === e.pointerId) {
1898
+ const cur = flow.getNode(node.id);
1899
+ if (cur) {
1900
+ onResizeEnd?.({
1901
+ width: cur.width ?? DEFAULT_NODE_WIDTH,
1902
+ height: cur.height ?? DEFAULT_NODE_HEIGHT
1903
+ });
1904
+ }
1905
+ dragRef.current = null;
1906
+ }
1907
+ };
1908
+ const handleColor = color ?? "var(--ods-accent)";
1909
+ const handleStyle = (corner) => {
1910
+ const base = {
1911
+ position: "absolute",
1912
+ width: 12,
1913
+ height: 12,
1914
+ background: "var(--ods-surface-canvas)",
1915
+ border: `2px solid ${handleColor}`,
1916
+ borderRadius: 2,
1917
+ cursor: cursorFor(corner),
1918
+ touchAction: "none",
1919
+ // Place each handle so its CENTRE sits on the corresponding corner.
1920
+ transform: "translate(-50%, -50%)"
1921
+ };
1922
+ switch (corner) {
1923
+ case "nw":
1924
+ return { ...base, top: 0, left: 0 };
1925
+ case "ne":
1926
+ return { ...base, top: 0, left: "100%" };
1927
+ case "sw":
1928
+ return { ...base, top: "100%", left: 0 };
1929
+ case "se":
1930
+ return { ...base, top: "100%", left: "100%" };
1931
+ }
1932
+ };
1933
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: cn("ods-node-resizer"), "data-flow-no-drag": "true", children: ["nw", "ne", "sw", "se"].map((corner) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1934
+ "div",
1935
+ {
1936
+ style: handleStyle(corner),
1937
+ onPointerDown: (e) => beginResize(e, corner),
1938
+ onPointerMove: onMove,
1939
+ onPointerUp: onUp,
1940
+ onPointerCancel: onUp,
1941
+ "aria-label": `Resize ${corner}`
1942
+ },
1943
+ corner
1944
+ )) });
1945
+ }
1946
+ function cursorFor(corner) {
1947
+ switch (corner) {
1948
+ case "nw":
1949
+ case "se":
1950
+ return "nwse-resize";
1951
+ case "ne":
1952
+ case "sw":
1953
+ return "nesw-resize";
1954
+ }
1955
+ }
1956
+
1957
+ // src/workflow/components/kinds/BaseNode.tsx
1958
+ var import_icons = require("@octaviaflow/icons");
1959
+ var import_react14 = require("react");
1960
+ var import_jsx_runtime6 = require("react/jsx-runtime");
1816
1961
  function BaseNode({
1817
1962
  kind,
1818
1963
  kindIcon,
@@ -1828,10 +1973,10 @@ function BaseNode({
1828
1973
  className,
1829
1974
  children
1830
1975
  }) {
1831
- const ctx = (0, import_react13.useContext)(FlowNodeContext);
1832
- const bridge = (0, import_react13.useContext)(FlowNodeBridgeContext);
1976
+ const ctx = (0, import_react14.useContext)(FlowNodeContext);
1977
+ const bridge = (0, import_react14.useContext)(FlowNodeBridgeContext);
1833
1978
  const deleteHandler = onDelete === false ? void 0 : onDelete ?? (ctx && bridge ? () => bridge.deleteNode(ctx.id) : void 0);
1834
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1979
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1835
1980
  "div",
1836
1981
  {
1837
1982
  className: cn(
@@ -1841,31 +1986,31 @@ function BaseNode({
1841
1986
  className
1842
1987
  ),
1843
1988
  children: [
1844
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "ods-flow-base-node__pill", children: [
1845
- kindIcon && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "ods-flow-base-node__pill-icon", "aria-hidden": "true", children: kindIcon }),
1846
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "ods-flow-base-node__pill-label", children: kind })
1989
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "ods-flow-base-node__pill", children: [
1990
+ kindIcon && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "ods-flow-base-node__pill-icon", "aria-hidden": "true", children: kindIcon }),
1991
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "ods-flow-base-node__pill-label", children: kind })
1847
1992
  ] }),
1848
- status && status !== "idle" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1993
+ status && status !== "idle" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1849
1994
  "span",
1850
1995
  {
1851
1996
  className: cn("ods-flow-base-node__status", `ods-flow-base-node__status--${status}`),
1852
1997
  "aria-hidden": "true"
1853
1998
  }
1854
1999
  ),
1855
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "ods-flow-base-node__body", children: [
1856
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "ods-flow-base-node__content", children: [
1857
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "ods-flow-base-node__bubble", "aria-hidden": "true", children: icon }),
1858
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "ods-flow-base-node__content-text", children: [
1859
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "ods-flow-base-node__content-title", children: title }),
1860
- (chip !== void 0 || description !== void 0 || valueChip !== void 0) && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "ods-flow-base-node__content-info", children: [
1861
- chip !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "ods-flow-base-node__chip", children: chip }),
1862
- description !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "ods-flow-base-node__description", children: description }),
1863
- valueChip !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "ods-flow-base-node__value-chip", children: valueChip })
2000
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "ods-flow-base-node__body", children: [
2001
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "ods-flow-base-node__content", children: [
2002
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "ods-flow-base-node__bubble", "aria-hidden": "true", children: icon }),
2003
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "ods-flow-base-node__content-text", children: [
2004
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "ods-flow-base-node__content-title", children: title }),
2005
+ (chip !== void 0 || description !== void 0 || valueChip !== void 0) && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "ods-flow-base-node__content-info", children: [
2006
+ chip !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "ods-flow-base-node__chip", children: chip }),
2007
+ description !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "ods-flow-base-node__description", children: description }),
2008
+ valueChip !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "ods-flow-base-node__value-chip", children: valueChip })
1864
2009
  ] })
1865
2010
  ] })
1866
2011
  ] }),
1867
- footer && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "ods-flow-base-node__footer", children: footer }),
1868
- deleteHandler && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2012
+ footer && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "ods-flow-base-node__footer", children: footer }),
2013
+ deleteHandler && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1869
2014
  "button",
1870
2015
  {
1871
2016
  type: "button",
@@ -1877,7 +2022,7 @@ function BaseNode({
1877
2022
  "aria-label": "Delete node",
1878
2023
  "data-flow-no-drag": "true",
1879
2024
  title: "Delete node",
1880
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons.TrashCanIcon, { size: 16, "aria-hidden": true })
2025
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_icons.TrashCanIcon, { size: 16, "aria-hidden": true })
1881
2026
  }
1882
2027
  )
1883
2028
  ] }),
@@ -1888,12 +2033,12 @@ function BaseNode({
1888
2033
  }
1889
2034
 
1890
2035
  // src/workflow/components/kinds/index.tsx
1891
- var import_jsx_runtime6 = require("react/jsx-runtime");
2036
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1892
2037
  var ActionNode = ({
1893
2038
  node
1894
2039
  }) => {
1895
2040
  const d = node.data ?? {};
1896
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2041
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1897
2042
  BaseNode,
1898
2043
  {
1899
2044
  kind: d.kind ?? "ACTION",
@@ -1905,8 +2050,8 @@ var ActionNode = ({
1905
2050
  status: d.status,
1906
2051
  accent: "green",
1907
2052
  children: [
1908
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Handle, { type: "target", position: "top" }),
1909
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Handle, { type: "source", position: "bottom" })
2053
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "target", position: "top" }),
2054
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "source", position: "bottom" })
1910
2055
  ]
1911
2056
  }
1912
2057
  );
@@ -1915,7 +2060,7 @@ var TriggerNode = ({
1915
2060
  node
1916
2061
  }) => {
1917
2062
  const d = node.data ?? {};
1918
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2063
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1919
2064
  BaseNode,
1920
2065
  {
1921
2066
  kind: d.kind ?? "TRIGGER",
@@ -1926,7 +2071,7 @@ var TriggerNode = ({
1926
2071
  valueChip: d.valueChip,
1927
2072
  status: d.status,
1928
2073
  accent: "green",
1929
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Handle, { type: "source", position: "bottom" })
2074
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "source", position: "bottom" })
1930
2075
  }
1931
2076
  );
1932
2077
  };
@@ -1938,7 +2083,7 @@ var ConditionNode = ({
1938
2083
  { id: "true", label: "true" },
1939
2084
  { id: "false", label: "false" }
1940
2085
  ];
1941
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2086
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1942
2087
  BaseNode,
1943
2088
  {
1944
2089
  kind: d.kind ?? "CONDITION",
@@ -1950,8 +2095,8 @@ var ConditionNode = ({
1950
2095
  status: d.status,
1951
2096
  accent: "amber",
1952
2097
  children: [
1953
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Handle, { type: "target", position: "top" }),
1954
- branches.map((b, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2098
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "target", position: "top" }),
2099
+ branches.map((b, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1955
2100
  Handle,
1956
2101
  {
1957
2102
  type: "source",
@@ -1972,24 +2117,27 @@ var GroupNode = ({
1972
2117
  }) => {
1973
2118
  const d = node.data ?? {};
1974
2119
  const collapsed = !!d.collapsed;
2120
+ const disabled = !!d.disabled;
1975
2121
  const hiddenCount = d.hiddenCount;
1976
2122
  const bridge = useFlowNodeBridge();
1977
2123
  const onChevronClick = (e) => {
1978
2124
  e.stopPropagation();
1979
2125
  bridge.toggleNodeCollapse(node.id);
1980
2126
  };
1981
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2127
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1982
2128
  "div",
1983
2129
  {
1984
2130
  className: "ods-flow-group",
1985
2131
  "data-collapsed": collapsed ? "true" : "false",
2132
+ "data-disabled": disabled ? "true" : void 0,
1986
2133
  style: {
1987
2134
  width: node.width ?? 360,
1988
2135
  height: collapsed ? 36 : node.height ?? 200
1989
2136
  },
1990
2137
  children: [
1991
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "ods-flow-group__header", "data-flow-no-drag": "false", children: [
1992
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2138
+ !collapsed && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(NodeResizer, { minWidth: 240, minHeight: 120 }),
2139
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "ods-flow-group__header", "data-flow-no-drag": "false", children: [
2140
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1993
2141
  "button",
1994
2142
  {
1995
2143
  type: "button",
@@ -2002,15 +2150,16 @@ var GroupNode = ({
2002
2150
  children: collapsed ? "\u25B8" : "\u25BE"
2003
2151
  }
2004
2152
  ),
2005
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "ods-flow-group__title", children: d.title ?? "Group" }),
2006
- d.subtitle && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "ods-flow-group__subtitle", children: d.subtitle }),
2007
- collapsed && hiddenCount !== void 0 && hiddenCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "ods-flow-group__count", "aria-label": `${hiddenCount} hidden steps`, children: [
2153
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ods-flow-group__title", children: d.title ?? "Group" }),
2154
+ d.subtitle && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ods-flow-group__subtitle", children: d.subtitle }),
2155
+ disabled && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ods-flow-group__disabled-badge", "aria-label": "Disabled subflow", children: "Disabled" }),
2156
+ collapsed && hiddenCount !== void 0 && hiddenCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "ods-flow-group__count", "aria-label": `${hiddenCount} hidden steps`, children: [
2008
2157
  hiddenCount,
2009
2158
  " steps"
2010
2159
  ] })
2011
2160
  ] }),
2012
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Handle, { type: "target", position: "top", id: "__group_in" }),
2013
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Handle, { type: "source", position: "bottom", id: "__group_out" })
2161
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "target", position: "top", id: "__group_in" }),
2162
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "source", position: "bottom", id: "__group_out" })
2014
2163
  ]
2015
2164
  }
2016
2165
  );
@@ -2021,24 +2170,27 @@ var ForEachNode = ({
2021
2170
  const d = node.data ?? {};
2022
2171
  const iteratorExpr = d.iterator ?? d.description ?? "items[]";
2023
2172
  const collapsed = !!d.collapsed;
2173
+ const disabled = !!d.disabled;
2024
2174
  const hiddenCount = d.hiddenCount;
2025
2175
  const bridge = useFlowNodeBridge();
2026
2176
  const onChevronClick = (e) => {
2027
2177
  e.stopPropagation();
2028
2178
  bridge.toggleNodeCollapse(node.id);
2029
2179
  };
2030
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2180
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2031
2181
  "div",
2032
2182
  {
2033
2183
  className: "ods-flow-foreach",
2034
2184
  "data-collapsed": collapsed ? "true" : "false",
2185
+ "data-disabled": disabled ? "true" : void 0,
2035
2186
  style: {
2036
2187
  width: node.width ?? 420,
2037
2188
  height: collapsed ? 40 : node.height ?? 260
2038
2189
  },
2039
2190
  children: [
2040
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "ods-flow-foreach__header", children: [
2041
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2191
+ !collapsed && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(NodeResizer, { minWidth: 240, minHeight: 120 }),
2192
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "ods-flow-foreach__header", children: [
2193
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2042
2194
  "button",
2043
2195
  {
2044
2196
  type: "button",
@@ -2051,24 +2203,57 @@ var ForEachNode = ({
2051
2203
  children: collapsed ? "\u25B8" : "\u25BE"
2052
2204
  }
2053
2205
  ),
2054
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "ods-flow-foreach__icon", "aria-hidden": "true", children: "\u21BB" }),
2055
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "ods-flow-foreach__title", children: d.title ?? "For each" }),
2056
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { className: "ods-flow-foreach__iterator", children: iteratorExpr }),
2057
- collapsed && hiddenCount !== void 0 && hiddenCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "ods-flow-foreach__count", "aria-label": `${hiddenCount} hidden steps`, children: [
2206
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ods-flow-foreach__icon", "aria-hidden": "true", children: "\u21BB" }),
2207
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ods-flow-foreach__title", children: d.title ?? "For each" }),
2208
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("code", { className: "ods-flow-foreach__iterator", children: iteratorExpr }),
2209
+ disabled && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2210
+ "span",
2211
+ {
2212
+ className: "ods-flow-foreach__disabled-badge",
2213
+ "aria-label": "Disabled subflow",
2214
+ children: "Disabled"
2215
+ }
2216
+ ),
2217
+ collapsed && hiddenCount !== void 0 && hiddenCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "ods-flow-foreach__count", "aria-label": `${hiddenCount} hidden steps`, children: [
2058
2218
  hiddenCount,
2059
2219
  " steps"
2060
2220
  ] })
2061
2221
  ] }),
2062
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Handle, { type: "target", position: "top", id: "__group_in" }),
2063
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Handle, { type: "source", position: "bottom", id: "__group_out" }),
2064
- !collapsed && // Expanded mode full 3-handle iterator surface (in / item / done).
2065
- // `in` shares the top edge with `__group_in`; consumers wiring an
2066
- // explicit `targetHandle: "in"` get the labelled, visible variant.
2067
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
2068
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Handle, { type: "target", position: "top", id: "in", label: "in" }),
2069
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Handle, { type: "source", position: "right", id: "item", label: "item" }),
2070
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Handle, { type: "source", position: "bottom", id: "done", label: "done" })
2071
- ] })
2222
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "target", position: "top", id: "__group_in", label: !collapsed ? "in" : void 0 }),
2223
+ collapsed ? (
2224
+ // Collapsed: single bottom exit so the container behaves like a
2225
+ // regular action in the chain.
2226
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "source", position: "bottom", id: "__group_out" })
2227
+ ) : (
2228
+ // Expanded: two bottom outputs spread across the bottom edge.
2229
+ // Index/total tell the Handle to position them at 33% and 66%
2230
+ // along the edge (per `handleSideStyle`). `each` is left of
2231
+ // centre, `__group_out` (labelled "done") is right of centre.
2232
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
2233
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2234
+ Handle,
2235
+ {
2236
+ type: "source",
2237
+ position: "bottom",
2238
+ id: "each",
2239
+ label: "each",
2240
+ index: 0,
2241
+ total: 2
2242
+ }
2243
+ ),
2244
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2245
+ Handle,
2246
+ {
2247
+ type: "source",
2248
+ position: "bottom",
2249
+ id: "__group_out",
2250
+ label: "done",
2251
+ index: 1,
2252
+ total: 2
2253
+ }
2254
+ )
2255
+ ] })
2256
+ )
2072
2257
  ]
2073
2258
  }
2074
2259
  );
@@ -2077,7 +2262,7 @@ var OutputNode = ({
2077
2262
  node
2078
2263
  }) => {
2079
2264
  const d = node.data ?? {};
2080
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2265
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2081
2266
  BaseNode,
2082
2267
  {
2083
2268
  kind: d.kind ?? "OUTPUT",
@@ -2087,7 +2272,7 @@ var OutputNode = ({
2087
2272
  description: d.description ?? d.subtitle,
2088
2273
  status: d.status,
2089
2274
  accent: "green",
2090
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Handle, { type: "target", position: "top" })
2275
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "target", position: "top" })
2091
2276
  }
2092
2277
  );
2093
2278
  };
@@ -2095,7 +2280,7 @@ var ErrorNode = ({
2095
2280
  node
2096
2281
  }) => {
2097
2282
  const d = node.data ?? {};
2098
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2283
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2099
2284
  BaseNode,
2100
2285
  {
2101
2286
  kind: d.kind ?? "ERROR",
@@ -2106,8 +2291,8 @@ var ErrorNode = ({
2106
2291
  status: d.status ?? "error",
2107
2292
  accent: "red",
2108
2293
  children: [
2109
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Handle, { type: "target", position: "top" }),
2110
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Handle, { type: "source", position: "bottom" })
2294
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "target", position: "top" }),
2295
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "source", position: "bottom" })
2111
2296
  ]
2112
2297
  }
2113
2298
  );
@@ -2118,7 +2303,7 @@ var WaitNode = ({
2118
2303
  const d = node.data ?? {};
2119
2304
  const waitMs = d.waitMs;
2120
2305
  const durationChip = waitMs ? `${Math.round(waitMs / 100) / 10}s` : void 0;
2121
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2306
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2122
2307
  BaseNode,
2123
2308
  {
2124
2309
  kind: d.kind ?? "WAIT",
@@ -2129,8 +2314,8 @@ var WaitNode = ({
2129
2314
  status: d.status,
2130
2315
  accent: "violet",
2131
2316
  children: [
2132
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Handle, { type: "target", position: "top" }),
2133
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Handle, { type: "source", position: "bottom" })
2317
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "target", position: "top" }),
2318
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "source", position: "bottom" })
2134
2319
  ]
2135
2320
  }
2136
2321
  );
@@ -2143,7 +2328,7 @@ var ParallelNode = ({
2143
2328
  { id: "a", label: "a" },
2144
2329
  { id: "b", label: "b" }
2145
2330
  ];
2146
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2331
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2147
2332
  BaseNode,
2148
2333
  {
2149
2334
  kind: d.kind ?? "PARALLEL",
@@ -2154,8 +2339,8 @@ var ParallelNode = ({
2154
2339
  status: d.status,
2155
2340
  accent: "blue",
2156
2341
  children: [
2157
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Handle, { type: "target", position: "top" }),
2158
- branches.map((b, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2342
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "target", position: "top" }),
2343
+ branches.map((b, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2159
2344
  Handle,
2160
2345
  {
2161
2346
  type: "source",
@@ -2175,7 +2360,7 @@ var StickyNode = ({
2175
2360
  node
2176
2361
  }) => {
2177
2362
  const d = node.data ?? {};
2178
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2363
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2179
2364
  "div",
2180
2365
  {
2181
2366
  className: "ods-flow-sticky",
@@ -2184,8 +2369,8 @@ var StickyNode = ({
2184
2369
  minHeight: node.height ?? 120
2185
2370
  },
2186
2371
  children: [
2187
- d.title && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "ods-flow-sticky__title", children: d.title }),
2188
- d.description && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "ods-flow-sticky__body", children: d.description })
2372
+ d.title && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "ods-flow-sticky__title", children: d.title }),
2373
+ d.description && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "ods-flow-sticky__body", children: d.description })
2189
2374
  ]
2190
2375
  }
2191
2376
  );
@@ -2194,7 +2379,7 @@ var WebhookNode = ({
2194
2379
  node
2195
2380
  }) => {
2196
2381
  const d = node.data ?? {};
2197
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2382
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2198
2383
  BaseNode,
2199
2384
  {
2200
2385
  kind: d.kind ?? "WEBHOOK",
@@ -2205,7 +2390,7 @@ var WebhookNode = ({
2205
2390
  valueChip: d.valueChip,
2206
2391
  status: d.status,
2207
2392
  accent: "blue",
2208
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Handle, { type: "source", position: "bottom" })
2393
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "source", position: "bottom" })
2209
2394
  }
2210
2395
  );
2211
2396
  };
@@ -2213,7 +2398,7 @@ var HttpRequestNode = ({
2213
2398
  node
2214
2399
  }) => {
2215
2400
  const d = node.data ?? {};
2216
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2401
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2217
2402
  BaseNode,
2218
2403
  {
2219
2404
  kind: d.kind ?? "HTTP",
@@ -2225,8 +2410,8 @@ var HttpRequestNode = ({
2225
2410
  status: d.status,
2226
2411
  accent: "blue",
2227
2412
  children: [
2228
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Handle, { type: "target", position: "top" }),
2229
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Handle, { type: "source", position: "bottom" })
2413
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "target", position: "top" }),
2414
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "source", position: "bottom" })
2230
2415
  ]
2231
2416
  }
2232
2417
  );
@@ -2247,7 +2432,7 @@ var DEFAULT_NODE_KINDS = {
2247
2432
  };
2248
2433
 
2249
2434
  // src/workflow/components/FlowCanvas/FlowCanvas.tsx
2250
- var import_jsx_runtime7 = require("react/jsx-runtime");
2435
+ var import_jsx_runtime8 = require("react/jsx-runtime");
2251
2436
  var DEFAULT_VIEWPORT2 = { x: 0, y: 0, zoom: 1 };
2252
2437
  function FlowCanvas(props) {
2253
2438
  const viewportPropProvided = props.viewport !== void 0 || props.defaultViewport !== void 0;
@@ -2289,6 +2474,9 @@ function FlowCanvas(props) {
2289
2474
  snapToGrid = false,
2290
2475
  nodeCollisionGap = -1,
2291
2476
  subflowCollisionGap,
2477
+ reparentOnDrag = false,
2478
+ autoResizeContainers = false,
2479
+ containerAutoResizePadding = 32,
2292
2480
  height = "100%",
2293
2481
  width = "100%",
2294
2482
  className,
@@ -2303,46 +2491,46 @@ function FlowCanvas(props) {
2303
2491
  };
2304
2492
  const panOnDrag = panOnDragProp ?? presetDefaults[preset].panOnDrag;
2305
2493
  const zoomOnScroll = zoomOnScrollProp ?? presetDefaults[preset].zoomOnScroll;
2306
- const store = (0, import_react14.useState)(
2494
+ const store = (0, import_react15.useState)(
2307
2495
  () => createFlowStore({
2308
2496
  initialNodes: nodes,
2309
2497
  initialEdges: edges,
2310
2498
  initialViewport: controlledViewport ?? defaultViewport
2311
2499
  })
2312
2500
  )[0];
2313
- const handleRegistry = (0, import_react14.useState)(() => createHandleRegistry())[0];
2314
- const [handleVersion, setHandleVersion] = (0, import_react14.useState)(0);
2315
- (0, import_react14.useEffect)(() => {
2501
+ const handleRegistry = (0, import_react15.useState)(() => createHandleRegistry())[0];
2502
+ const [handleVersion, setHandleVersion] = (0, import_react15.useState)(0);
2503
+ (0, import_react15.useEffect)(() => {
2316
2504
  const unsub = handleRegistry.subscribe(() => {
2317
2505
  setHandleVersion((v) => v + 1);
2318
2506
  });
2319
2507
  return unsub;
2320
2508
  }, [handleRegistry]);
2321
- const kinds = (0, import_react14.useMemo)(() => buildNodeKindRegistry(DEFAULT_NODE_KINDS, nodeKinds), [nodeKinds]);
2322
- const containerRef = (0, import_react14.useRef)(null);
2323
- (0, import_react14.useEffect)(() => store.setNodes(nodes), [store, nodes]);
2324
- (0, import_react14.useEffect)(() => store.setEdges(edges), [store, edges]);
2325
- const [uncontrolledVp, setUncontrolledVp] = (0, import_react14.useState)(controlledViewport ?? defaultViewport);
2509
+ const kinds = (0, import_react15.useMemo)(() => buildNodeKindRegistry(DEFAULT_NODE_KINDS, nodeKinds), [nodeKinds]);
2510
+ const containerRef = (0, import_react15.useRef)(null);
2511
+ (0, import_react15.useEffect)(() => store.setNodes(nodes), [store, nodes]);
2512
+ (0, import_react15.useEffect)(() => store.setEdges(edges), [store, edges]);
2513
+ const [uncontrolledVp, setUncontrolledVp] = (0, import_react15.useState)(controlledViewport ?? defaultViewport);
2326
2514
  const viewport = controlledViewport ?? uncontrolledVp;
2327
- (0, import_react14.useEffect)(() => store.setViewport(viewport), [store, viewport]);
2328
- const setViewport = (0, import_react14.useCallback)(
2515
+ (0, import_react15.useEffect)(() => store.setViewport(viewport), [store, viewport]);
2516
+ const setViewport = (0, import_react15.useCallback)(
2329
2517
  (next) => {
2330
2518
  if (controlledViewport === void 0) setUncontrolledVp(next);
2331
2519
  onViewportChange?.(next);
2332
2520
  },
2333
2521
  [controlledViewport, onViewportChange]
2334
2522
  );
2335
- const selectedNodeIds = (0, import_react14.useMemo)(() => {
2523
+ const selectedNodeIds = (0, import_react15.useMemo)(() => {
2336
2524
  const s = /* @__PURE__ */ new Set();
2337
2525
  for (const n of nodes) if (n.selected) s.add(n.id);
2338
2526
  return s;
2339
2527
  }, [nodes]);
2340
- const selectedEdgeIds = (0, import_react14.useMemo)(() => {
2528
+ const selectedEdgeIds = (0, import_react15.useMemo)(() => {
2341
2529
  const s = /* @__PURE__ */ new Set();
2342
2530
  for (const e of edges) if (e.selected) s.add(e.id);
2343
2531
  return s;
2344
2532
  }, [edges]);
2345
- (0, import_react14.useEffect)(() => {
2533
+ (0, import_react15.useEffect)(() => {
2346
2534
  store.setSelection(selectedNodeIds, selectedEdgeIds);
2347
2535
  if (onSelectionChange) {
2348
2536
  onSelectionChange({
@@ -2351,7 +2539,7 @@ function FlowCanvas(props) {
2351
2539
  });
2352
2540
  }
2353
2541
  }, [store, selectedNodeIds, selectedEdgeIds, nodes, edges, onSelectionChange]);
2354
- const selectNode = (0, import_react14.useCallback)(
2542
+ const selectNode = (0, import_react15.useCallback)(
2355
2543
  (id, additive) => {
2356
2544
  const next = [];
2357
2545
  const nextEdges = [];
@@ -2374,14 +2562,14 @@ function FlowCanvas(props) {
2374
2562
  },
2375
2563
  [nodes, edges, selectedNodeIds, onNodesChange, onEdgesChange]
2376
2564
  );
2377
- const notifyNodeClick = (0, import_react14.useCallback)(
2565
+ const notifyNodeClick = (0, import_react15.useCallback)(
2378
2566
  (id) => {
2379
2567
  const node = nodes.find((n) => n.id === id);
2380
2568
  if (node) onNodeClick?.(node);
2381
2569
  },
2382
2570
  [nodes, onNodeClick]
2383
2571
  );
2384
- const selectEdge = (0, import_react14.useCallback)(
2572
+ const selectEdge = (0, import_react15.useCallback)(
2385
2573
  (id, additive) => {
2386
2574
  const next = [];
2387
2575
  const nextNodes = [];
@@ -2406,7 +2594,7 @@ function FlowCanvas(props) {
2406
2594
  },
2407
2595
  [nodes, edges, selectedEdgeIds, onEdgesChange, onNodesChange, onEdgeClick]
2408
2596
  );
2409
- const clearSelection = (0, import_react14.useCallback)(() => {
2597
+ const clearSelection = (0, import_react15.useCallback)(() => {
2410
2598
  const ns = [];
2411
2599
  const es = [];
2412
2600
  for (const n of nodes) if (n.selected) ns.push(change.node.select(n.id, false));
@@ -2414,9 +2602,9 @@ function FlowCanvas(props) {
2414
2602
  if (ns.length) onNodesChange?.(ns);
2415
2603
  if (es.length) onEdgesChange?.(es);
2416
2604
  }, [nodes, edges, onNodesChange, onEdgesChange]);
2417
- const dragRef = (0, import_react14.useRef)(null);
2418
- const [draggingId, setDraggingId] = (0, import_react14.useState)(null);
2419
- const beginNodeDrag = (0, import_react14.useCallback)(
2605
+ const dragRef = (0, import_react15.useRef)(null);
2606
+ const [draggingId, setDraggingId] = (0, import_react15.useState)(null);
2607
+ const beginNodeDrag = (0, import_react15.useCallback)(
2420
2608
  (nodeId, pointerId, clientX, clientY, altKey = false) => {
2421
2609
  if (!nodesDraggable) return;
2422
2610
  const node = nodes.find((n) => n.id === nodeId);
@@ -2425,6 +2613,7 @@ function FlowCanvas(props) {
2425
2613
  id: d.id,
2426
2614
  startPosition: d.position
2427
2615
  }));
2616
+ const wantsReparent = altKey || reparentOnDragRef.current;
2428
2617
  dragRef.current = {
2429
2618
  pointerId,
2430
2619
  nodeId,
@@ -2432,7 +2621,7 @@ function FlowCanvas(props) {
2432
2621
  startClientY: clientY,
2433
2622
  startPosition: node.position,
2434
2623
  descendants: kids,
2435
- altDetach: altKey && !!node.parentId,
2624
+ altDetach: wantsReparent,
2436
2625
  rafScheduled: false,
2437
2626
  nextDelta: null
2438
2627
  };
@@ -2441,12 +2630,12 @@ function FlowCanvas(props) {
2441
2630
  },
2442
2631
  [nodes, nodesDraggable, selectNode]
2443
2632
  );
2444
- const [conn, setConn] = (0, import_react14.useState)(null);
2445
- const connRef = (0, import_react14.useRef)(null);
2446
- (0, import_react14.useEffect)(() => {
2633
+ const [conn, setConn] = (0, import_react15.useState)(null);
2634
+ const connRef = (0, import_react15.useRef)(null);
2635
+ (0, import_react15.useEffect)(() => {
2447
2636
  connRef.current = conn;
2448
2637
  }, [conn]);
2449
- const beginConnection = (0, import_react14.useCallback)(
2638
+ const beginConnection = (0, import_react15.useCallback)(
2450
2639
  (nodeId, handleId, handleType, pointerId, clientX, clientY) => {
2451
2640
  if (!nodesConnectable) return;
2452
2641
  const node = nodes.find((n) => n.id === nodeId);
@@ -2479,63 +2668,75 @@ function FlowCanvas(props) {
2479
2668
  },
2480
2669
  [nodes, nodesConnectable, handleRegistry, viewport, store, onConnectStart]
2481
2670
  );
2482
- const viewportRef = (0, import_react14.useRef)(viewport);
2483
- const nodesRef = (0, import_react14.useRef)(nodes);
2484
- const edgesRef = (0, import_react14.useRef)(edges);
2485
- const onNodesChangeRefForInstance = (0, import_react14.useRef)(onNodesChange);
2486
- const onEdgesChangeRefForInstance = (0, import_react14.useRef)(onEdgesChange);
2487
- const onBeforeDeleteRef = (0, import_react14.useRef)(onBeforeDelete);
2488
- const snapToGridRef = (0, import_react14.useRef)(snapToGrid);
2489
- const gridSizeRef = (0, import_react14.useRef)(gridSize);
2490
- const nodeCollisionGapRef = (0, import_react14.useRef)(nodeCollisionGap);
2491
- const subflowCollisionGapRef = (0, import_react14.useRef)(subflowCollisionGap ?? nodeCollisionGap);
2492
- (0, import_react14.useEffect)(() => {
2671
+ const viewportRef = (0, import_react15.useRef)(viewport);
2672
+ const nodesRef = (0, import_react15.useRef)(nodes);
2673
+ const edgesRef = (0, import_react15.useRef)(edges);
2674
+ const onNodesChangeRefForInstance = (0, import_react15.useRef)(onNodesChange);
2675
+ const onEdgesChangeRefForInstance = (0, import_react15.useRef)(onEdgesChange);
2676
+ const onBeforeDeleteRef = (0, import_react15.useRef)(onBeforeDelete);
2677
+ const snapToGridRef = (0, import_react15.useRef)(snapToGrid);
2678
+ const gridSizeRef = (0, import_react15.useRef)(gridSize);
2679
+ const nodeCollisionGapRef = (0, import_react15.useRef)(nodeCollisionGap);
2680
+ const subflowCollisionGapRef = (0, import_react15.useRef)(subflowCollisionGap ?? nodeCollisionGap);
2681
+ const reparentOnDragRef = (0, import_react15.useRef)(reparentOnDrag);
2682
+ const autoResizeContainersRef = (0, import_react15.useRef)(autoResizeContainers);
2683
+ const containerAutoResizePaddingRef = (0, import_react15.useRef)(containerAutoResizePadding);
2684
+ (0, import_react15.useEffect)(() => {
2493
2685
  edgesRef.current = edges;
2494
2686
  }, [edges]);
2495
- (0, import_react14.useEffect)(() => {
2687
+ (0, import_react15.useEffect)(() => {
2496
2688
  onNodesChangeRefForInstance.current = onNodesChange;
2497
2689
  }, [onNodesChange]);
2498
- (0, import_react14.useEffect)(() => {
2690
+ (0, import_react15.useEffect)(() => {
2499
2691
  onEdgesChangeRefForInstance.current = onEdgesChange;
2500
2692
  }, [onEdgesChange]);
2501
- (0, import_react14.useEffect)(() => {
2693
+ (0, import_react15.useEffect)(() => {
2502
2694
  onBeforeDeleteRef.current = onBeforeDelete;
2503
2695
  }, [onBeforeDelete]);
2504
- (0, import_react14.useEffect)(() => {
2696
+ (0, import_react15.useEffect)(() => {
2505
2697
  snapToGridRef.current = snapToGrid;
2506
2698
  }, [snapToGrid]);
2507
- (0, import_react14.useEffect)(() => {
2699
+ (0, import_react15.useEffect)(() => {
2508
2700
  gridSizeRef.current = gridSize;
2509
2701
  }, [gridSize]);
2510
- (0, import_react14.useEffect)(() => {
2702
+ (0, import_react15.useEffect)(() => {
2511
2703
  nodeCollisionGapRef.current = nodeCollisionGap;
2512
2704
  }, [nodeCollisionGap]);
2513
- (0, import_react14.useEffect)(() => {
2705
+ (0, import_react15.useEffect)(() => {
2514
2706
  subflowCollisionGapRef.current = subflowCollisionGap ?? nodeCollisionGap;
2515
2707
  }, [subflowCollisionGap, nodeCollisionGap]);
2516
- const onNodesChangeRef = (0, import_react14.useRef)(onNodesChange);
2517
- const onConnectRef = (0, import_react14.useRef)(onConnect);
2518
- const onConnectEndRef = (0, import_react14.useRef)(onConnectEnd);
2519
- const isValidConnectionRef = (0, import_react14.useRef)(isValidConnection);
2520
- (0, import_react14.useEffect)(() => {
2708
+ (0, import_react15.useEffect)(() => {
2709
+ reparentOnDragRef.current = reparentOnDrag;
2710
+ }, [reparentOnDrag]);
2711
+ (0, import_react15.useEffect)(() => {
2712
+ autoResizeContainersRef.current = autoResizeContainers;
2713
+ }, [autoResizeContainers]);
2714
+ (0, import_react15.useEffect)(() => {
2715
+ containerAutoResizePaddingRef.current = containerAutoResizePadding;
2716
+ }, [containerAutoResizePadding]);
2717
+ const onNodesChangeRef = (0, import_react15.useRef)(onNodesChange);
2718
+ const onConnectRef = (0, import_react15.useRef)(onConnect);
2719
+ const onConnectEndRef = (0, import_react15.useRef)(onConnectEnd);
2720
+ const isValidConnectionRef = (0, import_react15.useRef)(isValidConnection);
2721
+ (0, import_react15.useEffect)(() => {
2521
2722
  viewportRef.current = viewport;
2522
2723
  }, [viewport]);
2523
- (0, import_react14.useEffect)(() => {
2724
+ (0, import_react15.useEffect)(() => {
2524
2725
  nodesRef.current = nodes;
2525
2726
  }, [nodes]);
2526
- (0, import_react14.useEffect)(() => {
2727
+ (0, import_react15.useEffect)(() => {
2527
2728
  onNodesChangeRef.current = onNodesChange;
2528
2729
  }, [onNodesChange]);
2529
- (0, import_react14.useEffect)(() => {
2730
+ (0, import_react15.useEffect)(() => {
2530
2731
  onConnectRef.current = onConnect;
2531
2732
  }, [onConnect]);
2532
- (0, import_react14.useEffect)(() => {
2733
+ (0, import_react15.useEffect)(() => {
2533
2734
  onConnectEndRef.current = onConnectEnd;
2534
2735
  }, [onConnectEnd]);
2535
- (0, import_react14.useEffect)(() => {
2736
+ (0, import_react15.useEffect)(() => {
2536
2737
  isValidConnectionRef.current = isValidConnection;
2537
2738
  }, [isValidConnection]);
2538
- (0, import_react14.useEffect)(() => {
2739
+ (0, import_react15.useEffect)(() => {
2539
2740
  const onPointerMove = (e) => {
2540
2741
  const vp = viewportRef.current;
2541
2742
  const drag = dragRef.current;
@@ -2632,7 +2833,7 @@ function FlowCanvas(props) {
2632
2833
  )
2633
2834
  );
2634
2835
  }
2635
- if (drag.altDetach && dragNode.parentId) {
2836
+ if (drag.altDetach) {
2636
2837
  const targetGroup = findContainingGroup(
2637
2838
  {
2638
2839
  x: finalPos.x + (dragNode.width ?? 0) / 2,
@@ -2642,14 +2843,26 @@ function FlowCanvas(props) {
2642
2843
  [drag.nodeId, ...drag.descendants.map((d) => d.id)]
2643
2844
  );
2644
2845
  const nextParentId = targetGroup?.id;
2645
- const updated = {
2646
- ...dragNode,
2647
- position: finalPos,
2648
- parentId: nextParentId,
2649
- // Preserve extent only when staying in a group.
2650
- extent: nextParentId ? dragNode.extent : void 0
2651
- };
2652
- changes.push(change.node.replace(drag.nodeId, updated));
2846
+ if (nextParentId !== dragNode.parentId) {
2847
+ const updated = {
2848
+ ...dragNode,
2849
+ position: finalPos,
2850
+ parentId: nextParentId,
2851
+ // Preserve extent only when staying in a group.
2852
+ extent: nextParentId ? dragNode.extent : void 0
2853
+ };
2854
+ changes.push(change.node.replace(drag.nodeId, updated));
2855
+ }
2856
+ }
2857
+ if (autoResizeContainersRef.current) {
2858
+ const containerChanges = computeContainerAutoResize(
2859
+ nodesRef.current,
2860
+ // Projected children: apply the position + reparent
2861
+ // changes we just built before measuring bboxes.
2862
+ changes,
2863
+ containerAutoResizePaddingRef.current
2864
+ );
2865
+ for (const c2 of containerChanges) changes.push(c2);
2653
2866
  }
2654
2867
  onNodesChangeRef.current?.(changes);
2655
2868
  }
@@ -2722,7 +2935,7 @@ function FlowCanvas(props) {
2722
2935
  window.removeEventListener("pointercancel", onPointerCancel);
2723
2936
  };
2724
2937
  }, [store]);
2725
- const panRef = (0, import_react14.useRef)(null);
2938
+ const panRef = (0, import_react15.useRef)(null);
2726
2939
  const onCanvasPointerDown = (e) => {
2727
2940
  if (e.button !== 0) return;
2728
2941
  const t = e.target;
@@ -2747,7 +2960,7 @@ function FlowCanvas(props) {
2747
2960
  moved: false
2748
2961
  };
2749
2962
  };
2750
- (0, import_react14.useEffect)(() => {
2963
+ (0, import_react15.useEffect)(() => {
2751
2964
  const onMove = (e) => {
2752
2965
  const pan = panRef.current;
2753
2966
  if (!pan || pan.pointerId !== e.pointerId) return;
@@ -2803,7 +3016,7 @@ function FlowCanvas(props) {
2803
3016
  y: py - (py - viewport.y) * k
2804
3017
  });
2805
3018
  };
2806
- const dispatch = (0, import_react14.useCallback)(
3019
+ const dispatch = (0, import_react15.useCallback)(
2807
3020
  (a) => {
2808
3021
  if (a.type === "connection/start") {
2809
3022
  beginConnection(a.nodeId, a.handleId, a.handleType, a.pointerId, a.clientX, a.clientY);
@@ -2811,7 +3024,7 @@ function FlowCanvas(props) {
2811
3024
  },
2812
3025
  [beginConnection]
2813
3026
  );
2814
- const reportDimensions = (0, import_react14.useCallback)(
3027
+ const reportDimensions = (0, import_react15.useCallback)(
2815
3028
  (nodeId, width2, height2) => {
2816
3029
  const node = nodes.find((n) => n.id === nodeId);
2817
3030
  if (!node) return;
@@ -2820,7 +3033,7 @@ function FlowCanvas(props) {
2820
3033
  },
2821
3034
  [nodes, onNodesChange]
2822
3035
  );
2823
- const toggleNodeCollapseImpl = (0, import_react14.useCallback)(
3036
+ const toggleNodeCollapseImpl = (0, import_react15.useCallback)(
2824
3037
  (nodeId) => {
2825
3038
  const node = nodes.find((n) => n.id === nodeId);
2826
3039
  if (!node) return;
@@ -2833,7 +3046,7 @@ function FlowCanvas(props) {
2833
3046
  },
2834
3047
  [nodes, onNodesChange]
2835
3048
  );
2836
- const deleteNodeImpl = (0, import_react14.useCallback)(
3049
+ const deleteNodeImpl = (0, import_react15.useCallback)(
2837
3050
  (nodeId) => {
2838
3051
  const incidentEdgeIds = edgesRef.current.filter((e) => e.source === nodeId || e.target === nodeId).map((e) => e.id);
2839
3052
  if (incidentEdgeIds.length > 0) {
@@ -2843,7 +3056,7 @@ function FlowCanvas(props) {
2843
3056
  },
2844
3057
  [onNodesChange, onEdgesChange]
2845
3058
  );
2846
- const instance = (0, import_react14.useMemo)(
3059
+ const instance = (0, import_react15.useMemo)(
2847
3060
  () => ({
2848
3061
  // viewport
2849
3062
  getViewport: () => viewportRef.current,
@@ -2984,14 +3197,14 @@ function FlowCanvas(props) {
2984
3197
  }),
2985
3198
  [setViewport, minZoom, maxZoom]
2986
3199
  );
2987
- const initFiredRef = (0, import_react14.useRef)(false);
2988
- (0, import_react14.useEffect)(() => {
3200
+ const initFiredRef = (0, import_react15.useRef)(false);
3201
+ (0, import_react15.useEffect)(() => {
2989
3202
  if (initFiredRef.current) return;
2990
3203
  initFiredRef.current = true;
2991
3204
  onInit?.(instance);
2992
3205
  }, [instance, onInit]);
2993
- const fitOnInitFiredRef = (0, import_react14.useRef)(false);
2994
- (0, import_react14.useEffect)(() => {
3206
+ const fitOnInitFiredRef = (0, import_react15.useRef)(false);
3207
+ (0, import_react15.useEffect)(() => {
2995
3208
  if (fitOnInitFiredRef.current) return;
2996
3209
  const opt = fitViewOnInit;
2997
3210
  const shouldFit = opt === false ? false : opt !== void 0 ? true : !viewportPropProvided;
@@ -3006,7 +3219,7 @@ function FlowCanvas(props) {
3006
3219
  });
3007
3220
  return () => cancelAnimationFrame(raf);
3008
3221
  }, [fitViewOnInit, viewportPropProvided, nodes.length, instance]);
3009
- (0, import_react14.useEffect)(() => {
3222
+ (0, import_react15.useEffect)(() => {
3010
3223
  const onKey = (e) => {
3011
3224
  if (e.key !== "Backspace" && e.key !== "Delete") return;
3012
3225
  const target = e.target;
@@ -3027,7 +3240,7 @@ function FlowCanvas(props) {
3027
3240
  window.addEventListener("keydown", onKey);
3028
3241
  return () => window.removeEventListener("keydown", onKey);
3029
3242
  }, [instance, store]);
3030
- const bridge = (0, import_react14.useMemo)(
3243
+ const bridge = (0, import_react15.useMemo)(
3031
3244
  () => ({
3032
3245
  beginNodeDrag,
3033
3246
  selectNode,
@@ -3047,16 +3260,16 @@ function FlowCanvas(props) {
3047
3260
  toggleNodeCollapseImpl
3048
3261
  ]
3049
3262
  );
3050
- const [panGesture, setPanGesture] = (0, import_react14.useState)(false);
3263
+ const [panGesture, setPanGesture] = (0, import_react15.useState)(false);
3051
3264
  const isEmpty = nodes.length === 0 && edges.length === 0;
3052
3265
  const isConnecting = conn !== null;
3053
- const visibleNodes = (0, import_react14.useMemo)(() => nodes.filter((n) => !n.hidden), [nodes]);
3054
- const visibleEdges = (0, import_react14.useMemo)(() => {
3266
+ const visibleNodes = (0, import_react15.useMemo)(() => nodes.filter((n) => !n.hidden), [nodes]);
3267
+ const visibleEdges = (0, import_react15.useMemo)(() => {
3055
3268
  if (visibleNodes.length === nodes.length) return edges;
3056
3269
  const visibleIds = new Set(visibleNodes.map((n) => n.id));
3057
3270
  return edges.filter((e) => visibleIds.has(e.source) && visibleIds.has(e.target));
3058
3271
  }, [edges, nodes, visibleNodes]);
3059
- const orderedNodes = (0, import_react14.useMemo)(() => {
3272
+ const orderedNodes = (0, import_react15.useMemo)(() => {
3060
3273
  const isContainer = (n) => n.type === "group" || n.type === "forEach";
3061
3274
  const depth = (n) => {
3062
3275
  let d = 0;
@@ -3075,7 +3288,7 @@ function FlowCanvas(props) {
3075
3288
  containers.sort((a, b) => depth(a) - depth(b));
3076
3289
  return [...containers, ...others];
3077
3290
  }, [visibleNodes]);
3078
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FlowStoreContext.Provider, { value: store, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FlowInstanceContext.Provider, { value: instance, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(HandleRegistryContext.Provider, { value: handleRegistry, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FlowDispatchContext.Provider, { value: dispatch, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FlowNodeBridgeContext.Provider, { value: bridge, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
3291
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(FlowStoreContext.Provider, { value: store, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(FlowInstanceContext.Provider, { value: instance, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(HandleRegistryContext.Provider, { value: handleRegistry, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(FlowDispatchContext.Provider, { value: dispatch, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(FlowNodeBridgeContext.Provider, { value: bridge, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
3079
3292
  "div",
3080
3293
  {
3081
3294
  ref: containerRef,
@@ -3120,7 +3333,7 @@ function FlowCanvas(props) {
3120
3333
  },
3121
3334
  "data-empty": isEmpty ? "true" : void 0,
3122
3335
  children: [
3123
- background !== "none" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3336
+ background !== "none" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3124
3337
  "div",
3125
3338
  {
3126
3339
  className: cn(
@@ -3134,7 +3347,7 @@ function FlowCanvas(props) {
3134
3347
  }
3135
3348
  }
3136
3349
  ),
3137
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
3350
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
3138
3351
  "div",
3139
3352
  {
3140
3353
  className: "ods-flow-canvas-v2__viewport",
@@ -3145,7 +3358,7 @@ function FlowCanvas(props) {
3145
3358
  transformOrigin: "0 0"
3146
3359
  },
3147
3360
  children: [
3148
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3361
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3149
3362
  EdgesLayer,
3150
3363
  {
3151
3364
  edges: visibleEdges,
@@ -3160,7 +3373,7 @@ function FlowCanvas(props) {
3160
3373
  orderedNodes.map((node) => {
3161
3374
  const Kind = kinds[node.type] ?? kinds.action;
3162
3375
  if (!Kind) return null;
3163
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3376
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3164
3377
  FlowNode,
3165
3378
  {
3166
3379
  node,
@@ -3175,7 +3388,7 @@ function FlowCanvas(props) {
3175
3388
  ]
3176
3389
  }
3177
3390
  ),
3178
- isEmpty && emptyState && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "ods-flow-canvas-v2__empty", children: emptyState }),
3391
+ isEmpty && emptyState && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "ods-flow-canvas-v2__empty", children: emptyState }),
3179
3392
  children
3180
3393
  ]
3181
3394
  }
@@ -3184,7 +3397,60 @@ function FlowCanvas(props) {
3184
3397
  function onEdgesChangeRef(id, cb) {
3185
3398
  cb?.([change.edge.remove(id)]);
3186
3399
  }
3187
- var EdgesLayer = (0, import_react14.memo)(function EdgesLayer2({
3400
+ function computeContainerAutoResize(nodes, pending, padding) {
3401
+ const projected = /* @__PURE__ */ new Map();
3402
+ for (const n of nodes) projected.set(n.id, n);
3403
+ for (const c of pending) {
3404
+ if (c.type === "position" && c.position) {
3405
+ const cur = projected.get(c.id);
3406
+ if (cur) projected.set(c.id, { ...cur, position: c.position });
3407
+ } else if (c.type === "replace" && c.item) {
3408
+ projected.set(c.id, { ...projected.get(c.id), ...c.item });
3409
+ } else if (c.type === "add" && c.item) {
3410
+ projected.set(c.item.id, c.item);
3411
+ }
3412
+ }
3413
+ const HEADER = 56;
3414
+ const out = [];
3415
+ for (const parent of projected.values()) {
3416
+ if (parent.type !== "group" && parent.type !== "forEach") continue;
3417
+ const children = [];
3418
+ for (const n of projected.values()) {
3419
+ if (n.parentId === parent.id) children.push(n);
3420
+ }
3421
+ if (children.length === 0) continue;
3422
+ let minX = Number.POSITIVE_INFINITY;
3423
+ let minY = Number.POSITIVE_INFINITY;
3424
+ let maxX = Number.NEGATIVE_INFINITY;
3425
+ let maxY = Number.NEGATIVE_INFINITY;
3426
+ for (const c of children) {
3427
+ const cw = c.width ?? 240;
3428
+ const ch = c.height ?? 96;
3429
+ if (c.position.x < minX) minX = c.position.x;
3430
+ if (c.position.y < minY) minY = c.position.y;
3431
+ if (c.position.x + cw > maxX) maxX = c.position.x + cw;
3432
+ if (c.position.y + ch > maxY) maxY = c.position.y + ch;
3433
+ }
3434
+ const targetX = minX - padding;
3435
+ const targetY = minY - padding - HEADER;
3436
+ const targetW = maxX - minX + padding * 2;
3437
+ const targetH = maxY - minY + padding * 2 + HEADER;
3438
+ const curW = parent.width ?? 480;
3439
+ const curH = parent.height ?? 240;
3440
+ const nextW = Math.max(curW, targetW);
3441
+ const nextH = Math.max(curH, targetH);
3442
+ const positionDirty = parent.position.x !== targetX || parent.position.y !== targetY;
3443
+ const sizeDirty = curW !== nextW || curH !== nextH;
3444
+ if (positionDirty) {
3445
+ out.push(change.node.position(parent.id, { x: targetX, y: targetY }, false));
3446
+ }
3447
+ if (sizeDirty) {
3448
+ out.push(change.node.dimensions(parent.id, { width: nextW, height: nextH }));
3449
+ }
3450
+ }
3451
+ return out;
3452
+ }
3453
+ var EdgesLayer = (0, import_react15.memo)(function EdgesLayer2({
3188
3454
  edges,
3189
3455
  nodes,
3190
3456
  onSelect,
@@ -3193,7 +3459,7 @@ var EdgesLayer = (0, import_react14.memo)(function EdgesLayer2({
3193
3459
  ghost,
3194
3460
  handleVersion: _handleVersion
3195
3461
  }) {
3196
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
3462
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
3197
3463
  "svg",
3198
3464
  {
3199
3465
  className: "ods-flow-canvas-v2__edges",
@@ -3201,7 +3467,7 @@ var EdgesLayer = (0, import_react14.memo)(function EdgesLayer2({
3201
3467
  width: "100%",
3202
3468
  height: "100%",
3203
3469
  children: [
3204
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("g", { style: { pointerEvents: "auto" }, children: edges.map((edge) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3470
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("g", { style: { pointerEvents: "auto" }, children: edges.map((edge) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3205
3471
  FlowEdge,
3206
3472
  {
3207
3473
  edge,
@@ -3213,7 +3479,7 @@ var EdgesLayer = (0, import_react14.memo)(function EdgesLayer2({
3213
3479
  },
3214
3480
  edge.id
3215
3481
  )) }),
3216
- ghost && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3482
+ ghost && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3217
3483
  "path",
3218
3484
  {
3219
3485
  d: `M ${ghost.start.x} ${ghost.start.y} L ${ghost.end.x} ${ghost.end.y}`,
@@ -3228,151 +3494,6 @@ var EdgesLayer = (0, import_react14.memo)(function EdgesLayer2({
3228
3494
  );
3229
3495
  });
3230
3496
 
3231
- // src/workflow/components/NodeResizer/NodeResizer.tsx
3232
- var import_react15 = require("react");
3233
- var import_jsx_runtime8 = require("react/jsx-runtime");
3234
- function NodeResizer({
3235
- isVisible,
3236
- minWidth = 80,
3237
- minHeight = 60,
3238
- maxWidth,
3239
- maxHeight,
3240
- keepAspectRatio = false,
3241
- onResize,
3242
- onResizeEnd,
3243
- color
3244
- }) {
3245
- const { node, selected } = useFlowNodeContext();
3246
- const viewport = useViewport();
3247
- const flow = useFlow();
3248
- const dragRef = (0, import_react15.useRef)(null);
3249
- const show = isVisible ?? selected;
3250
- if (!show) return null;
3251
- const beginResize = (e, corner) => {
3252
- e.preventDefault();
3253
- e.stopPropagation();
3254
- e.target.setPointerCapture(e.pointerId);
3255
- const w = node.width ?? DEFAULT_NODE_WIDTH;
3256
- const h = node.height ?? DEFAULT_NODE_HEIGHT;
3257
- dragRef.current = {
3258
- pointerId: e.pointerId,
3259
- corner,
3260
- startClientX: e.clientX,
3261
- startClientY: e.clientY,
3262
- startWidth: w,
3263
- startHeight: h,
3264
- startX: node.position.x,
3265
- startY: node.position.y,
3266
- aspect: w / Math.max(1, h)
3267
- };
3268
- };
3269
- const onMove = (e) => {
3270
- const drag = dragRef.current;
3271
- if (!drag || drag.pointerId !== e.pointerId) return;
3272
- const dx = (e.clientX - drag.startClientX) / viewport.zoom;
3273
- const dy = (e.clientY - drag.startClientY) / viewport.zoom;
3274
- let nextW = drag.startWidth;
3275
- let nextH = drag.startHeight;
3276
- let nextX = drag.startX;
3277
- let nextY = drag.startY;
3278
- switch (drag.corner) {
3279
- case "se":
3280
- nextW = drag.startWidth + dx;
3281
- nextH = drag.startHeight + dy;
3282
- break;
3283
- case "sw":
3284
- nextW = drag.startWidth - dx;
3285
- nextH = drag.startHeight + dy;
3286
- nextX = drag.startX + dx;
3287
- break;
3288
- case "ne":
3289
- nextW = drag.startWidth + dx;
3290
- nextH = drag.startHeight - dy;
3291
- nextY = drag.startY + dy;
3292
- break;
3293
- case "nw":
3294
- nextW = drag.startWidth - dx;
3295
- nextH = drag.startHeight - dy;
3296
- nextX = drag.startX + dx;
3297
- nextY = drag.startY + dy;
3298
- break;
3299
- }
3300
- if (keepAspectRatio) {
3301
- nextH = nextW / drag.aspect;
3302
- if (drag.corner === "nw" || drag.corner === "ne") {
3303
- nextY = drag.startY + (drag.startHeight - nextH);
3304
- }
3305
- }
3306
- nextW = Math.max(minWidth, maxWidth ? Math.min(maxWidth, nextW) : nextW);
3307
- nextH = Math.max(minHeight, maxHeight ? Math.min(maxHeight, nextH) : nextH);
3308
- flow.updateNode(node.id, {
3309
- width: nextW,
3310
- height: nextH,
3311
- position: { x: nextX, y: nextY }
3312
- });
3313
- onResize?.({ width: nextW, height: nextH });
3314
- };
3315
- const onUp = (e) => {
3316
- if (dragRef.current?.pointerId === e.pointerId) {
3317
- const cur = flow.getNode(node.id);
3318
- if (cur) {
3319
- onResizeEnd?.({
3320
- width: cur.width ?? DEFAULT_NODE_WIDTH,
3321
- height: cur.height ?? DEFAULT_NODE_HEIGHT
3322
- });
3323
- }
3324
- dragRef.current = null;
3325
- }
3326
- };
3327
- const handleColor = color ?? "var(--ods-accent)";
3328
- const handleStyle = (corner) => {
3329
- const base = {
3330
- position: "absolute",
3331
- width: 12,
3332
- height: 12,
3333
- background: "var(--ods-surface-canvas)",
3334
- border: `2px solid ${handleColor}`,
3335
- borderRadius: 2,
3336
- cursor: cursorFor(corner),
3337
- touchAction: "none",
3338
- // Place each handle so its CENTRE sits on the corresponding corner.
3339
- transform: "translate(-50%, -50%)"
3340
- };
3341
- switch (corner) {
3342
- case "nw":
3343
- return { ...base, top: 0, left: 0 };
3344
- case "ne":
3345
- return { ...base, top: 0, left: "100%" };
3346
- case "sw":
3347
- return { ...base, top: "100%", left: 0 };
3348
- case "se":
3349
- return { ...base, top: "100%", left: "100%" };
3350
- }
3351
- };
3352
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: cn("ods-node-resizer"), "data-flow-no-drag": "true", children: ["nw", "ne", "sw", "se"].map((corner) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3353
- "div",
3354
- {
3355
- style: handleStyle(corner),
3356
- onPointerDown: (e) => beginResize(e, corner),
3357
- onPointerMove: onMove,
3358
- onPointerUp: onUp,
3359
- onPointerCancel: onUp,
3360
- "aria-label": `Resize ${corner}`
3361
- },
3362
- corner
3363
- )) });
3364
- }
3365
- function cursorFor(corner) {
3366
- switch (corner) {
3367
- case "nw":
3368
- case "se":
3369
- return "nwse-resize";
3370
- case "ne":
3371
- case "sw":
3372
- return "nesw-resize";
3373
- }
3374
- }
3375
-
3376
3497
  // src/workflow/components/NodeToolbar/NodeToolbar.tsx
3377
3498
  var import_jsx_runtime9 = require("react/jsx-runtime");
3378
3499
  function NodeToolbar({