@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.
- package/dist/client/client.js +309 -199
- package/dist/client/client.mjs +309 -199
- 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,
|
|
@@ -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 (
|
|
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
|
|
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
|
|
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:
|
|
5660
|
-
backgroundColor:
|
|
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
|
-
|
|
5687
|
-
|
|
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
|
-
|
|
5702
|
-
|
|
5703
|
-
const
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
const
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
|
|
5712
|
-
|
|
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
|
-
|
|
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 (!
|
|
5732
|
-
if (
|
|
5733
|
-
|
|
5734
|
-
|
|
5735
|
-
{
|
|
5736
|
-
|
|
5737
|
-
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
if (
|
|
5741
|
-
|
|
5742
|
-
|
|
5743
|
-
|
|
5744
|
-
|
|
5745
|
-
|
|
5746
|
-
|
|
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
|
-
|
|
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-
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
),
|
|
5790
|
-
children:
|
|
5791
|
-
|
|
5792
|
-
|
|
5793
|
-
|
|
5794
|
-
|
|
5795
|
-
|
|
5796
|
-
|
|
5797
|
-
|
|
5798
|
-
|
|
5799
|
-
|
|
5800
|
-
|
|
5801
|
-
|
|
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
|
-
|
|
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.
|
|
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 &&
|
|
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 &&
|
|
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
|
|
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
|
-
|
|
9348
|
-
|
|
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
|
}
|