@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.js
CHANGED
|
@@ -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,
|
|
@@ -5260,9 +5222,12 @@ function ensureUniqueNodeId(base, used) {
|
|
|
5260
5222
|
return `${base}::${idx}`;
|
|
5261
5223
|
}
|
|
5262
5224
|
var INSERT_NODE_ID_PREFIX = "insert:";
|
|
5225
|
+
var INSERT_CHILD_NODE_ID_PREFIX = "insert-child:";
|
|
5263
5226
|
function resolveStableNodeId(el, used) {
|
|
5264
5227
|
const persisted = el.getAttribute(DND_NODE_ID_ATTR);
|
|
5265
|
-
if (persisted && persisted.startsWith(INSERT_NODE_ID_PREFIX)
|
|
5228
|
+
if (persisted && (persisted.startsWith(INSERT_NODE_ID_PREFIX) || persisted.startsWith(INSERT_CHILD_NODE_ID_PREFIX))) {
|
|
5229
|
+
return persisted;
|
|
5230
|
+
}
|
|
5266
5231
|
if (persisted && !used.has(persisted)) return persisted;
|
|
5267
5232
|
const projected = projectUsageMeta(el);
|
|
5268
5233
|
if (projected) return ensureUniqueNodeId(projected.nodeId, used);
|
|
@@ -5579,9 +5544,29 @@ function useElementScanner(enabled) {
|
|
|
5579
5544
|
// src/client/dnd/design-mode/ElementHighlight.tsx
|
|
5580
5545
|
var import_react7 = require("react");
|
|
5581
5546
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
5547
|
+
function computeLaneKinshipContainerIds({
|
|
5548
|
+
candidateContainerIds,
|
|
5549
|
+
activeContainerId,
|
|
5550
|
+
draggingNodeId,
|
|
5551
|
+
getParentContainerId,
|
|
5552
|
+
getContainerChildren: getContainerChildren2
|
|
5553
|
+
}) {
|
|
5554
|
+
const anchorId = activeContainerId ?? getParentContainerId(draggingNodeId);
|
|
5555
|
+
if (!anchorId) return /* @__PURE__ */ new Set();
|
|
5556
|
+
const parentId = getParentContainerId(anchorId);
|
|
5557
|
+
const kin = /* @__PURE__ */ new Set();
|
|
5558
|
+
if (!parentId) return kin;
|
|
5559
|
+
if (candidateContainerIds.has(parentId)) kin.add(parentId);
|
|
5560
|
+
for (const siblingId of getContainerChildren2(parentId)) {
|
|
5561
|
+
if (siblingId === anchorId) continue;
|
|
5562
|
+
if (candidateContainerIds.has(siblingId)) kin.add(siblingId);
|
|
5563
|
+
}
|
|
5564
|
+
return kin;
|
|
5565
|
+
}
|
|
5582
5566
|
var HANDLES = ["nw", "n", "ne", "e", "se", "s", "sw", "w"];
|
|
5583
5567
|
var HANDLE_HIT_SIZE = 24;
|
|
5584
5568
|
var HANDLE_KNOB_SIZE = 8;
|
|
5569
|
+
var EMPTY_SCROLL_DELTA = { x: NaN, y: NaN };
|
|
5585
5570
|
var OVERLAY_ROOT_STYLE = {
|
|
5586
5571
|
position: "fixed",
|
|
5587
5572
|
inset: 0,
|
|
@@ -5655,16 +5640,38 @@ function handlePosition(dir) {
|
|
|
5655
5640
|
};
|
|
5656
5641
|
return positions[dir];
|
|
5657
5642
|
}
|
|
5658
|
-
function
|
|
5643
|
+
function getSelectedOutlineStyle(rect, inspectorTheme) {
|
|
5659
5644
|
return {
|
|
5660
5645
|
...OUTLINE_BASE_STYLE,
|
|
5661
5646
|
left: rect.left,
|
|
5662
5647
|
top: rect.top,
|
|
5663
5648
|
width: rect.width,
|
|
5664
5649
|
height: rect.height,
|
|
5665
|
-
border:
|
|
5666
|
-
backgroundColor:
|
|
5650
|
+
border: `2px solid ${inspectorTheme.accent}`,
|
|
5651
|
+
backgroundColor: inspectorTheme.accentSoft
|
|
5652
|
+
};
|
|
5653
|
+
}
|
|
5654
|
+
function getGuideOutlineStyle(rect, tier, inspectorTheme) {
|
|
5655
|
+
const base = {
|
|
5656
|
+
...OUTLINE_BASE_STYLE,
|
|
5657
|
+
left: rect.left,
|
|
5658
|
+
top: rect.top,
|
|
5659
|
+
width: rect.width,
|
|
5660
|
+
height: rect.height
|
|
5667
5661
|
};
|
|
5662
|
+
switch (tier) {
|
|
5663
|
+
case "candidate":
|
|
5664
|
+
return { ...base, border: `1px solid ${inspectorTheme.accent}`, opacity: 0.2 };
|
|
5665
|
+
case "lane-child":
|
|
5666
|
+
return { ...base, border: `1px dashed ${inspectorTheme.accent}`, opacity: 0.45 };
|
|
5667
|
+
case "lane":
|
|
5668
|
+
return {
|
|
5669
|
+
...base,
|
|
5670
|
+
border: `1.5px solid ${inspectorTheme.accent}`,
|
|
5671
|
+
backgroundColor: inspectorTheme.accentSoft,
|
|
5672
|
+
opacity: 0.75
|
|
5673
|
+
};
|
|
5674
|
+
}
|
|
5668
5675
|
}
|
|
5669
5676
|
function getResizeHandleStyle(position) {
|
|
5670
5677
|
return {
|
|
@@ -5688,40 +5695,58 @@ function getLabelStyle(labelLeft, labelTop, labelColor) {
|
|
|
5688
5695
|
backgroundColor: labelColor
|
|
5689
5696
|
};
|
|
5690
5697
|
}
|
|
5698
|
+
function projectDragRect(dragGuide, nodeId, sdx, sdy) {
|
|
5699
|
+
const r = dragGuide.rects.get(nodeId);
|
|
5700
|
+
if (!r) return null;
|
|
5701
|
+
return { left: r.left - sdx, top: r.top - sdy, width: r.width, height: r.height };
|
|
5702
|
+
}
|
|
5691
5703
|
function ElementHighlight({
|
|
5692
|
-
|
|
5693
|
-
|
|
5694
|
-
activeEl,
|
|
5695
|
-
arrangeSelectedNodeId,
|
|
5704
|
+
selected,
|
|
5705
|
+
dragGuide,
|
|
5696
5706
|
externalDragActive,
|
|
5697
5707
|
onResizeHandlePointerDown
|
|
5698
5708
|
}) {
|
|
5699
5709
|
const inspectorTheme = useDesignModeStore((s) => s.inspectorTheme);
|
|
5700
|
-
const internalDragInProgress = draggingNodeId !== null;
|
|
5701
|
-
const overlayVisible = arrangeSelectedNodeId !== null || internalDragInProgress;
|
|
5702
5710
|
const containerRef = (0, import_react7.useRef)(null);
|
|
5703
5711
|
const rafRef = (0, import_react7.useRef)(0);
|
|
5712
|
+
const lastScrollDeltaRef = (0, import_react7.useRef)(EMPTY_SCROLL_DELTA);
|
|
5704
5713
|
const syncPositions = (0, import_react7.useCallback)(() => {
|
|
5705
5714
|
const container = containerRef.current;
|
|
5706
5715
|
if (!container) return;
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
const
|
|
5710
|
-
|
|
5711
|
-
|
|
5712
|
-
const
|
|
5713
|
-
|
|
5714
|
-
|
|
5715
|
-
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
label.style.left = `${rect.left}px`;
|
|
5720
|
-
label.style.top = `${rect.top}px`;
|
|
5716
|
+
if (dragGuide) {
|
|
5717
|
+
const sdx = window.scrollX - dragGuide.startScroll.x;
|
|
5718
|
+
const sdy = window.scrollY - dragGuide.startScroll.y;
|
|
5719
|
+
if (sdx === lastScrollDeltaRef.current.x && sdy === lastScrollDeltaRef.current.y) return;
|
|
5720
|
+
lastScrollDeltaRef.current = { x: sdx, y: sdy };
|
|
5721
|
+
const outlines = container.querySelectorAll("[data-guide-for]");
|
|
5722
|
+
for (const outline2 of outlines) {
|
|
5723
|
+
const nodeId = outline2.getAttribute("data-guide-for");
|
|
5724
|
+
const r = dragGuide.rects.get(nodeId);
|
|
5725
|
+
if (!r) continue;
|
|
5726
|
+
outline2.style.left = `${r.left - sdx}px`;
|
|
5727
|
+
outline2.style.top = `${r.top - sdy}px`;
|
|
5721
5728
|
}
|
|
5729
|
+
return;
|
|
5722
5730
|
}
|
|
5723
|
-
|
|
5731
|
+
if (!selected) return;
|
|
5732
|
+
const rect2 = selected.element.getBoundingClientRect();
|
|
5733
|
+
const outline = container.querySelector("[data-outline-for]");
|
|
5734
|
+
if (outline) {
|
|
5735
|
+
outline.style.left = `${rect2.left}px`;
|
|
5736
|
+
outline.style.top = `${rect2.top}px`;
|
|
5737
|
+
outline.style.width = `${rect2.width}px`;
|
|
5738
|
+
outline.style.height = `${rect2.height}px`;
|
|
5739
|
+
}
|
|
5740
|
+
const label = container.querySelector("[data-drag-handle]");
|
|
5741
|
+
if (label) {
|
|
5742
|
+
label.style.left = `${rect2.left + 12}px`;
|
|
5743
|
+
label.style.top = `${Math.max(0, rect2.top - 20)}px`;
|
|
5744
|
+
}
|
|
5745
|
+
}, [dragGuide, selected]);
|
|
5746
|
+
const loopActive = !externalDragActive && (dragGuide !== null || selected !== null);
|
|
5724
5747
|
(0, import_react7.useEffect)(() => {
|
|
5748
|
+
if (!loopActive) return;
|
|
5749
|
+
lastScrollDeltaRef.current = EMPTY_SCROLL_DELTA;
|
|
5725
5750
|
let running = true;
|
|
5726
5751
|
const loop = () => {
|
|
5727
5752
|
if (!running) return;
|
|
@@ -5733,81 +5758,113 @@ function ElementHighlight({
|
|
|
5733
5758
|
running = false;
|
|
5734
5759
|
cancelAnimationFrame(rafRef.current);
|
|
5735
5760
|
};
|
|
5736
|
-
}, [syncPositions]);
|
|
5737
|
-
if (!
|
|
5738
|
-
if (
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
{
|
|
5742
|
-
|
|
5743
|
-
|
|
5744
|
-
|
|
5745
|
-
|
|
5746
|
-
if (
|
|
5747
|
-
|
|
5748
|
-
|
|
5749
|
-
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
|
|
5753
|
-
|
|
5754
|
-
|
|
5755
|
-
|
|
5756
|
-
|
|
5757
|
-
|
|
5758
|
-
|
|
5759
|
-
|
|
5760
|
-
|
|
5761
|
-
|
|
5762
|
-
|
|
5763
|
-
|
|
5764
|
-
|
|
5765
|
-
|
|
5766
|
-
|
|
5767
|
-
|
|
5768
|
-
|
|
5769
|
-
|
|
5770
|
-
|
|
5771
|
-
|
|
5772
|
-
|
|
5773
|
-
|
|
5774
|
-
|
|
5775
|
-
|
|
5776
|
-
|
|
5777
|
-
|
|
5778
|
-
|
|
5779
|
-
|
|
5780
|
-
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
5786
|
-
|
|
5761
|
+
}, [loopActive, syncPositions]);
|
|
5762
|
+
if (!loopActive) return null;
|
|
5763
|
+
if (dragGuide) {
|
|
5764
|
+
const sdx = window.scrollX - dragGuide.startScroll.x;
|
|
5765
|
+
const sdy = window.scrollY - dragGuide.startScroll.y;
|
|
5766
|
+
const { candidateContainerIds, activeContainerId, activeChildIds, draggingNodeId } = dragGuide;
|
|
5767
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { ref: containerRef, "data-design-mode-ui": true, style: OVERLAY_ROOT_STYLE, children: [
|
|
5768
|
+
[...candidateContainerIds].map((id) => {
|
|
5769
|
+
if (id === activeContainerId || id === draggingNodeId) return null;
|
|
5770
|
+
const rect2 = projectDragRect(dragGuide, id, sdx, sdy);
|
|
5771
|
+
if (!rect2) return null;
|
|
5772
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
5773
|
+
"div",
|
|
5774
|
+
{
|
|
5775
|
+
"data-guide-for": id,
|
|
5776
|
+
"data-guide-tier": "candidate",
|
|
5777
|
+
"data-design-mode-ui": true,
|
|
5778
|
+
style: getGuideOutlineStyle(rect2, "candidate", inspectorTheme)
|
|
5779
|
+
},
|
|
5780
|
+
`candidate:${id}`
|
|
5781
|
+
);
|
|
5782
|
+
}),
|
|
5783
|
+
activeContainerId !== null && activeChildIds.map((id) => {
|
|
5784
|
+
if (id === draggingNodeId) return null;
|
|
5785
|
+
const rect2 = projectDragRect(dragGuide, id, sdx, sdy);
|
|
5786
|
+
if (!rect2) return null;
|
|
5787
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
5788
|
+
"div",
|
|
5789
|
+
{
|
|
5790
|
+
"data-guide-for": id,
|
|
5791
|
+
"data-guide-tier": "lane-child",
|
|
5792
|
+
"data-design-mode-ui": true,
|
|
5793
|
+
style: getGuideOutlineStyle(rect2, "lane-child", inspectorTheme)
|
|
5794
|
+
},
|
|
5795
|
+
`lane-child:${id}`
|
|
5796
|
+
);
|
|
5797
|
+
}),
|
|
5798
|
+
activeContainerId !== null && activeContainerId !== draggingNodeId && (() => {
|
|
5799
|
+
const rect2 = projectDragRect(dragGuide, activeContainerId, sdx, sdy);
|
|
5800
|
+
if (!rect2) return null;
|
|
5801
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
5802
|
+
"div",
|
|
5803
|
+
{
|
|
5804
|
+
"data-guide-for": activeContainerId,
|
|
5805
|
+
"data-guide-tier": "lane",
|
|
5806
|
+
"data-design-mode-ui": true,
|
|
5807
|
+
style: getGuideOutlineStyle(rect2, "lane", inspectorTheme)
|
|
5808
|
+
},
|
|
5809
|
+
`lane:${activeContainerId}`
|
|
5810
|
+
);
|
|
5811
|
+
})()
|
|
5812
|
+
] });
|
|
5813
|
+
}
|
|
5814
|
+
if (!selected) return null;
|
|
5815
|
+
const rect = selected.element.getBoundingClientRect();
|
|
5816
|
+
const labelTop = Math.max(0, rect.top - 20);
|
|
5817
|
+
const labelLeft = rect.left + 12;
|
|
5818
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { ref: containerRef, "data-design-mode-ui": true, style: OVERLAY_ROOT_STYLE, children: [
|
|
5819
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
5820
|
+
"div",
|
|
5821
|
+
{
|
|
5822
|
+
"data-outline-for": selected.nodeId,
|
|
5823
|
+
"data-design-mode-ui": true,
|
|
5824
|
+
style: getSelectedOutlineStyle(rect, inspectorTheme),
|
|
5825
|
+
children: selected.draggable && HANDLES.map((dir) => {
|
|
5826
|
+
const pos = handlePosition(dir);
|
|
5827
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
5787
5828
|
"div",
|
|
5788
5829
|
{
|
|
5789
5830
|
"data-design-mode-ui": true,
|
|
5790
|
-
"data-
|
|
5791
|
-
|
|
5792
|
-
|
|
5793
|
-
|
|
5794
|
-
|
|
5795
|
-
),
|
|
5796
|
-
children:
|
|
5797
|
-
|
|
5798
|
-
|
|
5799
|
-
|
|
5800
|
-
|
|
5801
|
-
|
|
5802
|
-
|
|
5803
|
-
|
|
5804
|
-
|
|
5805
|
-
|
|
5806
|
-
|
|
5807
|
-
|
|
5808
|
-
|
|
5809
|
-
|
|
5810
|
-
|
|
5831
|
+
"data-resize-handle": dir,
|
|
5832
|
+
onPointerDown: (e) => {
|
|
5833
|
+
e.stopPropagation();
|
|
5834
|
+
onResizeHandlePointerDown?.(e, selected.nodeId, dir);
|
|
5835
|
+
},
|
|
5836
|
+
style: getResizeHandleStyle(pos),
|
|
5837
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
5838
|
+
"span",
|
|
5839
|
+
{
|
|
5840
|
+
"data-design-mode-ui": true,
|
|
5841
|
+
style: getResizeKnobStyle(inspectorTheme.accent)
|
|
5842
|
+
}
|
|
5843
|
+
)
|
|
5844
|
+
},
|
|
5845
|
+
dir
|
|
5846
|
+
);
|
|
5847
|
+
})
|
|
5848
|
+
}
|
|
5849
|
+
),
|
|
5850
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
5851
|
+
"div",
|
|
5852
|
+
{
|
|
5853
|
+
"data-design-mode-ui": true,
|
|
5854
|
+
"data-drag-handle": selected.nodeId,
|
|
5855
|
+
style: getLabelStyle(labelLeft, labelTop, inspectorTheme.accent),
|
|
5856
|
+
children: [
|
|
5857
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: LABEL_ICON_STYLE, children: "\u283F" }),
|
|
5858
|
+
selected.label,
|
|
5859
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: LABEL_DIMENSIONS_STYLE, children: [
|
|
5860
|
+
Math.round(rect.width),
|
|
5861
|
+
"\xD7",
|
|
5862
|
+
Math.round(rect.height)
|
|
5863
|
+
] })
|
|
5864
|
+
]
|
|
5865
|
+
}
|
|
5866
|
+
)
|
|
5867
|
+
] });
|
|
5811
5868
|
}
|
|
5812
5869
|
|
|
5813
5870
|
// src/client/dnd/design-mode/projection.ts
|
|
@@ -6093,6 +6150,15 @@ var NON_DRAGGABLE_DESCENDANT_TAGS = /* @__PURE__ */ new Set([
|
|
|
6093
6150
|
"source",
|
|
6094
6151
|
"track"
|
|
6095
6152
|
]);
|
|
6153
|
+
var ARCHIE_INSERTED_ATTR = "data-archie-inserted";
|
|
6154
|
+
var INSERT_CHILD_NODE_ID_PREFIX2 = "insert-child:";
|
|
6155
|
+
function sealDescendantNodeId(node) {
|
|
6156
|
+
if (node.hasAttribute("data-dnd-node-id")) return;
|
|
6157
|
+
const marker = node.getAttribute(ARCHIE_INSERTED_ATTR);
|
|
6158
|
+
if (!marker) return;
|
|
6159
|
+
if (marker.includes('"') || marker.includes("'")) return;
|
|
6160
|
+
node.setAttribute("data-dnd-node-id", `${INSERT_CHILD_NODE_ID_PREFIX2}${marker}`);
|
|
6161
|
+
}
|
|
6096
6162
|
function markInsertedDescendants(root) {
|
|
6097
6163
|
const descendants = root.querySelectorAll("*");
|
|
6098
6164
|
for (const node of descendants) {
|
|
@@ -6100,6 +6166,7 @@ function markInsertedDescendants(root) {
|
|
|
6100
6166
|
if (NON_DRAGGABLE_DESCENDANT_TAGS.has(tag)) continue;
|
|
6101
6167
|
node.setAttribute("data-dnd-force-allow", "");
|
|
6102
6168
|
node.setAttribute("data-dnd-moved", "");
|
|
6169
|
+
sealDescendantNodeId(node);
|
|
6103
6170
|
}
|
|
6104
6171
|
}
|
|
6105
6172
|
|
|
@@ -6601,30 +6668,6 @@ function applyDndCommandPlacement(command, direction, resolveNodeElement) {
|
|
|
6601
6668
|
return true;
|
|
6602
6669
|
}
|
|
6603
6670
|
|
|
6604
|
-
// src/client/dnd/design-mode/design-mode-collision.ts
|
|
6605
|
-
function filterDroppables(droppableContainers, blockedContainerIds) {
|
|
6606
|
-
if (!blockedContainerIds || blockedContainerIds.size === 0) return droppableContainers;
|
|
6607
|
-
return droppableContainers.filter((container) => !blockedContainerIds.has(String(container.id)));
|
|
6608
|
-
}
|
|
6609
|
-
function getCollisions(detector, args) {
|
|
6610
|
-
return detector(args);
|
|
6611
|
-
}
|
|
6612
|
-
function createDesignModeCollisionDetection(blockedContainerIds) {
|
|
6613
|
-
return (args) => {
|
|
6614
|
-
const droppableContainers = filterDroppables(args.droppableContainers, blockedContainerIds);
|
|
6615
|
-
if (droppableContainers.length === 0) return [];
|
|
6616
|
-
const scopedArgs = {
|
|
6617
|
-
...args,
|
|
6618
|
-
droppableContainers
|
|
6619
|
-
};
|
|
6620
|
-
const pointerHits = getCollisions(pointerWithin, scopedArgs);
|
|
6621
|
-
if (pointerHits.length > 0) return pointerHits;
|
|
6622
|
-
const cornerHits = getCollisions(closestCorners, scopedArgs);
|
|
6623
|
-
if (cornerHits.length > 0) return cornerHits;
|
|
6624
|
-
return getCollisions(closestCenter, scopedArgs);
|
|
6625
|
-
};
|
|
6626
|
-
}
|
|
6627
|
-
|
|
6628
6671
|
// src/client/dnd/design-mode/arrange-session.ts
|
|
6629
6672
|
function serializeArrangeChange(event, index) {
|
|
6630
6673
|
return {
|
|
@@ -6903,9 +6946,9 @@ function useOverlayRefs(undoRequestId, redoRequestId) {
|
|
|
6903
6946
|
const lastIntentRef = (0, import_react11.useRef)(null);
|
|
6904
6947
|
const visualIntentRef = (0, import_react11.useRef)(null);
|
|
6905
6948
|
const sourceContainerIdRef = (0, import_react11.useRef)(null);
|
|
6949
|
+
const activeLaneContainerIdRef = (0, import_react11.useRef)(null);
|
|
6906
6950
|
const rowLockedRef = (0, import_react11.useRef)(false);
|
|
6907
6951
|
const dragSessionAnchorRef = (0, import_react11.useRef)(null);
|
|
6908
|
-
const lockRef = (0, import_react11.useRef)({ containerId: null, isCrossUnlocked: false, exitSince: null, unlockUntilTs: null });
|
|
6909
6952
|
const targetPlaneRef = (0, import_react11.useRef)("lane");
|
|
6910
6953
|
const nestCandidateRef = (0, import_react11.useRef)(null);
|
|
6911
6954
|
const nestTargetRef = (0, import_react11.useRef)(null);
|
|
@@ -6915,7 +6958,6 @@ function useOverlayRefs(undoRequestId, redoRequestId) {
|
|
|
6915
6958
|
const sourceCommitLaneRef = (0, import_react11.useRef)(null);
|
|
6916
6959
|
const commitLaneCacheRef = (0, import_react11.useRef)(/* @__PURE__ */ new Map());
|
|
6917
6960
|
const safeZoneRef = (0, import_react11.useRef)(null);
|
|
6918
|
-
const blockedContainerIdsRef = (0, import_react11.useRef)(/* @__PURE__ */ new Set());
|
|
6919
6961
|
const historyRef = (0, import_react11.useRef)(new DndCommandHistory());
|
|
6920
6962
|
const processedUndoIdRef = (0, import_react11.useRef)(undoRequestId);
|
|
6921
6963
|
const processedRedoIdRef = (0, import_react11.useRef)(redoRequestId);
|
|
@@ -6935,9 +6977,9 @@ function useOverlayRefs(undoRequestId, redoRequestId) {
|
|
|
6935
6977
|
lastIntentRef,
|
|
6936
6978
|
visualIntentRef,
|
|
6937
6979
|
sourceContainerIdRef,
|
|
6980
|
+
activeLaneContainerIdRef,
|
|
6938
6981
|
rowLockedRef,
|
|
6939
6982
|
dragSessionAnchorRef,
|
|
6940
|
-
lockRef,
|
|
6941
6983
|
targetPlaneRef,
|
|
6942
6984
|
nestCandidateRef,
|
|
6943
6985
|
nestTargetRef,
|
|
@@ -6947,7 +6989,6 @@ function useOverlayRefs(undoRequestId, redoRequestId) {
|
|
|
6947
6989
|
sourceCommitLaneRef,
|
|
6948
6990
|
commitLaneCacheRef,
|
|
6949
6991
|
safeZoneRef,
|
|
6950
|
-
blockedContainerIdsRef,
|
|
6951
6992
|
historyRef,
|
|
6952
6993
|
processedUndoIdRef,
|
|
6953
6994
|
processedRedoIdRef,
|
|
@@ -7215,6 +7256,11 @@ function pointInRect(px, py, r) {
|
|
|
7215
7256
|
function pointInExpandedRect(px, py, r, inset) {
|
|
7216
7257
|
return px >= r.left - inset && px <= r.right + inset && py >= r.top - inset && py <= r.bottom + inset;
|
|
7217
7258
|
}
|
|
7259
|
+
function isInNestZone(px, py, rect) {
|
|
7260
|
+
const relX = (px - rect.left) / rect.width;
|
|
7261
|
+
const relY = (py - rect.top) / rect.height;
|
|
7262
|
+
return relX > NEST_EDGE_FRACTION && relX < 1 - NEST_EDGE_FRACTION && relY > NEST_EDGE_FRACTION && relY < 1 - NEST_EDGE_FRACTION;
|
|
7263
|
+
}
|
|
7218
7264
|
function buildSlotQuadtree(slotIndex) {
|
|
7219
7265
|
const rects = /* @__PURE__ */ new Map();
|
|
7220
7266
|
for (const [id, slot] of slotIndex) {
|
|
@@ -7257,6 +7303,11 @@ var DragIntentEngine = class {
|
|
|
7257
7303
|
__publicField(this, "laneAllowedContainers");
|
|
7258
7304
|
__publicField(this, "blockedContainerIds");
|
|
7259
7305
|
__publicField(this, "targetPlane", "lane");
|
|
7306
|
+
// Memoized result of getValidDropContainerIds(). Safe to cache because every
|
|
7307
|
+
// input it reads (containerIndex, slotIndex, activeId, laneAllowedContainers,
|
|
7308
|
+
// blockedContainerIds) is fixed in the constructor and never mutated during
|
|
7309
|
+
// a drag.
|
|
7310
|
+
__publicField(this, "validDropContainerIds", null);
|
|
7260
7311
|
this.projectionTree = projection.projectionTree;
|
|
7261
7312
|
this.containerIndex = projection.containerIndex;
|
|
7262
7313
|
this.slotIndex = projection.slotIndex;
|
|
@@ -7293,6 +7344,44 @@ var DragIntentEngine = class {
|
|
|
7293
7344
|
getContainerChildren(containerId) {
|
|
7294
7345
|
return this.containerIndex.get(containerId)?.children ?? [];
|
|
7295
7346
|
}
|
|
7347
|
+
/**
|
|
7348
|
+
* Every container id this engine would accept as a drop target for the
|
|
7349
|
+
* active node, at the current pointer position or any other — i.e. the
|
|
7350
|
+
* full set `resolvePointerContainer` draws from, not a snapshot of one
|
|
7351
|
+
* resolve() call. Intended for the visual layer to draw a guide that
|
|
7352
|
+
* matches exactly what the engine can land on, without re-deriving the
|
|
7353
|
+
* eligibility rule itself.
|
|
7354
|
+
*
|
|
7355
|
+
* Always queries with `laneLock: true`. That is not an approximation of
|
|
7356
|
+
* the "real" default — it IS the real answer for every reachable caller:
|
|
7357
|
+
*
|
|
7358
|
+
* - With a row lock active (`laneAllowedContainers` set), `isLaneContainer`
|
|
7359
|
+
* restricts eligibility to that set, so this returns exactly
|
|
7360
|
+
* `{srcContainerId}` — the ARCH-1071 lock, reproduced faithfully.
|
|
7361
|
+
* - Without a row lock, `laneAllowedContainers` is null and
|
|
7362
|
+
* `isLaneContainer` returns true unconditionally, so `laneLock`'s value
|
|
7363
|
+
* makes no difference — passing `true` costs nothing here.
|
|
7364
|
+
* - The engine's own 'nest' plane does call `isEligibleDropContainer` with
|
|
7365
|
+
* `laneLock: false` (see `peekNestIntent` → `resolvePointerContainer`),
|
|
7366
|
+
* but that plane is unreachable for a locked drag: `computeAllowNest`
|
|
7367
|
+
* (useDragVisualLoop.ts) short-circuits `rowLocked` drags before
|
|
7368
|
+
* `setTargetPlane('nest')` is ever called, so `targetPlane` stays
|
|
7369
|
+
* 'lane' for the drag's whole lifetime. If that guard is ever removed,
|
|
7370
|
+
* this method will under-report nest-only targets for locked drags —
|
|
7371
|
+
* keep the two in sync.
|
|
7372
|
+
*
|
|
7373
|
+
* Cached after the first call: every input (containerIndex, slotIndex,
|
|
7374
|
+
* activeId, laneAllowedContainers, blockedContainerIds) is fixed at
|
|
7375
|
+
* construction and never changes for the life of a drag.
|
|
7376
|
+
*/
|
|
7377
|
+
getValidDropContainerIds() {
|
|
7378
|
+
if (this.validDropContainerIds) return this.validDropContainerIds;
|
|
7379
|
+
const ids2 = /* @__PURE__ */ new Set();
|
|
7380
|
+
for (const id of this.containerIndex.keys()) {
|
|
7381
|
+
if (this.isEligibleDropContainer(id, true)) ids2.add(id);
|
|
7382
|
+
}
|
|
7383
|
+
return this.validDropContainerIds = ids2;
|
|
7384
|
+
}
|
|
7296
7385
|
setTargetPlane(plane) {
|
|
7297
7386
|
this.targetPlane = plane;
|
|
7298
7387
|
}
|
|
@@ -7311,6 +7400,17 @@ var DragIntentEngine = class {
|
|
|
7311
7400
|
isInvalidDropContainer(containerId) {
|
|
7312
7401
|
return containerId === this.activeId || this.isContainerDescendantOf(containerId, this.activeId);
|
|
7313
7402
|
}
|
|
7403
|
+
/**
|
|
7404
|
+
* The full "can this container accept the active node this drag" predicate.
|
|
7405
|
+
* SINGLE definition — every caller routes through it so no two parts of the
|
|
7406
|
+
* system can disagree about which containers are droppable.
|
|
7407
|
+
*/
|
|
7408
|
+
isEligibleDropContainer(containerId, laneLock) {
|
|
7409
|
+
if (this.isInvalidDropContainer(containerId)) return false;
|
|
7410
|
+
if (this.isBlockedContainer(containerId)) return false;
|
|
7411
|
+
if (laneLock && !this.isLaneContainer(containerId)) return false;
|
|
7412
|
+
return this.hasUsableSlots(containerId);
|
|
7413
|
+
}
|
|
7314
7414
|
/**
|
|
7315
7415
|
* Resolve the drag intent from the current pointer position.
|
|
7316
7416
|
*
|
|
@@ -7398,9 +7498,7 @@ var DragIntentEngine = class {
|
|
|
7398
7498
|
const childNode = this.getNodeRect(childId);
|
|
7399
7499
|
if (!childNode) continue;
|
|
7400
7500
|
if (!pointInRect(px, py, childNode)) continue;
|
|
7401
|
-
|
|
7402
|
-
const relY = (py - childNode.top) / childNode.height;
|
|
7403
|
-
if (relX > NEST_EDGE_FRACTION && relX < 1 - NEST_EDGE_FRACTION && relY > NEST_EDGE_FRACTION && relY < 1 - NEST_EDGE_FRACTION) {
|
|
7501
|
+
if (isInNestZone(px, py, childNode)) {
|
|
7404
7502
|
return {
|
|
7405
7503
|
containerId: pointerContainerId,
|
|
7406
7504
|
index: container.children.indexOf(childId),
|
|
@@ -7414,11 +7512,8 @@ var DragIntentEngine = class {
|
|
|
7414
7512
|
resolvePointerContainer(px, py, laneLock) {
|
|
7415
7513
|
const pointerContainers = [];
|
|
7416
7514
|
for (const [id, node] of this.containerIndex) {
|
|
7417
|
-
if (this.isInvalidDropContainer(id)) continue;
|
|
7418
|
-
if (this.isBlockedContainer(id)) continue;
|
|
7419
|
-
if (laneLock && !this.isLaneContainer(id)) continue;
|
|
7420
7515
|
if (!pointInRect(px, py, node.rect)) continue;
|
|
7421
|
-
if (this.
|
|
7516
|
+
if (!this.isEligibleDropContainer(id, laneLock)) continue;
|
|
7422
7517
|
const r = node.rect;
|
|
7423
7518
|
const edgeDistX = Math.min(px - r.left, r.right - px);
|
|
7424
7519
|
const edgeDistY = Math.min(py - r.top, r.bottom - py);
|
|
@@ -7435,11 +7530,11 @@ var DragIntentEngine = class {
|
|
|
7435
7530
|
let pointerContainerId = pointerContainers[0]?.id ?? null;
|
|
7436
7531
|
if (!pointerContainerId && this.lastIntent?.mode === "reorder") {
|
|
7437
7532
|
const lastContainer = this.containerIndex.get(this.lastIntent.containerId);
|
|
7438
|
-
if (lastContainer &&
|
|
7533
|
+
if (lastContainer && this.isEligibleDropContainer(lastContainer.id, laneLock) && pointInExpandedRect(px, py, lastContainer.rect, LAST_CONTAINER_REENTRY_SLOP_PX)) {
|
|
7439
7534
|
pointerContainerId = lastContainer.id;
|
|
7440
7535
|
}
|
|
7441
7536
|
}
|
|
7442
|
-
if (this.originContainerId && this.originContainerId !== pointerContainerId &&
|
|
7537
|
+
if (this.originContainerId && this.originContainerId !== pointerContainerId && this.isEligibleDropContainer(this.originContainerId, laneLock)) {
|
|
7443
7538
|
const originNode = this.containerIndex.get(this.originContainerId);
|
|
7444
7539
|
const currentNode = pointerContainerId ? this.containerIndex.get(pointerContainerId) : null;
|
|
7445
7540
|
const originIsDeeper = originNode && (!currentNode || originNode.depth >= currentNode.depth);
|
|
@@ -7852,7 +7947,8 @@ function useDragVisualLoop({
|
|
|
7852
7947
|
refs,
|
|
7853
7948
|
getCommitLaneSnapshot,
|
|
7854
7949
|
setInsideRect,
|
|
7855
|
-
setDropLine
|
|
7950
|
+
setDropLine,
|
|
7951
|
+
setActiveLaneContainerId
|
|
7856
7952
|
}) {
|
|
7857
7953
|
(0, import_react12.useEffect)(() => {
|
|
7858
7954
|
const engine = refs.engineRef.current;
|
|
@@ -7860,6 +7956,11 @@ function useDragVisualLoop({
|
|
|
7860
7956
|
if (!activeDrag || !engine || !snapshot) return;
|
|
7861
7957
|
let rafId;
|
|
7862
7958
|
const animator = refs.animatorRef.current;
|
|
7959
|
+
const publishActiveLane = (containerId) => {
|
|
7960
|
+
if (refs.activeLaneContainerIdRef.current === containerId) return;
|
|
7961
|
+
refs.activeLaneContainerIdRef.current = containerId;
|
|
7962
|
+
setActiveLaneContainerId(containerId);
|
|
7963
|
+
};
|
|
7863
7964
|
const setTargetPlane = (nextPlane) => {
|
|
7864
7965
|
const prevPlane = refs.targetPlaneRef.current;
|
|
7865
7966
|
if (prevPlane === nextPlane) return;
|
|
@@ -7878,6 +7979,7 @@ function useDragVisualLoop({
|
|
|
7878
7979
|
const safeZone = refs.safeZoneRef.current;
|
|
7879
7980
|
if (isPointerBlocked(px, py, safeZone)) {
|
|
7880
7981
|
setTargetPlane("lane");
|
|
7982
|
+
publishActiveLane(null);
|
|
7881
7983
|
refs.lastIntentRef.current = null;
|
|
7882
7984
|
refs.visualIntentRef.current = null;
|
|
7883
7985
|
refs.nestCandidateRef.current = null;
|
|
@@ -7919,6 +8021,7 @@ function useDragVisualLoop({
|
|
|
7919
8021
|
let intent = engine.resolve(px, py, window.scrollX, window.scrollY, snapshot.scroll.x, snapshot.scroll.y);
|
|
7920
8022
|
if (!intent) {
|
|
7921
8023
|
setTargetPlane("lane");
|
|
8024
|
+
publishActiveLane(null);
|
|
7922
8025
|
refs.lastIntentRef.current = null;
|
|
7923
8026
|
refs.visualIntentRef.current = null;
|
|
7924
8027
|
refs.nestCandidateRef.current = null;
|
|
@@ -7944,6 +8047,7 @@ function useDragVisualLoop({
|
|
|
7944
8047
|
const targetId = intent.slotId.split("::nest::")[1] ?? "";
|
|
7945
8048
|
if (!targetId) {
|
|
7946
8049
|
setTargetPlane("lane");
|
|
8050
|
+
publishActiveLane(null);
|
|
7947
8051
|
rafId = requestAnimationFrame(tick);
|
|
7948
8052
|
return;
|
|
7949
8053
|
}
|
|
@@ -7965,12 +8069,14 @@ function useDragVisualLoop({
|
|
|
7965
8069
|
};
|
|
7966
8070
|
refs.visualIntentRef.current = intent;
|
|
7967
8071
|
refs.lastIntentRef.current = intent;
|
|
8072
|
+
publishActiveLane(intent.containerId);
|
|
7968
8073
|
} else {
|
|
7969
8074
|
setTargetPlane("lane");
|
|
7970
8075
|
refs.nestCandidateRef.current = null;
|
|
7971
8076
|
refs.nestTargetRef.current = null;
|
|
7972
8077
|
refs.lastIntentRef.current = intent;
|
|
7973
8078
|
refs.visualIntentRef.current = intent;
|
|
8079
|
+
publishActiveLane(intent.containerId);
|
|
7974
8080
|
setInsideRect(null);
|
|
7975
8081
|
const proj = refs.projectionRef.current;
|
|
7976
8082
|
const slot = proj.slotIndex.get(intent.slotId);
|
|
@@ -8277,7 +8383,8 @@ function useDragLifecycle({
|
|
|
8277
8383
|
syncHistoryAvailability,
|
|
8278
8384
|
resolveNodeElement,
|
|
8279
8385
|
setInsideRect,
|
|
8280
|
-
setDropLine
|
|
8386
|
+
setDropLine,
|
|
8387
|
+
setActiveLaneContainerId
|
|
8281
8388
|
}) {
|
|
8282
8389
|
const [activeDrag, setActiveDrag] = (0, import_react13.useState)(null);
|
|
8283
8390
|
const clearDragState = (0, import_react13.useCallback)(() => {
|
|
@@ -8288,13 +8395,12 @@ function useDragLifecycle({
|
|
|
8288
8395
|
refs.snapshotRef.current = null;
|
|
8289
8396
|
refs.projectionRef.current = EMPTY_PROJECTION;
|
|
8290
8397
|
refs.engineRef.current = null;
|
|
8291
|
-
refs.blockedContainerIdsRef.current = /* @__PURE__ */ new Set();
|
|
8292
8398
|
refs.lastIntentRef.current = null;
|
|
8293
8399
|
refs.visualIntentRef.current = null;
|
|
8294
8400
|
refs.sourceContainerIdRef.current = null;
|
|
8401
|
+
refs.activeLaneContainerIdRef.current = null;
|
|
8295
8402
|
refs.rowLockedRef.current = false;
|
|
8296
8403
|
refs.dragSessionAnchorRef.current = null;
|
|
8297
|
-
refs.lockRef.current = { containerId: null, isCrossUnlocked: false, exitSince: null, unlockUntilTs: null };
|
|
8298
8404
|
refs.targetPlaneRef.current = "lane";
|
|
8299
8405
|
refs.nestCandidateRef.current = null;
|
|
8300
8406
|
refs.nestTargetRef.current = null;
|
|
@@ -8305,6 +8411,7 @@ function useDragLifecycle({
|
|
|
8305
8411
|
refs.safeZoneRef.current = null;
|
|
8306
8412
|
setInsideRect(null);
|
|
8307
8413
|
setDropLine(null);
|
|
8414
|
+
setActiveLaneContainerId(null);
|
|
8308
8415
|
setActiveDrag(null);
|
|
8309
8416
|
resume();
|
|
8310
8417
|
}, [clearCommitLaneCache, resume]);
|
|
@@ -8362,7 +8469,6 @@ function useDragLifecycle({
|
|
|
8362
8469
|
const sourceCommitLane = getCommitLaneSnapshot(srcContainerId);
|
|
8363
8470
|
const startPosition = getCurrentCommitPlacement(anchorNodeId, srcContainerId);
|
|
8364
8471
|
const blockedContainerIds = buildBlockedStructuralContainerIds(proj, refs.nodeMapRef.current, srcContainerId);
|
|
8365
|
-
refs.blockedContainerIdsRef.current = blockedContainerIds;
|
|
8366
8472
|
const engineOptions = buildDragIntentEngineOptions(anchorScanned.element, srcContainerId, blockedContainerIds);
|
|
8367
8473
|
refs.rowLockedRef.current = !!engineOptions.laneAllowedContainers;
|
|
8368
8474
|
refs.engineRef.current = createDragIntentEngine(proj, anchorNodeId, engineOptions);
|
|
@@ -8371,7 +8477,6 @@ function useDragLifecycle({
|
|
|
8371
8477
|
refs.sourceContainerIdRef.current = srcContainerId;
|
|
8372
8478
|
refs.sourceCommitLaneRef.current = sourceCommitLane;
|
|
8373
8479
|
refs.dragSessionAnchorRef.current = anchor;
|
|
8374
|
-
refs.lockRef.current = { containerId: srcContainerId, isCrossUnlocked: true, exitSince: null, unlockUntilTs: null };
|
|
8375
8480
|
refs.dragStartPositionRef.current = startPosition;
|
|
8376
8481
|
refs.safeZoneRef.current = resolveSafeZoneRect();
|
|
8377
8482
|
pause();
|
|
@@ -8853,7 +8958,7 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
|
|
|
8853
8958
|
const candidate = postInsertChildren[i];
|
|
8854
8959
|
const candidateNodeId = candidate.getAttribute(DND_NODE_ID_ATTR);
|
|
8855
8960
|
if (!candidateNodeId) continue;
|
|
8856
|
-
const isEarlierInsert = candidateNodeId.startsWith("insert:");
|
|
8961
|
+
const isEarlierInsert = candidateNodeId.startsWith("insert:") || candidateNodeId.startsWith("insert-child:");
|
|
8857
8962
|
if (!isEarlierInsert && !getInspectorRefFromElement(candidate)) continue;
|
|
8858
8963
|
beforeSiblingEl = candidate;
|
|
8859
8964
|
beforeSiblingNodeId = candidateNodeId;
|
|
@@ -8930,6 +9035,7 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
|
|
|
8930
9035
|
// src/client/dnd/design-mode/DesignModeOverlay.tsx
|
|
8931
9036
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
8932
9037
|
var DROP_ANIMATION = { duration: DURATION_MS, easing: EASING };
|
|
9038
|
+
var EMPTY_CONTAINER_ID_SET = /* @__PURE__ */ new Set();
|
|
8933
9039
|
function resizeCursorFromHandle(handle) {
|
|
8934
9040
|
switch (handle) {
|
|
8935
9041
|
case "n":
|
|
@@ -9217,13 +9323,9 @@ function DesignModeOverlay() {
|
|
|
9217
9323
|
const sensors = useSensors(
|
|
9218
9324
|
useSensor(PointerSensor, { activationConstraint: { distance: 8 } })
|
|
9219
9325
|
);
|
|
9220
|
-
const collisionDetection = (0, import_react16.useCallback)(
|
|
9221
|
-
(args) => createDesignModeCollisionDetection(refs.blockedContainerIdsRef.current)(args),
|
|
9222
|
-
[]
|
|
9223
|
-
// eslint-disable-line react-hooks/exhaustive-deps -- refs are stable
|
|
9224
|
-
);
|
|
9225
9326
|
const [insideRect, setInsideRect] = (0, import_react16.useState)(null);
|
|
9226
9327
|
const [dropLine, setDropLine] = (0, import_react16.useState)(null);
|
|
9328
|
+
const [activeLaneContainerId, setActiveLaneContainerId] = (0, import_react16.useState)(null);
|
|
9227
9329
|
(0, import_react16.useEffect)(() => {
|
|
9228
9330
|
if (!enabled) return;
|
|
9229
9331
|
const fn = (e) => {
|
|
@@ -9259,8 +9361,55 @@ function DesignModeOverlay() {
|
|
|
9259
9361
|
syncHistoryAvailability,
|
|
9260
9362
|
resolveNodeElement,
|
|
9261
9363
|
setInsideRect,
|
|
9262
|
-
setDropLine
|
|
9364
|
+
setDropLine,
|
|
9365
|
+
setActiveLaneContainerId
|
|
9263
9366
|
});
|
|
9367
|
+
const dropCandidateContainerIds = (0, import_react16.useMemo)(
|
|
9368
|
+
() => activeDrag ? refs.engineRef.current?.getValidDropContainerIds() ?? null : null,
|
|
9369
|
+
[activeDrag]
|
|
9370
|
+
// eslint-disable-line react-hooks/exhaustive-deps -- refs are stable
|
|
9371
|
+
);
|
|
9372
|
+
const laneKinshipContainerIds = (0, import_react16.useMemo)(() => {
|
|
9373
|
+
if (!activeDrag || !dropCandidateContainerIds) return null;
|
|
9374
|
+
const engine = refs.engineRef.current;
|
|
9375
|
+
if (!engine) return null;
|
|
9376
|
+
return computeLaneKinshipContainerIds({
|
|
9377
|
+
candidateContainerIds: dropCandidateContainerIds,
|
|
9378
|
+
activeContainerId: activeLaneContainerId,
|
|
9379
|
+
draggingNodeId: activeDrag.nodeId,
|
|
9380
|
+
getParentContainerId: (id) => engine.getNodeParentContainerId(id),
|
|
9381
|
+
getContainerChildren: (id) => engine.getContainerChildren(id)
|
|
9382
|
+
});
|
|
9383
|
+
}, [activeDrag, activeLaneContainerId, dropCandidateContainerIds]);
|
|
9384
|
+
const visibleCandidateContainerIds = (0, import_react16.useMemo)(() => {
|
|
9385
|
+
if (!laneKinshipContainerIds) return null;
|
|
9386
|
+
const rects = refs.snapshotRef.current?.rects;
|
|
9387
|
+
if (!rects) return laneKinshipContainerIds;
|
|
9388
|
+
const vw = window.innerWidth;
|
|
9389
|
+
const vh = window.innerHeight;
|
|
9390
|
+
const visible = /* @__PURE__ */ new Set();
|
|
9391
|
+
for (const id of laneKinshipContainerIds) {
|
|
9392
|
+
const r = rects.get(id);
|
|
9393
|
+
if (!r) continue;
|
|
9394
|
+
if (r.right < 0 || r.bottom < 0 || r.left > vw || r.top > vh) continue;
|
|
9395
|
+
visible.add(id);
|
|
9396
|
+
}
|
|
9397
|
+
return visible;
|
|
9398
|
+
}, [laneKinshipContainerIds]);
|
|
9399
|
+
const dragGuide = (0, import_react16.useMemo)(() => {
|
|
9400
|
+
if (!activeDrag) return null;
|
|
9401
|
+
const snapshot = refs.snapshotRef.current;
|
|
9402
|
+
if (!snapshot) return null;
|
|
9403
|
+
const activeChildIds = activeLaneContainerId ? refs.engineRef.current?.getContainerChildren(activeLaneContainerId) ?? [] : [];
|
|
9404
|
+
return {
|
|
9405
|
+
rects: snapshot.rects,
|
|
9406
|
+
startScroll: snapshot.scroll,
|
|
9407
|
+
candidateContainerIds: visibleCandidateContainerIds ?? EMPTY_CONTAINER_ID_SET,
|
|
9408
|
+
activeContainerId: activeLaneContainerId,
|
|
9409
|
+
activeChildIds,
|
|
9410
|
+
draggingNodeId: activeDrag.nodeId
|
|
9411
|
+
};
|
|
9412
|
+
}, [activeDrag, activeLaneContainerId, visibleCandidateContainerIds]);
|
|
9264
9413
|
(0, import_react16.useEffect)(() => {
|
|
9265
9414
|
if (!enabled || activeDrag) return;
|
|
9266
9415
|
if (undoRequestId === refs.processedUndoIdRef.current) return;
|
|
@@ -9323,7 +9472,7 @@ function DesignModeOverlay() {
|
|
|
9323
9472
|
safeZoneRef: refs.safeZoneRef,
|
|
9324
9473
|
autoScrollStateRef: refs.autoScrollStateRef
|
|
9325
9474
|
});
|
|
9326
|
-
useDragVisualLoop({ activeDrag, refs, getCommitLaneSnapshot, setInsideRect, setDropLine });
|
|
9475
|
+
useDragVisualLoop({ activeDrag, refs, getCommitLaneSnapshot, setInsideRect, setDropLine, setActiveLaneContainerId });
|
|
9327
9476
|
useExternalDragLoop({
|
|
9328
9477
|
externalDrag,
|
|
9329
9478
|
refs,
|
|
@@ -9343,7 +9492,6 @@ function DesignModeOverlay() {
|
|
|
9343
9492
|
DndContext,
|
|
9344
9493
|
{
|
|
9345
9494
|
sensors,
|
|
9346
|
-
collisionDetection,
|
|
9347
9495
|
autoScroll: false,
|
|
9348
9496
|
onDragStart: handleDragStart,
|
|
9349
9497
|
onDragEnd: handleDragEnd,
|
|
@@ -9352,10 +9500,8 @@ function DesignModeOverlay() {
|
|
|
9352
9500
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
9353
9501
|
ElementHighlight,
|
|
9354
9502
|
{
|
|
9355
|
-
|
|
9356
|
-
|
|
9357
|
-
activeEl: refs.activeElRef.current,
|
|
9358
|
-
arrangeSelectedNodeId,
|
|
9503
|
+
selected: arrangeSelectedNodeId ? nodeMap.get(arrangeSelectedNodeId) ?? null : null,
|
|
9504
|
+
dragGuide,
|
|
9359
9505
|
externalDragActive: externalDrag !== null,
|
|
9360
9506
|
onResizeHandlePointerDown: handleResizeHandlePointerDown
|
|
9361
9507
|
}
|