@archie/devtools 0.0.43 → 0.0.45

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.
@@ -616,44 +616,6 @@ function getFirstCollision(collisions, property) {
616
616
  const [firstCollision] = collisions;
617
617
  return property ? firstCollision[property] : firstCollision;
618
618
  }
619
- function centerOfRectangle(rect, left, top) {
620
- if (left === void 0) {
621
- left = rect.left;
622
- }
623
- if (top === void 0) {
624
- top = rect.top;
625
- }
626
- return {
627
- x: left + rect.width * 0.5,
628
- y: top + rect.height * 0.5
629
- };
630
- }
631
- var closestCenter = (_ref) => {
632
- let {
633
- collisionRect,
634
- droppableRects,
635
- droppableContainers
636
- } = _ref;
637
- const centerRect = centerOfRectangle(collisionRect, collisionRect.left, collisionRect.top);
638
- const collisions = [];
639
- for (const droppableContainer of droppableContainers) {
640
- const {
641
- id
642
- } = droppableContainer;
643
- const rect = droppableRects.get(id);
644
- if (rect) {
645
- const distBetween = distanceBetween(centerOfRectangle(rect), centerRect);
646
- collisions.push({
647
- id,
648
- data: {
649
- droppableContainer,
650
- value: distBetween
651
- }
652
- });
653
- }
654
- }
655
- return collisions.sort(sortCollisionsAsc);
656
- };
657
619
  var closestCorners = (_ref) => {
658
620
  let {
659
621
  collisionRect,
@@ -5259,8 +5221,10 @@ function ensureUniqueNodeId(base, used) {
5259
5221
  while (used.has(`${base}::${idx}`)) idx += 1;
5260
5222
  return `${base}::${idx}`;
5261
5223
  }
5224
+ var INSERT_NODE_ID_PREFIX = "insert:";
5262
5225
  function resolveStableNodeId(el, used) {
5263
5226
  const persisted = el.getAttribute(DND_NODE_ID_ATTR);
5227
+ if (persisted && persisted.startsWith(INSERT_NODE_ID_PREFIX)) return persisted;
5264
5228
  if (persisted && !used.has(persisted)) return persisted;
5265
5229
  const projected = projectUsageMeta(el);
5266
5230
  if (projected) return ensureUniqueNodeId(projected.nodeId, used);
@@ -5331,7 +5295,7 @@ function isFlexOrGridParent(el) {
5331
5295
  const d = getComputedStyle(el).display;
5332
5296
  return d === "flex" || d === "grid" || d === "inline-flex" || d === "inline-grid";
5333
5297
  }
5334
- function scanElements(root, depth = 0, usedNodeIds = /* @__PURE__ */ new Set(), seenResolvedHosts = /* @__PURE__ */ new WeakSet()) {
5298
+ function scanElements(root, depth = 0, usedNodeIds = /* @__PURE__ */ new Set(), seenResolvedHosts = /* @__PURE__ */ new WeakSet(), resolvedUnreported = /* @__PURE__ */ new Set()) {
5335
5299
  if (depth > MAX_DEPTH) return [];
5336
5300
  const results = [];
5337
5301
  for (const child of Array.from(root.children)) {
@@ -5356,7 +5320,9 @@ function scanElements(root, depth = 0, usedNodeIds = /* @__PURE__ */ new Set(),
5356
5320
  const nodeId2 = resolveStableNodeId(el, usedNodeIds);
5357
5321
  usedNodeIds.add(nodeId2);
5358
5322
  el.setAttribute(DND_NODE_ID_ATTR, nodeId2);
5359
- if (!isZeroRect) {
5323
+ if (isZeroRect) {
5324
+ resolvedUnreported.add(el);
5325
+ } else {
5360
5326
  seenResolvedHosts.add(el);
5361
5327
  const surfaceMeta2 = el instanceof HTMLElement ? getDirectEditorMeta(el) ?? void 0 : void 0;
5362
5328
  const identityMeta3 = projectUsageMeta(el) ?? surfaceMeta2;
@@ -5380,7 +5346,7 @@ function scanElements(root, depth = 0, usedNodeIds = /* @__PURE__ */ new Set(),
5380
5346
  });
5381
5347
  }
5382
5348
  }
5383
- if (!isSvgRoot) results.push(...scanElements(el, depth + 1, usedNodeIds, seenResolvedHosts));
5349
+ if (!isSvgRoot) results.push(...scanElements(el, depth + 1, usedNodeIds, seenResolvedHosts, resolvedUnreported));
5384
5350
  continue;
5385
5351
  }
5386
5352
  if (isSvgRoot && isInspectorEligible(el) === null) {
@@ -5389,7 +5355,7 @@ function scanElements(root, depth = 0, usedNodeIds = /* @__PURE__ */ new Set(),
5389
5355
  const eligibilitySource = isInspectorEligible(el);
5390
5356
  const inferredEligibility = eligibilitySource ?? inferEligibilityFromSortableParent(el) ?? (projectUsageMeta(el) ? "projected-usage" : null);
5391
5357
  if (inferredEligibility === null) {
5392
- const childResults = scanElements(el, depth + 1, usedNodeIds, seenResolvedHosts);
5358
+ const childResults = scanElements(el, depth + 1, usedNodeIds, seenResolvedHosts, resolvedUnreported);
5393
5359
  results.push(...childResults);
5394
5360
  if (isFlexOrGridParent(el) && !seenResolvedHosts.has(el) && childResults.some((r) => r.draggable && r.element.parentElement === el)) {
5395
5361
  const nodeId2 = resolveStableNodeId(el, usedNodeIds);
@@ -5417,13 +5383,13 @@ function scanElements(root, depth = 0, usedNodeIds = /* @__PURE__ */ new Set(),
5417
5383
  const dragSurface = resolveDragSurface(el);
5418
5384
  const hostEl = dragSurface.host;
5419
5385
  if (!hostEl) {
5420
- if (!isSvgRoot) results.push(...scanElements(el, depth + 1, usedNodeIds, seenResolvedHosts));
5386
+ if (!isSvgRoot) results.push(...scanElements(el, depth + 1, usedNodeIds, seenResolvedHosts, resolvedUnreported));
5421
5387
  continue;
5422
5388
  }
5423
5389
  const hostRect = hostEl.getBoundingClientRect();
5424
5390
  const nodeId = resolveStableNodeId(hostEl, usedNodeIds);
5425
5391
  if (seenResolvedHosts.has(hostEl)) {
5426
- if (!isSvgRoot) results.push(...scanElements(el, depth + 1, usedNodeIds, seenResolvedHosts));
5392
+ if (!isSvgRoot) results.push(...scanElements(el, depth + 1, usedNodeIds, seenResolvedHosts, resolvedUnreported));
5427
5393
  continue;
5428
5394
  }
5429
5395
  seenResolvedHosts.add(hostEl);
@@ -5453,9 +5419,9 @@ function scanElements(root, depth = 0, usedNodeIds = /* @__PURE__ */ new Set(),
5453
5419
  identityOrigin: templateFrameLabel(identityMeta2),
5454
5420
  editorMeta: surfaceMeta
5455
5421
  });
5456
- if (!isSvgRoot) results.push(...scanElements(el, depth + 1, usedNodeIds, seenResolvedHosts));
5422
+ if (!isSvgRoot) results.push(...scanElements(el, depth + 1, usedNodeIds, seenResolvedHosts, resolvedUnreported));
5457
5423
  } else {
5458
- if (!isSvgRoot) results.push(...scanElements(el, depth + 1, usedNodeIds, seenResolvedHosts));
5424
+ if (!isSvgRoot) results.push(...scanElements(el, depth + 1, usedNodeIds, seenResolvedHosts, resolvedUnreported));
5459
5425
  }
5460
5426
  }
5461
5427
  return results;
@@ -5511,8 +5477,10 @@ function useElementScanner(enabled) {
5511
5477
  if (pausedRef.current) return;
5512
5478
  const root = document.getElementById("root") ?? document.body;
5513
5479
  const usedNodeIds = /* @__PURE__ */ new Set();
5514
- const scanned = scanElements(root, 0, usedNodeIds);
5480
+ const resolvedUnreported = /* @__PURE__ */ new Set();
5481
+ const scanned = scanElements(root, 0, usedNodeIds, void 0, resolvedUnreported);
5515
5482
  const seenEls = new Set(scanned.map((s) => s.element));
5483
+ for (const el of resolvedUnreported) seenEls.add(el);
5516
5484
  for (const el of Array.from(document.querySelectorAll("[data-dnd-moved]"))) {
5517
5485
  if (seenEls.has(el)) continue;
5518
5486
  const entry = buildMovedElementEntry(el, usedNodeIds);
@@ -5576,6 +5544,7 @@ var import_jsx_runtime2 = require("react/jsx-runtime");
5576
5544
  var HANDLES = ["nw", "n", "ne", "e", "se", "s", "sw", "w"];
5577
5545
  var HANDLE_HIT_SIZE = 24;
5578
5546
  var HANDLE_KNOB_SIZE = 8;
5547
+ var EMPTY_SCROLL_DELTA = { x: NaN, y: NaN };
5579
5548
  var OVERLAY_ROOT_STYLE = {
5580
5549
  position: "fixed",
5581
5550
  inset: 0,
@@ -5649,17 +5618,39 @@ function handlePosition(dir) {
5649
5618
  };
5650
5619
  return positions[dir];
5651
5620
  }
5652
- function getOutlineStyle(rect, isSelected, inspectorTheme) {
5621
+ function getSelectedOutlineStyle(rect, inspectorTheme) {
5653
5622
  return {
5654
5623
  ...OUTLINE_BASE_STYLE,
5655
5624
  left: rect.left,
5656
5625
  top: rect.top,
5657
5626
  width: rect.width,
5658
5627
  height: rect.height,
5659
- border: isSelected ? `2px solid ${inspectorTheme.accent}` : `1px dashed ${inspectorTheme.shared}`,
5660
- backgroundColor: isSelected ? inspectorTheme.accentSoft : "transparent"
5628
+ border: `2px solid ${inspectorTheme.accent}`,
5629
+ backgroundColor: inspectorTheme.accentSoft
5661
5630
  };
5662
5631
  }
5632
+ function getGuideOutlineStyle(rect, tier, inspectorTheme) {
5633
+ const base = {
5634
+ ...OUTLINE_BASE_STYLE,
5635
+ left: rect.left,
5636
+ top: rect.top,
5637
+ width: rect.width,
5638
+ height: rect.height
5639
+ };
5640
+ switch (tier) {
5641
+ case "candidate":
5642
+ return { ...base, border: `1px solid ${inspectorTheme.accent}`, opacity: 0.2 };
5643
+ case "lane-child":
5644
+ return { ...base, border: `1px dashed ${inspectorTheme.accent}`, opacity: 0.45 };
5645
+ case "lane":
5646
+ return {
5647
+ ...base,
5648
+ border: `1.5px solid ${inspectorTheme.accent}`,
5649
+ backgroundColor: inspectorTheme.accentSoft,
5650
+ opacity: 0.75
5651
+ };
5652
+ }
5653
+ }
5663
5654
  function getResizeHandleStyle(position) {
5664
5655
  return {
5665
5656
  ...RESIZE_HANDLE_BASE_STYLE,
@@ -5682,40 +5673,58 @@ function getLabelStyle(labelLeft, labelTop, labelColor) {
5682
5673
  backgroundColor: labelColor
5683
5674
  };
5684
5675
  }
5676
+ function projectDragRect(dragGuide, nodeId, sdx, sdy) {
5677
+ const r = dragGuide.rects.get(nodeId);
5678
+ if (!r) return null;
5679
+ return { left: r.left - sdx, top: r.top - sdy, width: r.width, height: r.height };
5680
+ }
5685
5681
  function ElementHighlight({
5686
- elements,
5687
- draggingNodeId,
5688
- activeEl,
5689
- arrangeSelectedNodeId,
5682
+ selected,
5683
+ dragGuide,
5690
5684
  externalDragActive,
5691
5685
  onResizeHandlePointerDown
5692
5686
  }) {
5693
5687
  const inspectorTheme = useDesignModeStore((s) => s.inspectorTheme);
5694
- const internalDragInProgress = draggingNodeId !== null;
5695
- const overlayVisible = arrangeSelectedNodeId !== null || internalDragInProgress;
5696
5688
  const containerRef = (0, import_react7.useRef)(null);
5697
5689
  const rafRef = (0, import_react7.useRef)(0);
5690
+ const lastScrollDeltaRef = (0, import_react7.useRef)(EMPTY_SCROLL_DELTA);
5698
5691
  const syncPositions = (0, import_react7.useCallback)(() => {
5699
5692
  const container = containerRef.current;
5700
5693
  if (!container) return;
5701
- const outlines = container.querySelectorAll("[data-outline-for]");
5702
- for (const outline of outlines) {
5703
- const nodeId = outline.getAttribute("data-outline-for");
5704
- const el = elements.find((e) => e.nodeId === nodeId);
5705
- if (!el) continue;
5706
- const rect = el.element.getBoundingClientRect();
5707
- outline.style.left = `${rect.left}px`;
5708
- outline.style.top = `${rect.top}px`;
5709
- outline.style.width = `${rect.width}px`;
5710
- outline.style.height = `${rect.height}px`;
5711
- const label = outline.nextElementSibling;
5712
- if (label) {
5713
- label.style.left = `${rect.left}px`;
5714
- label.style.top = `${rect.top}px`;
5694
+ if (dragGuide) {
5695
+ const sdx = window.scrollX - dragGuide.startScroll.x;
5696
+ const sdy = window.scrollY - dragGuide.startScroll.y;
5697
+ if (sdx === lastScrollDeltaRef.current.x && sdy === lastScrollDeltaRef.current.y) return;
5698
+ lastScrollDeltaRef.current = { x: sdx, y: sdy };
5699
+ const outlines = container.querySelectorAll("[data-guide-for]");
5700
+ for (const outline2 of outlines) {
5701
+ const nodeId = outline2.getAttribute("data-guide-for");
5702
+ const r = dragGuide.rects.get(nodeId);
5703
+ if (!r) continue;
5704
+ outline2.style.left = `${r.left - sdx}px`;
5705
+ outline2.style.top = `${r.top - sdy}px`;
5715
5706
  }
5707
+ return;
5716
5708
  }
5717
- }, [elements]);
5709
+ if (!selected) return;
5710
+ const rect2 = selected.element.getBoundingClientRect();
5711
+ const outline = container.querySelector("[data-outline-for]");
5712
+ if (outline) {
5713
+ outline.style.left = `${rect2.left}px`;
5714
+ outline.style.top = `${rect2.top}px`;
5715
+ outline.style.width = `${rect2.width}px`;
5716
+ outline.style.height = `${rect2.height}px`;
5717
+ }
5718
+ const label = container.querySelector("[data-drag-handle]");
5719
+ if (label) {
5720
+ label.style.left = `${rect2.left + 12}px`;
5721
+ label.style.top = `${Math.max(0, rect2.top - 20)}px`;
5722
+ }
5723
+ }, [dragGuide, selected]);
5724
+ const loopActive = !externalDragActive && (dragGuide !== null || selected !== null);
5718
5725
  (0, import_react7.useEffect)(() => {
5726
+ if (!loopActive) return;
5727
+ lastScrollDeltaRef.current = EMPTY_SCROLL_DELTA;
5719
5728
  let running = true;
5720
5729
  const loop = () => {
5721
5730
  if (!running) return;
@@ -5727,81 +5736,113 @@ function ElementHighlight({
5727
5736
  running = false;
5728
5737
  cancelAnimationFrame(rafRef.current);
5729
5738
  };
5730
- }, [syncPositions]);
5731
- if (!overlayVisible) return null;
5732
- if (externalDragActive) return null;
5733
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5734
- "div",
5735
- {
5736
- ref: containerRef,
5737
- "data-design-mode-ui": true,
5738
- style: OVERLAY_ROOT_STYLE,
5739
- children: elements.map((el) => {
5740
- if (el.nodeId === draggingNodeId) return null;
5741
- if (activeEl && activeEl !== el.element && activeEl.contains(el.element)) return null;
5742
- const isSelected = el.nodeId === arrangeSelectedNodeId;
5743
- if (!isSelected && !internalDragInProgress) return null;
5744
- const rect = el.element.getBoundingClientRect();
5745
- const showLabel = isSelected;
5746
- const labelTop = isSelected ? Math.max(0, rect.top - 20) : rect.top;
5747
- const labelLeft = isSelected ? rect.left + 12 : rect.left;
5748
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
5749
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5750
- "div",
5751
- {
5752
- "data-outline-for": el.nodeId,
5753
- "data-design-mode-ui": true,
5754
- style: getOutlineStyle(rect, isSelected, inspectorTheme),
5755
- children: isSelected && HANDLES.map((dir) => {
5756
- const pos = handlePosition(dir);
5757
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5758
- "div",
5759
- {
5760
- "data-design-mode-ui": true,
5761
- "data-resize-handle": dir,
5762
- onPointerDown: (e) => {
5763
- e.stopPropagation();
5764
- onResizeHandlePointerDown?.(e, el.nodeId, dir);
5765
- },
5766
- style: getResizeHandleStyle(pos),
5767
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5768
- "span",
5769
- {
5770
- "data-design-mode-ui": true,
5771
- style: getResizeKnobStyle(inspectorTheme.accent)
5772
- }
5773
- )
5774
- },
5775
- dir
5776
- );
5777
- })
5778
- }
5779
- ),
5780
- showLabel && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
5739
+ }, [loopActive, syncPositions]);
5740
+ if (!loopActive) return null;
5741
+ if (dragGuide) {
5742
+ const sdx = window.scrollX - dragGuide.startScroll.x;
5743
+ const sdy = window.scrollY - dragGuide.startScroll.y;
5744
+ const { candidateContainerIds, activeContainerId, activeChildIds, draggingNodeId } = dragGuide;
5745
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { ref: containerRef, "data-design-mode-ui": true, style: OVERLAY_ROOT_STYLE, children: [
5746
+ [...candidateContainerIds].map((id) => {
5747
+ if (id === activeContainerId || id === draggingNodeId) return null;
5748
+ const rect2 = projectDragRect(dragGuide, id, sdx, sdy);
5749
+ if (!rect2) return null;
5750
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5751
+ "div",
5752
+ {
5753
+ "data-guide-for": id,
5754
+ "data-guide-tier": "candidate",
5755
+ "data-design-mode-ui": true,
5756
+ style: getGuideOutlineStyle(rect2, "candidate", inspectorTheme)
5757
+ },
5758
+ `candidate:${id}`
5759
+ );
5760
+ }),
5761
+ activeContainerId !== null && activeChildIds.map((id) => {
5762
+ if (id === draggingNodeId) return null;
5763
+ const rect2 = projectDragRect(dragGuide, id, sdx, sdy);
5764
+ if (!rect2) return null;
5765
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5766
+ "div",
5767
+ {
5768
+ "data-guide-for": id,
5769
+ "data-guide-tier": "lane-child",
5770
+ "data-design-mode-ui": true,
5771
+ style: getGuideOutlineStyle(rect2, "lane-child", inspectorTheme)
5772
+ },
5773
+ `lane-child:${id}`
5774
+ );
5775
+ }),
5776
+ activeContainerId !== null && activeContainerId !== draggingNodeId && (() => {
5777
+ const rect2 = projectDragRect(dragGuide, activeContainerId, sdx, sdy);
5778
+ if (!rect2) return null;
5779
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5780
+ "div",
5781
+ {
5782
+ "data-guide-for": activeContainerId,
5783
+ "data-guide-tier": "lane",
5784
+ "data-design-mode-ui": true,
5785
+ style: getGuideOutlineStyle(rect2, "lane", inspectorTheme)
5786
+ },
5787
+ `lane:${activeContainerId}`
5788
+ );
5789
+ })()
5790
+ ] });
5791
+ }
5792
+ if (!selected) return null;
5793
+ const rect = selected.element.getBoundingClientRect();
5794
+ const labelTop = Math.max(0, rect.top - 20);
5795
+ const labelLeft = rect.left + 12;
5796
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { ref: containerRef, "data-design-mode-ui": true, style: OVERLAY_ROOT_STYLE, children: [
5797
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5798
+ "div",
5799
+ {
5800
+ "data-outline-for": selected.nodeId,
5801
+ "data-design-mode-ui": true,
5802
+ style: getSelectedOutlineStyle(rect, inspectorTheme),
5803
+ children: selected.draggable && HANDLES.map((dir) => {
5804
+ const pos = handlePosition(dir);
5805
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5781
5806
  "div",
5782
5807
  {
5783
5808
  "data-design-mode-ui": true,
5784
- "data-drag-handle": el.nodeId,
5785
- style: getLabelStyle(
5786
- labelLeft,
5787
- labelTop,
5788
- isSelected ? inspectorTheme.accent : inspectorTheme.hover
5789
- ),
5790
- children: [
5791
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: LABEL_ICON_STYLE, children: "\u283F" }),
5792
- el.label,
5793
- isSelected && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: LABEL_DIMENSIONS_STYLE, children: [
5794
- Math.round(rect.width),
5795
- "\xD7",
5796
- Math.round(rect.height)
5797
- ] })
5798
- ]
5799
- }
5800
- )
5801
- ] }, el.nodeId);
5802
- })
5803
- }
5804
- );
5809
+ "data-resize-handle": dir,
5810
+ onPointerDown: (e) => {
5811
+ e.stopPropagation();
5812
+ onResizeHandlePointerDown?.(e, selected.nodeId, dir);
5813
+ },
5814
+ style: getResizeHandleStyle(pos),
5815
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5816
+ "span",
5817
+ {
5818
+ "data-design-mode-ui": true,
5819
+ style: getResizeKnobStyle(inspectorTheme.accent)
5820
+ }
5821
+ )
5822
+ },
5823
+ dir
5824
+ );
5825
+ })
5826
+ }
5827
+ ),
5828
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
5829
+ "div",
5830
+ {
5831
+ "data-design-mode-ui": true,
5832
+ "data-drag-handle": selected.nodeId,
5833
+ style: getLabelStyle(labelLeft, labelTop, inspectorTheme.accent),
5834
+ children: [
5835
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: LABEL_ICON_STYLE, children: "\u283F" }),
5836
+ selected.label,
5837
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: LABEL_DIMENSIONS_STYLE, children: [
5838
+ Math.round(rect.width),
5839
+ "\xD7",
5840
+ Math.round(rect.height)
5841
+ ] })
5842
+ ]
5843
+ }
5844
+ )
5845
+ ] });
5805
5846
  }
5806
5847
 
5807
5848
  // src/client/dnd/design-mode/projection.ts
@@ -6595,30 +6636,6 @@ function applyDndCommandPlacement(command, direction, resolveNodeElement) {
6595
6636
  return true;
6596
6637
  }
6597
6638
 
6598
- // src/client/dnd/design-mode/design-mode-collision.ts
6599
- function filterDroppables(droppableContainers, blockedContainerIds) {
6600
- if (!blockedContainerIds || blockedContainerIds.size === 0) return droppableContainers;
6601
- return droppableContainers.filter((container) => !blockedContainerIds.has(String(container.id)));
6602
- }
6603
- function getCollisions(detector, args) {
6604
- return detector(args);
6605
- }
6606
- function createDesignModeCollisionDetection(blockedContainerIds) {
6607
- return (args) => {
6608
- const droppableContainers = filterDroppables(args.droppableContainers, blockedContainerIds);
6609
- if (droppableContainers.length === 0) return [];
6610
- const scopedArgs = {
6611
- ...args,
6612
- droppableContainers
6613
- };
6614
- const pointerHits = getCollisions(pointerWithin, scopedArgs);
6615
- if (pointerHits.length > 0) return pointerHits;
6616
- const cornerHits = getCollisions(closestCorners, scopedArgs);
6617
- if (cornerHits.length > 0) return cornerHits;
6618
- return getCollisions(closestCenter, scopedArgs);
6619
- };
6620
- }
6621
-
6622
6639
  // src/client/dnd/design-mode/arrange-session.ts
6623
6640
  function serializeArrangeChange(event, index) {
6624
6641
  return {
@@ -6897,9 +6914,9 @@ function useOverlayRefs(undoRequestId, redoRequestId) {
6897
6914
  const lastIntentRef = (0, import_react11.useRef)(null);
6898
6915
  const visualIntentRef = (0, import_react11.useRef)(null);
6899
6916
  const sourceContainerIdRef = (0, import_react11.useRef)(null);
6917
+ const activeLaneContainerIdRef = (0, import_react11.useRef)(null);
6900
6918
  const rowLockedRef = (0, import_react11.useRef)(false);
6901
6919
  const dragSessionAnchorRef = (0, import_react11.useRef)(null);
6902
- const lockRef = (0, import_react11.useRef)({ containerId: null, isCrossUnlocked: false, exitSince: null, unlockUntilTs: null });
6903
6920
  const targetPlaneRef = (0, import_react11.useRef)("lane");
6904
6921
  const nestCandidateRef = (0, import_react11.useRef)(null);
6905
6922
  const nestTargetRef = (0, import_react11.useRef)(null);
@@ -6909,7 +6926,6 @@ function useOverlayRefs(undoRequestId, redoRequestId) {
6909
6926
  const sourceCommitLaneRef = (0, import_react11.useRef)(null);
6910
6927
  const commitLaneCacheRef = (0, import_react11.useRef)(/* @__PURE__ */ new Map());
6911
6928
  const safeZoneRef = (0, import_react11.useRef)(null);
6912
- const blockedContainerIdsRef = (0, import_react11.useRef)(/* @__PURE__ */ new Set());
6913
6929
  const historyRef = (0, import_react11.useRef)(new DndCommandHistory());
6914
6930
  const processedUndoIdRef = (0, import_react11.useRef)(undoRequestId);
6915
6931
  const processedRedoIdRef = (0, import_react11.useRef)(redoRequestId);
@@ -6929,9 +6945,9 @@ function useOverlayRefs(undoRequestId, redoRequestId) {
6929
6945
  lastIntentRef,
6930
6946
  visualIntentRef,
6931
6947
  sourceContainerIdRef,
6948
+ activeLaneContainerIdRef,
6932
6949
  rowLockedRef,
6933
6950
  dragSessionAnchorRef,
6934
- lockRef,
6935
6951
  targetPlaneRef,
6936
6952
  nestCandidateRef,
6937
6953
  nestTargetRef,
@@ -6941,7 +6957,6 @@ function useOverlayRefs(undoRequestId, redoRequestId) {
6941
6957
  sourceCommitLaneRef,
6942
6958
  commitLaneCacheRef,
6943
6959
  safeZoneRef,
6944
- blockedContainerIdsRef,
6945
6960
  historyRef,
6946
6961
  processedUndoIdRef,
6947
6962
  processedRedoIdRef,
@@ -7209,6 +7224,11 @@ function pointInRect(px, py, r) {
7209
7224
  function pointInExpandedRect(px, py, r, inset) {
7210
7225
  return px >= r.left - inset && px <= r.right + inset && py >= r.top - inset && py <= r.bottom + inset;
7211
7226
  }
7227
+ function isInNestZone(px, py, rect) {
7228
+ const relX = (px - rect.left) / rect.width;
7229
+ const relY = (py - rect.top) / rect.height;
7230
+ return relX > NEST_EDGE_FRACTION && relX < 1 - NEST_EDGE_FRACTION && relY > NEST_EDGE_FRACTION && relY < 1 - NEST_EDGE_FRACTION;
7231
+ }
7212
7232
  function buildSlotQuadtree(slotIndex) {
7213
7233
  const rects = /* @__PURE__ */ new Map();
7214
7234
  for (const [id, slot] of slotIndex) {
@@ -7251,6 +7271,11 @@ var DragIntentEngine = class {
7251
7271
  __publicField(this, "laneAllowedContainers");
7252
7272
  __publicField(this, "blockedContainerIds");
7253
7273
  __publicField(this, "targetPlane", "lane");
7274
+ // Memoized result of getValidDropContainerIds(). Safe to cache because every
7275
+ // input it reads (containerIndex, slotIndex, activeId, laneAllowedContainers,
7276
+ // blockedContainerIds) is fixed in the constructor and never mutated during
7277
+ // a drag.
7278
+ __publicField(this, "validDropContainerIds", null);
7254
7279
  this.projectionTree = projection.projectionTree;
7255
7280
  this.containerIndex = projection.containerIndex;
7256
7281
  this.slotIndex = projection.slotIndex;
@@ -7287,6 +7312,44 @@ var DragIntentEngine = class {
7287
7312
  getContainerChildren(containerId) {
7288
7313
  return this.containerIndex.get(containerId)?.children ?? [];
7289
7314
  }
7315
+ /**
7316
+ * Every container id this engine would accept as a drop target for the
7317
+ * active node, at the current pointer position or any other — i.e. the
7318
+ * full set `resolvePointerContainer` draws from, not a snapshot of one
7319
+ * resolve() call. Intended for the visual layer to draw a guide that
7320
+ * matches exactly what the engine can land on, without re-deriving the
7321
+ * eligibility rule itself.
7322
+ *
7323
+ * Always queries with `laneLock: true`. That is not an approximation of
7324
+ * the "real" default — it IS the real answer for every reachable caller:
7325
+ *
7326
+ * - With a row lock active (`laneAllowedContainers` set), `isLaneContainer`
7327
+ * restricts eligibility to that set, so this returns exactly
7328
+ * `{srcContainerId}` — the ARCH-1071 lock, reproduced faithfully.
7329
+ * - Without a row lock, `laneAllowedContainers` is null and
7330
+ * `isLaneContainer` returns true unconditionally, so `laneLock`'s value
7331
+ * makes no difference — passing `true` costs nothing here.
7332
+ * - The engine's own 'nest' plane does call `isEligibleDropContainer` with
7333
+ * `laneLock: false` (see `peekNestIntent` → `resolvePointerContainer`),
7334
+ * but that plane is unreachable for a locked drag: `computeAllowNest`
7335
+ * (useDragVisualLoop.ts) short-circuits `rowLocked` drags before
7336
+ * `setTargetPlane('nest')` is ever called, so `targetPlane` stays
7337
+ * 'lane' for the drag's whole lifetime. If that guard is ever removed,
7338
+ * this method will under-report nest-only targets for locked drags —
7339
+ * keep the two in sync.
7340
+ *
7341
+ * Cached after the first call: every input (containerIndex, slotIndex,
7342
+ * activeId, laneAllowedContainers, blockedContainerIds) is fixed at
7343
+ * construction and never changes for the life of a drag.
7344
+ */
7345
+ getValidDropContainerIds() {
7346
+ if (this.validDropContainerIds) return this.validDropContainerIds;
7347
+ const ids2 = /* @__PURE__ */ new Set();
7348
+ for (const id of this.containerIndex.keys()) {
7349
+ if (this.isEligibleDropContainer(id, true)) ids2.add(id);
7350
+ }
7351
+ return this.validDropContainerIds = ids2;
7352
+ }
7290
7353
  setTargetPlane(plane) {
7291
7354
  this.targetPlane = plane;
7292
7355
  }
@@ -7305,6 +7368,17 @@ var DragIntentEngine = class {
7305
7368
  isInvalidDropContainer(containerId) {
7306
7369
  return containerId === this.activeId || this.isContainerDescendantOf(containerId, this.activeId);
7307
7370
  }
7371
+ /**
7372
+ * The full "can this container accept the active node this drag" predicate.
7373
+ * SINGLE definition — every caller routes through it so no two parts of the
7374
+ * system can disagree about which containers are droppable.
7375
+ */
7376
+ isEligibleDropContainer(containerId, laneLock) {
7377
+ if (this.isInvalidDropContainer(containerId)) return false;
7378
+ if (this.isBlockedContainer(containerId)) return false;
7379
+ if (laneLock && !this.isLaneContainer(containerId)) return false;
7380
+ return this.hasUsableSlots(containerId);
7381
+ }
7308
7382
  /**
7309
7383
  * Resolve the drag intent from the current pointer position.
7310
7384
  *
@@ -7392,9 +7466,7 @@ var DragIntentEngine = class {
7392
7466
  const childNode = this.getNodeRect(childId);
7393
7467
  if (!childNode) continue;
7394
7468
  if (!pointInRect(px, py, childNode)) continue;
7395
- const relX = (px - childNode.left) / childNode.width;
7396
- const relY = (py - childNode.top) / childNode.height;
7397
- if (relX > NEST_EDGE_FRACTION && relX < 1 - NEST_EDGE_FRACTION && relY > NEST_EDGE_FRACTION && relY < 1 - NEST_EDGE_FRACTION) {
7469
+ if (isInNestZone(px, py, childNode)) {
7398
7470
  return {
7399
7471
  containerId: pointerContainerId,
7400
7472
  index: container.children.indexOf(childId),
@@ -7408,11 +7480,8 @@ var DragIntentEngine = class {
7408
7480
  resolvePointerContainer(px, py, laneLock) {
7409
7481
  const pointerContainers = [];
7410
7482
  for (const [id, node] of this.containerIndex) {
7411
- if (this.isInvalidDropContainer(id)) continue;
7412
- if (this.isBlockedContainer(id)) continue;
7413
- if (laneLock && !this.isLaneContainer(id)) continue;
7414
7483
  if (!pointInRect(px, py, node.rect)) continue;
7415
- if (this.hasUsableSlots(id) === false) continue;
7484
+ if (!this.isEligibleDropContainer(id, laneLock)) continue;
7416
7485
  const r = node.rect;
7417
7486
  const edgeDistX = Math.min(px - r.left, r.right - px);
7418
7487
  const edgeDistY = Math.min(py - r.top, r.bottom - py);
@@ -7429,11 +7498,11 @@ var DragIntentEngine = class {
7429
7498
  let pointerContainerId = pointerContainers[0]?.id ?? null;
7430
7499
  if (!pointerContainerId && this.lastIntent?.mode === "reorder") {
7431
7500
  const lastContainer = this.containerIndex.get(this.lastIntent.containerId);
7432
- if (lastContainer && !this.isInvalidDropContainer(lastContainer.id) && !this.isBlockedContainer(lastContainer.id) && (!laneLock || this.isLaneContainer(lastContainer.id)) && this.hasUsableSlots(lastContainer.id) && pointInExpandedRect(px, py, lastContainer.rect, LAST_CONTAINER_REENTRY_SLOP_PX)) {
7501
+ if (lastContainer && this.isEligibleDropContainer(lastContainer.id, laneLock) && pointInExpandedRect(px, py, lastContainer.rect, LAST_CONTAINER_REENTRY_SLOP_PX)) {
7433
7502
  pointerContainerId = lastContainer.id;
7434
7503
  }
7435
7504
  }
7436
- if (this.originContainerId && this.originContainerId !== pointerContainerId && !this.isInvalidDropContainer(this.originContainerId) && !this.isBlockedContainer(this.originContainerId) && (!laneLock || this.isLaneContainer(this.originContainerId)) && this.hasUsableSlots(this.originContainerId)) {
7505
+ if (this.originContainerId && this.originContainerId !== pointerContainerId && this.isEligibleDropContainer(this.originContainerId, laneLock)) {
7437
7506
  const originNode = this.containerIndex.get(this.originContainerId);
7438
7507
  const currentNode = pointerContainerId ? this.containerIndex.get(pointerContainerId) : null;
7439
7508
  const originIsDeeper = originNode && (!currentNode || originNode.depth >= currentNode.depth);
@@ -7846,7 +7915,8 @@ function useDragVisualLoop({
7846
7915
  refs,
7847
7916
  getCommitLaneSnapshot,
7848
7917
  setInsideRect,
7849
- setDropLine
7918
+ setDropLine,
7919
+ setActiveLaneContainerId
7850
7920
  }) {
7851
7921
  (0, import_react12.useEffect)(() => {
7852
7922
  const engine = refs.engineRef.current;
@@ -7854,6 +7924,11 @@ function useDragVisualLoop({
7854
7924
  if (!activeDrag || !engine || !snapshot) return;
7855
7925
  let rafId;
7856
7926
  const animator = refs.animatorRef.current;
7927
+ const publishActiveLane = (containerId) => {
7928
+ if (refs.activeLaneContainerIdRef.current === containerId) return;
7929
+ refs.activeLaneContainerIdRef.current = containerId;
7930
+ setActiveLaneContainerId(containerId);
7931
+ };
7857
7932
  const setTargetPlane = (nextPlane) => {
7858
7933
  const prevPlane = refs.targetPlaneRef.current;
7859
7934
  if (prevPlane === nextPlane) return;
@@ -7872,6 +7947,7 @@ function useDragVisualLoop({
7872
7947
  const safeZone = refs.safeZoneRef.current;
7873
7948
  if (isPointerBlocked(px, py, safeZone)) {
7874
7949
  setTargetPlane("lane");
7950
+ publishActiveLane(null);
7875
7951
  refs.lastIntentRef.current = null;
7876
7952
  refs.visualIntentRef.current = null;
7877
7953
  refs.nestCandidateRef.current = null;
@@ -7913,6 +7989,7 @@ function useDragVisualLoop({
7913
7989
  let intent = engine.resolve(px, py, window.scrollX, window.scrollY, snapshot.scroll.x, snapshot.scroll.y);
7914
7990
  if (!intent) {
7915
7991
  setTargetPlane("lane");
7992
+ publishActiveLane(null);
7916
7993
  refs.lastIntentRef.current = null;
7917
7994
  refs.visualIntentRef.current = null;
7918
7995
  refs.nestCandidateRef.current = null;
@@ -7938,6 +8015,7 @@ function useDragVisualLoop({
7938
8015
  const targetId = intent.slotId.split("::nest::")[1] ?? "";
7939
8016
  if (!targetId) {
7940
8017
  setTargetPlane("lane");
8018
+ publishActiveLane(null);
7941
8019
  rafId = requestAnimationFrame(tick);
7942
8020
  return;
7943
8021
  }
@@ -7959,12 +8037,14 @@ function useDragVisualLoop({
7959
8037
  };
7960
8038
  refs.visualIntentRef.current = intent;
7961
8039
  refs.lastIntentRef.current = intent;
8040
+ publishActiveLane(intent.containerId);
7962
8041
  } else {
7963
8042
  setTargetPlane("lane");
7964
8043
  refs.nestCandidateRef.current = null;
7965
8044
  refs.nestTargetRef.current = null;
7966
8045
  refs.lastIntentRef.current = intent;
7967
8046
  refs.visualIntentRef.current = intent;
8047
+ publishActiveLane(intent.containerId);
7968
8048
  setInsideRect(null);
7969
8049
  const proj = refs.projectionRef.current;
7970
8050
  const slot = proj.slotIndex.get(intent.slotId);
@@ -8271,7 +8351,8 @@ function useDragLifecycle({
8271
8351
  syncHistoryAvailability,
8272
8352
  resolveNodeElement,
8273
8353
  setInsideRect,
8274
- setDropLine
8354
+ setDropLine,
8355
+ setActiveLaneContainerId
8275
8356
  }) {
8276
8357
  const [activeDrag, setActiveDrag] = (0, import_react13.useState)(null);
8277
8358
  const clearDragState = (0, import_react13.useCallback)(() => {
@@ -8282,13 +8363,12 @@ function useDragLifecycle({
8282
8363
  refs.snapshotRef.current = null;
8283
8364
  refs.projectionRef.current = EMPTY_PROJECTION;
8284
8365
  refs.engineRef.current = null;
8285
- refs.blockedContainerIdsRef.current = /* @__PURE__ */ new Set();
8286
8366
  refs.lastIntentRef.current = null;
8287
8367
  refs.visualIntentRef.current = null;
8288
8368
  refs.sourceContainerIdRef.current = null;
8369
+ refs.activeLaneContainerIdRef.current = null;
8289
8370
  refs.rowLockedRef.current = false;
8290
8371
  refs.dragSessionAnchorRef.current = null;
8291
- refs.lockRef.current = { containerId: null, isCrossUnlocked: false, exitSince: null, unlockUntilTs: null };
8292
8372
  refs.targetPlaneRef.current = "lane";
8293
8373
  refs.nestCandidateRef.current = null;
8294
8374
  refs.nestTargetRef.current = null;
@@ -8299,6 +8379,7 @@ function useDragLifecycle({
8299
8379
  refs.safeZoneRef.current = null;
8300
8380
  setInsideRect(null);
8301
8381
  setDropLine(null);
8382
+ setActiveLaneContainerId(null);
8302
8383
  setActiveDrag(null);
8303
8384
  resume();
8304
8385
  }, [clearCommitLaneCache, resume]);
@@ -8356,7 +8437,6 @@ function useDragLifecycle({
8356
8437
  const sourceCommitLane = getCommitLaneSnapshot(srcContainerId);
8357
8438
  const startPosition = getCurrentCommitPlacement(anchorNodeId, srcContainerId);
8358
8439
  const blockedContainerIds = buildBlockedStructuralContainerIds(proj, refs.nodeMapRef.current, srcContainerId);
8359
- refs.blockedContainerIdsRef.current = blockedContainerIds;
8360
8440
  const engineOptions = buildDragIntentEngineOptions(anchorScanned.element, srcContainerId, blockedContainerIds);
8361
8441
  refs.rowLockedRef.current = !!engineOptions.laneAllowedContainers;
8362
8442
  refs.engineRef.current = createDragIntentEngine(proj, anchorNodeId, engineOptions);
@@ -8365,7 +8445,6 @@ function useDragLifecycle({
8365
8445
  refs.sourceContainerIdRef.current = srcContainerId;
8366
8446
  refs.sourceCommitLaneRef.current = sourceCommitLane;
8367
8447
  refs.dragSessionAnchorRef.current = anchor;
8368
- refs.lockRef.current = { containerId: srcContainerId, isCrossUnlocked: true, exitSince: null, unlockUntilTs: null };
8369
8448
  refs.dragStartPositionRef.current = startPosition;
8370
8449
  refs.safeZoneRef.current = resolveSafeZoneRect();
8371
8450
  pause();
@@ -8519,7 +8598,9 @@ function useResizeSession({
8519
8598
  }) {
8520
8599
  const handleResizeHandlePointerDown = (0, import_react14.useCallback)((e, nodeId, dir) => {
8521
8600
  if (refs.resizeSessionRef.current) return;
8522
- const selectedEl = refs.nodeMapRef.current.get(nodeId)?.element ?? document.querySelector(`[data-dnd-node-id="${nodeId}"]`);
8601
+ const scanned = refs.nodeMapRef.current.get(nodeId);
8602
+ if (scanned && scanned.draggable === false) return;
8603
+ const selectedEl = scanned?.element ?? document.querySelector(`[data-dnd-node-id="${nodeId}"]`);
8523
8604
  if (!selectedEl) return;
8524
8605
  e.preventDefault();
8525
8606
  e.stopPropagation();
@@ -8922,6 +9003,7 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
8922
9003
  // src/client/dnd/design-mode/DesignModeOverlay.tsx
8923
9004
  var import_jsx_runtime4 = require("react/jsx-runtime");
8924
9005
  var DROP_ANIMATION = { duration: DURATION_MS, easing: EASING };
9006
+ var EMPTY_CONTAINER_ID_SET = /* @__PURE__ */ new Set();
8925
9007
  function resizeCursorFromHandle(handle) {
8926
9008
  switch (handle) {
8927
9009
  case "n":
@@ -9209,13 +9291,9 @@ function DesignModeOverlay() {
9209
9291
  const sensors = useSensors(
9210
9292
  useSensor(PointerSensor, { activationConstraint: { distance: 8 } })
9211
9293
  );
9212
- const collisionDetection = (0, import_react16.useCallback)(
9213
- (args) => createDesignModeCollisionDetection(refs.blockedContainerIdsRef.current)(args),
9214
- []
9215
- // eslint-disable-line react-hooks/exhaustive-deps -- refs are stable
9216
- );
9217
9294
  const [insideRect, setInsideRect] = (0, import_react16.useState)(null);
9218
9295
  const [dropLine, setDropLine] = (0, import_react16.useState)(null);
9296
+ const [activeLaneContainerId, setActiveLaneContainerId] = (0, import_react16.useState)(null);
9219
9297
  (0, import_react16.useEffect)(() => {
9220
9298
  if (!enabled) return;
9221
9299
  const fn = (e) => {
@@ -9251,8 +9329,43 @@ function DesignModeOverlay() {
9251
9329
  syncHistoryAvailability,
9252
9330
  resolveNodeElement,
9253
9331
  setInsideRect,
9254
- setDropLine
9332
+ setDropLine,
9333
+ setActiveLaneContainerId
9255
9334
  });
9335
+ const dropCandidateContainerIds = (0, import_react16.useMemo)(
9336
+ () => activeDrag ? refs.engineRef.current?.getValidDropContainerIds() ?? null : null,
9337
+ [activeDrag]
9338
+ // eslint-disable-line react-hooks/exhaustive-deps -- refs are stable
9339
+ );
9340
+ const visibleCandidateContainerIds = (0, import_react16.useMemo)(() => {
9341
+ if (!dropCandidateContainerIds) return null;
9342
+ const rects = refs.snapshotRef.current?.rects;
9343
+ if (!rects) return dropCandidateContainerIds;
9344
+ const vw = window.innerWidth;
9345
+ const vh = window.innerHeight;
9346
+ const visible = /* @__PURE__ */ new Set();
9347
+ for (const id of dropCandidateContainerIds) {
9348
+ const r = rects.get(id);
9349
+ if (!r) continue;
9350
+ if (r.right < 0 || r.bottom < 0 || r.left > vw || r.top > vh) continue;
9351
+ visible.add(id);
9352
+ }
9353
+ return visible;
9354
+ }, [dropCandidateContainerIds]);
9355
+ const dragGuide = (0, import_react16.useMemo)(() => {
9356
+ if (!activeDrag) return null;
9357
+ const snapshot = refs.snapshotRef.current;
9358
+ if (!snapshot) return null;
9359
+ const activeChildIds = activeLaneContainerId ? refs.engineRef.current?.getContainerChildren(activeLaneContainerId) ?? [] : [];
9360
+ return {
9361
+ rects: snapshot.rects,
9362
+ startScroll: snapshot.scroll,
9363
+ candidateContainerIds: visibleCandidateContainerIds ?? EMPTY_CONTAINER_ID_SET,
9364
+ activeContainerId: activeLaneContainerId,
9365
+ activeChildIds,
9366
+ draggingNodeId: activeDrag.nodeId
9367
+ };
9368
+ }, [activeDrag, activeLaneContainerId, visibleCandidateContainerIds]);
9256
9369
  (0, import_react16.useEffect)(() => {
9257
9370
  if (!enabled || activeDrag) return;
9258
9371
  if (undoRequestId === refs.processedUndoIdRef.current) return;
@@ -9315,7 +9428,7 @@ function DesignModeOverlay() {
9315
9428
  safeZoneRef: refs.safeZoneRef,
9316
9429
  autoScrollStateRef: refs.autoScrollStateRef
9317
9430
  });
9318
- useDragVisualLoop({ activeDrag, refs, getCommitLaneSnapshot, setInsideRect, setDropLine });
9431
+ useDragVisualLoop({ activeDrag, refs, getCommitLaneSnapshot, setInsideRect, setDropLine, setActiveLaneContainerId });
9319
9432
  useExternalDragLoop({
9320
9433
  externalDrag,
9321
9434
  refs,
@@ -9335,7 +9448,6 @@ function DesignModeOverlay() {
9335
9448
  DndContext,
9336
9449
  {
9337
9450
  sensors,
9338
- collisionDetection,
9339
9451
  autoScroll: false,
9340
9452
  onDragStart: handleDragStart,
9341
9453
  onDragEnd: handleDragEnd,
@@ -9344,10 +9456,8 @@ function DesignModeOverlay() {
9344
9456
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9345
9457
  ElementHighlight,
9346
9458
  {
9347
- elements,
9348
- draggingNodeId: activeDrag?.nodeId ?? null,
9349
- activeEl: refs.activeElRef.current,
9350
- arrangeSelectedNodeId,
9459
+ selected: arrangeSelectedNodeId ? nodeMap.get(arrangeSelectedNodeId) ?? null : null,
9460
+ dragGuide,
9351
9461
  externalDragActive: externalDrag !== null,
9352
9462
  onResizeHandlePointerDown: handleResizeHandlePointerDown
9353
9463
  }