@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.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,
|
|
@@ -5224,8 +5186,10 @@ function ensureUniqueNodeId(base, used) {
|
|
|
5224
5186
|
while (used.has(`${base}::${idx}`)) idx += 1;
|
|
5225
5187
|
return `${base}::${idx}`;
|
|
5226
5188
|
}
|
|
5189
|
+
var INSERT_NODE_ID_PREFIX = "insert:";
|
|
5227
5190
|
function resolveStableNodeId(el, used) {
|
|
5228
5191
|
const persisted = el.getAttribute(DND_NODE_ID_ATTR);
|
|
5192
|
+
if (persisted && persisted.startsWith(INSERT_NODE_ID_PREFIX)) return persisted;
|
|
5229
5193
|
if (persisted && !used.has(persisted)) return persisted;
|
|
5230
5194
|
const projected = projectUsageMeta(el);
|
|
5231
5195
|
if (projected) return ensureUniqueNodeId(projected.nodeId, used);
|
|
@@ -5296,7 +5260,7 @@ function isFlexOrGridParent(el) {
|
|
|
5296
5260
|
const d = getComputedStyle(el).display;
|
|
5297
5261
|
return d === "flex" || d === "grid" || d === "inline-flex" || d === "inline-grid";
|
|
5298
5262
|
}
|
|
5299
|
-
function scanElements(root, depth = 0, usedNodeIds = /* @__PURE__ */ new Set(), seenResolvedHosts = /* @__PURE__ */ new WeakSet()) {
|
|
5263
|
+
function scanElements(root, depth = 0, usedNodeIds = /* @__PURE__ */ new Set(), seenResolvedHosts = /* @__PURE__ */ new WeakSet(), resolvedUnreported = /* @__PURE__ */ new Set()) {
|
|
5300
5264
|
if (depth > MAX_DEPTH) return [];
|
|
5301
5265
|
const results = [];
|
|
5302
5266
|
for (const child of Array.from(root.children)) {
|
|
@@ -5321,7 +5285,9 @@ function scanElements(root, depth = 0, usedNodeIds = /* @__PURE__ */ new Set(),
|
|
|
5321
5285
|
const nodeId2 = resolveStableNodeId(el, usedNodeIds);
|
|
5322
5286
|
usedNodeIds.add(nodeId2);
|
|
5323
5287
|
el.setAttribute(DND_NODE_ID_ATTR, nodeId2);
|
|
5324
|
-
if (
|
|
5288
|
+
if (isZeroRect) {
|
|
5289
|
+
resolvedUnreported.add(el);
|
|
5290
|
+
} else {
|
|
5325
5291
|
seenResolvedHosts.add(el);
|
|
5326
5292
|
const surfaceMeta2 = el instanceof HTMLElement ? getDirectEditorMeta(el) ?? void 0 : void 0;
|
|
5327
5293
|
const identityMeta3 = projectUsageMeta(el) ?? surfaceMeta2;
|
|
@@ -5345,7 +5311,7 @@ function scanElements(root, depth = 0, usedNodeIds = /* @__PURE__ */ new Set(),
|
|
|
5345
5311
|
});
|
|
5346
5312
|
}
|
|
5347
5313
|
}
|
|
5348
|
-
if (!isSvgRoot) results.push(...scanElements(el, depth + 1, usedNodeIds, seenResolvedHosts));
|
|
5314
|
+
if (!isSvgRoot) results.push(...scanElements(el, depth + 1, usedNodeIds, seenResolvedHosts, resolvedUnreported));
|
|
5349
5315
|
continue;
|
|
5350
5316
|
}
|
|
5351
5317
|
if (isSvgRoot && isInspectorEligible(el) === null) {
|
|
@@ -5354,7 +5320,7 @@ function scanElements(root, depth = 0, usedNodeIds = /* @__PURE__ */ new Set(),
|
|
|
5354
5320
|
const eligibilitySource = isInspectorEligible(el);
|
|
5355
5321
|
const inferredEligibility = eligibilitySource ?? inferEligibilityFromSortableParent(el) ?? (projectUsageMeta(el) ? "projected-usage" : null);
|
|
5356
5322
|
if (inferredEligibility === null) {
|
|
5357
|
-
const childResults = scanElements(el, depth + 1, usedNodeIds, seenResolvedHosts);
|
|
5323
|
+
const childResults = scanElements(el, depth + 1, usedNodeIds, seenResolvedHosts, resolvedUnreported);
|
|
5358
5324
|
results.push(...childResults);
|
|
5359
5325
|
if (isFlexOrGridParent(el) && !seenResolvedHosts.has(el) && childResults.some((r) => r.draggable && r.element.parentElement === el)) {
|
|
5360
5326
|
const nodeId2 = resolveStableNodeId(el, usedNodeIds);
|
|
@@ -5382,13 +5348,13 @@ function scanElements(root, depth = 0, usedNodeIds = /* @__PURE__ */ new Set(),
|
|
|
5382
5348
|
const dragSurface = resolveDragSurface(el);
|
|
5383
5349
|
const hostEl = dragSurface.host;
|
|
5384
5350
|
if (!hostEl) {
|
|
5385
|
-
if (!isSvgRoot) results.push(...scanElements(el, depth + 1, usedNodeIds, seenResolvedHosts));
|
|
5351
|
+
if (!isSvgRoot) results.push(...scanElements(el, depth + 1, usedNodeIds, seenResolvedHosts, resolvedUnreported));
|
|
5386
5352
|
continue;
|
|
5387
5353
|
}
|
|
5388
5354
|
const hostRect = hostEl.getBoundingClientRect();
|
|
5389
5355
|
const nodeId = resolveStableNodeId(hostEl, usedNodeIds);
|
|
5390
5356
|
if (seenResolvedHosts.has(hostEl)) {
|
|
5391
|
-
if (!isSvgRoot) results.push(...scanElements(el, depth + 1, usedNodeIds, seenResolvedHosts));
|
|
5357
|
+
if (!isSvgRoot) results.push(...scanElements(el, depth + 1, usedNodeIds, seenResolvedHosts, resolvedUnreported));
|
|
5392
5358
|
continue;
|
|
5393
5359
|
}
|
|
5394
5360
|
seenResolvedHosts.add(hostEl);
|
|
@@ -5418,9 +5384,9 @@ function scanElements(root, depth = 0, usedNodeIds = /* @__PURE__ */ new Set(),
|
|
|
5418
5384
|
identityOrigin: templateFrameLabel(identityMeta2),
|
|
5419
5385
|
editorMeta: surfaceMeta
|
|
5420
5386
|
});
|
|
5421
|
-
if (!isSvgRoot) results.push(...scanElements(el, depth + 1, usedNodeIds, seenResolvedHosts));
|
|
5387
|
+
if (!isSvgRoot) results.push(...scanElements(el, depth + 1, usedNodeIds, seenResolvedHosts, resolvedUnreported));
|
|
5422
5388
|
} else {
|
|
5423
|
-
if (!isSvgRoot) results.push(...scanElements(el, depth + 1, usedNodeIds, seenResolvedHosts));
|
|
5389
|
+
if (!isSvgRoot) results.push(...scanElements(el, depth + 1, usedNodeIds, seenResolvedHosts, resolvedUnreported));
|
|
5424
5390
|
}
|
|
5425
5391
|
}
|
|
5426
5392
|
return results;
|
|
@@ -5476,8 +5442,10 @@ function useElementScanner(enabled) {
|
|
|
5476
5442
|
if (pausedRef.current) return;
|
|
5477
5443
|
const root = document.getElementById("root") ?? document.body;
|
|
5478
5444
|
const usedNodeIds = /* @__PURE__ */ new Set();
|
|
5479
|
-
const
|
|
5445
|
+
const resolvedUnreported = /* @__PURE__ */ new Set();
|
|
5446
|
+
const scanned = scanElements(root, 0, usedNodeIds, void 0, resolvedUnreported);
|
|
5480
5447
|
const seenEls = new Set(scanned.map((s) => s.element));
|
|
5448
|
+
for (const el of resolvedUnreported) seenEls.add(el);
|
|
5481
5449
|
for (const el of Array.from(document.querySelectorAll("[data-dnd-moved]"))) {
|
|
5482
5450
|
if (seenEls.has(el)) continue;
|
|
5483
5451
|
const entry = buildMovedElementEntry(el, usedNodeIds);
|
|
@@ -5541,6 +5509,7 @@ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
|
5541
5509
|
var HANDLES = ["nw", "n", "ne", "e", "se", "s", "sw", "w"];
|
|
5542
5510
|
var HANDLE_HIT_SIZE = 24;
|
|
5543
5511
|
var HANDLE_KNOB_SIZE = 8;
|
|
5512
|
+
var EMPTY_SCROLL_DELTA = { x: NaN, y: NaN };
|
|
5544
5513
|
var OVERLAY_ROOT_STYLE = {
|
|
5545
5514
|
position: "fixed",
|
|
5546
5515
|
inset: 0,
|
|
@@ -5614,17 +5583,39 @@ function handlePosition(dir) {
|
|
|
5614
5583
|
};
|
|
5615
5584
|
return positions[dir];
|
|
5616
5585
|
}
|
|
5617
|
-
function
|
|
5586
|
+
function getSelectedOutlineStyle(rect, inspectorTheme) {
|
|
5618
5587
|
return {
|
|
5619
5588
|
...OUTLINE_BASE_STYLE,
|
|
5620
5589
|
left: rect.left,
|
|
5621
5590
|
top: rect.top,
|
|
5622
5591
|
width: rect.width,
|
|
5623
5592
|
height: rect.height,
|
|
5624
|
-
border:
|
|
5625
|
-
backgroundColor:
|
|
5593
|
+
border: `2px solid ${inspectorTheme.accent}`,
|
|
5594
|
+
backgroundColor: inspectorTheme.accentSoft
|
|
5626
5595
|
};
|
|
5627
5596
|
}
|
|
5597
|
+
function getGuideOutlineStyle(rect, tier, inspectorTheme) {
|
|
5598
|
+
const base = {
|
|
5599
|
+
...OUTLINE_BASE_STYLE,
|
|
5600
|
+
left: rect.left,
|
|
5601
|
+
top: rect.top,
|
|
5602
|
+
width: rect.width,
|
|
5603
|
+
height: rect.height
|
|
5604
|
+
};
|
|
5605
|
+
switch (tier) {
|
|
5606
|
+
case "candidate":
|
|
5607
|
+
return { ...base, border: `1px solid ${inspectorTheme.accent}`, opacity: 0.2 };
|
|
5608
|
+
case "lane-child":
|
|
5609
|
+
return { ...base, border: `1px dashed ${inspectorTheme.accent}`, opacity: 0.45 };
|
|
5610
|
+
case "lane":
|
|
5611
|
+
return {
|
|
5612
|
+
...base,
|
|
5613
|
+
border: `1.5px solid ${inspectorTheme.accent}`,
|
|
5614
|
+
backgroundColor: inspectorTheme.accentSoft,
|
|
5615
|
+
opacity: 0.75
|
|
5616
|
+
};
|
|
5617
|
+
}
|
|
5618
|
+
}
|
|
5628
5619
|
function getResizeHandleStyle(position) {
|
|
5629
5620
|
return {
|
|
5630
5621
|
...RESIZE_HANDLE_BASE_STYLE,
|
|
@@ -5647,40 +5638,58 @@ function getLabelStyle(labelLeft, labelTop, labelColor) {
|
|
|
5647
5638
|
backgroundColor: labelColor
|
|
5648
5639
|
};
|
|
5649
5640
|
}
|
|
5641
|
+
function projectDragRect(dragGuide, nodeId, sdx, sdy) {
|
|
5642
|
+
const r = dragGuide.rects.get(nodeId);
|
|
5643
|
+
if (!r) return null;
|
|
5644
|
+
return { left: r.left - sdx, top: r.top - sdy, width: r.width, height: r.height };
|
|
5645
|
+
}
|
|
5650
5646
|
function ElementHighlight({
|
|
5651
|
-
|
|
5652
|
-
|
|
5653
|
-
activeEl,
|
|
5654
|
-
arrangeSelectedNodeId,
|
|
5647
|
+
selected,
|
|
5648
|
+
dragGuide,
|
|
5655
5649
|
externalDragActive,
|
|
5656
5650
|
onResizeHandlePointerDown
|
|
5657
5651
|
}) {
|
|
5658
5652
|
const inspectorTheme = useDesignModeStore((s) => s.inspectorTheme);
|
|
5659
|
-
const internalDragInProgress = draggingNodeId !== null;
|
|
5660
|
-
const overlayVisible = arrangeSelectedNodeId !== null || internalDragInProgress;
|
|
5661
5653
|
const containerRef = useRef5(null);
|
|
5662
5654
|
const rafRef = useRef5(0);
|
|
5655
|
+
const lastScrollDeltaRef = useRef5(EMPTY_SCROLL_DELTA);
|
|
5663
5656
|
const syncPositions = useCallback5(() => {
|
|
5664
5657
|
const container = containerRef.current;
|
|
5665
5658
|
if (!container) return;
|
|
5666
|
-
|
|
5667
|
-
|
|
5668
|
-
const
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
const
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
label.style.left = `${rect.left}px`;
|
|
5679
|
-
label.style.top = `${rect.top}px`;
|
|
5659
|
+
if (dragGuide) {
|
|
5660
|
+
const sdx = window.scrollX - dragGuide.startScroll.x;
|
|
5661
|
+
const sdy = window.scrollY - dragGuide.startScroll.y;
|
|
5662
|
+
if (sdx === lastScrollDeltaRef.current.x && sdy === lastScrollDeltaRef.current.y) return;
|
|
5663
|
+
lastScrollDeltaRef.current = { x: sdx, y: sdy };
|
|
5664
|
+
const outlines = container.querySelectorAll("[data-guide-for]");
|
|
5665
|
+
for (const outline2 of outlines) {
|
|
5666
|
+
const nodeId = outline2.getAttribute("data-guide-for");
|
|
5667
|
+
const r = dragGuide.rects.get(nodeId);
|
|
5668
|
+
if (!r) continue;
|
|
5669
|
+
outline2.style.left = `${r.left - sdx}px`;
|
|
5670
|
+
outline2.style.top = `${r.top - sdy}px`;
|
|
5680
5671
|
}
|
|
5672
|
+
return;
|
|
5681
5673
|
}
|
|
5682
|
-
|
|
5674
|
+
if (!selected) return;
|
|
5675
|
+
const rect2 = selected.element.getBoundingClientRect();
|
|
5676
|
+
const outline = container.querySelector("[data-outline-for]");
|
|
5677
|
+
if (outline) {
|
|
5678
|
+
outline.style.left = `${rect2.left}px`;
|
|
5679
|
+
outline.style.top = `${rect2.top}px`;
|
|
5680
|
+
outline.style.width = `${rect2.width}px`;
|
|
5681
|
+
outline.style.height = `${rect2.height}px`;
|
|
5682
|
+
}
|
|
5683
|
+
const label = container.querySelector("[data-drag-handle]");
|
|
5684
|
+
if (label) {
|
|
5685
|
+
label.style.left = `${rect2.left + 12}px`;
|
|
5686
|
+
label.style.top = `${Math.max(0, rect2.top - 20)}px`;
|
|
5687
|
+
}
|
|
5688
|
+
}, [dragGuide, selected]);
|
|
5689
|
+
const loopActive = !externalDragActive && (dragGuide !== null || selected !== null);
|
|
5683
5690
|
useEffect5(() => {
|
|
5691
|
+
if (!loopActive) return;
|
|
5692
|
+
lastScrollDeltaRef.current = EMPTY_SCROLL_DELTA;
|
|
5684
5693
|
let running = true;
|
|
5685
5694
|
const loop = () => {
|
|
5686
5695
|
if (!running) return;
|
|
@@ -5692,81 +5701,113 @@ function ElementHighlight({
|
|
|
5692
5701
|
running = false;
|
|
5693
5702
|
cancelAnimationFrame(rafRef.current);
|
|
5694
5703
|
};
|
|
5695
|
-
}, [syncPositions]);
|
|
5696
|
-
if (!
|
|
5697
|
-
if (
|
|
5698
|
-
|
|
5699
|
-
|
|
5700
|
-
{
|
|
5701
|
-
|
|
5702
|
-
|
|
5703
|
-
|
|
5704
|
-
|
|
5705
|
-
if (
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
|
|
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
|
-
|
|
5704
|
+
}, [loopActive, syncPositions]);
|
|
5705
|
+
if (!loopActive) return null;
|
|
5706
|
+
if (dragGuide) {
|
|
5707
|
+
const sdx = window.scrollX - dragGuide.startScroll.x;
|
|
5708
|
+
const sdy = window.scrollY - dragGuide.startScroll.y;
|
|
5709
|
+
const { candidateContainerIds, activeContainerId, activeChildIds, draggingNodeId } = dragGuide;
|
|
5710
|
+
return /* @__PURE__ */ jsxs("div", { ref: containerRef, "data-design-mode-ui": true, style: OVERLAY_ROOT_STYLE, children: [
|
|
5711
|
+
[...candidateContainerIds].map((id) => {
|
|
5712
|
+
if (id === activeContainerId || id === draggingNodeId) return null;
|
|
5713
|
+
const rect2 = projectDragRect(dragGuide, id, sdx, sdy);
|
|
5714
|
+
if (!rect2) return null;
|
|
5715
|
+
return /* @__PURE__ */ jsx2(
|
|
5716
|
+
"div",
|
|
5717
|
+
{
|
|
5718
|
+
"data-guide-for": id,
|
|
5719
|
+
"data-guide-tier": "candidate",
|
|
5720
|
+
"data-design-mode-ui": true,
|
|
5721
|
+
style: getGuideOutlineStyle(rect2, "candidate", inspectorTheme)
|
|
5722
|
+
},
|
|
5723
|
+
`candidate:${id}`
|
|
5724
|
+
);
|
|
5725
|
+
}),
|
|
5726
|
+
activeContainerId !== null && activeChildIds.map((id) => {
|
|
5727
|
+
if (id === draggingNodeId) return null;
|
|
5728
|
+
const rect2 = projectDragRect(dragGuide, id, sdx, sdy);
|
|
5729
|
+
if (!rect2) return null;
|
|
5730
|
+
return /* @__PURE__ */ jsx2(
|
|
5731
|
+
"div",
|
|
5732
|
+
{
|
|
5733
|
+
"data-guide-for": id,
|
|
5734
|
+
"data-guide-tier": "lane-child",
|
|
5735
|
+
"data-design-mode-ui": true,
|
|
5736
|
+
style: getGuideOutlineStyle(rect2, "lane-child", inspectorTheme)
|
|
5737
|
+
},
|
|
5738
|
+
`lane-child:${id}`
|
|
5739
|
+
);
|
|
5740
|
+
}),
|
|
5741
|
+
activeContainerId !== null && activeContainerId !== draggingNodeId && (() => {
|
|
5742
|
+
const rect2 = projectDragRect(dragGuide, activeContainerId, sdx, sdy);
|
|
5743
|
+
if (!rect2) return null;
|
|
5744
|
+
return /* @__PURE__ */ jsx2(
|
|
5745
|
+
"div",
|
|
5746
|
+
{
|
|
5747
|
+
"data-guide-for": activeContainerId,
|
|
5748
|
+
"data-guide-tier": "lane",
|
|
5749
|
+
"data-design-mode-ui": true,
|
|
5750
|
+
style: getGuideOutlineStyle(rect2, "lane", inspectorTheme)
|
|
5751
|
+
},
|
|
5752
|
+
`lane:${activeContainerId}`
|
|
5753
|
+
);
|
|
5754
|
+
})()
|
|
5755
|
+
] });
|
|
5756
|
+
}
|
|
5757
|
+
if (!selected) return null;
|
|
5758
|
+
const rect = selected.element.getBoundingClientRect();
|
|
5759
|
+
const labelTop = Math.max(0, rect.top - 20);
|
|
5760
|
+
const labelLeft = rect.left + 12;
|
|
5761
|
+
return /* @__PURE__ */ jsxs("div", { ref: containerRef, "data-design-mode-ui": true, style: OVERLAY_ROOT_STYLE, children: [
|
|
5762
|
+
/* @__PURE__ */ jsx2(
|
|
5763
|
+
"div",
|
|
5764
|
+
{
|
|
5765
|
+
"data-outline-for": selected.nodeId,
|
|
5766
|
+
"data-design-mode-ui": true,
|
|
5767
|
+
style: getSelectedOutlineStyle(rect, inspectorTheme),
|
|
5768
|
+
children: selected.draggable && HANDLES.map((dir) => {
|
|
5769
|
+
const pos = handlePosition(dir);
|
|
5770
|
+
return /* @__PURE__ */ jsx2(
|
|
5746
5771
|
"div",
|
|
5747
5772
|
{
|
|
5748
5773
|
"data-design-mode-ui": true,
|
|
5749
|
-
"data-
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
|
|
5753
|
-
|
|
5754
|
-
),
|
|
5755
|
-
children:
|
|
5756
|
-
|
|
5757
|
-
|
|
5758
|
-
|
|
5759
|
-
|
|
5760
|
-
|
|
5761
|
-
|
|
5762
|
-
|
|
5763
|
-
|
|
5764
|
-
|
|
5765
|
-
|
|
5766
|
-
|
|
5767
|
-
|
|
5768
|
-
|
|
5769
|
-
|
|
5774
|
+
"data-resize-handle": dir,
|
|
5775
|
+
onPointerDown: (e) => {
|
|
5776
|
+
e.stopPropagation();
|
|
5777
|
+
onResizeHandlePointerDown?.(e, selected.nodeId, dir);
|
|
5778
|
+
},
|
|
5779
|
+
style: getResizeHandleStyle(pos),
|
|
5780
|
+
children: /* @__PURE__ */ jsx2(
|
|
5781
|
+
"span",
|
|
5782
|
+
{
|
|
5783
|
+
"data-design-mode-ui": true,
|
|
5784
|
+
style: getResizeKnobStyle(inspectorTheme.accent)
|
|
5785
|
+
}
|
|
5786
|
+
)
|
|
5787
|
+
},
|
|
5788
|
+
dir
|
|
5789
|
+
);
|
|
5790
|
+
})
|
|
5791
|
+
}
|
|
5792
|
+
),
|
|
5793
|
+
/* @__PURE__ */ jsxs(
|
|
5794
|
+
"div",
|
|
5795
|
+
{
|
|
5796
|
+
"data-design-mode-ui": true,
|
|
5797
|
+
"data-drag-handle": selected.nodeId,
|
|
5798
|
+
style: getLabelStyle(labelLeft, labelTop, inspectorTheme.accent),
|
|
5799
|
+
children: [
|
|
5800
|
+
/* @__PURE__ */ jsx2("span", { style: LABEL_ICON_STYLE, children: "\u283F" }),
|
|
5801
|
+
selected.label,
|
|
5802
|
+
/* @__PURE__ */ jsxs("span", { style: LABEL_DIMENSIONS_STYLE, children: [
|
|
5803
|
+
Math.round(rect.width),
|
|
5804
|
+
"\xD7",
|
|
5805
|
+
Math.round(rect.height)
|
|
5806
|
+
] })
|
|
5807
|
+
]
|
|
5808
|
+
}
|
|
5809
|
+
)
|
|
5810
|
+
] });
|
|
5770
5811
|
}
|
|
5771
5812
|
|
|
5772
5813
|
// src/client/dnd/design-mode/projection.ts
|
|
@@ -6560,30 +6601,6 @@ function applyDndCommandPlacement(command, direction, resolveNodeElement) {
|
|
|
6560
6601
|
return true;
|
|
6561
6602
|
}
|
|
6562
6603
|
|
|
6563
|
-
// src/client/dnd/design-mode/design-mode-collision.ts
|
|
6564
|
-
function filterDroppables(droppableContainers, blockedContainerIds) {
|
|
6565
|
-
if (!blockedContainerIds || blockedContainerIds.size === 0) return droppableContainers;
|
|
6566
|
-
return droppableContainers.filter((container) => !blockedContainerIds.has(String(container.id)));
|
|
6567
|
-
}
|
|
6568
|
-
function getCollisions(detector, args) {
|
|
6569
|
-
return detector(args);
|
|
6570
|
-
}
|
|
6571
|
-
function createDesignModeCollisionDetection(blockedContainerIds) {
|
|
6572
|
-
return (args) => {
|
|
6573
|
-
const droppableContainers = filterDroppables(args.droppableContainers, blockedContainerIds);
|
|
6574
|
-
if (droppableContainers.length === 0) return [];
|
|
6575
|
-
const scopedArgs = {
|
|
6576
|
-
...args,
|
|
6577
|
-
droppableContainers
|
|
6578
|
-
};
|
|
6579
|
-
const pointerHits = getCollisions(pointerWithin, scopedArgs);
|
|
6580
|
-
if (pointerHits.length > 0) return pointerHits;
|
|
6581
|
-
const cornerHits = getCollisions(closestCorners, scopedArgs);
|
|
6582
|
-
if (cornerHits.length > 0) return cornerHits;
|
|
6583
|
-
return getCollisions(closestCenter, scopedArgs);
|
|
6584
|
-
};
|
|
6585
|
-
}
|
|
6586
|
-
|
|
6587
6604
|
// src/client/dnd/design-mode/arrange-session.ts
|
|
6588
6605
|
function serializeArrangeChange(event, index) {
|
|
6589
6606
|
return {
|
|
@@ -6862,9 +6879,9 @@ function useOverlayRefs(undoRequestId, redoRequestId) {
|
|
|
6862
6879
|
const lastIntentRef = useRef8(null);
|
|
6863
6880
|
const visualIntentRef = useRef8(null);
|
|
6864
6881
|
const sourceContainerIdRef = useRef8(null);
|
|
6882
|
+
const activeLaneContainerIdRef = useRef8(null);
|
|
6865
6883
|
const rowLockedRef = useRef8(false);
|
|
6866
6884
|
const dragSessionAnchorRef = useRef8(null);
|
|
6867
|
-
const lockRef = useRef8({ containerId: null, isCrossUnlocked: false, exitSince: null, unlockUntilTs: null });
|
|
6868
6885
|
const targetPlaneRef = useRef8("lane");
|
|
6869
6886
|
const nestCandidateRef = useRef8(null);
|
|
6870
6887
|
const nestTargetRef = useRef8(null);
|
|
@@ -6874,7 +6891,6 @@ function useOverlayRefs(undoRequestId, redoRequestId) {
|
|
|
6874
6891
|
const sourceCommitLaneRef = useRef8(null);
|
|
6875
6892
|
const commitLaneCacheRef = useRef8(/* @__PURE__ */ new Map());
|
|
6876
6893
|
const safeZoneRef = useRef8(null);
|
|
6877
|
-
const blockedContainerIdsRef = useRef8(/* @__PURE__ */ new Set());
|
|
6878
6894
|
const historyRef = useRef8(new DndCommandHistory());
|
|
6879
6895
|
const processedUndoIdRef = useRef8(undoRequestId);
|
|
6880
6896
|
const processedRedoIdRef = useRef8(redoRequestId);
|
|
@@ -6894,9 +6910,9 @@ function useOverlayRefs(undoRequestId, redoRequestId) {
|
|
|
6894
6910
|
lastIntentRef,
|
|
6895
6911
|
visualIntentRef,
|
|
6896
6912
|
sourceContainerIdRef,
|
|
6913
|
+
activeLaneContainerIdRef,
|
|
6897
6914
|
rowLockedRef,
|
|
6898
6915
|
dragSessionAnchorRef,
|
|
6899
|
-
lockRef,
|
|
6900
6916
|
targetPlaneRef,
|
|
6901
6917
|
nestCandidateRef,
|
|
6902
6918
|
nestTargetRef,
|
|
@@ -6906,7 +6922,6 @@ function useOverlayRefs(undoRequestId, redoRequestId) {
|
|
|
6906
6922
|
sourceCommitLaneRef,
|
|
6907
6923
|
commitLaneCacheRef,
|
|
6908
6924
|
safeZoneRef,
|
|
6909
|
-
blockedContainerIdsRef,
|
|
6910
6925
|
historyRef,
|
|
6911
6926
|
processedUndoIdRef,
|
|
6912
6927
|
processedRedoIdRef,
|
|
@@ -7174,6 +7189,11 @@ function pointInRect(px, py, r) {
|
|
|
7174
7189
|
function pointInExpandedRect(px, py, r, inset) {
|
|
7175
7190
|
return px >= r.left - inset && px <= r.right + inset && py >= r.top - inset && py <= r.bottom + inset;
|
|
7176
7191
|
}
|
|
7192
|
+
function isInNestZone(px, py, rect) {
|
|
7193
|
+
const relX = (px - rect.left) / rect.width;
|
|
7194
|
+
const relY = (py - rect.top) / rect.height;
|
|
7195
|
+
return relX > NEST_EDGE_FRACTION && relX < 1 - NEST_EDGE_FRACTION && relY > NEST_EDGE_FRACTION && relY < 1 - NEST_EDGE_FRACTION;
|
|
7196
|
+
}
|
|
7177
7197
|
function buildSlotQuadtree(slotIndex) {
|
|
7178
7198
|
const rects = /* @__PURE__ */ new Map();
|
|
7179
7199
|
for (const [id, slot] of slotIndex) {
|
|
@@ -7216,6 +7236,11 @@ var DragIntentEngine = class {
|
|
|
7216
7236
|
__publicField(this, "laneAllowedContainers");
|
|
7217
7237
|
__publicField(this, "blockedContainerIds");
|
|
7218
7238
|
__publicField(this, "targetPlane", "lane");
|
|
7239
|
+
// Memoized result of getValidDropContainerIds(). Safe to cache because every
|
|
7240
|
+
// input it reads (containerIndex, slotIndex, activeId, laneAllowedContainers,
|
|
7241
|
+
// blockedContainerIds) is fixed in the constructor and never mutated during
|
|
7242
|
+
// a drag.
|
|
7243
|
+
__publicField(this, "validDropContainerIds", null);
|
|
7219
7244
|
this.projectionTree = projection.projectionTree;
|
|
7220
7245
|
this.containerIndex = projection.containerIndex;
|
|
7221
7246
|
this.slotIndex = projection.slotIndex;
|
|
@@ -7252,6 +7277,44 @@ var DragIntentEngine = class {
|
|
|
7252
7277
|
getContainerChildren(containerId) {
|
|
7253
7278
|
return this.containerIndex.get(containerId)?.children ?? [];
|
|
7254
7279
|
}
|
|
7280
|
+
/**
|
|
7281
|
+
* Every container id this engine would accept as a drop target for the
|
|
7282
|
+
* active node, at the current pointer position or any other — i.e. the
|
|
7283
|
+
* full set `resolvePointerContainer` draws from, not a snapshot of one
|
|
7284
|
+
* resolve() call. Intended for the visual layer to draw a guide that
|
|
7285
|
+
* matches exactly what the engine can land on, without re-deriving the
|
|
7286
|
+
* eligibility rule itself.
|
|
7287
|
+
*
|
|
7288
|
+
* Always queries with `laneLock: true`. That is not an approximation of
|
|
7289
|
+
* the "real" default — it IS the real answer for every reachable caller:
|
|
7290
|
+
*
|
|
7291
|
+
* - With a row lock active (`laneAllowedContainers` set), `isLaneContainer`
|
|
7292
|
+
* restricts eligibility to that set, so this returns exactly
|
|
7293
|
+
* `{srcContainerId}` — the ARCH-1071 lock, reproduced faithfully.
|
|
7294
|
+
* - Without a row lock, `laneAllowedContainers` is null and
|
|
7295
|
+
* `isLaneContainer` returns true unconditionally, so `laneLock`'s value
|
|
7296
|
+
* makes no difference — passing `true` costs nothing here.
|
|
7297
|
+
* - The engine's own 'nest' plane does call `isEligibleDropContainer` with
|
|
7298
|
+
* `laneLock: false` (see `peekNestIntent` → `resolvePointerContainer`),
|
|
7299
|
+
* but that plane is unreachable for a locked drag: `computeAllowNest`
|
|
7300
|
+
* (useDragVisualLoop.ts) short-circuits `rowLocked` drags before
|
|
7301
|
+
* `setTargetPlane('nest')` is ever called, so `targetPlane` stays
|
|
7302
|
+
* 'lane' for the drag's whole lifetime. If that guard is ever removed,
|
|
7303
|
+
* this method will under-report nest-only targets for locked drags —
|
|
7304
|
+
* keep the two in sync.
|
|
7305
|
+
*
|
|
7306
|
+
* Cached after the first call: every input (containerIndex, slotIndex,
|
|
7307
|
+
* activeId, laneAllowedContainers, blockedContainerIds) is fixed at
|
|
7308
|
+
* construction and never changes for the life of a drag.
|
|
7309
|
+
*/
|
|
7310
|
+
getValidDropContainerIds() {
|
|
7311
|
+
if (this.validDropContainerIds) return this.validDropContainerIds;
|
|
7312
|
+
const ids2 = /* @__PURE__ */ new Set();
|
|
7313
|
+
for (const id of this.containerIndex.keys()) {
|
|
7314
|
+
if (this.isEligibleDropContainer(id, true)) ids2.add(id);
|
|
7315
|
+
}
|
|
7316
|
+
return this.validDropContainerIds = ids2;
|
|
7317
|
+
}
|
|
7255
7318
|
setTargetPlane(plane) {
|
|
7256
7319
|
this.targetPlane = plane;
|
|
7257
7320
|
}
|
|
@@ -7270,6 +7333,17 @@ var DragIntentEngine = class {
|
|
|
7270
7333
|
isInvalidDropContainer(containerId) {
|
|
7271
7334
|
return containerId === this.activeId || this.isContainerDescendantOf(containerId, this.activeId);
|
|
7272
7335
|
}
|
|
7336
|
+
/**
|
|
7337
|
+
* The full "can this container accept the active node this drag" predicate.
|
|
7338
|
+
* SINGLE definition — every caller routes through it so no two parts of the
|
|
7339
|
+
* system can disagree about which containers are droppable.
|
|
7340
|
+
*/
|
|
7341
|
+
isEligibleDropContainer(containerId, laneLock) {
|
|
7342
|
+
if (this.isInvalidDropContainer(containerId)) return false;
|
|
7343
|
+
if (this.isBlockedContainer(containerId)) return false;
|
|
7344
|
+
if (laneLock && !this.isLaneContainer(containerId)) return false;
|
|
7345
|
+
return this.hasUsableSlots(containerId);
|
|
7346
|
+
}
|
|
7273
7347
|
/**
|
|
7274
7348
|
* Resolve the drag intent from the current pointer position.
|
|
7275
7349
|
*
|
|
@@ -7357,9 +7431,7 @@ var DragIntentEngine = class {
|
|
|
7357
7431
|
const childNode = this.getNodeRect(childId);
|
|
7358
7432
|
if (!childNode) continue;
|
|
7359
7433
|
if (!pointInRect(px, py, childNode)) continue;
|
|
7360
|
-
|
|
7361
|
-
const relY = (py - childNode.top) / childNode.height;
|
|
7362
|
-
if (relX > NEST_EDGE_FRACTION && relX < 1 - NEST_EDGE_FRACTION && relY > NEST_EDGE_FRACTION && relY < 1 - NEST_EDGE_FRACTION) {
|
|
7434
|
+
if (isInNestZone(px, py, childNode)) {
|
|
7363
7435
|
return {
|
|
7364
7436
|
containerId: pointerContainerId,
|
|
7365
7437
|
index: container.children.indexOf(childId),
|
|
@@ -7373,11 +7445,8 @@ var DragIntentEngine = class {
|
|
|
7373
7445
|
resolvePointerContainer(px, py, laneLock) {
|
|
7374
7446
|
const pointerContainers = [];
|
|
7375
7447
|
for (const [id, node] of this.containerIndex) {
|
|
7376
|
-
if (this.isInvalidDropContainer(id)) continue;
|
|
7377
|
-
if (this.isBlockedContainer(id)) continue;
|
|
7378
|
-
if (laneLock && !this.isLaneContainer(id)) continue;
|
|
7379
7448
|
if (!pointInRect(px, py, node.rect)) continue;
|
|
7380
|
-
if (this.
|
|
7449
|
+
if (!this.isEligibleDropContainer(id, laneLock)) continue;
|
|
7381
7450
|
const r = node.rect;
|
|
7382
7451
|
const edgeDistX = Math.min(px - r.left, r.right - px);
|
|
7383
7452
|
const edgeDistY = Math.min(py - r.top, r.bottom - py);
|
|
@@ -7394,11 +7463,11 @@ var DragIntentEngine = class {
|
|
|
7394
7463
|
let pointerContainerId = pointerContainers[0]?.id ?? null;
|
|
7395
7464
|
if (!pointerContainerId && this.lastIntent?.mode === "reorder") {
|
|
7396
7465
|
const lastContainer = this.containerIndex.get(this.lastIntent.containerId);
|
|
7397
|
-
if (lastContainer &&
|
|
7466
|
+
if (lastContainer && this.isEligibleDropContainer(lastContainer.id, laneLock) && pointInExpandedRect(px, py, lastContainer.rect, LAST_CONTAINER_REENTRY_SLOP_PX)) {
|
|
7398
7467
|
pointerContainerId = lastContainer.id;
|
|
7399
7468
|
}
|
|
7400
7469
|
}
|
|
7401
|
-
if (this.originContainerId && this.originContainerId !== pointerContainerId &&
|
|
7470
|
+
if (this.originContainerId && this.originContainerId !== pointerContainerId && this.isEligibleDropContainer(this.originContainerId, laneLock)) {
|
|
7402
7471
|
const originNode = this.containerIndex.get(this.originContainerId);
|
|
7403
7472
|
const currentNode = pointerContainerId ? this.containerIndex.get(pointerContainerId) : null;
|
|
7404
7473
|
const originIsDeeper = originNode && (!currentNode || originNode.depth >= currentNode.depth);
|
|
@@ -7811,7 +7880,8 @@ function useDragVisualLoop({
|
|
|
7811
7880
|
refs,
|
|
7812
7881
|
getCommitLaneSnapshot,
|
|
7813
7882
|
setInsideRect,
|
|
7814
|
-
setDropLine
|
|
7883
|
+
setDropLine,
|
|
7884
|
+
setActiveLaneContainerId
|
|
7815
7885
|
}) {
|
|
7816
7886
|
useEffect8(() => {
|
|
7817
7887
|
const engine = refs.engineRef.current;
|
|
@@ -7819,6 +7889,11 @@ function useDragVisualLoop({
|
|
|
7819
7889
|
if (!activeDrag || !engine || !snapshot) return;
|
|
7820
7890
|
let rafId;
|
|
7821
7891
|
const animator = refs.animatorRef.current;
|
|
7892
|
+
const publishActiveLane = (containerId) => {
|
|
7893
|
+
if (refs.activeLaneContainerIdRef.current === containerId) return;
|
|
7894
|
+
refs.activeLaneContainerIdRef.current = containerId;
|
|
7895
|
+
setActiveLaneContainerId(containerId);
|
|
7896
|
+
};
|
|
7822
7897
|
const setTargetPlane = (nextPlane) => {
|
|
7823
7898
|
const prevPlane = refs.targetPlaneRef.current;
|
|
7824
7899
|
if (prevPlane === nextPlane) return;
|
|
@@ -7837,6 +7912,7 @@ function useDragVisualLoop({
|
|
|
7837
7912
|
const safeZone = refs.safeZoneRef.current;
|
|
7838
7913
|
if (isPointerBlocked(px, py, safeZone)) {
|
|
7839
7914
|
setTargetPlane("lane");
|
|
7915
|
+
publishActiveLane(null);
|
|
7840
7916
|
refs.lastIntentRef.current = null;
|
|
7841
7917
|
refs.visualIntentRef.current = null;
|
|
7842
7918
|
refs.nestCandidateRef.current = null;
|
|
@@ -7878,6 +7954,7 @@ function useDragVisualLoop({
|
|
|
7878
7954
|
let intent = engine.resolve(px, py, window.scrollX, window.scrollY, snapshot.scroll.x, snapshot.scroll.y);
|
|
7879
7955
|
if (!intent) {
|
|
7880
7956
|
setTargetPlane("lane");
|
|
7957
|
+
publishActiveLane(null);
|
|
7881
7958
|
refs.lastIntentRef.current = null;
|
|
7882
7959
|
refs.visualIntentRef.current = null;
|
|
7883
7960
|
refs.nestCandidateRef.current = null;
|
|
@@ -7903,6 +7980,7 @@ function useDragVisualLoop({
|
|
|
7903
7980
|
const targetId = intent.slotId.split("::nest::")[1] ?? "";
|
|
7904
7981
|
if (!targetId) {
|
|
7905
7982
|
setTargetPlane("lane");
|
|
7983
|
+
publishActiveLane(null);
|
|
7906
7984
|
rafId = requestAnimationFrame(tick);
|
|
7907
7985
|
return;
|
|
7908
7986
|
}
|
|
@@ -7924,12 +8002,14 @@ function useDragVisualLoop({
|
|
|
7924
8002
|
};
|
|
7925
8003
|
refs.visualIntentRef.current = intent;
|
|
7926
8004
|
refs.lastIntentRef.current = intent;
|
|
8005
|
+
publishActiveLane(intent.containerId);
|
|
7927
8006
|
} else {
|
|
7928
8007
|
setTargetPlane("lane");
|
|
7929
8008
|
refs.nestCandidateRef.current = null;
|
|
7930
8009
|
refs.nestTargetRef.current = null;
|
|
7931
8010
|
refs.lastIntentRef.current = intent;
|
|
7932
8011
|
refs.visualIntentRef.current = intent;
|
|
8012
|
+
publishActiveLane(intent.containerId);
|
|
7933
8013
|
setInsideRect(null);
|
|
7934
8014
|
const proj = refs.projectionRef.current;
|
|
7935
8015
|
const slot = proj.slotIndex.get(intent.slotId);
|
|
@@ -8236,7 +8316,8 @@ function useDragLifecycle({
|
|
|
8236
8316
|
syncHistoryAvailability,
|
|
8237
8317
|
resolveNodeElement,
|
|
8238
8318
|
setInsideRect,
|
|
8239
|
-
setDropLine
|
|
8319
|
+
setDropLine,
|
|
8320
|
+
setActiveLaneContainerId
|
|
8240
8321
|
}) {
|
|
8241
8322
|
const [activeDrag, setActiveDrag] = useState5(null);
|
|
8242
8323
|
const clearDragState = useCallback6(() => {
|
|
@@ -8247,13 +8328,12 @@ function useDragLifecycle({
|
|
|
8247
8328
|
refs.snapshotRef.current = null;
|
|
8248
8329
|
refs.projectionRef.current = EMPTY_PROJECTION;
|
|
8249
8330
|
refs.engineRef.current = null;
|
|
8250
|
-
refs.blockedContainerIdsRef.current = /* @__PURE__ */ new Set();
|
|
8251
8331
|
refs.lastIntentRef.current = null;
|
|
8252
8332
|
refs.visualIntentRef.current = null;
|
|
8253
8333
|
refs.sourceContainerIdRef.current = null;
|
|
8334
|
+
refs.activeLaneContainerIdRef.current = null;
|
|
8254
8335
|
refs.rowLockedRef.current = false;
|
|
8255
8336
|
refs.dragSessionAnchorRef.current = null;
|
|
8256
|
-
refs.lockRef.current = { containerId: null, isCrossUnlocked: false, exitSince: null, unlockUntilTs: null };
|
|
8257
8337
|
refs.targetPlaneRef.current = "lane";
|
|
8258
8338
|
refs.nestCandidateRef.current = null;
|
|
8259
8339
|
refs.nestTargetRef.current = null;
|
|
@@ -8264,6 +8344,7 @@ function useDragLifecycle({
|
|
|
8264
8344
|
refs.safeZoneRef.current = null;
|
|
8265
8345
|
setInsideRect(null);
|
|
8266
8346
|
setDropLine(null);
|
|
8347
|
+
setActiveLaneContainerId(null);
|
|
8267
8348
|
setActiveDrag(null);
|
|
8268
8349
|
resume();
|
|
8269
8350
|
}, [clearCommitLaneCache, resume]);
|
|
@@ -8321,7 +8402,6 @@ function useDragLifecycle({
|
|
|
8321
8402
|
const sourceCommitLane = getCommitLaneSnapshot(srcContainerId);
|
|
8322
8403
|
const startPosition = getCurrentCommitPlacement(anchorNodeId, srcContainerId);
|
|
8323
8404
|
const blockedContainerIds = buildBlockedStructuralContainerIds(proj, refs.nodeMapRef.current, srcContainerId);
|
|
8324
|
-
refs.blockedContainerIdsRef.current = blockedContainerIds;
|
|
8325
8405
|
const engineOptions = buildDragIntentEngineOptions(anchorScanned.element, srcContainerId, blockedContainerIds);
|
|
8326
8406
|
refs.rowLockedRef.current = !!engineOptions.laneAllowedContainers;
|
|
8327
8407
|
refs.engineRef.current = createDragIntentEngine(proj, anchorNodeId, engineOptions);
|
|
@@ -8330,7 +8410,6 @@ function useDragLifecycle({
|
|
|
8330
8410
|
refs.sourceContainerIdRef.current = srcContainerId;
|
|
8331
8411
|
refs.sourceCommitLaneRef.current = sourceCommitLane;
|
|
8332
8412
|
refs.dragSessionAnchorRef.current = anchor;
|
|
8333
|
-
refs.lockRef.current = { containerId: srcContainerId, isCrossUnlocked: true, exitSince: null, unlockUntilTs: null };
|
|
8334
8413
|
refs.dragStartPositionRef.current = startPosition;
|
|
8335
8414
|
refs.safeZoneRef.current = resolveSafeZoneRect();
|
|
8336
8415
|
pause();
|
|
@@ -8484,7 +8563,9 @@ function useResizeSession({
|
|
|
8484
8563
|
}) {
|
|
8485
8564
|
const handleResizeHandlePointerDown = useCallback7((e, nodeId, dir) => {
|
|
8486
8565
|
if (refs.resizeSessionRef.current) return;
|
|
8487
|
-
const
|
|
8566
|
+
const scanned = refs.nodeMapRef.current.get(nodeId);
|
|
8567
|
+
if (scanned && scanned.draggable === false) return;
|
|
8568
|
+
const selectedEl = scanned?.element ?? document.querySelector(`[data-dnd-node-id="${nodeId}"]`);
|
|
8488
8569
|
if (!selectedEl) return;
|
|
8489
8570
|
e.preventDefault();
|
|
8490
8571
|
e.stopPropagation();
|
|
@@ -8887,6 +8968,7 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
|
|
|
8887
8968
|
// src/client/dnd/design-mode/DesignModeOverlay.tsx
|
|
8888
8969
|
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
8889
8970
|
var DROP_ANIMATION = { duration: DURATION_MS, easing: EASING };
|
|
8971
|
+
var EMPTY_CONTAINER_ID_SET = /* @__PURE__ */ new Set();
|
|
8890
8972
|
function resizeCursorFromHandle(handle) {
|
|
8891
8973
|
switch (handle) {
|
|
8892
8974
|
case "n":
|
|
@@ -9174,13 +9256,9 @@ function DesignModeOverlay() {
|
|
|
9174
9256
|
const sensors = useSensors(
|
|
9175
9257
|
useSensor(PointerSensor, { activationConstraint: { distance: 8 } })
|
|
9176
9258
|
);
|
|
9177
|
-
const collisionDetection = useCallback8(
|
|
9178
|
-
(args) => createDesignModeCollisionDetection(refs.blockedContainerIdsRef.current)(args),
|
|
9179
|
-
[]
|
|
9180
|
-
// eslint-disable-line react-hooks/exhaustive-deps -- refs are stable
|
|
9181
|
-
);
|
|
9182
9259
|
const [insideRect, setInsideRect] = useState6(null);
|
|
9183
9260
|
const [dropLine, setDropLine] = useState6(null);
|
|
9261
|
+
const [activeLaneContainerId, setActiveLaneContainerId] = useState6(null);
|
|
9184
9262
|
useEffect11(() => {
|
|
9185
9263
|
if (!enabled) return;
|
|
9186
9264
|
const fn = (e) => {
|
|
@@ -9216,8 +9294,43 @@ function DesignModeOverlay() {
|
|
|
9216
9294
|
syncHistoryAvailability,
|
|
9217
9295
|
resolveNodeElement,
|
|
9218
9296
|
setInsideRect,
|
|
9219
|
-
setDropLine
|
|
9297
|
+
setDropLine,
|
|
9298
|
+
setActiveLaneContainerId
|
|
9220
9299
|
});
|
|
9300
|
+
const dropCandidateContainerIds = useMemo6(
|
|
9301
|
+
() => activeDrag ? refs.engineRef.current?.getValidDropContainerIds() ?? null : null,
|
|
9302
|
+
[activeDrag]
|
|
9303
|
+
// eslint-disable-line react-hooks/exhaustive-deps -- refs are stable
|
|
9304
|
+
);
|
|
9305
|
+
const visibleCandidateContainerIds = useMemo6(() => {
|
|
9306
|
+
if (!dropCandidateContainerIds) return null;
|
|
9307
|
+
const rects = refs.snapshotRef.current?.rects;
|
|
9308
|
+
if (!rects) return dropCandidateContainerIds;
|
|
9309
|
+
const vw = window.innerWidth;
|
|
9310
|
+
const vh = window.innerHeight;
|
|
9311
|
+
const visible = /* @__PURE__ */ new Set();
|
|
9312
|
+
for (const id of dropCandidateContainerIds) {
|
|
9313
|
+
const r = rects.get(id);
|
|
9314
|
+
if (!r) continue;
|
|
9315
|
+
if (r.right < 0 || r.bottom < 0 || r.left > vw || r.top > vh) continue;
|
|
9316
|
+
visible.add(id);
|
|
9317
|
+
}
|
|
9318
|
+
return visible;
|
|
9319
|
+
}, [dropCandidateContainerIds]);
|
|
9320
|
+
const dragGuide = useMemo6(() => {
|
|
9321
|
+
if (!activeDrag) return null;
|
|
9322
|
+
const snapshot = refs.snapshotRef.current;
|
|
9323
|
+
if (!snapshot) return null;
|
|
9324
|
+
const activeChildIds = activeLaneContainerId ? refs.engineRef.current?.getContainerChildren(activeLaneContainerId) ?? [] : [];
|
|
9325
|
+
return {
|
|
9326
|
+
rects: snapshot.rects,
|
|
9327
|
+
startScroll: snapshot.scroll,
|
|
9328
|
+
candidateContainerIds: visibleCandidateContainerIds ?? EMPTY_CONTAINER_ID_SET,
|
|
9329
|
+
activeContainerId: activeLaneContainerId,
|
|
9330
|
+
activeChildIds,
|
|
9331
|
+
draggingNodeId: activeDrag.nodeId
|
|
9332
|
+
};
|
|
9333
|
+
}, [activeDrag, activeLaneContainerId, visibleCandidateContainerIds]);
|
|
9221
9334
|
useEffect11(() => {
|
|
9222
9335
|
if (!enabled || activeDrag) return;
|
|
9223
9336
|
if (undoRequestId === refs.processedUndoIdRef.current) return;
|
|
@@ -9280,7 +9393,7 @@ function DesignModeOverlay() {
|
|
|
9280
9393
|
safeZoneRef: refs.safeZoneRef,
|
|
9281
9394
|
autoScrollStateRef: refs.autoScrollStateRef
|
|
9282
9395
|
});
|
|
9283
|
-
useDragVisualLoop({ activeDrag, refs, getCommitLaneSnapshot, setInsideRect, setDropLine });
|
|
9396
|
+
useDragVisualLoop({ activeDrag, refs, getCommitLaneSnapshot, setInsideRect, setDropLine, setActiveLaneContainerId });
|
|
9284
9397
|
useExternalDragLoop({
|
|
9285
9398
|
externalDrag,
|
|
9286
9399
|
refs,
|
|
@@ -9300,7 +9413,6 @@ function DesignModeOverlay() {
|
|
|
9300
9413
|
DndContext,
|
|
9301
9414
|
{
|
|
9302
9415
|
sensors,
|
|
9303
|
-
collisionDetection,
|
|
9304
9416
|
autoScroll: false,
|
|
9305
9417
|
onDragStart: handleDragStart,
|
|
9306
9418
|
onDragEnd: handleDragEnd,
|
|
@@ -9309,10 +9421,8 @@ function DesignModeOverlay() {
|
|
|
9309
9421
|
/* @__PURE__ */ jsx4(
|
|
9310
9422
|
ElementHighlight,
|
|
9311
9423
|
{
|
|
9312
|
-
|
|
9313
|
-
|
|
9314
|
-
activeEl: refs.activeElRef.current,
|
|
9315
|
-
arrangeSelectedNodeId,
|
|
9424
|
+
selected: arrangeSelectedNodeId ? nodeMap.get(arrangeSelectedNodeId) ?? null : null,
|
|
9425
|
+
dragGuide,
|
|
9316
9426
|
externalDragActive: externalDrag !== null,
|
|
9317
9427
|
onResizeHandlePointerDown: handleResizeHandlePointerDown
|
|
9318
9428
|
}
|