geonodes-web-render 0.3.24 → 0.3.25

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.
package/README.md CHANGED
@@ -79,6 +79,14 @@ Set `showCopyButton={false}` (or `{ payload, showCopyButton: false }` for
79
79
  `mountGraphView`) to hide the "Copy TreeClipper Magic String" button and disable
80
80
  the right-click copy action. Defaults to `true`.
81
81
 
82
+ Set `allowSelection={false}` to disable node selection (left-drag pans instead
83
+ of box-selecting). Defaults to `true`. Combine both for a read-only pan/zoom
84
+ viewer:
85
+
86
+ ```tsx
87
+ <GraphView payload="TreeClipper::H4sI..." showCopyButton={false} allowSelection={false} />
88
+ ```
89
+
82
90
  > **Preview the embed locally.** The embed view (with the "Copy TreeClipper
83
91
  > Magic String" button and toast) isn't reachable from the standalone app, so a
84
92
  > dev-only harness page is included. Run `npm run dev` and open
package/dist/embed.js CHANGED
@@ -265,18 +265,18 @@ function ie(e) {
265
265
  function ae() {
266
266
  return this.firstElementChild;
267
267
  }
268
- function K(e) {
268
+ function oe(e) {
269
269
  return this.select(e == null ? ae : ie(typeof e == "function" ? e : ne(e)));
270
270
  }
271
271
  //#endregion
272
272
  //#region node_modules/d3-selection/src/selection/selectChildren.js
273
- var oe = Array.prototype.filter;
273
+ var K = Array.prototype.filter;
274
274
  function se() {
275
275
  return Array.from(this.children);
276
276
  }
277
277
  function ce(e) {
278
278
  return function() {
279
- return oe.call(this.children, e);
279
+ return K.call(this.children, e);
280
280
  };
281
281
  }
282
282
  function le(e) {
@@ -773,7 +773,7 @@ It.prototype = Lt.prototype = {
773
773
  constructor: It,
774
774
  select: V,
775
775
  selectAll: ee,
776
- selectChild: K,
776
+ selectChild: oe,
777
777
  selectChildren: le,
778
778
  filter: ue,
779
779
  data: ve,
@@ -6316,9 +6316,9 @@ function Hu({ id: e, edgesFocusable: t, edgesReconnectable: n, elementsSelectabl
6316
6316
  s(e, { ...T });
6317
6317
  } : void 0, ae = c ? (e) => {
6318
6318
  c(e, { ...T });
6319
- } : void 0, K = l ? (e) => {
6319
+ } : void 0, oe = l ? (e) => {
6320
6320
  l(e, { ...T });
6321
- } : void 0, oe = p ? (e) => {
6321
+ } : void 0, K = p ? (e) => {
6322
6322
  p(e, { ...T });
6323
6323
  } : void 0;
6324
6324
  return g("svg", {
@@ -6341,8 +6341,8 @@ function Hu({ id: e, edgesFocusable: t, edgesReconnectable: n, elementsSelectabl
6341
6341
  onDoubleClick: re,
6342
6342
  onContextMenu: ie,
6343
6343
  onMouseEnter: ae,
6344
- onMouseMove: K,
6345
- onMouseLeave: oe,
6344
+ onMouseMove: oe,
6345
+ onMouseLeave: K,
6346
6346
  onKeyDown: A ? (t) => {
6347
6347
  if (!w && ya.includes(t.key) && M) {
6348
6348
  let { unselectNodesAndEdges: n, addSelectedEdges: r } = R.getState();
@@ -6582,7 +6582,7 @@ function od() {
6582
6582
  }
6583
6583
  }, []);
6584
6584
  }
6585
- function sd({ nodeTypes: e, edgeTypes: t, onInit: n, onNodeClick: r, onEdgeClick: i, onNodeDoubleClick: a, onEdgeDoubleClick: o, onNodeMouseEnter: s, onNodeMouseMove: c, onNodeMouseLeave: l, onNodeContextMenu: u, onSelectionContextMenu: d, onSelectionStart: f, onSelectionEnd: p, connectionLineType: m, connectionLineStyle: h, connectionLineComponent: v, connectionLineContainerStyle: y, selectionKeyCode: b, selectionOnDrag: x, selectionMode: S, multiSelectionKeyCode: C, panActivationKeyCode: w, zoomActivationKeyCode: T, deleteKeyCode: E, onlyRenderVisibleElements: D, elementsSelectable: O, defaultViewport: k, translateExtent: A, minZoom: j, maxZoom: M, preventScrolling: N, defaultMarkerColor: P, zoomOnScroll: F, zoomOnPinch: I, panOnScroll: L, panOnScrollSpeed: R, panOnScrollMode: z, zoomOnDoubleClick: B, panOnDrag: V, autoPanOnSelection: H, onPaneClick: U, onPaneMouseEnter: W, onPaneMouseMove: G, onPaneMouseLeave: ee, onPaneScroll: te, onPaneContextMenu: ne, paneClickDistance: re, nodeClickDistance: ie, onEdgeContextMenu: ae, onEdgeMouseEnter: K, onEdgeMouseMove: oe, onEdgeMouseLeave: se, reconnectRadius: ce, onReconnect: le, onReconnectStart: ue, onReconnectEnd: de, noDragClassName: fe, noWheelClassName: pe, noPanClassName: me, disableKeyboardA11y: he, nodeExtent: ge, rfId: _e, viewport: ve, onViewportChange: ye }) {
6585
+ function sd({ nodeTypes: e, edgeTypes: t, onInit: n, onNodeClick: r, onEdgeClick: i, onNodeDoubleClick: a, onEdgeDoubleClick: o, onNodeMouseEnter: s, onNodeMouseMove: c, onNodeMouseLeave: l, onNodeContextMenu: u, onSelectionContextMenu: d, onSelectionStart: f, onSelectionEnd: p, connectionLineType: m, connectionLineStyle: h, connectionLineComponent: v, connectionLineContainerStyle: y, selectionKeyCode: b, selectionOnDrag: x, selectionMode: S, multiSelectionKeyCode: C, panActivationKeyCode: w, zoomActivationKeyCode: T, deleteKeyCode: E, onlyRenderVisibleElements: D, elementsSelectable: O, defaultViewport: k, translateExtent: A, minZoom: j, maxZoom: M, preventScrolling: N, defaultMarkerColor: P, zoomOnScroll: F, zoomOnPinch: I, panOnScroll: L, panOnScrollSpeed: R, panOnScrollMode: z, zoomOnDoubleClick: B, panOnDrag: V, autoPanOnSelection: H, onPaneClick: U, onPaneMouseEnter: W, onPaneMouseMove: G, onPaneMouseLeave: ee, onPaneScroll: te, onPaneContextMenu: ne, paneClickDistance: re, nodeClickDistance: ie, onEdgeContextMenu: ae, onEdgeMouseEnter: oe, onEdgeMouseMove: K, onEdgeMouseLeave: se, reconnectRadius: ce, onReconnect: le, onReconnectStart: ue, onReconnectEnd: de, noDragClassName: fe, noWheelClassName: pe, noPanClassName: me, disableKeyboardA11y: he, nodeExtent: ge, rfId: _e, viewport: ve, onViewportChange: ye }) {
6586
6586
  return ad(e), ad(t), od(), Yu(n), Zu(ve), g(Xl, {
6587
6587
  onPaneClick: U,
6588
6588
  onPaneMouseEnter: W,
@@ -6631,8 +6631,8 @@ function sd({ nodeTypes: e, edgeTypes: t, onInit: n, onNodeClick: r, onEdgeClick
6631
6631
  onReconnectEnd: de,
6632
6632
  onlyRenderVisibleElements: D,
6633
6633
  onEdgeContextMenu: ae,
6634
- onEdgeMouseEnter: K,
6635
- onEdgeMouseMove: oe,
6634
+ onEdgeMouseEnter: oe,
6635
+ onEdgeMouseMove: K,
6636
6636
  onEdgeMouseLeave: se,
6637
6637
  reconnectRadius: ce,
6638
6638
  defaultMarkerColor: P,
@@ -7004,7 +7004,7 @@ var md = {
7004
7004
  position: "relative",
7005
7005
  zIndex: 0
7006
7006
  };
7007
- function hd({ nodes: e, edges: t, defaultNodes: n, defaultEdges: r, className: i, nodeTypes: o, edgeTypes: s, onNodeClick: c, onEdgeClick: l, onInit: u, onMove: d, onMoveStart: f, onMoveEnd: p, onConnect: m, onConnectStart: h, onConnectEnd: v, onClickConnectStart: y, onClickConnectEnd: b, onNodeMouseEnter: x, onNodeMouseMove: S, onNodeMouseLeave: C, onNodeContextMenu: w, onNodeDoubleClick: T, onNodeDragStart: E, onNodeDrag: O, onNodeDragStop: k, onNodesDelete: A, onEdgesDelete: j, onDelete: M, onSelectionChange: N, onSelectionDragStart: P, onSelectionDrag: F, onSelectionDragStop: I, onSelectionContextMenu: L, onSelectionStart: R, onSelectionEnd: z, onBeforeDelete: B, connectionMode: V, connectionLineType: H = Ta.Bezier, connectionLineStyle: U, connectionLineComponent: W, connectionLineContainerStyle: G, deleteKeyCode: ee = "Backspace", selectionKeyCode: te = "Shift", selectionOnDrag: ne = !1, selectionMode: re = Ca.Full, panActivationKeyCode: ie = "Space", multiSelectionKeyCode: ae = lo() ? "Meta" : "Control", zoomActivationKeyCode: K = lo() ? "Meta" : "Control", snapToGrid: oe, snapGrid: se, onlyRenderVisibleElements: ce = !1, selectNodesOnDrag: le, nodesDraggable: ue, autoPanOnNodeFocus: de, nodesConnectable: fe, nodesFocusable: pe, nodeOrigin: me = Fc, edgesFocusable: he, edgesReconnectable: ge, elementsSelectable: _e = !0, defaultViewport: ve = Ic, minZoom: ye = .5, maxZoom: be = 2, translateExtent: xe = va, preventScrolling: Se = !0, nodeExtent: Ce, defaultMarkerColor: we = "#b1b1b7", zoomOnScroll: Te = !0, zoomOnPinch: Ee = !0, panOnScroll: De = !1, panOnScrollSpeed: Oe = .5, panOnScrollMode: ke = Sa.Free, zoomOnDoubleClick: Ae = !0, panOnDrag: je = !0, onPaneClick: Me, onPaneMouseEnter: Ne, onPaneMouseMove: Pe, onPaneMouseLeave: Fe, onPaneScroll: Ie, onPaneContextMenu: Le, paneClickDistance: Re = 1, nodeClickDistance: ze = 0, children: Be, onReconnect: Ve, onReconnectStart: He, onReconnectEnd: Ue, onEdgeContextMenu: We, onEdgeDoubleClick: Ge, onEdgeMouseEnter: Ke, onEdgeMouseMove: qe, onEdgeMouseLeave: Je, reconnectRadius: Ye = 10, onNodesChange: Xe, onEdgesChange: Ze, noDragClassName: Qe = "nodrag", noWheelClassName: $e = "nowheel", noPanClassName: et = "nopan", fitView: tt, fitViewOptions: nt, connectOnClick: rt, attributionPosition: it, proOptions: at, defaultEdgeOptions: ot, elevateNodesOnSelect: st = !0, elevateEdgesOnSelect: ct = !1, disableKeyboardA11y: lt = !1, autoPanOnConnect: ut, autoPanOnNodeDrag: dt, autoPanOnSelection: ft = !0, autoPanSpeed: pt, connectionRadius: mt, isValidConnection: ht, onError: gt, style: _t, id: vt, nodeDragThreshold: yt, connectionDragThreshold: bt, viewport: xt, onViewportChange: St, width: Ct, height: wt, colorMode: Tt = "light", debug: Et, onScroll: Dt, ariaLabelConfig: Ot, zIndexMode: kt = "basic", ...At }, jt) {
7007
+ function hd({ nodes: e, edges: t, defaultNodes: n, defaultEdges: r, className: i, nodeTypes: o, edgeTypes: s, onNodeClick: c, onEdgeClick: l, onInit: u, onMove: d, onMoveStart: f, onMoveEnd: p, onConnect: m, onConnectStart: h, onConnectEnd: v, onClickConnectStart: y, onClickConnectEnd: b, onNodeMouseEnter: x, onNodeMouseMove: S, onNodeMouseLeave: C, onNodeContextMenu: w, onNodeDoubleClick: T, onNodeDragStart: E, onNodeDrag: O, onNodeDragStop: k, onNodesDelete: A, onEdgesDelete: j, onDelete: M, onSelectionChange: N, onSelectionDragStart: P, onSelectionDrag: F, onSelectionDragStop: I, onSelectionContextMenu: L, onSelectionStart: R, onSelectionEnd: z, onBeforeDelete: B, connectionMode: V, connectionLineType: H = Ta.Bezier, connectionLineStyle: U, connectionLineComponent: W, connectionLineContainerStyle: G, deleteKeyCode: ee = "Backspace", selectionKeyCode: te = "Shift", selectionOnDrag: ne = !1, selectionMode: re = Ca.Full, panActivationKeyCode: ie = "Space", multiSelectionKeyCode: ae = lo() ? "Meta" : "Control", zoomActivationKeyCode: oe = lo() ? "Meta" : "Control", snapToGrid: K, snapGrid: se, onlyRenderVisibleElements: ce = !1, selectNodesOnDrag: le, nodesDraggable: ue, autoPanOnNodeFocus: de, nodesConnectable: fe, nodesFocusable: pe, nodeOrigin: me = Fc, edgesFocusable: he, edgesReconnectable: ge, elementsSelectable: _e = !0, defaultViewport: ve = Ic, minZoom: ye = .5, maxZoom: be = 2, translateExtent: xe = va, preventScrolling: Se = !0, nodeExtent: Ce, defaultMarkerColor: we = "#b1b1b7", zoomOnScroll: Te = !0, zoomOnPinch: Ee = !0, panOnScroll: De = !1, panOnScrollSpeed: Oe = .5, panOnScrollMode: ke = Sa.Free, zoomOnDoubleClick: Ae = !0, panOnDrag: je = !0, onPaneClick: Me, onPaneMouseEnter: Ne, onPaneMouseMove: Pe, onPaneMouseLeave: Fe, onPaneScroll: Ie, onPaneContextMenu: Le, paneClickDistance: Re = 1, nodeClickDistance: ze = 0, children: Be, onReconnect: Ve, onReconnectStart: He, onReconnectEnd: Ue, onEdgeContextMenu: We, onEdgeDoubleClick: Ge, onEdgeMouseEnter: Ke, onEdgeMouseMove: qe, onEdgeMouseLeave: Je, reconnectRadius: Ye = 10, onNodesChange: Xe, onEdgesChange: Ze, noDragClassName: Qe = "nodrag", noWheelClassName: $e = "nowheel", noPanClassName: et = "nopan", fitView: tt, fitViewOptions: nt, connectOnClick: rt, attributionPosition: it, proOptions: at, defaultEdgeOptions: ot, elevateNodesOnSelect: st = !0, elevateEdgesOnSelect: ct = !1, disableKeyboardA11y: lt = !1, autoPanOnConnect: ut, autoPanOnNodeDrag: dt, autoPanOnSelection: ft = !0, autoPanSpeed: pt, connectionRadius: mt, isValidConnection: ht, onError: gt, style: _t, id: vt, nodeDragThreshold: yt, connectionDragThreshold: bt, viewport: xt, onViewportChange: St, width: Ct, height: wt, colorMode: Tt = "light", debug: Et, onScroll: Dt, ariaLabelConfig: Ot, zIndexMode: kt = "basic", ...At }, jt) {
7008
7008
  let Mt = vt || "1", Nt = Hc(Tt), Pt = a((e) => {
7009
7009
  e.currentTarget.scrollTo({
7010
7010
  top: 0,
@@ -7065,7 +7065,7 @@ function hd({ nodes: e, edges: t, defaultNodes: n, defaultEdges: r, className: i
7065
7065
  nodeExtent: Ce,
7066
7066
  onNodesChange: Xe,
7067
7067
  onEdgesChange: Ze,
7068
- snapToGrid: oe,
7068
+ snapToGrid: K,
7069
7069
  snapGrid: se,
7070
7070
  connectionMode: V,
7071
7071
  translateExtent: xe,
@@ -7123,7 +7123,7 @@ function hd({ nodes: e, edges: t, defaultNodes: n, defaultEdges: r, className: i
7123
7123
  deleteKeyCode: ee,
7124
7124
  multiSelectionKeyCode: ae,
7125
7125
  panActivationKeyCode: ie,
7126
- zoomActivationKeyCode: K,
7126
+ zoomActivationKeyCode: oe,
7127
7127
  onlyRenderVisibleElements: ce,
7128
7128
  defaultViewport: ve,
7129
7129
  translateExtent: xe,
@@ -7515,13 +7515,13 @@ function Xd({ style: e, className: t, nodeStrokeColor: n, nodeColor: r, nodeClas
7515
7515
  P,
7516
7516
  F
7517
7517
  ]);
7518
- let K = v ? (e) => {
7518
+ let oe = v ? (e) => {
7519
7519
  let [t, n] = ae.current?.pointer(e) || [0, 0];
7520
7520
  v(e, {
7521
7521
  x: t,
7522
7522
  y: n
7523
7523
  });
7524
- } : void 0, oe = y ? a((e, t) => {
7524
+ } : void 0, K = y ? a((e, t) => {
7525
7525
  let n = E.getState().nodeLookup.get(t).internals.userNode;
7526
7526
  y(e, n);
7527
7527
  }, []) : void 0, se = S ?? I["minimap.ariaLabel"];
@@ -7547,14 +7547,14 @@ function Xd({ style: e, className: t, nodeStrokeColor: n, nodeColor: r, nodeClas
7547
7547
  role: "img",
7548
7548
  "aria-labelledby": re,
7549
7549
  ref: O,
7550
- onClick: K,
7550
+ onClick: oe,
7551
7551
  children: [
7552
7552
  se && g("title", {
7553
7553
  id: re,
7554
7554
  children: se
7555
7555
  }),
7556
7556
  g(Wd, {
7557
- onClick: oe,
7557
+ onClick: K,
7558
7558
  nodeColor: r,
7559
7559
  nodeStrokeColor: n,
7560
7560
  nodeBorderRadius: o,
@@ -8899,129 +8899,129 @@ var gp = {
8899
8899
  nodeFrame: hp
8900
8900
  }, _p = { padding: .08 };
8901
8901
  function vp(e) {
8902
- let { nodes: t, edges: n, jsonText: r, breadcrumbs: i, onNavigate: o, onSelectionIds: s, onCopiedMagicString: l, interaction: u = "always", allowCopy: p = !0 } = e, { fitView: m, getNodes: h, getNodesBounds: v } = ml(), y = bd(), b = d(null), x = d(!1), S = d([]), [C, w] = f(null), [D, O] = f(!1), [k, A] = f(!1), j = d(null), [M, N] = f("mouse"), P = d(-Infinity), [F, I] = f(!1), [L, R] = f(!1), z = d([]), [B, V, H] = _d(t), [U, W, G] = vd(n), [ee, te] = f(void 0);
8902
+ let { nodes: t, edges: n, jsonText: r, breadcrumbs: i, onNavigate: o, onSelectionIds: s, onCopiedMagicString: l, interaction: u = "always", allowCopy: p = !0, allowSelection: m = !0 } = e, { fitView: h, getNodes: v, getNodesBounds: y } = ml(), b = bd(), x = d(null), S = d(!1), C = d([]), [w, D] = f(null), [O, k] = f(!1), [A, j] = f(!1), M = d(null), [N, P] = f("mouse"), F = d(-Infinity), [I, L] = f(!1), [R, z] = f(!1), B = d([]), [V, H, U] = _d(t), [W, G, ee] = vd(n), [te, ne] = f(void 0);
8903
8903
  c(() => {
8904
- if (!y) return;
8905
- let e = v(h());
8906
- te([[e.x, e.y], [e.x + e.width, e.y + e.height]]);
8904
+ if (!b) return;
8905
+ let e = y(v());
8906
+ ne([[e.x, e.y], [e.x + e.width, e.y + e.height]]);
8907
8907
  }, [
8908
- y,
8908
+ b,
8909
8909
  t,
8910
- h,
8911
- v
8910
+ v,
8911
+ y
8912
8912
  ]), c(() => {
8913
- V(t), s?.([]), x.current = !1, m(_p);
8913
+ H(t), s?.([]), S.current = !1, h(_p);
8914
8914
  }, [
8915
8915
  t,
8916
- V,
8916
+ H,
8917
8917
  s,
8918
- m
8918
+ h
8919
8919
  ]), c(() => {
8920
- W(n);
8921
- }, [n, W]), c(() => {
8922
- let e = b.current;
8920
+ G(n);
8921
+ }, [n, G]), c(() => {
8922
+ let e = x.current;
8923
8923
  if (!e) return;
8924
8924
  let t = new ResizeObserver(() => {
8925
- x.current || m(_p);
8925
+ S.current || h(_p);
8926
8926
  });
8927
8927
  return t.observe(e), () => t.disconnect();
8928
- }, [m]);
8929
- let ne = a((e) => {
8930
- e && (x.current = !0);
8931
- }, []), re = a(({ nodes: e }) => {
8928
+ }, [h]);
8929
+ let re = a((e) => {
8930
+ e && (S.current = !0);
8931
+ }, []), ie = a(({ nodes: e }) => {
8932
8932
  let t = e.map((e) => e.id);
8933
- S.current = t, s?.(t);
8934
- }, [s]), ie = a((e) => {
8933
+ C.current = t, s?.(t);
8934
+ }, [s]), ae = a((e) => {
8935
8935
  if (!p) return;
8936
8936
  e.preventDefault();
8937
- let t = b.current?.getBoundingClientRect();
8938
- w({
8937
+ let t = x.current?.getBoundingClientRect();
8938
+ D({
8939
8939
  x: e.clientX - (t?.left ?? 0),
8940
8940
  y: e.clientY - (t?.top ?? 0)
8941
8941
  });
8942
- }, [p]), ae = a(async () => {
8943
- w(null);
8942
+ }, [p]), oe = a(async () => {
8943
+ D(null);
8944
8944
  try {
8945
- let e = JSON.parse(r), t = new Set(S.current.map(Number).filter(Number.isFinite)), n = t.size > 0 ? E(e, t) : e, i = await T(JSON.stringify(n));
8945
+ let e = JSON.parse(r), t = new Set(C.current.map(Number).filter(Number.isFinite)), n = t.size > 0 ? E(e, t) : e, i = await T(JSON.stringify(n));
8946
8946
  if (await navigator.clipboard.writeText(i), l) {
8947
8947
  l();
8948
8948
  return;
8949
8949
  }
8950
- z.current.forEach(clearTimeout), R(!1), I(!0), z.current = [setTimeout(() => R(!0), 2500), setTimeout(() => {
8951
- I(!1), R(!1);
8950
+ B.current.forEach(clearTimeout), z(!1), L(!0), B.current = [setTimeout(() => z(!0), 2500), setTimeout(() => {
8951
+ L(!1), z(!1);
8952
8952
  }, 3e3)];
8953
8953
  } catch {}
8954
8954
  }, [r, l]);
8955
- c(() => () => z.current.forEach(clearTimeout), []), c(() => () => {
8956
- j.current && clearTimeout(j.current);
8955
+ c(() => () => B.current.forEach(clearTimeout), []), c(() => () => {
8956
+ M.current && clearTimeout(M.current);
8957
8957
  }, []);
8958
- let K = u === "hybrid", oe = u === "always" || K && D, se = oe && M === "mouse", ce = oe && M === "trackpad", le = [1];
8958
+ let K = u === "hybrid", se = u === "always" || K && O, ce = se && N === "mouse", le = se && N === "trackpad", ue = m ? [1] : [0, 1], de = m;
8959
8959
  c(() => {
8960
- let e = b.current;
8960
+ let e = x.current;
8961
8961
  if (!e) return;
8962
8962
  let t = (e) => {
8963
8963
  if (!e.ctrlKey) {
8964
- e.deltaX !== 0 && (P.current = e.timeStamp);
8965
- let t = e.timeStamp - P.current < 400 ? "trackpad" : "mouse";
8966
- N((e) => e === t ? e : t);
8964
+ e.deltaX !== 0 && (F.current = e.timeStamp);
8965
+ let t = e.timeStamp - F.current < 400 ? "trackpad" : "mouse";
8966
+ P((e) => e === t ? e : t);
8967
8967
  }
8968
- K && !D && !e.ctrlKey && (A(!0), j.current && clearTimeout(j.current), j.current = setTimeout(() => A(!1), 1600));
8968
+ K && !O && !e.ctrlKey && (j(!0), M.current && clearTimeout(M.current), M.current = setTimeout(() => j(!1), 1600));
8969
8969
  };
8970
8970
  return e.addEventListener("wheel", t, {
8971
8971
  capture: !0,
8972
8972
  passive: !0
8973
8973
  }), () => e.removeEventListener("wheel", t, { capture: !0 });
8974
- }, [K, D]);
8975
- let ue = a((e) => {
8976
- K && e.button === 0 && (O(!0), A(!1));
8977
- }, [K]), de = a(() => {
8978
- K && O(!1);
8974
+ }, [K, O]);
8975
+ let fe = a((e) => {
8976
+ K && e.button === 0 && (k(!0), j(!1));
8977
+ }, [K]), pe = a(() => {
8978
+ K && k(!1);
8979
8979
  }, [K]);
8980
8980
  return c(() => {
8981
- if (!C) return;
8982
- let e = () => w(null), t = (e) => {
8983
- e.key === "Escape" && w(null);
8981
+ if (!w) return;
8982
+ let e = () => D(null), t = (e) => {
8983
+ e.key === "Escape" && D(null);
8984
8984
  };
8985
8985
  return window.addEventListener("click", e), window.addEventListener("scroll", e, !0), window.addEventListener("keydown", t), () => {
8986
8986
  window.removeEventListener("click", e), window.removeEventListener("scroll", e, !0), window.removeEventListener("keydown", t);
8987
8987
  };
8988
- }, [C]), /* @__PURE__ */ _("div", {
8989
- ref: b,
8990
- className: `gn-canvas-wrapper${K && D ? " gn-canvas-wrapper--engaged" : ""}`,
8988
+ }, [w]), /* @__PURE__ */ _("div", {
8989
+ ref: x,
8990
+ className: `gn-canvas-wrapper${K && O ? " gn-canvas-wrapper--engaged" : ""}`,
8991
8991
  style: {
8992
8992
  width: "100%",
8993
8993
  height: "100%",
8994
8994
  position: "relative"
8995
8995
  },
8996
- onContextMenu: ie,
8997
- onPointerDown: ue,
8998
- onPointerLeave: de,
8996
+ onContextMenu: ae,
8997
+ onPointerDown: fe,
8998
+ onPointerLeave: pe,
8999
8999
  children: [
9000
9000
  /* @__PURE__ */ _(gd, {
9001
- nodes: B,
9002
- edges: U,
9003
- onNodesChange: H,
9004
- onEdgesChange: G,
9005
- onSelectionChange: re,
9006
- onMoveStart: ne,
9001
+ nodes: V,
9002
+ edges: W,
9003
+ onNodesChange: U,
9004
+ onEdgesChange: ee,
9005
+ onSelectionChange: ie,
9006
+ onMoveStart: re,
9007
9007
  nodeTypes: gp,
9008
9008
  fitView: !0,
9009
9009
  fitViewOptions: _p,
9010
9010
  minZoom: .2,
9011
- translateExtent: ee,
9011
+ translateExtent: te,
9012
9012
  nodesDraggable: !1,
9013
9013
  nodesConnectable: !1,
9014
- elementsSelectable: !0,
9014
+ elementsSelectable: m,
9015
9015
  nodesFocusable: !1,
9016
9016
  edgesFocusable: !1,
9017
9017
  selectNodesOnDrag: !1,
9018
- selectionOnDrag: !0,
9018
+ selectionOnDrag: de,
9019
9019
  selectionMode: Ca.Partial,
9020
9020
  connectOnClick: !1,
9021
- panOnDrag: le,
9022
- zoomOnScroll: se,
9023
- panOnScroll: ce,
9024
- preventScrolling: oe,
9021
+ panOnDrag: ue,
9022
+ zoomOnScroll: ce,
9023
+ panOnScroll: le,
9024
+ preventScrolling: se,
9025
9025
  zoomOnDoubleClick: !1,
9026
9026
  children: [
9027
9027
  /* @__PURE__ */ g(Dd, {
@@ -9030,7 +9030,7 @@ function vp(e) {
9030
9030
  color: "var(--grid-dot, #3a3a3a)"
9031
9031
  }),
9032
9032
  /* @__PURE__ */ g(Id, { showInteractive: !1 }),
9033
- K && k ? /* @__PURE__ */ g(Dc, {
9033
+ K && A ? /* @__PURE__ */ g(Dc, {
9034
9034
  position: "bottom-center",
9035
9035
  children: /* @__PURE__ */ g("div", {
9036
9036
  className: "gn-zoom-hint",
@@ -9044,7 +9044,7 @@ function vp(e) {
9044
9044
  className: "gn-top-left",
9045
9045
  children: [/* @__PURE__ */ _("span", {
9046
9046
  className: "gn-version-badge",
9047
- children: ["node-web-render v", "0.3.24"]
9047
+ children: ["node-web-render v", "0.3.25"]
9048
9048
  }), i.length > 1 ? /* @__PURE__ */ g("nav", {
9049
9049
  className: "gn-breadcrumbs",
9050
9050
  "aria-label": "Node group path",
@@ -9073,11 +9073,11 @@ function vp(e) {
9073
9073
  })
9074
9074
  ]
9075
9075
  }),
9076
- C ? /* @__PURE__ */ g("div", {
9076
+ w ? /* @__PURE__ */ g("div", {
9077
9077
  className: "gn-context-menu",
9078
9078
  style: {
9079
- left: C.x,
9080
- top: C.y
9079
+ left: w.x,
9080
+ top: w.y
9081
9081
  },
9082
9082
  onClick: (e) => e.stopPropagation(),
9083
9083
  role: "menu",
@@ -9085,12 +9085,12 @@ function vp(e) {
9085
9085
  type: "button",
9086
9086
  className: "gn-context-menu__item",
9087
9087
  role: "menuitem",
9088
- onClick: ae,
9088
+ onClick: oe,
9089
9089
  children: "Copy selected nodes to Tree Clipper magic string"
9090
9090
  })
9091
9091
  }) : null,
9092
- F || L ? /* @__PURE__ */ g("div", {
9093
- className: `gn-context-toast${L ? " gnwr-leaving" : ""}`,
9092
+ I || R ? /* @__PURE__ */ g("div", {
9093
+ className: `gn-context-toast${R ? " gnwr-leaving" : ""}`,
9094
9094
  role: "status",
9095
9095
  children: "Copied Tree Clipper magic string"
9096
9096
  }) : null
@@ -9098,10 +9098,10 @@ function vp(e) {
9098
9098
  });
9099
9099
  }
9100
9100
  function yp(e) {
9101
- let { jsonText: t, showHeader: n = !0, onSelectionChange: r, onCopiedMagicString: i, interaction: o = "always", allowCopy: s = !0 } = e, [l, d] = f({
9101
+ let { jsonText: t, showHeader: n = !0, onSelectionChange: r, onCopiedMagicString: i, interaction: o = "always", allowCopy: s = !0, allowSelection: l = !0 } = e, [d, p] = f({
9102
9102
  json: t,
9103
9103
  ids: []
9104
- }), p = u(() => {
9104
+ }), m = u(() => {
9105
9105
  if (!t.trim()) return null;
9106
9106
  try {
9107
9107
  let { rootId: e, trees: n } = xf(JSON.parse(t)), r = {};
@@ -9124,36 +9124,36 @@ function yp(e) {
9124
9124
  error: e instanceof Error ? e.message : String(e)
9125
9125
  };
9126
9126
  }
9127
- }, [t]), m = u(() => {
9128
- if (!p?.views) return [];
9129
- let e = l.json === t ? l.ids : [], n = [p.rootId];
9130
- for (let t of e) p.views[t] && n.push(t);
9127
+ }, [t]), h = u(() => {
9128
+ if (!m?.views) return [];
9129
+ let e = d.json === t ? d.ids : [], n = [m.rootId];
9130
+ for (let t of e) m.views[t] && n.push(t);
9131
9131
  return n;
9132
9132
  }, [
9133
- p,
9134
- l,
9133
+ m,
9134
+ d,
9135
9135
  t
9136
- ]), h = p?.views ? p.views[m[m.length - 1]] : null, v = a((e) => {
9137
- d((n) => ({
9136
+ ]), v = m?.views ? m.views[h[h.length - 1]] : null, y = a((e) => {
9137
+ p((n) => ({
9138
9138
  json: t,
9139
9139
  ids: n.json === t ? [...n.ids, e] : [e]
9140
9140
  }));
9141
- }, [t]), y = u(() => ({ openGroup: v }), [v]);
9141
+ }, [t]), b = u(() => ({ openGroup: y }), [y]);
9142
9142
  c(() => {
9143
- if (m.length <= 1) return;
9143
+ if (h.length <= 1) return;
9144
9144
  function e(e) {
9145
9145
  if (e.key !== "Tab" && e.key !== "Escape" || e.ctrlKey || e.metaKey || e.altKey) return;
9146
9146
  let n = e.target;
9147
- n && (n.isContentEditable || n.tagName === "INPUT" || n.tagName === "TEXTAREA" || n.closest(".cm-editor")) || (e.preventDefault(), d({
9147
+ n && (n.isContentEditable || n.tagName === "INPUT" || n.tagName === "TEXTAREA" || n.closest(".cm-editor")) || (e.preventDefault(), p({
9148
9148
  json: t,
9149
- ids: m.slice(1, -1)
9149
+ ids: h.slice(1, -1)
9150
9150
  }));
9151
9151
  }
9152
9152
  return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
9153
- }, [m, t]);
9154
- let b = p?.views ? m.map((e) => ({
9153
+ }, [h, t]);
9154
+ let x = m?.views ? h.map((e) => ({
9155
9155
  id: e,
9156
- label: p.views[e].graph.label
9156
+ label: m.views[e].graph.label
9157
9157
  })) : [];
9158
9158
  return /* @__PURE__ */ _("div", {
9159
9159
  className: "panel flow-panel",
@@ -9165,29 +9165,30 @@ function yp(e) {
9165
9165
  }), /* @__PURE__ */ g("div", {
9166
9166
  className: "panel-status",
9167
9167
  "aria-live": "polite",
9168
- children: h ? `${h.graph.nodes.length} nodes, ${h.graph.edges.length} links` : null
9168
+ children: v ? `${v.graph.nodes.length} nodes, ${v.graph.edges.length} links` : null
9169
9169
  })]
9170
9170
  }) : null, /* @__PURE__ */ g("div", {
9171
9171
  className: "panel-body flow-panel__body",
9172
- children: p?.error ? /* @__PURE__ */ _("div", {
9172
+ children: m?.error ? /* @__PURE__ */ _("div", {
9173
9173
  className: "flow-error",
9174
9174
  role: "alert",
9175
- children: [/* @__PURE__ */ g("strong", { children: "Parse error" }), /* @__PURE__ */ g("span", { children: p.error })]
9176
- }) : h ? /* @__PURE__ */ g(Kf.Provider, {
9177
- value: y,
9175
+ children: [/* @__PURE__ */ g("strong", { children: "Parse error" }), /* @__PURE__ */ g("span", { children: m.error })]
9176
+ }) : v ? /* @__PURE__ */ g(Kf.Provider, {
9177
+ value: b,
9178
9178
  children: /* @__PURE__ */ g(fd, { children: /* @__PURE__ */ g(vp, {
9179
- nodes: h.flow.nodes,
9180
- edges: h.flow.edges,
9179
+ nodes: v.flow.nodes,
9180
+ edges: v.flow.edges,
9181
9181
  jsonText: t,
9182
- breadcrumbs: b,
9183
- onNavigate: (e) => d({
9182
+ breadcrumbs: x,
9183
+ onNavigate: (e) => p({
9184
9184
  json: t,
9185
- ids: m.slice(1, e + 1)
9185
+ ids: h.slice(1, e + 1)
9186
9186
  }),
9187
9187
  onSelectionIds: r,
9188
9188
  onCopiedMagicString: i,
9189
9189
  interaction: o,
9190
- allowCopy: s
9190
+ allowCopy: s,
9191
+ allowSelection: l
9191
9192
  }) })
9192
9193
  }) : /* @__PURE__ */ g("div", {
9193
9194
  className: "flow-empty",
@@ -9260,38 +9261,38 @@ function bp({ className: e }) {
9260
9261
  //#endregion
9261
9262
  //#region src/embed.tsx
9262
9263
  function xp(e) {
9263
- let { payload: t, showCopyButton: n = !0 } = e, [r, i] = f(""), [a, o] = f(null), [s, l] = f(!0), [u, p] = f([]), [m, v] = f(!1), [y, b] = f(!1), S = d(!1), C = d(!1), w = d(null), D = d(null), O = d(null), k = () => {
9264
- !C.current || S.current || (b(!0), O.current && clearTimeout(O.current), O.current = setTimeout(() => {
9265
- v(!1), b(!1);
9264
+ let { payload: t, showCopyButton: n = !0, allowSelection: r = !0 } = e, [i, a] = f(""), [o, s] = f(null), [l, u] = f(!0), [p, m] = f([]), [v, y] = f(!1), [b, S] = f(!1), C = d(!1), w = d(!1), D = d(null), O = d(null), k = d(null), A = () => {
9265
+ !w.current || C.current || (S(!0), k.current && clearTimeout(k.current), k.current = setTimeout(() => {
9266
+ y(!1), S(!1);
9266
9267
  }, 500));
9267
- }, A = () => {
9268
- O.current && clearTimeout(O.current), b(!1), v(!0), C.current = !1, w.current && clearTimeout(w.current), w.current = setTimeout(() => {
9269
- C.current = !0, k();
9268
+ }, j = () => {
9269
+ k.current && clearTimeout(k.current), S(!1), y(!0), w.current = !1, D.current && clearTimeout(D.current), D.current = setTimeout(() => {
9270
+ w.current = !0, A();
9270
9271
  }, 3e3);
9271
- }, j = async () => {
9272
+ }, M = async () => {
9272
9273
  try {
9273
- let e = t, n = new Set(u.map(Number).filter(Number.isFinite));
9274
+ let e = t, n = new Set(p.map(Number).filter(Number.isFinite));
9274
9275
  if (n.size > 0) {
9275
- let t = E(JSON.parse(r), n);
9276
+ let t = E(JSON.parse(i), n);
9276
9277
  e = await T(JSON.stringify(t));
9277
9278
  }
9278
- await navigator.clipboard.writeText(e), A();
9279
+ await navigator.clipboard.writeText(e), j();
9279
9280
  } catch {}
9280
- }, M = () => {
9281
- S.current = !0, D.current && clearTimeout(D.current), y && (O.current && clearTimeout(O.current), b(!1));
9282
9281
  }, N = () => {
9283
- D.current && clearTimeout(D.current), D.current = setTimeout(() => {
9284
- S.current = !1, k();
9282
+ C.current = !0, O.current && clearTimeout(O.current), b && (k.current && clearTimeout(k.current), S(!1));
9283
+ }, P = () => {
9284
+ O.current && clearTimeout(O.current), O.current = setTimeout(() => {
9285
+ C.current = !1, A();
9285
9286
  }, 150);
9286
9287
  };
9287
9288
  return c(() => () => {
9288
- w.current && clearTimeout(w.current), D.current && clearTimeout(D.current), O.current && clearTimeout(O.current);
9289
+ D.current && clearTimeout(D.current), O.current && clearTimeout(O.current), k.current && clearTimeout(k.current);
9289
9290
  }, []), c(() => {
9290
9291
  let e = !1;
9291
- return l(!0), o(null), x(t).then((t) => {
9292
- e || (i(t), l(!1));
9292
+ return u(!0), s(null), x(t).then((t) => {
9293
+ e || (a(t), u(!1));
9293
9294
  }).catch((t) => {
9294
- e || (o(t instanceof Error ? t.message : String(t)), l(!1));
9295
+ e || (s(t instanceof Error ? t.message : String(t)), u(!1));
9295
9296
  }), () => {
9296
9297
  e = !0;
9297
9298
  };
@@ -9299,7 +9300,7 @@ function xp(e) {
9299
9300
  className: "geonodes-embed geonodes-embed--dark",
9300
9301
  children: /* @__PURE__ */ g("div", {
9301
9302
  className: "geonodes-embed__body",
9302
- children: s ? /* @__PURE__ */ _("div", {
9303
+ children: l ? /* @__PURE__ */ _("div", {
9303
9304
  className: "gnwr-loading",
9304
9305
  role: "status",
9305
9306
  "aria-live": "polite",
@@ -9307,25 +9308,26 @@ function xp(e) {
9307
9308
  className: "gnwr-loading__label",
9308
9309
  children: "Loading graph…"
9309
9310
  })]
9310
- }) : a ? /* @__PURE__ */ _("div", {
9311
+ }) : o ? /* @__PURE__ */ _("div", {
9311
9312
  className: "flow-error",
9312
9313
  role: "alert",
9313
- children: [/* @__PURE__ */ g("strong", { children: "Decode error" }), /* @__PURE__ */ g("span", { children: a })]
9314
+ children: [/* @__PURE__ */ g("strong", { children: "Decode error" }), /* @__PURE__ */ g("span", { children: o })]
9314
9315
  }) : /* @__PURE__ */ _(h, { children: [/* @__PURE__ */ g(yp, {
9315
- jsonText: r,
9316
+ jsonText: i,
9316
9317
  showHeader: !1,
9317
9318
  interaction: "hybrid",
9318
- onSelectionChange: p,
9319
- onCopiedMagicString: A,
9320
- allowCopy: n
9319
+ onSelectionChange: m,
9320
+ onCopiedMagicString: j,
9321
+ allowCopy: n,
9322
+ allowSelection: r
9321
9323
  }), n && /* @__PURE__ */ _(h, { children: [/* @__PURE__ */ g("button", {
9322
9324
  type: "button",
9323
- className: `gnwr-copy-button${m || y ? " gnwr-copy-button--copied" : ""}`,
9324
- onClick: j,
9325
- onMouseEnter: M,
9326
- onMouseLeave: N,
9325
+ className: `gnwr-copy-button${v || b ? " gnwr-copy-button--copied" : ""}`,
9326
+ onClick: M,
9327
+ onMouseEnter: N,
9328
+ onMouseLeave: P,
9327
9329
  title: "Copy the Tree Clipper magic string — paste into Blender with the Tree Clipper add-on",
9328
- children: m || y ? /* @__PURE__ */ _(h, { children: [/* @__PURE__ */ g("svg", {
9330
+ children: v || b ? /* @__PURE__ */ _(h, { children: [/* @__PURE__ */ g("svg", {
9329
9331
  className: "gnwr-copy-button__check",
9330
9332
  viewBox: "0 0 24 24",
9331
9333
  "aria-hidden": "true",
@@ -9337,12 +9339,12 @@ function xp(e) {
9337
9339
  strokeLinecap: "round",
9338
9340
  strokeLinejoin: "round"
9339
9341
  })
9340
- }), /* @__PURE__ */ g("span", { children: "Copied!" })] }) : /* @__PURE__ */ _(h, { children: [/* @__PURE__ */ g(bp, { className: "gnwr-copy-button__logo" }), /* @__PURE__ */ g("span", { children: u.length > 0 ? `Copy Magic String of ${u.length} selected node${u.length === 1 ? "" : "s"}` : "Copy TreeClipper Magic String" })] })
9341
- }), (m || y) && /* @__PURE__ */ _("div", {
9342
- className: `gnwr-copy-toast${y ? " gnwr-leaving" : ""}`,
9342
+ }), /* @__PURE__ */ g("span", { children: "Copied!" })] }) : /* @__PURE__ */ _(h, { children: [/* @__PURE__ */ g(bp, { className: "gnwr-copy-button__logo" }), /* @__PURE__ */ g("span", { children: p.length > 0 ? `Copy Magic String of ${p.length} selected node${p.length === 1 ? "" : "s"}` : "Copy TreeClipper Magic String" })] })
9343
+ }), (v || b) && /* @__PURE__ */ _("div", {
9344
+ className: `gnwr-copy-toast${b ? " gnwr-leaving" : ""}`,
9343
9345
  role: "status",
9344
- onMouseEnter: M,
9345
- onMouseLeave: N,
9346
+ onMouseEnter: N,
9347
+ onMouseLeave: P,
9346
9348
  children: [
9347
9349
  "Now, you can use this magic string in Blender with the",
9348
9350
  " ",
@@ -6,6 +6,9 @@ export type GraphViewEmbedOptions = {
6
6
  /** When false, hide the "Copy TreeClipper Magic String" button and disable the
7
7
  * right-click copy action. Default true. */
8
8
  showCopyButton?: boolean;
9
+ /** When false, disable node selection; left-drag pans instead of box-selecting.
10
+ * Default true. */
11
+ allowSelection?: boolean;
9
12
  };
10
13
  export declare function GraphView(props: GraphViewEmbedOptions): import("react").JSX.Element;
11
14
  /**
@@ -23,4 +23,7 @@ export declare function GeometryNodesFlow(props: {
23
23
  /** When false, disable copying to a Tree Clipper magic string (hides the
24
24
  * right-click "copy" context menu). Default true. */
25
25
  allowCopy?: boolean;
26
+ /** When false, disable node selection; left-drag pans instead of box-selecting.
27
+ * Default true. */
28
+ allowSelection?: boolean;
26
29
  }): import("react").JSX.Element;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "geonodes-web-render",
3
- "version": "0.3.24",
3
+ "version": "0.3.25",
4
4
  "description": "Browser-based viewer for Blender Geometry Nodes exported via Tree Clipper. Renders node trees as a read-only, Blender-styled graph.",
5
5
  "type": "module",
6
6
  "exports": {