@archie/devtools 0.0.44 → 0.0.46
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/dist/client/client.js +337 -191
- package/dist/client/client.mjs +337 -191
- package/package.json +1 -1
package/dist/client/client.mjs
CHANGED
|
@@ -581,44 +581,6 @@ function getFirstCollision(collisions, property) {
|
|
|
581
581
|
const [firstCollision] = collisions;
|
|
582
582
|
return property ? firstCollision[property] : firstCollision;
|
|
583
583
|
}
|
|
584
|
-
function centerOfRectangle(rect, left, top) {
|
|
585
|
-
if (left === void 0) {
|
|
586
|
-
left = rect.left;
|
|
587
|
-
}
|
|
588
|
-
if (top === void 0) {
|
|
589
|
-
top = rect.top;
|
|
590
|
-
}
|
|
591
|
-
return {
|
|
592
|
-
x: left + rect.width * 0.5,
|
|
593
|
-
y: top + rect.height * 0.5
|
|
594
|
-
};
|
|
595
|
-
}
|
|
596
|
-
var closestCenter = (_ref) => {
|
|
597
|
-
let {
|
|
598
|
-
collisionRect,
|
|
599
|
-
droppableRects,
|
|
600
|
-
droppableContainers
|
|
601
|
-
} = _ref;
|
|
602
|
-
const centerRect = centerOfRectangle(collisionRect, collisionRect.left, collisionRect.top);
|
|
603
|
-
const collisions = [];
|
|
604
|
-
for (const droppableContainer of droppableContainers) {
|
|
605
|
-
const {
|
|
606
|
-
id
|
|
607
|
-
} = droppableContainer;
|
|
608
|
-
const rect = droppableRects.get(id);
|
|
609
|
-
if (rect) {
|
|
610
|
-
const distBetween = distanceBetween(centerOfRectangle(rect), centerRect);
|
|
611
|
-
collisions.push({
|
|
612
|
-
id,
|
|
613
|
-
data: {
|
|
614
|
-
droppableContainer,
|
|
615
|
-
value: distBetween
|
|
616
|
-
}
|
|
617
|
-
});
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
return collisions.sort(sortCollisionsAsc);
|
|
621
|
-
};
|
|
622
584
|
var closestCorners = (_ref) => {
|
|
623
585
|
let {
|
|
624
586
|
collisionRect,
|
|
@@ -5225,9 +5187,12 @@ function ensureUniqueNodeId(base, used) {
|
|
|
5225
5187
|
return `${base}::${idx}`;
|
|
5226
5188
|
}
|
|
5227
5189
|
var INSERT_NODE_ID_PREFIX = "insert:";
|
|
5190
|
+
var INSERT_CHILD_NODE_ID_PREFIX = "insert-child:";
|
|
5228
5191
|
function resolveStableNodeId(el, used) {
|
|
5229
5192
|
const persisted = el.getAttribute(DND_NODE_ID_ATTR);
|
|
5230
|
-
if (persisted && persisted.startsWith(INSERT_NODE_ID_PREFIX)
|
|
5193
|
+
if (persisted && (persisted.startsWith(INSERT_NODE_ID_PREFIX) || persisted.startsWith(INSERT_CHILD_NODE_ID_PREFIX))) {
|
|
5194
|
+
return persisted;
|
|
5195
|
+
}
|
|
5231
5196
|
if (persisted && !used.has(persisted)) return persisted;
|
|
5232
5197
|
const projected = projectUsageMeta(el);
|
|
5233
5198
|
if (projected) return ensureUniqueNodeId(projected.nodeId, used);
|
|
@@ -5544,9 +5509,29 @@ function useElementScanner(enabled) {
|
|
|
5544
5509
|
// src/client/dnd/design-mode/ElementHighlight.tsx
|
|
5545
5510
|
import { useRef as useRef5, useEffect as useEffect5, useCallback as useCallback5 } from "react";
|
|
5546
5511
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
5512
|
+
function computeLaneKinshipContainerIds({
|
|
5513
|
+
candidateContainerIds,
|
|
5514
|
+
activeContainerId,
|
|
5515
|
+
draggingNodeId,
|
|
5516
|
+
getParentContainerId,
|
|
5517
|
+
getContainerChildren: getContainerChildren2
|
|
5518
|
+
}) {
|
|
5519
|
+
const anchorId = activeContainerId ?? getParentContainerId(draggingNodeId);
|
|
5520
|
+
if (!anchorId) return /* @__PURE__ */ new Set();
|
|
5521
|
+
const parentId = getParentContainerId(anchorId);
|
|
5522
|
+
const kin = /* @__PURE__ */ new Set();
|
|
5523
|
+
if (!parentId) return kin;
|
|
5524
|
+
if (candidateContainerIds.has(parentId)) kin.add(parentId);
|
|
5525
|
+
for (const siblingId of getContainerChildren2(parentId)) {
|
|
5526
|
+
if (siblingId === anchorId) continue;
|
|
5527
|
+
if (candidateContainerIds.has(siblingId)) kin.add(siblingId);
|
|
5528
|
+
}
|
|
5529
|
+
return kin;
|
|
5530
|
+
}
|
|
5547
5531
|
var HANDLES = ["nw", "n", "ne", "e", "se", "s", "sw", "w"];
|
|
5548
5532
|
var HANDLE_HIT_SIZE = 24;
|
|
5549
5533
|
var HANDLE_KNOB_SIZE = 8;
|
|
5534
|
+
var EMPTY_SCROLL_DELTA = { x: NaN, y: NaN };
|
|
5550
5535
|
var OVERLAY_ROOT_STYLE = {
|
|
5551
5536
|
position: "fixed",
|
|
5552
5537
|
inset: 0,
|
|
@@ -5620,16 +5605,38 @@ function handlePosition(dir) {
|
|
|
5620
5605
|
};
|
|
5621
5606
|
return positions[dir];
|
|
5622
5607
|
}
|
|
5623
|
-
function
|
|
5608
|
+
function getSelectedOutlineStyle(rect, inspectorTheme) {
|
|
5624
5609
|
return {
|
|
5625
5610
|
...OUTLINE_BASE_STYLE,
|
|
5626
5611
|
left: rect.left,
|
|
5627
5612
|
top: rect.top,
|
|
5628
5613
|
width: rect.width,
|
|
5629
5614
|
height: rect.height,
|
|
5630
|
-
border:
|
|
5631
|
-
backgroundColor:
|
|
5615
|
+
border: `2px solid ${inspectorTheme.accent}`,
|
|
5616
|
+
backgroundColor: inspectorTheme.accentSoft
|
|
5617
|
+
};
|
|
5618
|
+
}
|
|
5619
|
+
function getGuideOutlineStyle(rect, tier, inspectorTheme) {
|
|
5620
|
+
const base = {
|
|
5621
|
+
...OUTLINE_BASE_STYLE,
|
|
5622
|
+
left: rect.left,
|
|
5623
|
+
top: rect.top,
|
|
5624
|
+
width: rect.width,
|
|
5625
|
+
height: rect.height
|
|
5632
5626
|
};
|
|
5627
|
+
switch (tier) {
|
|
5628
|
+
case "candidate":
|
|
5629
|
+
return { ...base, border: `1px solid ${inspectorTheme.accent}`, opacity: 0.2 };
|
|
5630
|
+
case "lane-child":
|
|
5631
|
+
return { ...base, border: `1px dashed ${inspectorTheme.accent}`, opacity: 0.45 };
|
|
5632
|
+
case "lane":
|
|
5633
|
+
return {
|
|
5634
|
+
...base,
|
|
5635
|
+
border: `1.5px solid ${inspectorTheme.accent}`,
|
|
5636
|
+
backgroundColor: inspectorTheme.accentSoft,
|
|
5637
|
+
opacity: 0.75
|
|
5638
|
+
};
|
|
5639
|
+
}
|
|
5633
5640
|
}
|
|
5634
5641
|
function getResizeHandleStyle(position) {
|
|
5635
5642
|
return {
|
|
@@ -5653,40 +5660,58 @@ function getLabelStyle(labelLeft, labelTop, labelColor) {
|
|
|
5653
5660
|
backgroundColor: labelColor
|
|
5654
5661
|
};
|
|
5655
5662
|
}
|
|
5663
|
+
function projectDragRect(dragGuide, nodeId, sdx, sdy) {
|
|
5664
|
+
const r = dragGuide.rects.get(nodeId);
|
|
5665
|
+
if (!r) return null;
|
|
5666
|
+
return { left: r.left - sdx, top: r.top - sdy, width: r.width, height: r.height };
|
|
5667
|
+
}
|
|
5656
5668
|
function ElementHighlight({
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
activeEl,
|
|
5660
|
-
arrangeSelectedNodeId,
|
|
5669
|
+
selected,
|
|
5670
|
+
dragGuide,
|
|
5661
5671
|
externalDragActive,
|
|
5662
5672
|
onResizeHandlePointerDown
|
|
5663
5673
|
}) {
|
|
5664
5674
|
const inspectorTheme = useDesignModeStore((s) => s.inspectorTheme);
|
|
5665
|
-
const internalDragInProgress = draggingNodeId !== null;
|
|
5666
|
-
const overlayVisible = arrangeSelectedNodeId !== null || internalDragInProgress;
|
|
5667
5675
|
const containerRef = useRef5(null);
|
|
5668
5676
|
const rafRef = useRef5(0);
|
|
5677
|
+
const lastScrollDeltaRef = useRef5(EMPTY_SCROLL_DELTA);
|
|
5669
5678
|
const syncPositions = useCallback5(() => {
|
|
5670
5679
|
const container = containerRef.current;
|
|
5671
5680
|
if (!container) return;
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
const
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
const
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
label.style.left = `${rect.left}px`;
|
|
5685
|
-
label.style.top = `${rect.top}px`;
|
|
5681
|
+
if (dragGuide) {
|
|
5682
|
+
const sdx = window.scrollX - dragGuide.startScroll.x;
|
|
5683
|
+
const sdy = window.scrollY - dragGuide.startScroll.y;
|
|
5684
|
+
if (sdx === lastScrollDeltaRef.current.x && sdy === lastScrollDeltaRef.current.y) return;
|
|
5685
|
+
lastScrollDeltaRef.current = { x: sdx, y: sdy };
|
|
5686
|
+
const outlines = container.querySelectorAll("[data-guide-for]");
|
|
5687
|
+
for (const outline2 of outlines) {
|
|
5688
|
+
const nodeId = outline2.getAttribute("data-guide-for");
|
|
5689
|
+
const r = dragGuide.rects.get(nodeId);
|
|
5690
|
+
if (!r) continue;
|
|
5691
|
+
outline2.style.left = `${r.left - sdx}px`;
|
|
5692
|
+
outline2.style.top = `${r.top - sdy}px`;
|
|
5686
5693
|
}
|
|
5694
|
+
return;
|
|
5687
5695
|
}
|
|
5688
|
-
|
|
5696
|
+
if (!selected) return;
|
|
5697
|
+
const rect2 = selected.element.getBoundingClientRect();
|
|
5698
|
+
const outline = container.querySelector("[data-outline-for]");
|
|
5699
|
+
if (outline) {
|
|
5700
|
+
outline.style.left = `${rect2.left}px`;
|
|
5701
|
+
outline.style.top = `${rect2.top}px`;
|
|
5702
|
+
outline.style.width = `${rect2.width}px`;
|
|
5703
|
+
outline.style.height = `${rect2.height}px`;
|
|
5704
|
+
}
|
|
5705
|
+
const label = container.querySelector("[data-drag-handle]");
|
|
5706
|
+
if (label) {
|
|
5707
|
+
label.style.left = `${rect2.left + 12}px`;
|
|
5708
|
+
label.style.top = `${Math.max(0, rect2.top - 20)}px`;
|
|
5709
|
+
}
|
|
5710
|
+
}, [dragGuide, selected]);
|
|
5711
|
+
const loopActive = !externalDragActive && (dragGuide !== null || selected !== null);
|
|
5689
5712
|
useEffect5(() => {
|
|
5713
|
+
if (!loopActive) return;
|
|
5714
|
+
lastScrollDeltaRef.current = EMPTY_SCROLL_DELTA;
|
|
5690
5715
|
let running = true;
|
|
5691
5716
|
const loop = () => {
|
|
5692
5717
|
if (!running) return;
|
|
@@ -5698,81 +5723,113 @@ function ElementHighlight({
|
|
|
5698
5723
|
running = false;
|
|
5699
5724
|
cancelAnimationFrame(rafRef.current);
|
|
5700
5725
|
};
|
|
5701
|
-
}, [syncPositions]);
|
|
5702
|
-
if (!
|
|
5703
|
-
if (
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
{
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
if (
|
|
5712
|
-
|
|
5713
|
-
|
|
5714
|
-
|
|
5715
|
-
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
|
|
5728
|
-
|
|
5729
|
-
|
|
5730
|
-
|
|
5731
|
-
|
|
5732
|
-
|
|
5733
|
-
|
|
5734
|
-
|
|
5735
|
-
|
|
5736
|
-
|
|
5737
|
-
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
|
|
5742
|
-
|
|
5743
|
-
|
|
5744
|
-
|
|
5745
|
-
|
|
5746
|
-
|
|
5747
|
-
|
|
5748
|
-
|
|
5749
|
-
|
|
5750
|
-
|
|
5751
|
-
|
|
5726
|
+
}, [loopActive, syncPositions]);
|
|
5727
|
+
if (!loopActive) return null;
|
|
5728
|
+
if (dragGuide) {
|
|
5729
|
+
const sdx = window.scrollX - dragGuide.startScroll.x;
|
|
5730
|
+
const sdy = window.scrollY - dragGuide.startScroll.y;
|
|
5731
|
+
const { candidateContainerIds, activeContainerId, activeChildIds, draggingNodeId } = dragGuide;
|
|
5732
|
+
return /* @__PURE__ */ jsxs("div", { ref: containerRef, "data-design-mode-ui": true, style: OVERLAY_ROOT_STYLE, children: [
|
|
5733
|
+
[...candidateContainerIds].map((id) => {
|
|
5734
|
+
if (id === activeContainerId || id === draggingNodeId) return null;
|
|
5735
|
+
const rect2 = projectDragRect(dragGuide, id, sdx, sdy);
|
|
5736
|
+
if (!rect2) return null;
|
|
5737
|
+
return /* @__PURE__ */ jsx2(
|
|
5738
|
+
"div",
|
|
5739
|
+
{
|
|
5740
|
+
"data-guide-for": id,
|
|
5741
|
+
"data-guide-tier": "candidate",
|
|
5742
|
+
"data-design-mode-ui": true,
|
|
5743
|
+
style: getGuideOutlineStyle(rect2, "candidate", inspectorTheme)
|
|
5744
|
+
},
|
|
5745
|
+
`candidate:${id}`
|
|
5746
|
+
);
|
|
5747
|
+
}),
|
|
5748
|
+
activeContainerId !== null && activeChildIds.map((id) => {
|
|
5749
|
+
if (id === draggingNodeId) return null;
|
|
5750
|
+
const rect2 = projectDragRect(dragGuide, id, sdx, sdy);
|
|
5751
|
+
if (!rect2) return null;
|
|
5752
|
+
return /* @__PURE__ */ jsx2(
|
|
5753
|
+
"div",
|
|
5754
|
+
{
|
|
5755
|
+
"data-guide-for": id,
|
|
5756
|
+
"data-guide-tier": "lane-child",
|
|
5757
|
+
"data-design-mode-ui": true,
|
|
5758
|
+
style: getGuideOutlineStyle(rect2, "lane-child", inspectorTheme)
|
|
5759
|
+
},
|
|
5760
|
+
`lane-child:${id}`
|
|
5761
|
+
);
|
|
5762
|
+
}),
|
|
5763
|
+
activeContainerId !== null && activeContainerId !== draggingNodeId && (() => {
|
|
5764
|
+
const rect2 = projectDragRect(dragGuide, activeContainerId, sdx, sdy);
|
|
5765
|
+
if (!rect2) return null;
|
|
5766
|
+
return /* @__PURE__ */ jsx2(
|
|
5767
|
+
"div",
|
|
5768
|
+
{
|
|
5769
|
+
"data-guide-for": activeContainerId,
|
|
5770
|
+
"data-guide-tier": "lane",
|
|
5771
|
+
"data-design-mode-ui": true,
|
|
5772
|
+
style: getGuideOutlineStyle(rect2, "lane", inspectorTheme)
|
|
5773
|
+
},
|
|
5774
|
+
`lane:${activeContainerId}`
|
|
5775
|
+
);
|
|
5776
|
+
})()
|
|
5777
|
+
] });
|
|
5778
|
+
}
|
|
5779
|
+
if (!selected) return null;
|
|
5780
|
+
const rect = selected.element.getBoundingClientRect();
|
|
5781
|
+
const labelTop = Math.max(0, rect.top - 20);
|
|
5782
|
+
const labelLeft = rect.left + 12;
|
|
5783
|
+
return /* @__PURE__ */ jsxs("div", { ref: containerRef, "data-design-mode-ui": true, style: OVERLAY_ROOT_STYLE, children: [
|
|
5784
|
+
/* @__PURE__ */ jsx2(
|
|
5785
|
+
"div",
|
|
5786
|
+
{
|
|
5787
|
+
"data-outline-for": selected.nodeId,
|
|
5788
|
+
"data-design-mode-ui": true,
|
|
5789
|
+
style: getSelectedOutlineStyle(rect, inspectorTheme),
|
|
5790
|
+
children: selected.draggable && HANDLES.map((dir) => {
|
|
5791
|
+
const pos = handlePosition(dir);
|
|
5792
|
+
return /* @__PURE__ */ jsx2(
|
|
5752
5793
|
"div",
|
|
5753
5794
|
{
|
|
5754
5795
|
"data-design-mode-ui": true,
|
|
5755
|
-
"data-
|
|
5756
|
-
|
|
5757
|
-
|
|
5758
|
-
|
|
5759
|
-
|
|
5760
|
-
),
|
|
5761
|
-
children:
|
|
5762
|
-
|
|
5763
|
-
|
|
5764
|
-
|
|
5765
|
-
|
|
5766
|
-
|
|
5767
|
-
|
|
5768
|
-
|
|
5769
|
-
|
|
5770
|
-
|
|
5771
|
-
|
|
5772
|
-
|
|
5773
|
-
|
|
5774
|
-
|
|
5775
|
-
|
|
5796
|
+
"data-resize-handle": dir,
|
|
5797
|
+
onPointerDown: (e) => {
|
|
5798
|
+
e.stopPropagation();
|
|
5799
|
+
onResizeHandlePointerDown?.(e, selected.nodeId, dir);
|
|
5800
|
+
},
|
|
5801
|
+
style: getResizeHandleStyle(pos),
|
|
5802
|
+
children: /* @__PURE__ */ jsx2(
|
|
5803
|
+
"span",
|
|
5804
|
+
{
|
|
5805
|
+
"data-design-mode-ui": true,
|
|
5806
|
+
style: getResizeKnobStyle(inspectorTheme.accent)
|
|
5807
|
+
}
|
|
5808
|
+
)
|
|
5809
|
+
},
|
|
5810
|
+
dir
|
|
5811
|
+
);
|
|
5812
|
+
})
|
|
5813
|
+
}
|
|
5814
|
+
),
|
|
5815
|
+
/* @__PURE__ */ jsxs(
|
|
5816
|
+
"div",
|
|
5817
|
+
{
|
|
5818
|
+
"data-design-mode-ui": true,
|
|
5819
|
+
"data-drag-handle": selected.nodeId,
|
|
5820
|
+
style: getLabelStyle(labelLeft, labelTop, inspectorTheme.accent),
|
|
5821
|
+
children: [
|
|
5822
|
+
/* @__PURE__ */ jsx2("span", { style: LABEL_ICON_STYLE, children: "\u283F" }),
|
|
5823
|
+
selected.label,
|
|
5824
|
+
/* @__PURE__ */ jsxs("span", { style: LABEL_DIMENSIONS_STYLE, children: [
|
|
5825
|
+
Math.round(rect.width),
|
|
5826
|
+
"\xD7",
|
|
5827
|
+
Math.round(rect.height)
|
|
5828
|
+
] })
|
|
5829
|
+
]
|
|
5830
|
+
}
|
|
5831
|
+
)
|
|
5832
|
+
] });
|
|
5776
5833
|
}
|
|
5777
5834
|
|
|
5778
5835
|
// src/client/dnd/design-mode/projection.ts
|
|
@@ -6058,6 +6115,15 @@ var NON_DRAGGABLE_DESCENDANT_TAGS = /* @__PURE__ */ new Set([
|
|
|
6058
6115
|
"source",
|
|
6059
6116
|
"track"
|
|
6060
6117
|
]);
|
|
6118
|
+
var ARCHIE_INSERTED_ATTR = "data-archie-inserted";
|
|
6119
|
+
var INSERT_CHILD_NODE_ID_PREFIX2 = "insert-child:";
|
|
6120
|
+
function sealDescendantNodeId(node) {
|
|
6121
|
+
if (node.hasAttribute("data-dnd-node-id")) return;
|
|
6122
|
+
const marker = node.getAttribute(ARCHIE_INSERTED_ATTR);
|
|
6123
|
+
if (!marker) return;
|
|
6124
|
+
if (marker.includes('"') || marker.includes("'")) return;
|
|
6125
|
+
node.setAttribute("data-dnd-node-id", `${INSERT_CHILD_NODE_ID_PREFIX2}${marker}`);
|
|
6126
|
+
}
|
|
6061
6127
|
function markInsertedDescendants(root) {
|
|
6062
6128
|
const descendants = root.querySelectorAll("*");
|
|
6063
6129
|
for (const node of descendants) {
|
|
@@ -6065,6 +6131,7 @@ function markInsertedDescendants(root) {
|
|
|
6065
6131
|
if (NON_DRAGGABLE_DESCENDANT_TAGS.has(tag)) continue;
|
|
6066
6132
|
node.setAttribute("data-dnd-force-allow", "");
|
|
6067
6133
|
node.setAttribute("data-dnd-moved", "");
|
|
6134
|
+
sealDescendantNodeId(node);
|
|
6068
6135
|
}
|
|
6069
6136
|
}
|
|
6070
6137
|
|
|
@@ -6566,30 +6633,6 @@ function applyDndCommandPlacement(command, direction, resolveNodeElement) {
|
|
|
6566
6633
|
return true;
|
|
6567
6634
|
}
|
|
6568
6635
|
|
|
6569
|
-
// src/client/dnd/design-mode/design-mode-collision.ts
|
|
6570
|
-
function filterDroppables(droppableContainers, blockedContainerIds) {
|
|
6571
|
-
if (!blockedContainerIds || blockedContainerIds.size === 0) return droppableContainers;
|
|
6572
|
-
return droppableContainers.filter((container) => !blockedContainerIds.has(String(container.id)));
|
|
6573
|
-
}
|
|
6574
|
-
function getCollisions(detector, args) {
|
|
6575
|
-
return detector(args);
|
|
6576
|
-
}
|
|
6577
|
-
function createDesignModeCollisionDetection(blockedContainerIds) {
|
|
6578
|
-
return (args) => {
|
|
6579
|
-
const droppableContainers = filterDroppables(args.droppableContainers, blockedContainerIds);
|
|
6580
|
-
if (droppableContainers.length === 0) return [];
|
|
6581
|
-
const scopedArgs = {
|
|
6582
|
-
...args,
|
|
6583
|
-
droppableContainers
|
|
6584
|
-
};
|
|
6585
|
-
const pointerHits = getCollisions(pointerWithin, scopedArgs);
|
|
6586
|
-
if (pointerHits.length > 0) return pointerHits;
|
|
6587
|
-
const cornerHits = getCollisions(closestCorners, scopedArgs);
|
|
6588
|
-
if (cornerHits.length > 0) return cornerHits;
|
|
6589
|
-
return getCollisions(closestCenter, scopedArgs);
|
|
6590
|
-
};
|
|
6591
|
-
}
|
|
6592
|
-
|
|
6593
6636
|
// src/client/dnd/design-mode/arrange-session.ts
|
|
6594
6637
|
function serializeArrangeChange(event, index) {
|
|
6595
6638
|
return {
|
|
@@ -6868,9 +6911,9 @@ function useOverlayRefs(undoRequestId, redoRequestId) {
|
|
|
6868
6911
|
const lastIntentRef = useRef8(null);
|
|
6869
6912
|
const visualIntentRef = useRef8(null);
|
|
6870
6913
|
const sourceContainerIdRef = useRef8(null);
|
|
6914
|
+
const activeLaneContainerIdRef = useRef8(null);
|
|
6871
6915
|
const rowLockedRef = useRef8(false);
|
|
6872
6916
|
const dragSessionAnchorRef = useRef8(null);
|
|
6873
|
-
const lockRef = useRef8({ containerId: null, isCrossUnlocked: false, exitSince: null, unlockUntilTs: null });
|
|
6874
6917
|
const targetPlaneRef = useRef8("lane");
|
|
6875
6918
|
const nestCandidateRef = useRef8(null);
|
|
6876
6919
|
const nestTargetRef = useRef8(null);
|
|
@@ -6880,7 +6923,6 @@ function useOverlayRefs(undoRequestId, redoRequestId) {
|
|
|
6880
6923
|
const sourceCommitLaneRef = useRef8(null);
|
|
6881
6924
|
const commitLaneCacheRef = useRef8(/* @__PURE__ */ new Map());
|
|
6882
6925
|
const safeZoneRef = useRef8(null);
|
|
6883
|
-
const blockedContainerIdsRef = useRef8(/* @__PURE__ */ new Set());
|
|
6884
6926
|
const historyRef = useRef8(new DndCommandHistory());
|
|
6885
6927
|
const processedUndoIdRef = useRef8(undoRequestId);
|
|
6886
6928
|
const processedRedoIdRef = useRef8(redoRequestId);
|
|
@@ -6900,9 +6942,9 @@ function useOverlayRefs(undoRequestId, redoRequestId) {
|
|
|
6900
6942
|
lastIntentRef,
|
|
6901
6943
|
visualIntentRef,
|
|
6902
6944
|
sourceContainerIdRef,
|
|
6945
|
+
activeLaneContainerIdRef,
|
|
6903
6946
|
rowLockedRef,
|
|
6904
6947
|
dragSessionAnchorRef,
|
|
6905
|
-
lockRef,
|
|
6906
6948
|
targetPlaneRef,
|
|
6907
6949
|
nestCandidateRef,
|
|
6908
6950
|
nestTargetRef,
|
|
@@ -6912,7 +6954,6 @@ function useOverlayRefs(undoRequestId, redoRequestId) {
|
|
|
6912
6954
|
sourceCommitLaneRef,
|
|
6913
6955
|
commitLaneCacheRef,
|
|
6914
6956
|
safeZoneRef,
|
|
6915
|
-
blockedContainerIdsRef,
|
|
6916
6957
|
historyRef,
|
|
6917
6958
|
processedUndoIdRef,
|
|
6918
6959
|
processedRedoIdRef,
|
|
@@ -7180,6 +7221,11 @@ function pointInRect(px, py, r) {
|
|
|
7180
7221
|
function pointInExpandedRect(px, py, r, inset) {
|
|
7181
7222
|
return px >= r.left - inset && px <= r.right + inset && py >= r.top - inset && py <= r.bottom + inset;
|
|
7182
7223
|
}
|
|
7224
|
+
function isInNestZone(px, py, rect) {
|
|
7225
|
+
const relX = (px - rect.left) / rect.width;
|
|
7226
|
+
const relY = (py - rect.top) / rect.height;
|
|
7227
|
+
return relX > NEST_EDGE_FRACTION && relX < 1 - NEST_EDGE_FRACTION && relY > NEST_EDGE_FRACTION && relY < 1 - NEST_EDGE_FRACTION;
|
|
7228
|
+
}
|
|
7183
7229
|
function buildSlotQuadtree(slotIndex) {
|
|
7184
7230
|
const rects = /* @__PURE__ */ new Map();
|
|
7185
7231
|
for (const [id, slot] of slotIndex) {
|
|
@@ -7222,6 +7268,11 @@ var DragIntentEngine = class {
|
|
|
7222
7268
|
__publicField(this, "laneAllowedContainers");
|
|
7223
7269
|
__publicField(this, "blockedContainerIds");
|
|
7224
7270
|
__publicField(this, "targetPlane", "lane");
|
|
7271
|
+
// Memoized result of getValidDropContainerIds(). Safe to cache because every
|
|
7272
|
+
// input it reads (containerIndex, slotIndex, activeId, laneAllowedContainers,
|
|
7273
|
+
// blockedContainerIds) is fixed in the constructor and never mutated during
|
|
7274
|
+
// a drag.
|
|
7275
|
+
__publicField(this, "validDropContainerIds", null);
|
|
7225
7276
|
this.projectionTree = projection.projectionTree;
|
|
7226
7277
|
this.containerIndex = projection.containerIndex;
|
|
7227
7278
|
this.slotIndex = projection.slotIndex;
|
|
@@ -7258,6 +7309,44 @@ var DragIntentEngine = class {
|
|
|
7258
7309
|
getContainerChildren(containerId) {
|
|
7259
7310
|
return this.containerIndex.get(containerId)?.children ?? [];
|
|
7260
7311
|
}
|
|
7312
|
+
/**
|
|
7313
|
+
* Every container id this engine would accept as a drop target for the
|
|
7314
|
+
* active node, at the current pointer position or any other — i.e. the
|
|
7315
|
+
* full set `resolvePointerContainer` draws from, not a snapshot of one
|
|
7316
|
+
* resolve() call. Intended for the visual layer to draw a guide that
|
|
7317
|
+
* matches exactly what the engine can land on, without re-deriving the
|
|
7318
|
+
* eligibility rule itself.
|
|
7319
|
+
*
|
|
7320
|
+
* Always queries with `laneLock: true`. That is not an approximation of
|
|
7321
|
+
* the "real" default — it IS the real answer for every reachable caller:
|
|
7322
|
+
*
|
|
7323
|
+
* - With a row lock active (`laneAllowedContainers` set), `isLaneContainer`
|
|
7324
|
+
* restricts eligibility to that set, so this returns exactly
|
|
7325
|
+
* `{srcContainerId}` — the ARCH-1071 lock, reproduced faithfully.
|
|
7326
|
+
* - Without a row lock, `laneAllowedContainers` is null and
|
|
7327
|
+
* `isLaneContainer` returns true unconditionally, so `laneLock`'s value
|
|
7328
|
+
* makes no difference — passing `true` costs nothing here.
|
|
7329
|
+
* - The engine's own 'nest' plane does call `isEligibleDropContainer` with
|
|
7330
|
+
* `laneLock: false` (see `peekNestIntent` → `resolvePointerContainer`),
|
|
7331
|
+
* but that plane is unreachable for a locked drag: `computeAllowNest`
|
|
7332
|
+
* (useDragVisualLoop.ts) short-circuits `rowLocked` drags before
|
|
7333
|
+
* `setTargetPlane('nest')` is ever called, so `targetPlane` stays
|
|
7334
|
+
* 'lane' for the drag's whole lifetime. If that guard is ever removed,
|
|
7335
|
+
* this method will under-report nest-only targets for locked drags —
|
|
7336
|
+
* keep the two in sync.
|
|
7337
|
+
*
|
|
7338
|
+
* Cached after the first call: every input (containerIndex, slotIndex,
|
|
7339
|
+
* activeId, laneAllowedContainers, blockedContainerIds) is fixed at
|
|
7340
|
+
* construction and never changes for the life of a drag.
|
|
7341
|
+
*/
|
|
7342
|
+
getValidDropContainerIds() {
|
|
7343
|
+
if (this.validDropContainerIds) return this.validDropContainerIds;
|
|
7344
|
+
const ids2 = /* @__PURE__ */ new Set();
|
|
7345
|
+
for (const id of this.containerIndex.keys()) {
|
|
7346
|
+
if (this.isEligibleDropContainer(id, true)) ids2.add(id);
|
|
7347
|
+
}
|
|
7348
|
+
return this.validDropContainerIds = ids2;
|
|
7349
|
+
}
|
|
7261
7350
|
setTargetPlane(plane) {
|
|
7262
7351
|
this.targetPlane = plane;
|
|
7263
7352
|
}
|
|
@@ -7276,6 +7365,17 @@ var DragIntentEngine = class {
|
|
|
7276
7365
|
isInvalidDropContainer(containerId) {
|
|
7277
7366
|
return containerId === this.activeId || this.isContainerDescendantOf(containerId, this.activeId);
|
|
7278
7367
|
}
|
|
7368
|
+
/**
|
|
7369
|
+
* The full "can this container accept the active node this drag" predicate.
|
|
7370
|
+
* SINGLE definition — every caller routes through it so no two parts of the
|
|
7371
|
+
* system can disagree about which containers are droppable.
|
|
7372
|
+
*/
|
|
7373
|
+
isEligibleDropContainer(containerId, laneLock) {
|
|
7374
|
+
if (this.isInvalidDropContainer(containerId)) return false;
|
|
7375
|
+
if (this.isBlockedContainer(containerId)) return false;
|
|
7376
|
+
if (laneLock && !this.isLaneContainer(containerId)) return false;
|
|
7377
|
+
return this.hasUsableSlots(containerId);
|
|
7378
|
+
}
|
|
7279
7379
|
/**
|
|
7280
7380
|
* Resolve the drag intent from the current pointer position.
|
|
7281
7381
|
*
|
|
@@ -7363,9 +7463,7 @@ var DragIntentEngine = class {
|
|
|
7363
7463
|
const childNode = this.getNodeRect(childId);
|
|
7364
7464
|
if (!childNode) continue;
|
|
7365
7465
|
if (!pointInRect(px, py, childNode)) continue;
|
|
7366
|
-
|
|
7367
|
-
const relY = (py - childNode.top) / childNode.height;
|
|
7368
|
-
if (relX > NEST_EDGE_FRACTION && relX < 1 - NEST_EDGE_FRACTION && relY > NEST_EDGE_FRACTION && relY < 1 - NEST_EDGE_FRACTION) {
|
|
7466
|
+
if (isInNestZone(px, py, childNode)) {
|
|
7369
7467
|
return {
|
|
7370
7468
|
containerId: pointerContainerId,
|
|
7371
7469
|
index: container.children.indexOf(childId),
|
|
@@ -7379,11 +7477,8 @@ var DragIntentEngine = class {
|
|
|
7379
7477
|
resolvePointerContainer(px, py, laneLock) {
|
|
7380
7478
|
const pointerContainers = [];
|
|
7381
7479
|
for (const [id, node] of this.containerIndex) {
|
|
7382
|
-
if (this.isInvalidDropContainer(id)) continue;
|
|
7383
|
-
if (this.isBlockedContainer(id)) continue;
|
|
7384
|
-
if (laneLock && !this.isLaneContainer(id)) continue;
|
|
7385
7480
|
if (!pointInRect(px, py, node.rect)) continue;
|
|
7386
|
-
if (this.
|
|
7481
|
+
if (!this.isEligibleDropContainer(id, laneLock)) continue;
|
|
7387
7482
|
const r = node.rect;
|
|
7388
7483
|
const edgeDistX = Math.min(px - r.left, r.right - px);
|
|
7389
7484
|
const edgeDistY = Math.min(py - r.top, r.bottom - py);
|
|
@@ -7400,11 +7495,11 @@ var DragIntentEngine = class {
|
|
|
7400
7495
|
let pointerContainerId = pointerContainers[0]?.id ?? null;
|
|
7401
7496
|
if (!pointerContainerId && this.lastIntent?.mode === "reorder") {
|
|
7402
7497
|
const lastContainer = this.containerIndex.get(this.lastIntent.containerId);
|
|
7403
|
-
if (lastContainer &&
|
|
7498
|
+
if (lastContainer && this.isEligibleDropContainer(lastContainer.id, laneLock) && pointInExpandedRect(px, py, lastContainer.rect, LAST_CONTAINER_REENTRY_SLOP_PX)) {
|
|
7404
7499
|
pointerContainerId = lastContainer.id;
|
|
7405
7500
|
}
|
|
7406
7501
|
}
|
|
7407
|
-
if (this.originContainerId && this.originContainerId !== pointerContainerId &&
|
|
7502
|
+
if (this.originContainerId && this.originContainerId !== pointerContainerId && this.isEligibleDropContainer(this.originContainerId, laneLock)) {
|
|
7408
7503
|
const originNode = this.containerIndex.get(this.originContainerId);
|
|
7409
7504
|
const currentNode = pointerContainerId ? this.containerIndex.get(pointerContainerId) : null;
|
|
7410
7505
|
const originIsDeeper = originNode && (!currentNode || originNode.depth >= currentNode.depth);
|
|
@@ -7817,7 +7912,8 @@ function useDragVisualLoop({
|
|
|
7817
7912
|
refs,
|
|
7818
7913
|
getCommitLaneSnapshot,
|
|
7819
7914
|
setInsideRect,
|
|
7820
|
-
setDropLine
|
|
7915
|
+
setDropLine,
|
|
7916
|
+
setActiveLaneContainerId
|
|
7821
7917
|
}) {
|
|
7822
7918
|
useEffect8(() => {
|
|
7823
7919
|
const engine = refs.engineRef.current;
|
|
@@ -7825,6 +7921,11 @@ function useDragVisualLoop({
|
|
|
7825
7921
|
if (!activeDrag || !engine || !snapshot) return;
|
|
7826
7922
|
let rafId;
|
|
7827
7923
|
const animator = refs.animatorRef.current;
|
|
7924
|
+
const publishActiveLane = (containerId) => {
|
|
7925
|
+
if (refs.activeLaneContainerIdRef.current === containerId) return;
|
|
7926
|
+
refs.activeLaneContainerIdRef.current = containerId;
|
|
7927
|
+
setActiveLaneContainerId(containerId);
|
|
7928
|
+
};
|
|
7828
7929
|
const setTargetPlane = (nextPlane) => {
|
|
7829
7930
|
const prevPlane = refs.targetPlaneRef.current;
|
|
7830
7931
|
if (prevPlane === nextPlane) return;
|
|
@@ -7843,6 +7944,7 @@ function useDragVisualLoop({
|
|
|
7843
7944
|
const safeZone = refs.safeZoneRef.current;
|
|
7844
7945
|
if (isPointerBlocked(px, py, safeZone)) {
|
|
7845
7946
|
setTargetPlane("lane");
|
|
7947
|
+
publishActiveLane(null);
|
|
7846
7948
|
refs.lastIntentRef.current = null;
|
|
7847
7949
|
refs.visualIntentRef.current = null;
|
|
7848
7950
|
refs.nestCandidateRef.current = null;
|
|
@@ -7884,6 +7986,7 @@ function useDragVisualLoop({
|
|
|
7884
7986
|
let intent = engine.resolve(px, py, window.scrollX, window.scrollY, snapshot.scroll.x, snapshot.scroll.y);
|
|
7885
7987
|
if (!intent) {
|
|
7886
7988
|
setTargetPlane("lane");
|
|
7989
|
+
publishActiveLane(null);
|
|
7887
7990
|
refs.lastIntentRef.current = null;
|
|
7888
7991
|
refs.visualIntentRef.current = null;
|
|
7889
7992
|
refs.nestCandidateRef.current = null;
|
|
@@ -7909,6 +8012,7 @@ function useDragVisualLoop({
|
|
|
7909
8012
|
const targetId = intent.slotId.split("::nest::")[1] ?? "";
|
|
7910
8013
|
if (!targetId) {
|
|
7911
8014
|
setTargetPlane("lane");
|
|
8015
|
+
publishActiveLane(null);
|
|
7912
8016
|
rafId = requestAnimationFrame(tick);
|
|
7913
8017
|
return;
|
|
7914
8018
|
}
|
|
@@ -7930,12 +8034,14 @@ function useDragVisualLoop({
|
|
|
7930
8034
|
};
|
|
7931
8035
|
refs.visualIntentRef.current = intent;
|
|
7932
8036
|
refs.lastIntentRef.current = intent;
|
|
8037
|
+
publishActiveLane(intent.containerId);
|
|
7933
8038
|
} else {
|
|
7934
8039
|
setTargetPlane("lane");
|
|
7935
8040
|
refs.nestCandidateRef.current = null;
|
|
7936
8041
|
refs.nestTargetRef.current = null;
|
|
7937
8042
|
refs.lastIntentRef.current = intent;
|
|
7938
8043
|
refs.visualIntentRef.current = intent;
|
|
8044
|
+
publishActiveLane(intent.containerId);
|
|
7939
8045
|
setInsideRect(null);
|
|
7940
8046
|
const proj = refs.projectionRef.current;
|
|
7941
8047
|
const slot = proj.slotIndex.get(intent.slotId);
|
|
@@ -8242,7 +8348,8 @@ function useDragLifecycle({
|
|
|
8242
8348
|
syncHistoryAvailability,
|
|
8243
8349
|
resolveNodeElement,
|
|
8244
8350
|
setInsideRect,
|
|
8245
|
-
setDropLine
|
|
8351
|
+
setDropLine,
|
|
8352
|
+
setActiveLaneContainerId
|
|
8246
8353
|
}) {
|
|
8247
8354
|
const [activeDrag, setActiveDrag] = useState5(null);
|
|
8248
8355
|
const clearDragState = useCallback6(() => {
|
|
@@ -8253,13 +8360,12 @@ function useDragLifecycle({
|
|
|
8253
8360
|
refs.snapshotRef.current = null;
|
|
8254
8361
|
refs.projectionRef.current = EMPTY_PROJECTION;
|
|
8255
8362
|
refs.engineRef.current = null;
|
|
8256
|
-
refs.blockedContainerIdsRef.current = /* @__PURE__ */ new Set();
|
|
8257
8363
|
refs.lastIntentRef.current = null;
|
|
8258
8364
|
refs.visualIntentRef.current = null;
|
|
8259
8365
|
refs.sourceContainerIdRef.current = null;
|
|
8366
|
+
refs.activeLaneContainerIdRef.current = null;
|
|
8260
8367
|
refs.rowLockedRef.current = false;
|
|
8261
8368
|
refs.dragSessionAnchorRef.current = null;
|
|
8262
|
-
refs.lockRef.current = { containerId: null, isCrossUnlocked: false, exitSince: null, unlockUntilTs: null };
|
|
8263
8369
|
refs.targetPlaneRef.current = "lane";
|
|
8264
8370
|
refs.nestCandidateRef.current = null;
|
|
8265
8371
|
refs.nestTargetRef.current = null;
|
|
@@ -8270,6 +8376,7 @@ function useDragLifecycle({
|
|
|
8270
8376
|
refs.safeZoneRef.current = null;
|
|
8271
8377
|
setInsideRect(null);
|
|
8272
8378
|
setDropLine(null);
|
|
8379
|
+
setActiveLaneContainerId(null);
|
|
8273
8380
|
setActiveDrag(null);
|
|
8274
8381
|
resume();
|
|
8275
8382
|
}, [clearCommitLaneCache, resume]);
|
|
@@ -8327,7 +8434,6 @@ function useDragLifecycle({
|
|
|
8327
8434
|
const sourceCommitLane = getCommitLaneSnapshot(srcContainerId);
|
|
8328
8435
|
const startPosition = getCurrentCommitPlacement(anchorNodeId, srcContainerId);
|
|
8329
8436
|
const blockedContainerIds = buildBlockedStructuralContainerIds(proj, refs.nodeMapRef.current, srcContainerId);
|
|
8330
|
-
refs.blockedContainerIdsRef.current = blockedContainerIds;
|
|
8331
8437
|
const engineOptions = buildDragIntentEngineOptions(anchorScanned.element, srcContainerId, blockedContainerIds);
|
|
8332
8438
|
refs.rowLockedRef.current = !!engineOptions.laneAllowedContainers;
|
|
8333
8439
|
refs.engineRef.current = createDragIntentEngine(proj, anchorNodeId, engineOptions);
|
|
@@ -8336,7 +8442,6 @@ function useDragLifecycle({
|
|
|
8336
8442
|
refs.sourceContainerIdRef.current = srcContainerId;
|
|
8337
8443
|
refs.sourceCommitLaneRef.current = sourceCommitLane;
|
|
8338
8444
|
refs.dragSessionAnchorRef.current = anchor;
|
|
8339
|
-
refs.lockRef.current = { containerId: srcContainerId, isCrossUnlocked: true, exitSince: null, unlockUntilTs: null };
|
|
8340
8445
|
refs.dragStartPositionRef.current = startPosition;
|
|
8341
8446
|
refs.safeZoneRef.current = resolveSafeZoneRect();
|
|
8342
8447
|
pause();
|
|
@@ -8818,7 +8923,7 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
|
|
|
8818
8923
|
const candidate = postInsertChildren[i];
|
|
8819
8924
|
const candidateNodeId = candidate.getAttribute(DND_NODE_ID_ATTR);
|
|
8820
8925
|
if (!candidateNodeId) continue;
|
|
8821
|
-
const isEarlierInsert = candidateNodeId.startsWith("insert:");
|
|
8926
|
+
const isEarlierInsert = candidateNodeId.startsWith("insert:") || candidateNodeId.startsWith("insert-child:");
|
|
8822
8927
|
if (!isEarlierInsert && !getInspectorRefFromElement(candidate)) continue;
|
|
8823
8928
|
beforeSiblingEl = candidate;
|
|
8824
8929
|
beforeSiblingNodeId = candidateNodeId;
|
|
@@ -8895,6 +9000,7 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
|
|
|
8895
9000
|
// src/client/dnd/design-mode/DesignModeOverlay.tsx
|
|
8896
9001
|
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
8897
9002
|
var DROP_ANIMATION = { duration: DURATION_MS, easing: EASING };
|
|
9003
|
+
var EMPTY_CONTAINER_ID_SET = /* @__PURE__ */ new Set();
|
|
8898
9004
|
function resizeCursorFromHandle(handle) {
|
|
8899
9005
|
switch (handle) {
|
|
8900
9006
|
case "n":
|
|
@@ -9182,13 +9288,9 @@ function DesignModeOverlay() {
|
|
|
9182
9288
|
const sensors = useSensors(
|
|
9183
9289
|
useSensor(PointerSensor, { activationConstraint: { distance: 8 } })
|
|
9184
9290
|
);
|
|
9185
|
-
const collisionDetection = useCallback8(
|
|
9186
|
-
(args) => createDesignModeCollisionDetection(refs.blockedContainerIdsRef.current)(args),
|
|
9187
|
-
[]
|
|
9188
|
-
// eslint-disable-line react-hooks/exhaustive-deps -- refs are stable
|
|
9189
|
-
);
|
|
9190
9291
|
const [insideRect, setInsideRect] = useState6(null);
|
|
9191
9292
|
const [dropLine, setDropLine] = useState6(null);
|
|
9293
|
+
const [activeLaneContainerId, setActiveLaneContainerId] = useState6(null);
|
|
9192
9294
|
useEffect11(() => {
|
|
9193
9295
|
if (!enabled) return;
|
|
9194
9296
|
const fn = (e) => {
|
|
@@ -9224,8 +9326,55 @@ function DesignModeOverlay() {
|
|
|
9224
9326
|
syncHistoryAvailability,
|
|
9225
9327
|
resolveNodeElement,
|
|
9226
9328
|
setInsideRect,
|
|
9227
|
-
setDropLine
|
|
9329
|
+
setDropLine,
|
|
9330
|
+
setActiveLaneContainerId
|
|
9228
9331
|
});
|
|
9332
|
+
const dropCandidateContainerIds = useMemo6(
|
|
9333
|
+
() => activeDrag ? refs.engineRef.current?.getValidDropContainerIds() ?? null : null,
|
|
9334
|
+
[activeDrag]
|
|
9335
|
+
// eslint-disable-line react-hooks/exhaustive-deps -- refs are stable
|
|
9336
|
+
);
|
|
9337
|
+
const laneKinshipContainerIds = useMemo6(() => {
|
|
9338
|
+
if (!activeDrag || !dropCandidateContainerIds) return null;
|
|
9339
|
+
const engine = refs.engineRef.current;
|
|
9340
|
+
if (!engine) return null;
|
|
9341
|
+
return computeLaneKinshipContainerIds({
|
|
9342
|
+
candidateContainerIds: dropCandidateContainerIds,
|
|
9343
|
+
activeContainerId: activeLaneContainerId,
|
|
9344
|
+
draggingNodeId: activeDrag.nodeId,
|
|
9345
|
+
getParentContainerId: (id) => engine.getNodeParentContainerId(id),
|
|
9346
|
+
getContainerChildren: (id) => engine.getContainerChildren(id)
|
|
9347
|
+
});
|
|
9348
|
+
}, [activeDrag, activeLaneContainerId, dropCandidateContainerIds]);
|
|
9349
|
+
const visibleCandidateContainerIds = useMemo6(() => {
|
|
9350
|
+
if (!laneKinshipContainerIds) return null;
|
|
9351
|
+
const rects = refs.snapshotRef.current?.rects;
|
|
9352
|
+
if (!rects) return laneKinshipContainerIds;
|
|
9353
|
+
const vw = window.innerWidth;
|
|
9354
|
+
const vh = window.innerHeight;
|
|
9355
|
+
const visible = /* @__PURE__ */ new Set();
|
|
9356
|
+
for (const id of laneKinshipContainerIds) {
|
|
9357
|
+
const r = rects.get(id);
|
|
9358
|
+
if (!r) continue;
|
|
9359
|
+
if (r.right < 0 || r.bottom < 0 || r.left > vw || r.top > vh) continue;
|
|
9360
|
+
visible.add(id);
|
|
9361
|
+
}
|
|
9362
|
+
return visible;
|
|
9363
|
+
}, [laneKinshipContainerIds]);
|
|
9364
|
+
const dragGuide = useMemo6(() => {
|
|
9365
|
+
if (!activeDrag) return null;
|
|
9366
|
+
const snapshot = refs.snapshotRef.current;
|
|
9367
|
+
if (!snapshot) return null;
|
|
9368
|
+
const activeChildIds = activeLaneContainerId ? refs.engineRef.current?.getContainerChildren(activeLaneContainerId) ?? [] : [];
|
|
9369
|
+
return {
|
|
9370
|
+
rects: snapshot.rects,
|
|
9371
|
+
startScroll: snapshot.scroll,
|
|
9372
|
+
candidateContainerIds: visibleCandidateContainerIds ?? EMPTY_CONTAINER_ID_SET,
|
|
9373
|
+
activeContainerId: activeLaneContainerId,
|
|
9374
|
+
activeChildIds,
|
|
9375
|
+
draggingNodeId: activeDrag.nodeId
|
|
9376
|
+
};
|
|
9377
|
+
}, [activeDrag, activeLaneContainerId, visibleCandidateContainerIds]);
|
|
9229
9378
|
useEffect11(() => {
|
|
9230
9379
|
if (!enabled || activeDrag) return;
|
|
9231
9380
|
if (undoRequestId === refs.processedUndoIdRef.current) return;
|
|
@@ -9288,7 +9437,7 @@ function DesignModeOverlay() {
|
|
|
9288
9437
|
safeZoneRef: refs.safeZoneRef,
|
|
9289
9438
|
autoScrollStateRef: refs.autoScrollStateRef
|
|
9290
9439
|
});
|
|
9291
|
-
useDragVisualLoop({ activeDrag, refs, getCommitLaneSnapshot, setInsideRect, setDropLine });
|
|
9440
|
+
useDragVisualLoop({ activeDrag, refs, getCommitLaneSnapshot, setInsideRect, setDropLine, setActiveLaneContainerId });
|
|
9292
9441
|
useExternalDragLoop({
|
|
9293
9442
|
externalDrag,
|
|
9294
9443
|
refs,
|
|
@@ -9308,7 +9457,6 @@ function DesignModeOverlay() {
|
|
|
9308
9457
|
DndContext,
|
|
9309
9458
|
{
|
|
9310
9459
|
sensors,
|
|
9311
|
-
collisionDetection,
|
|
9312
9460
|
autoScroll: false,
|
|
9313
9461
|
onDragStart: handleDragStart,
|
|
9314
9462
|
onDragEnd: handleDragEnd,
|
|
@@ -9317,10 +9465,8 @@ function DesignModeOverlay() {
|
|
|
9317
9465
|
/* @__PURE__ */ jsx4(
|
|
9318
9466
|
ElementHighlight,
|
|
9319
9467
|
{
|
|
9320
|
-
|
|
9321
|
-
|
|
9322
|
-
activeEl: refs.activeElRef.current,
|
|
9323
|
-
arrangeSelectedNodeId,
|
|
9468
|
+
selected: arrangeSelectedNodeId ? nodeMap.get(arrangeSelectedNodeId) ?? null : null,
|
|
9469
|
+
dragGuide,
|
|
9324
9470
|
externalDragActive: externalDrag !== null,
|
|
9325
9471
|
onResizeHandlePointerDown: handleResizeHandlePointerDown
|
|
9326
9472
|
}
|