@almadar/ui 5.58.0 → 5.60.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -38389,6 +38389,12 @@ function getGroupColor(group, groups) {
38389
38389
  const idx = groups.indexOf(group);
38390
38390
  return GROUP_COLORS2[idx % GROUP_COLORS2.length];
38391
38391
  }
38392
+ function resolveColor2(color, el) {
38393
+ const m = /^var\((--[^,)]+)(?:,\s*([^)]+))?\)$/.exec(color.trim());
38394
+ if (!m) return color;
38395
+ const resolved = getComputedStyle(el).getPropertyValue(m[1]).trim();
38396
+ return resolved || (m[2]?.trim() ?? "#888888");
38397
+ }
38392
38398
  var GROUP_COLORS2; exports.GraphCanvas = void 0;
38393
38399
  var init_GraphCanvas = __esm({
38394
38400
  "components/core/molecules/GraphCanvas.tsx"() {
@@ -38419,6 +38425,9 @@ var init_GraphCanvas = __esm({
38419
38425
  actions,
38420
38426
  onNodeClick,
38421
38427
  nodeClickEvent,
38428
+ selectedNodeId,
38429
+ repulsion = 800,
38430
+ linkDistance = 100,
38422
38431
  layout = "force",
38423
38432
  entity,
38424
38433
  isLoading = false,
@@ -38434,6 +38443,37 @@ var init_GraphCanvas = __esm({
38434
38443
  const [hoveredNode, setHoveredNode] = React76.useState(null);
38435
38444
  const nodesRef = React76.useRef([]);
38436
38445
  const [, forceUpdate] = React76.useState(0);
38446
+ const interactionRef = React76.useRef({
38447
+ mode: "none",
38448
+ dragNodeId: null,
38449
+ startMouse: { x: 0, y: 0 },
38450
+ startOffset: { x: 0, y: 0 },
38451
+ downPos: { x: 0, y: 0 }
38452
+ });
38453
+ const toCoords = React76.useCallback(
38454
+ (e) => {
38455
+ const canvas = canvasRef.current;
38456
+ if (!canvas) return null;
38457
+ const rect = canvas.getBoundingClientRect();
38458
+ const scaleX = rect.width > 0 ? canvas.width / rect.width : 1;
38459
+ const scaleY = rect.height > 0 ? canvas.height / rect.height : 1;
38460
+ const screenX = (e.clientX - rect.left) * scaleX;
38461
+ const screenY = (e.clientY - rect.top) * scaleY;
38462
+ return {
38463
+ screenX,
38464
+ screenY,
38465
+ graphX: (screenX - offset.x) / zoom,
38466
+ graphY: (screenY - offset.y) / zoom
38467
+ };
38468
+ },
38469
+ [offset, zoom]
38470
+ );
38471
+ const nodeAt = React76.useCallback((graphX, graphY) => {
38472
+ return nodesRef.current.find((n) => {
38473
+ const dist = Math.sqrt((n.x - graphX) ** 2 + (n.y - graphY) ** 2);
38474
+ return dist < (n.size || 8) + 4;
38475
+ });
38476
+ }, []);
38437
38477
  const handleAction = React76.useCallback(
38438
38478
  (action) => {
38439
38479
  if (action.event) {
@@ -38499,7 +38539,7 @@ var init_GraphCanvas = __esm({
38499
38539
  const dx = nodes[j].x - nodes[i].x;
38500
38540
  const dy = nodes[j].y - nodes[i].y;
38501
38541
  const dist = Math.sqrt(dx * dx + dy * dy) || 1;
38502
- const force = 800 / (dist * dist);
38542
+ const force = repulsion / (dist * dist);
38503
38543
  const fx = dx / dist * force;
38504
38544
  const fy = dy / dist * force;
38505
38545
  nodes[i].fx -= fx;
@@ -38515,7 +38555,7 @@ var init_GraphCanvas = __esm({
38515
38555
  const dx = target.x - source.x;
38516
38556
  const dy = target.y - source.y;
38517
38557
  const dist = Math.sqrt(dx * dx + dy * dy) || 1;
38518
- const force = (dist - 100) * 0.05;
38558
+ const force = (dist - linkDistance) * 0.05;
38519
38559
  const fx = dx / dist * force;
38520
38560
  const fy = dy / dist * force;
38521
38561
  source.fx += fx;
@@ -38549,7 +38589,7 @@ var init_GraphCanvas = __esm({
38549
38589
  return () => {
38550
38590
  cancelAnimationFrame(animRef.current);
38551
38591
  };
38552
- }, [propNodes, propEdges, layout]);
38592
+ }, [propNodes, propEdges, layout, repulsion, linkDistance]);
38553
38593
  React76.useEffect(() => {
38554
38594
  const canvas = canvasRef.current;
38555
38595
  if (!canvas) return;
@@ -38558,6 +38598,7 @@ var init_GraphCanvas = __esm({
38558
38598
  const w = canvas.width;
38559
38599
  const h = canvas.height;
38560
38600
  const nodes = nodesRef.current;
38601
+ const accentColor = resolveColor2("var(--color-accent)", canvas);
38561
38602
  ctx.clearRect(0, 0, w, h);
38562
38603
  ctx.save();
38563
38604
  ctx.translate(offset.x, offset.y);
@@ -38583,20 +38624,27 @@ var init_GraphCanvas = __esm({
38583
38624
  }
38584
38625
  for (const node of nodes) {
38585
38626
  const size = node.size || 8;
38586
- const color = node.color || getGroupColor(node.group, groups);
38627
+ const color = resolveColor2(node.color || getGroupColor(node.group, groups), canvas);
38587
38628
  const isHovered = hoveredNode === node.id;
38629
+ const isSelected = selectedNodeId !== void 0 && node.id === selectedNodeId;
38630
+ const radius = isSelected ? size + 4 : isHovered ? size + 2 : size;
38588
38631
  ctx.beginPath();
38589
- ctx.arc(node.x, node.y, isHovered ? size + 2 : size, 0, Math.PI * 2);
38632
+ ctx.arc(node.x, node.y, radius, 0, Math.PI * 2);
38590
38633
  ctx.fillStyle = color;
38591
38634
  ctx.fill();
38592
- ctx.strokeStyle = isHovered ? "#ffffff" : "#00000020";
38593
- ctx.lineWidth = isHovered ? 2 : 1;
38635
+ if (isSelected) {
38636
+ ctx.strokeStyle = accentColor;
38637
+ ctx.lineWidth = 3;
38638
+ } else {
38639
+ ctx.strokeStyle = isHovered ? "#ffffff" : "#00000020";
38640
+ ctx.lineWidth = isHovered ? 2 : 1;
38641
+ }
38594
38642
  ctx.stroke();
38595
38643
  if (showLabels && node.label) {
38596
38644
  ctx.fillStyle = "#666666";
38597
- ctx.font = `${isHovered ? "bold " : ""}10px system-ui`;
38645
+ ctx.font = `${isSelected || isHovered ? "bold " : ""}10px system-ui`;
38598
38646
  ctx.textAlign = "center";
38599
- ctx.fillText(node.label, node.x, node.y + size + 12);
38647
+ ctx.fillText(node.label, node.x, node.y + radius + 12);
38600
38648
  }
38601
38649
  }
38602
38650
  ctx.restore();
@@ -38607,6 +38655,97 @@ var init_GraphCanvas = __esm({
38607
38655
  setZoom(1);
38608
38656
  setOffset({ x: 0, y: 0 });
38609
38657
  }, []);
38658
+ const handleWheel = React76.useCallback(
38659
+ (e) => {
38660
+ if (!interactive) return;
38661
+ e.preventDefault();
38662
+ const coords = toCoords(e);
38663
+ if (!coords) return;
38664
+ const oldZoom = zoom;
38665
+ const factor = e.deltaY < 0 ? 1.1 : 1 / 1.1;
38666
+ const newZoom = Math.max(0.3, Math.min(3, oldZoom * factor));
38667
+ if (newZoom === oldZoom) return;
38668
+ setOffset((o) => ({
38669
+ x: coords.screenX - (coords.screenX - o.x) * (newZoom / oldZoom),
38670
+ y: coords.screenY - (coords.screenY - o.y) * (newZoom / oldZoom)
38671
+ }));
38672
+ setZoom(newZoom);
38673
+ },
38674
+ [interactive, toCoords, zoom]
38675
+ );
38676
+ const handleMouseDown = React76.useCallback(
38677
+ (e) => {
38678
+ const coords = toCoords(e);
38679
+ if (!coords) return;
38680
+ const node = nodeAt(coords.graphX, coords.graphY);
38681
+ const state = interactionRef.current;
38682
+ state.downPos = { x: e.clientX, y: e.clientY };
38683
+ state.startMouse = { x: e.clientX, y: e.clientY };
38684
+ state.startOffset = { ...offset };
38685
+ if (draggable && node) {
38686
+ state.mode = "dragging";
38687
+ state.dragNodeId = node.id;
38688
+ } else if (interactive) {
38689
+ state.mode = "panning";
38690
+ state.dragNodeId = null;
38691
+ } else {
38692
+ state.mode = "none";
38693
+ state.dragNodeId = null;
38694
+ }
38695
+ },
38696
+ [toCoords, nodeAt, draggable, interactive, offset]
38697
+ );
38698
+ const handleMouseMove = React76.useCallback(
38699
+ (e) => {
38700
+ const state = interactionRef.current;
38701
+ if (state.mode === "panning") {
38702
+ const dx = e.clientX - state.startMouse.x;
38703
+ const dy = e.clientY - state.startMouse.y;
38704
+ setOffset({ x: state.startOffset.x + dx, y: state.startOffset.y + dy });
38705
+ return;
38706
+ }
38707
+ if (state.mode === "dragging" && state.dragNodeId) {
38708
+ const coords2 = toCoords(e);
38709
+ if (!coords2) return;
38710
+ const node2 = nodesRef.current.find((n) => n.id === state.dragNodeId);
38711
+ if (node2) {
38712
+ node2.x = coords2.graphX;
38713
+ node2.y = coords2.graphY;
38714
+ node2.vx = 0;
38715
+ node2.vy = 0;
38716
+ forceUpdate((n) => n + 1);
38717
+ }
38718
+ return;
38719
+ }
38720
+ const coords = toCoords(e);
38721
+ if (!coords) return;
38722
+ const node = nodeAt(coords.graphX, coords.graphY);
38723
+ setHoveredNode(node?.id ?? null);
38724
+ },
38725
+ [toCoords, nodeAt]
38726
+ );
38727
+ const handleMouseUp = React76.useCallback(
38728
+ (e) => {
38729
+ const state = interactionRef.current;
38730
+ const moved = Math.abs(e.clientX - state.downPos.x) + Math.abs(e.clientY - state.downPos.y);
38731
+ state.mode = "none";
38732
+ state.dragNodeId = null;
38733
+ if (moved < 4) {
38734
+ const coords = toCoords(e);
38735
+ if (!coords) return;
38736
+ const node = nodeAt(coords.graphX, coords.graphY);
38737
+ if (node) {
38738
+ handleNodeClick(node);
38739
+ }
38740
+ }
38741
+ },
38742
+ [toCoords, nodeAt, handleNodeClick]
38743
+ );
38744
+ const handleMouseLeave = React76.useCallback(() => {
38745
+ interactionRef.current.mode = "none";
38746
+ interactionRef.current.dragNodeId = null;
38747
+ setHoveredNode(null);
38748
+ }, []);
38610
38749
  if (isLoading) {
38611
38750
  return /* @__PURE__ */ jsxRuntime.jsx(exports.LoadingState, { message: t("common.loading"), className });
38612
38751
  }
@@ -38668,20 +38807,11 @@ var init_GraphCanvas = __esm({
38668
38807
  height,
38669
38808
  className: "w-full cursor-grab active:cursor-grabbing",
38670
38809
  style: { height },
38671
- onClick: (e) => {
38672
- const canvas = canvasRef.current;
38673
- if (!canvas) return;
38674
- const rect = canvas.getBoundingClientRect();
38675
- const x = (e.clientX - rect.left - offset.x) / zoom;
38676
- const y = (e.clientY - rect.top - offset.y) / zoom;
38677
- const clickedNode = nodesRef.current.find((n) => {
38678
- const dist = Math.sqrt((n.x - x) ** 2 + (n.y - y) ** 2);
38679
- return dist < (n.size || 8) + 4;
38680
- });
38681
- if (clickedNode) {
38682
- handleNodeClick(clickedNode);
38683
- }
38684
- }
38810
+ onWheel: handleWheel,
38811
+ onMouseDown: handleMouseDown,
38812
+ onMouseMove: handleMouseMove,
38813
+ onMouseUp: handleMouseUp,
38814
+ onMouseLeave: handleMouseLeave
38685
38815
  }
38686
38816
  ) }),
38687
38817
  groups.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(exports.HStack, { gap: "md", className: "px-4 py-2 border-t border-border", wrap: true, children: groups.map((group, idx) => /* @__PURE__ */ jsxRuntime.jsxs(exports.HStack, { gap: "xs", align: "center", children: [
@@ -38343,6 +38343,12 @@ function getGroupColor(group, groups) {
38343
38343
  const idx = groups.indexOf(group);
38344
38344
  return GROUP_COLORS2[idx % GROUP_COLORS2.length];
38345
38345
  }
38346
+ function resolveColor2(color, el) {
38347
+ const m = /^var\((--[^,)]+)(?:,\s*([^)]+))?\)$/.exec(color.trim());
38348
+ if (!m) return color;
38349
+ const resolved = getComputedStyle(el).getPropertyValue(m[1]).trim();
38350
+ return resolved || (m[2]?.trim() ?? "#888888");
38351
+ }
38346
38352
  var GROUP_COLORS2, GraphCanvas;
38347
38353
  var init_GraphCanvas = __esm({
38348
38354
  "components/core/molecules/GraphCanvas.tsx"() {
@@ -38373,6 +38379,9 @@ var init_GraphCanvas = __esm({
38373
38379
  actions,
38374
38380
  onNodeClick,
38375
38381
  nodeClickEvent,
38382
+ selectedNodeId,
38383
+ repulsion = 800,
38384
+ linkDistance = 100,
38376
38385
  layout = "force",
38377
38386
  entity,
38378
38387
  isLoading = false,
@@ -38388,6 +38397,37 @@ var init_GraphCanvas = __esm({
38388
38397
  const [hoveredNode, setHoveredNode] = useState(null);
38389
38398
  const nodesRef = useRef([]);
38390
38399
  const [, forceUpdate] = useState(0);
38400
+ const interactionRef = useRef({
38401
+ mode: "none",
38402
+ dragNodeId: null,
38403
+ startMouse: { x: 0, y: 0 },
38404
+ startOffset: { x: 0, y: 0 },
38405
+ downPos: { x: 0, y: 0 }
38406
+ });
38407
+ const toCoords = useCallback(
38408
+ (e) => {
38409
+ const canvas = canvasRef.current;
38410
+ if (!canvas) return null;
38411
+ const rect = canvas.getBoundingClientRect();
38412
+ const scaleX = rect.width > 0 ? canvas.width / rect.width : 1;
38413
+ const scaleY = rect.height > 0 ? canvas.height / rect.height : 1;
38414
+ const screenX = (e.clientX - rect.left) * scaleX;
38415
+ const screenY = (e.clientY - rect.top) * scaleY;
38416
+ return {
38417
+ screenX,
38418
+ screenY,
38419
+ graphX: (screenX - offset.x) / zoom,
38420
+ graphY: (screenY - offset.y) / zoom
38421
+ };
38422
+ },
38423
+ [offset, zoom]
38424
+ );
38425
+ const nodeAt = useCallback((graphX, graphY) => {
38426
+ return nodesRef.current.find((n) => {
38427
+ const dist = Math.sqrt((n.x - graphX) ** 2 + (n.y - graphY) ** 2);
38428
+ return dist < (n.size || 8) + 4;
38429
+ });
38430
+ }, []);
38391
38431
  const handleAction = useCallback(
38392
38432
  (action) => {
38393
38433
  if (action.event) {
@@ -38453,7 +38493,7 @@ var init_GraphCanvas = __esm({
38453
38493
  const dx = nodes[j].x - nodes[i].x;
38454
38494
  const dy = nodes[j].y - nodes[i].y;
38455
38495
  const dist = Math.sqrt(dx * dx + dy * dy) || 1;
38456
- const force = 800 / (dist * dist);
38496
+ const force = repulsion / (dist * dist);
38457
38497
  const fx = dx / dist * force;
38458
38498
  const fy = dy / dist * force;
38459
38499
  nodes[i].fx -= fx;
@@ -38469,7 +38509,7 @@ var init_GraphCanvas = __esm({
38469
38509
  const dx = target.x - source.x;
38470
38510
  const dy = target.y - source.y;
38471
38511
  const dist = Math.sqrt(dx * dx + dy * dy) || 1;
38472
- const force = (dist - 100) * 0.05;
38512
+ const force = (dist - linkDistance) * 0.05;
38473
38513
  const fx = dx / dist * force;
38474
38514
  const fy = dy / dist * force;
38475
38515
  source.fx += fx;
@@ -38503,7 +38543,7 @@ var init_GraphCanvas = __esm({
38503
38543
  return () => {
38504
38544
  cancelAnimationFrame(animRef.current);
38505
38545
  };
38506
- }, [propNodes, propEdges, layout]);
38546
+ }, [propNodes, propEdges, layout, repulsion, linkDistance]);
38507
38547
  useEffect(() => {
38508
38548
  const canvas = canvasRef.current;
38509
38549
  if (!canvas) return;
@@ -38512,6 +38552,7 @@ var init_GraphCanvas = __esm({
38512
38552
  const w = canvas.width;
38513
38553
  const h = canvas.height;
38514
38554
  const nodes = nodesRef.current;
38555
+ const accentColor = resolveColor2("var(--color-accent)", canvas);
38515
38556
  ctx.clearRect(0, 0, w, h);
38516
38557
  ctx.save();
38517
38558
  ctx.translate(offset.x, offset.y);
@@ -38537,20 +38578,27 @@ var init_GraphCanvas = __esm({
38537
38578
  }
38538
38579
  for (const node of nodes) {
38539
38580
  const size = node.size || 8;
38540
- const color = node.color || getGroupColor(node.group, groups);
38581
+ const color = resolveColor2(node.color || getGroupColor(node.group, groups), canvas);
38541
38582
  const isHovered = hoveredNode === node.id;
38583
+ const isSelected = selectedNodeId !== void 0 && node.id === selectedNodeId;
38584
+ const radius = isSelected ? size + 4 : isHovered ? size + 2 : size;
38542
38585
  ctx.beginPath();
38543
- ctx.arc(node.x, node.y, isHovered ? size + 2 : size, 0, Math.PI * 2);
38586
+ ctx.arc(node.x, node.y, radius, 0, Math.PI * 2);
38544
38587
  ctx.fillStyle = color;
38545
38588
  ctx.fill();
38546
- ctx.strokeStyle = isHovered ? "#ffffff" : "#00000020";
38547
- ctx.lineWidth = isHovered ? 2 : 1;
38589
+ if (isSelected) {
38590
+ ctx.strokeStyle = accentColor;
38591
+ ctx.lineWidth = 3;
38592
+ } else {
38593
+ ctx.strokeStyle = isHovered ? "#ffffff" : "#00000020";
38594
+ ctx.lineWidth = isHovered ? 2 : 1;
38595
+ }
38548
38596
  ctx.stroke();
38549
38597
  if (showLabels && node.label) {
38550
38598
  ctx.fillStyle = "#666666";
38551
- ctx.font = `${isHovered ? "bold " : ""}10px system-ui`;
38599
+ ctx.font = `${isSelected || isHovered ? "bold " : ""}10px system-ui`;
38552
38600
  ctx.textAlign = "center";
38553
- ctx.fillText(node.label, node.x, node.y + size + 12);
38601
+ ctx.fillText(node.label, node.x, node.y + radius + 12);
38554
38602
  }
38555
38603
  }
38556
38604
  ctx.restore();
@@ -38561,6 +38609,97 @@ var init_GraphCanvas = __esm({
38561
38609
  setZoom(1);
38562
38610
  setOffset({ x: 0, y: 0 });
38563
38611
  }, []);
38612
+ const handleWheel = useCallback(
38613
+ (e) => {
38614
+ if (!interactive) return;
38615
+ e.preventDefault();
38616
+ const coords = toCoords(e);
38617
+ if (!coords) return;
38618
+ const oldZoom = zoom;
38619
+ const factor = e.deltaY < 0 ? 1.1 : 1 / 1.1;
38620
+ const newZoom = Math.max(0.3, Math.min(3, oldZoom * factor));
38621
+ if (newZoom === oldZoom) return;
38622
+ setOffset((o) => ({
38623
+ x: coords.screenX - (coords.screenX - o.x) * (newZoom / oldZoom),
38624
+ y: coords.screenY - (coords.screenY - o.y) * (newZoom / oldZoom)
38625
+ }));
38626
+ setZoom(newZoom);
38627
+ },
38628
+ [interactive, toCoords, zoom]
38629
+ );
38630
+ const handleMouseDown = useCallback(
38631
+ (e) => {
38632
+ const coords = toCoords(e);
38633
+ if (!coords) return;
38634
+ const node = nodeAt(coords.graphX, coords.graphY);
38635
+ const state = interactionRef.current;
38636
+ state.downPos = { x: e.clientX, y: e.clientY };
38637
+ state.startMouse = { x: e.clientX, y: e.clientY };
38638
+ state.startOffset = { ...offset };
38639
+ if (draggable && node) {
38640
+ state.mode = "dragging";
38641
+ state.dragNodeId = node.id;
38642
+ } else if (interactive) {
38643
+ state.mode = "panning";
38644
+ state.dragNodeId = null;
38645
+ } else {
38646
+ state.mode = "none";
38647
+ state.dragNodeId = null;
38648
+ }
38649
+ },
38650
+ [toCoords, nodeAt, draggable, interactive, offset]
38651
+ );
38652
+ const handleMouseMove = useCallback(
38653
+ (e) => {
38654
+ const state = interactionRef.current;
38655
+ if (state.mode === "panning") {
38656
+ const dx = e.clientX - state.startMouse.x;
38657
+ const dy = e.clientY - state.startMouse.y;
38658
+ setOffset({ x: state.startOffset.x + dx, y: state.startOffset.y + dy });
38659
+ return;
38660
+ }
38661
+ if (state.mode === "dragging" && state.dragNodeId) {
38662
+ const coords2 = toCoords(e);
38663
+ if (!coords2) return;
38664
+ const node2 = nodesRef.current.find((n) => n.id === state.dragNodeId);
38665
+ if (node2) {
38666
+ node2.x = coords2.graphX;
38667
+ node2.y = coords2.graphY;
38668
+ node2.vx = 0;
38669
+ node2.vy = 0;
38670
+ forceUpdate((n) => n + 1);
38671
+ }
38672
+ return;
38673
+ }
38674
+ const coords = toCoords(e);
38675
+ if (!coords) return;
38676
+ const node = nodeAt(coords.graphX, coords.graphY);
38677
+ setHoveredNode(node?.id ?? null);
38678
+ },
38679
+ [toCoords, nodeAt]
38680
+ );
38681
+ const handleMouseUp = useCallback(
38682
+ (e) => {
38683
+ const state = interactionRef.current;
38684
+ const moved = Math.abs(e.clientX - state.downPos.x) + Math.abs(e.clientY - state.downPos.y);
38685
+ state.mode = "none";
38686
+ state.dragNodeId = null;
38687
+ if (moved < 4) {
38688
+ const coords = toCoords(e);
38689
+ if (!coords) return;
38690
+ const node = nodeAt(coords.graphX, coords.graphY);
38691
+ if (node) {
38692
+ handleNodeClick(node);
38693
+ }
38694
+ }
38695
+ },
38696
+ [toCoords, nodeAt, handleNodeClick]
38697
+ );
38698
+ const handleMouseLeave = useCallback(() => {
38699
+ interactionRef.current.mode = "none";
38700
+ interactionRef.current.dragNodeId = null;
38701
+ setHoveredNode(null);
38702
+ }, []);
38564
38703
  if (isLoading) {
38565
38704
  return /* @__PURE__ */ jsx(LoadingState, { message: t("common.loading"), className });
38566
38705
  }
@@ -38622,20 +38761,11 @@ var init_GraphCanvas = __esm({
38622
38761
  height,
38623
38762
  className: "w-full cursor-grab active:cursor-grabbing",
38624
38763
  style: { height },
38625
- onClick: (e) => {
38626
- const canvas = canvasRef.current;
38627
- if (!canvas) return;
38628
- const rect = canvas.getBoundingClientRect();
38629
- const x = (e.clientX - rect.left - offset.x) / zoom;
38630
- const y = (e.clientY - rect.top - offset.y) / zoom;
38631
- const clickedNode = nodesRef.current.find((n) => {
38632
- const dist = Math.sqrt((n.x - x) ** 2 + (n.y - y) ** 2);
38633
- return dist < (n.size || 8) + 4;
38634
- });
38635
- if (clickedNode) {
38636
- handleNodeClick(clickedNode);
38637
- }
38638
- }
38764
+ onWheel: handleWheel,
38765
+ onMouseDown: handleMouseDown,
38766
+ onMouseMove: handleMouseMove,
38767
+ onMouseUp: handleMouseUp,
38768
+ onMouseLeave: handleMouseLeave
38639
38769
  }
38640
38770
  ) }),
38641
38771
  groups.length > 1 && /* @__PURE__ */ jsx(HStack, { gap: "md", className: "px-4 py-2 border-t border-border", wrap: true, children: groups.map((group, idx) => /* @__PURE__ */ jsxs(HStack, { gap: "xs", align: "center", children: [