@archie/devtools 0.0.21 → 0.0.22
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.d.mts +3 -1
- package/dist/client/client.d.ts +3 -1
- package/dist/client/client.js +279 -138
- package/dist/client/client.mjs +242 -100
- package/dist/index.js +21 -9
- package/dist/index.mjs +21 -9
- package/dist/inspector.standalone.js +102 -3
- package/package.json +2 -3
package/dist/client/client.mjs
CHANGED
|
@@ -3,7 +3,7 @@ var __defNormalProp = (obj, key2, value) => key2 in obj ? __defProp(obj, key2, {
|
|
|
3
3
|
var __publicField = (obj, key2, value) => __defNormalProp(obj, typeof key2 !== "symbol" ? key2 + "" : key2, value);
|
|
4
4
|
|
|
5
5
|
// src/client/dnd/DndProvider.tsx
|
|
6
|
-
import { useCallback as useCallback9, useEffect as
|
|
6
|
+
import { useCallback as useCallback9, useEffect as useEffect12 } from "react";
|
|
7
7
|
|
|
8
8
|
// node_modules/@dnd-kit/core/dist/core.esm.js
|
|
9
9
|
import React2, { createContext, useContext, useEffect as useEffect2, useState as useState2, useCallback as useCallback3, useMemo as useMemo2, useRef as useRef2, memo, useReducer, cloneElement, forwardRef } from "react";
|
|
@@ -4280,6 +4280,9 @@ function findMetaOwnerElement(el) {
|
|
|
4280
4280
|
}
|
|
4281
4281
|
function resolveHostElementFromFiberChain(el) {
|
|
4282
4282
|
if (shouldIgnoreAsVirtualRuntime(el)) return null;
|
|
4283
|
+
if (el.hasAttribute("data-dnd-force-allow")) {
|
|
4284
|
+
return el;
|
|
4285
|
+
}
|
|
4283
4286
|
const directMeta = getDirectEditorMeta(el);
|
|
4284
4287
|
const ownerMeta = directMeta ?? getEditorMeta(el);
|
|
4285
4288
|
if (isPassthroughMeta(ownerMeta)) {
|
|
@@ -4635,8 +4638,8 @@ function buildEmptyArrangeSessionState() {
|
|
|
4635
4638
|
var useDesignModeStore = create((set, get) => ({
|
|
4636
4639
|
// UI state
|
|
4637
4640
|
enabled: false,
|
|
4638
|
-
hoveredSelector: null,
|
|
4639
4641
|
selectedSelector: null,
|
|
4642
|
+
inspectorSelectedNodeIds: [],
|
|
4640
4643
|
historyMode: "local",
|
|
4641
4644
|
inspectorTheme: DEFAULT_INSPECTOR_THEME,
|
|
4642
4645
|
canUndo: false,
|
|
@@ -4652,16 +4655,23 @@ var useDesignModeStore = create((set, get) => ({
|
|
|
4652
4655
|
// UI actions
|
|
4653
4656
|
toggle: () => set((s) => ({ enabled: !s.enabled, ...buildEmptyArrangeSessionState() })),
|
|
4654
4657
|
setEnabled: (enabled) => set({ enabled }),
|
|
4655
|
-
setHovered: (selector) => set({ hoveredSelector: selector }),
|
|
4656
4658
|
setSelected: (selector) => set({ selectedSelector: selector }),
|
|
4659
|
+
setInspectorSelection: (nodeIds) => {
|
|
4660
|
+
const next = nodeIds.filter((id) => typeof id === "string" && id.length > 0);
|
|
4661
|
+
const prev = get().inspectorSelectedNodeIds;
|
|
4662
|
+
if (prev.length === next.length && prev.every((id, i) => id === next[i])) {
|
|
4663
|
+
return;
|
|
4664
|
+
}
|
|
4665
|
+
set({ inspectorSelectedNodeIds: next });
|
|
4666
|
+
},
|
|
4657
4667
|
setHistoryMode: (historyMode) => set({ historyMode }),
|
|
4658
4668
|
setInspectorTheme: (theme) => set((s) => ({ inspectorTheme: mergeInspectorTheme({ ...s.inspectorTheme, ...theme }) })),
|
|
4659
4669
|
setHistoryAvailability: (canUndo, canRedo) => set({ canUndo, canRedo }),
|
|
4660
4670
|
requestUndo: () => set((s) => ({ undoRequestId: s.undoRequestId + 1 })),
|
|
4661
4671
|
requestRedo: () => set((s) => ({ redoRequestId: s.redoRequestId + 1 })),
|
|
4662
4672
|
resetAll: () => set({
|
|
4663
|
-
hoveredSelector: null,
|
|
4664
4673
|
selectedSelector: null,
|
|
4674
|
+
inspectorSelectedNodeIds: [],
|
|
4665
4675
|
canUndo: false,
|
|
4666
4676
|
canRedo: false
|
|
4667
4677
|
}),
|
|
@@ -4779,9 +4789,13 @@ var useDesignModeStore = create((set, get) => ({
|
|
|
4779
4789
|
inspectorRef,
|
|
4780
4790
|
displayName,
|
|
4781
4791
|
html,
|
|
4792
|
+
tsxCode,
|
|
4793
|
+
tsxImports,
|
|
4782
4794
|
containerId,
|
|
4783
4795
|
containerNodeKey,
|
|
4784
|
-
index
|
|
4796
|
+
index,
|
|
4797
|
+
beforeSiblingInspectorRef,
|
|
4798
|
+
beforeSiblingNodeKey
|
|
4785
4799
|
}) => {
|
|
4786
4800
|
const now = Date.now();
|
|
4787
4801
|
const normalizedOperationId = operationId ?? buildFallbackOperationId(now, nodeId);
|
|
@@ -4793,9 +4807,13 @@ var useDesignModeStore = create((set, get) => ({
|
|
|
4793
4807
|
inspectorRef,
|
|
4794
4808
|
displayName,
|
|
4795
4809
|
html,
|
|
4810
|
+
tsxCode: tsxCode ?? null,
|
|
4811
|
+
tsxImports: tsxImports ?? null,
|
|
4796
4812
|
containerId,
|
|
4797
4813
|
containerNodeKey,
|
|
4798
4814
|
index,
|
|
4815
|
+
beforeSiblingInspectorRef: beforeSiblingInspectorRef ?? null,
|
|
4816
|
+
beforeSiblingNodeKey: beforeSiblingNodeKey ?? null,
|
|
4799
4817
|
at: now
|
|
4800
4818
|
};
|
|
4801
4819
|
set((s) => {
|
|
@@ -4873,7 +4891,7 @@ var useDesignModeStore = create((set, get) => ({
|
|
|
4873
4891
|
}));
|
|
4874
4892
|
|
|
4875
4893
|
// src/client/dnd/design-mode/DesignModeOverlay.tsx
|
|
4876
|
-
import { useRef as useRef10, useCallback as useCallback8, useEffect as
|
|
4894
|
+
import { useRef as useRef10, useCallback as useCallback8, useEffect as useEffect11, useLayoutEffect as useLayoutEffect2, useState as useState6, useMemo as useMemo6 } from "react";
|
|
4877
4895
|
|
|
4878
4896
|
// src/client/dnd/design-mode/useElementScanner.ts
|
|
4879
4897
|
import { useState as useState4, useEffect as useEffect4, useCallback as useCallback4, useRef as useRef4 } from "react";
|
|
@@ -5402,14 +5420,14 @@ function handlePosition(dir) {
|
|
|
5402
5420
|
};
|
|
5403
5421
|
return positions[dir];
|
|
5404
5422
|
}
|
|
5405
|
-
function getOutlineStyle(rect, isSelected,
|
|
5423
|
+
function getOutlineStyle(rect, isSelected, inspectorTheme) {
|
|
5406
5424
|
return {
|
|
5407
5425
|
...OUTLINE_BASE_STYLE,
|
|
5408
5426
|
left: rect.left,
|
|
5409
5427
|
top: rect.top,
|
|
5410
5428
|
width: rect.width,
|
|
5411
5429
|
height: rect.height,
|
|
5412
|
-
border: isSelected ? `2px solid ${inspectorTheme.accent}` :
|
|
5430
|
+
border: isSelected ? `2px solid ${inspectorTheme.accent}` : `1px dashed ${inspectorTheme.shared}`,
|
|
5413
5431
|
backgroundColor: isSelected ? inspectorTheme.accentSoft : "transparent"
|
|
5414
5432
|
};
|
|
5415
5433
|
}
|
|
@@ -5439,11 +5457,13 @@ function ElementHighlight({
|
|
|
5439
5457
|
elements,
|
|
5440
5458
|
draggingNodeId,
|
|
5441
5459
|
activeEl,
|
|
5460
|
+
arrangeSelectedNodeId,
|
|
5461
|
+
externalDragActive,
|
|
5442
5462
|
onResizeHandlePointerDown
|
|
5443
5463
|
}) {
|
|
5444
|
-
const hoveredSelector = useDesignModeStore((s) => s.hoveredSelector);
|
|
5445
|
-
const selectedSelector = useDesignModeStore((s) => s.selectedSelector);
|
|
5446
5464
|
const inspectorTheme = useDesignModeStore((s) => s.inspectorTheme);
|
|
5465
|
+
const internalDragInProgress = draggingNodeId !== null;
|
|
5466
|
+
const overlayVisible = arrangeSelectedNodeId !== null || internalDragInProgress;
|
|
5447
5467
|
const containerRef = useRef5(null);
|
|
5448
5468
|
const rafRef = useRef5(0);
|
|
5449
5469
|
const syncPositions = useCallback5(() => {
|
|
@@ -5467,7 +5487,6 @@ function ElementHighlight({
|
|
|
5467
5487
|
}
|
|
5468
5488
|
}, [elements]);
|
|
5469
5489
|
useEffect5(() => {
|
|
5470
|
-
if (draggingNodeId) return;
|
|
5471
5490
|
let running = true;
|
|
5472
5491
|
const loop = () => {
|
|
5473
5492
|
if (!running) return;
|
|
@@ -5479,8 +5498,9 @@ function ElementHighlight({
|
|
|
5479
5498
|
running = false;
|
|
5480
5499
|
cancelAnimationFrame(rafRef.current);
|
|
5481
5500
|
};
|
|
5482
|
-
}, [syncPositions
|
|
5483
|
-
if (
|
|
5501
|
+
}, [syncPositions]);
|
|
5502
|
+
if (!overlayVisible) return null;
|
|
5503
|
+
if (externalDragActive) return null;
|
|
5484
5504
|
return /* @__PURE__ */ jsx2(
|
|
5485
5505
|
"div",
|
|
5486
5506
|
{
|
|
@@ -5490,10 +5510,10 @@ function ElementHighlight({
|
|
|
5490
5510
|
children: elements.map((el) => {
|
|
5491
5511
|
if (el.nodeId === draggingNodeId) return null;
|
|
5492
5512
|
if (activeEl && activeEl !== el.element && activeEl.contains(el.element)) return null;
|
|
5493
|
-
const
|
|
5494
|
-
|
|
5513
|
+
const isSelected = el.nodeId === arrangeSelectedNodeId;
|
|
5514
|
+
if (!isSelected && !internalDragInProgress) return null;
|
|
5495
5515
|
const rect = el.element.getBoundingClientRect();
|
|
5496
|
-
const showLabel =
|
|
5516
|
+
const showLabel = isSelected;
|
|
5497
5517
|
const labelTop = isSelected ? Math.max(0, rect.top - 20) : rect.top;
|
|
5498
5518
|
const labelLeft = isSelected ? rect.left + 12 : rect.left;
|
|
5499
5519
|
return /* @__PURE__ */ jsxs("div", { children: [
|
|
@@ -5502,7 +5522,7 @@ function ElementHighlight({
|
|
|
5502
5522
|
{
|
|
5503
5523
|
"data-outline-for": el.nodeId,
|
|
5504
5524
|
"data-design-mode-ui": true,
|
|
5505
|
-
style: getOutlineStyle(rect, isSelected,
|
|
5525
|
+
style: getOutlineStyle(rect, isSelected, inspectorTheme),
|
|
5506
5526
|
children: isSelected && HANDLES.map((dir) => {
|
|
5507
5527
|
const pos = handlePosition(dir);
|
|
5508
5528
|
return /* @__PURE__ */ jsx2(
|
|
@@ -5797,6 +5817,57 @@ function buildRectSlotRect(children, nodeMap, cRect, i, n, rows) {
|
|
|
5797
5817
|
};
|
|
5798
5818
|
}
|
|
5799
5819
|
|
|
5820
|
+
// src/client/dnd/design-mode/inserted-descendants.ts
|
|
5821
|
+
var NON_DRAGGABLE_DESCENDANT_TAGS = /* @__PURE__ */ new Set([
|
|
5822
|
+
// SVG internals — the whole <svg> is the unit; its parts must stay together.
|
|
5823
|
+
"svg",
|
|
5824
|
+
"path",
|
|
5825
|
+
"circle",
|
|
5826
|
+
"rect",
|
|
5827
|
+
"line",
|
|
5828
|
+
"polyline",
|
|
5829
|
+
"polygon",
|
|
5830
|
+
"g",
|
|
5831
|
+
"defs",
|
|
5832
|
+
"use",
|
|
5833
|
+
// <select>/<option>: options live inside their <select>, never standalone.
|
|
5834
|
+
"option",
|
|
5835
|
+
"optgroup",
|
|
5836
|
+
// Table internals: only meaningful in their <table> tree.
|
|
5837
|
+
"caption",
|
|
5838
|
+
"thead",
|
|
5839
|
+
"tbody",
|
|
5840
|
+
"tfoot",
|
|
5841
|
+
"tr",
|
|
5842
|
+
"th",
|
|
5843
|
+
"td",
|
|
5844
|
+
"col",
|
|
5845
|
+
"colgroup",
|
|
5846
|
+
// Self-closing inline atoms with no draggable surface.
|
|
5847
|
+
"br",
|
|
5848
|
+
"wbr",
|
|
5849
|
+
"hr",
|
|
5850
|
+
// Non-rendered metadata.
|
|
5851
|
+
"script",
|
|
5852
|
+
"style",
|
|
5853
|
+
"meta",
|
|
5854
|
+
"link",
|
|
5855
|
+
"title",
|
|
5856
|
+
"noscript",
|
|
5857
|
+
// Replaced media controls handled by their parent player.
|
|
5858
|
+
"source",
|
|
5859
|
+
"track"
|
|
5860
|
+
]);
|
|
5861
|
+
function markInsertedDescendants(root) {
|
|
5862
|
+
const descendants = root.querySelectorAll("*");
|
|
5863
|
+
for (const node of descendants) {
|
|
5864
|
+
const tag = node.tagName.toLowerCase();
|
|
5865
|
+
if (NON_DRAGGABLE_DESCENDANT_TAGS.has(tag)) continue;
|
|
5866
|
+
node.setAttribute("data-dnd-force-allow", "");
|
|
5867
|
+
node.setAttribute("data-dnd-moved", "");
|
|
5868
|
+
}
|
|
5869
|
+
}
|
|
5870
|
+
|
|
5800
5871
|
// src/client/dnd/design-mode/history.ts
|
|
5801
5872
|
function applyInsertCommand(command, direction, resolveNodeElement) {
|
|
5802
5873
|
if (direction === "undo") {
|
|
@@ -5819,6 +5890,7 @@ function applyInsertCommand(command, direction, resolveNodeElement) {
|
|
|
5819
5890
|
(c) => c instanceof HTMLElement
|
|
5820
5891
|
);
|
|
5821
5892
|
container.insertBefore(newEl, kids[command.index] ?? null);
|
|
5893
|
+
markInsertedDescendants(newEl);
|
|
5822
5894
|
return true;
|
|
5823
5895
|
}
|
|
5824
5896
|
var DEFAULT_LIMIT = 300;
|
|
@@ -6344,6 +6416,8 @@ function serializeArrangeChange(event, index) {
|
|
|
6344
6416
|
containerId: event.kind === "insert" ? event.containerId : void 0,
|
|
6345
6417
|
containerNodeKey: event.kind === "insert" ? event.containerNodeKey : void 0,
|
|
6346
6418
|
insertIndex: event.kind === "insert" ? event.index : void 0,
|
|
6419
|
+
beforeSiblingInspectorRef: event.kind === "insert" ? event.beforeSiblingInspectorRef : void 0,
|
|
6420
|
+
beforeSiblingNodeKey: event.kind === "insert" ? event.beforeSiblingNodeKey : void 0,
|
|
6347
6421
|
summary: summarizeEditorChangeEvent(event),
|
|
6348
6422
|
at: event.at
|
|
6349
6423
|
};
|
|
@@ -6641,50 +6715,8 @@ function useOverlayRefs(undoRequestId, redoRequestId) {
|
|
|
6641
6715
|
}), []);
|
|
6642
6716
|
}
|
|
6643
6717
|
|
|
6644
|
-
// src/client/dnd/design-mode/useHoverDetection.ts
|
|
6645
|
-
import { useEffect as useEffect8 } from "react";
|
|
6646
|
-
function useHoverDetection({
|
|
6647
|
-
enabled,
|
|
6648
|
-
activeDrag,
|
|
6649
|
-
elementsRef,
|
|
6650
|
-
setHovered
|
|
6651
|
-
}) {
|
|
6652
|
-
useEffect8(() => {
|
|
6653
|
-
if (!enabled) {
|
|
6654
|
-
setHovered(null);
|
|
6655
|
-
return;
|
|
6656
|
-
}
|
|
6657
|
-
let lastNodeId = null;
|
|
6658
|
-
const fn = (e) => {
|
|
6659
|
-
if (activeDrag) return;
|
|
6660
|
-
let best = null;
|
|
6661
|
-
let bestArea = Infinity;
|
|
6662
|
-
for (const sc of elementsRef.current) {
|
|
6663
|
-
const r = sc.rect;
|
|
6664
|
-
if (e.clientX >= r.left && e.clientX <= r.right && e.clientY >= r.top && e.clientY <= r.bottom) {
|
|
6665
|
-
const a = r.width * r.height;
|
|
6666
|
-
if (a < bestArea) {
|
|
6667
|
-
bestArea = a;
|
|
6668
|
-
best = sc;
|
|
6669
|
-
}
|
|
6670
|
-
}
|
|
6671
|
-
}
|
|
6672
|
-
const nodeId = best?.nodeId ?? null;
|
|
6673
|
-
if (nodeId !== lastNodeId) {
|
|
6674
|
-
lastNodeId = nodeId;
|
|
6675
|
-
setHovered(nodeId);
|
|
6676
|
-
}
|
|
6677
|
-
};
|
|
6678
|
-
document.addEventListener("mousemove", fn);
|
|
6679
|
-
return () => {
|
|
6680
|
-
document.removeEventListener("mousemove", fn);
|
|
6681
|
-
setHovered(null);
|
|
6682
|
-
};
|
|
6683
|
-
}, [enabled, setHovered, activeDrag]);
|
|
6684
|
-
}
|
|
6685
|
-
|
|
6686
6718
|
// src/client/dnd/design-mode/useDragVisualLoop.ts
|
|
6687
|
-
import { useEffect as
|
|
6719
|
+
import { useEffect as useEffect8 } from "react";
|
|
6688
6720
|
|
|
6689
6721
|
// src/client/dnd/design-mode/quadtree.ts
|
|
6690
6722
|
function overlaps(a, b) {
|
|
@@ -7573,7 +7605,7 @@ function useDragVisualLoop({
|
|
|
7573
7605
|
setInsideRect,
|
|
7574
7606
|
setDropLine
|
|
7575
7607
|
}) {
|
|
7576
|
-
|
|
7608
|
+
useEffect8(() => {
|
|
7577
7609
|
const engine = refs.engineRef.current;
|
|
7578
7610
|
const snapshot = refs.snapshotRef.current;
|
|
7579
7611
|
if (!activeDrag || !engine || !snapshot) return;
|
|
@@ -8195,7 +8227,7 @@ function useDragLifecycle({
|
|
|
8195
8227
|
}
|
|
8196
8228
|
|
|
8197
8229
|
// src/client/dnd/design-mode/useResizeSession.ts
|
|
8198
|
-
import { useCallback as useCallback7, useEffect as
|
|
8230
|
+
import { useCallback as useCallback7, useEffect as useEffect9 } from "react";
|
|
8199
8231
|
var RESIZE_POINTER_TOLERANCE_PX = 2;
|
|
8200
8232
|
var RESIZE_DRAG_BLOCK_MS = 180;
|
|
8201
8233
|
var RESIZE_MIN = 24;
|
|
@@ -8367,7 +8399,7 @@ function useResizeSession({
|
|
|
8367
8399
|
});
|
|
8368
8400
|
syncHistoryAvailability();
|
|
8369
8401
|
}, [applyCommand, recordResizeChange, syncHistoryAvailability]);
|
|
8370
|
-
|
|
8402
|
+
useEffect9(() => {
|
|
8371
8403
|
if (!enabled) return;
|
|
8372
8404
|
const handleResizePointerCancel = (e) => {
|
|
8373
8405
|
const session = refs.resizeSessionRef.current;
|
|
@@ -8392,8 +8424,13 @@ function useResizeSession({
|
|
|
8392
8424
|
}
|
|
8393
8425
|
|
|
8394
8426
|
// src/client/dnd/design-mode/useExternalDragLoop.ts
|
|
8395
|
-
import { useEffect as
|
|
8427
|
+
import { useEffect as useEffect10, useRef as useRef9 } from "react";
|
|
8396
8428
|
var EXTERNAL_DRAG_ACTIVE_ID = "__external-drag-placeholder__";
|
|
8429
|
+
var insertNodeIdCounter = 0;
|
|
8430
|
+
function nextInsertNodeId() {
|
|
8431
|
+
insertNodeIdCounter += 1;
|
|
8432
|
+
return `insert:${Date.now()}:${insertNodeIdCounter}`;
|
|
8433
|
+
}
|
|
8397
8434
|
function useExternalDragLoop({
|
|
8398
8435
|
externalDrag,
|
|
8399
8436
|
refs,
|
|
@@ -8403,7 +8440,7 @@ function useExternalDragLoop({
|
|
|
8403
8440
|
}) {
|
|
8404
8441
|
const engineRef = useRef9(null);
|
|
8405
8442
|
const lastIntentRef = useRef9(null);
|
|
8406
|
-
|
|
8443
|
+
useEffect10(() => {
|
|
8407
8444
|
if (!externalDrag) {
|
|
8408
8445
|
engineRef.current = null;
|
|
8409
8446
|
lastIntentRef.current = null;
|
|
@@ -8493,7 +8530,7 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
|
|
|
8493
8530
|
setDropLine(null);
|
|
8494
8531
|
return;
|
|
8495
8532
|
}
|
|
8496
|
-
const nodeId =
|
|
8533
|
+
const nodeId = nextInsertNodeId();
|
|
8497
8534
|
newElement.setAttribute(DND_NODE_ID_ATTR, nodeId);
|
|
8498
8535
|
newElement.setAttribute("data-dnd-force-allow", "");
|
|
8499
8536
|
newElement.setAttribute("data-dnd-moved", "");
|
|
@@ -8502,6 +8539,23 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
|
|
|
8502
8539
|
);
|
|
8503
8540
|
const beforeChild = children[intent.index] ?? null;
|
|
8504
8541
|
containerEl.insertBefore(newElement, beforeChild);
|
|
8542
|
+
markInsertedDescendants(newElement);
|
|
8543
|
+
const postInsertChildren = Array.from(containerEl.children).filter(
|
|
8544
|
+
(child) => child instanceof HTMLElement
|
|
8545
|
+
);
|
|
8546
|
+
let beforeSiblingEl = null;
|
|
8547
|
+
let beforeSiblingNodeId = null;
|
|
8548
|
+
const startIdx = postInsertChildren.indexOf(newElement) + 1;
|
|
8549
|
+
for (let i = startIdx; i < postInsertChildren.length; i += 1) {
|
|
8550
|
+
const candidate = postInsertChildren[i];
|
|
8551
|
+
const candidateNodeId = candidate.getAttribute(DND_NODE_ID_ATTR);
|
|
8552
|
+
if (!candidateNodeId) continue;
|
|
8553
|
+
const isEarlierInsert = candidateNodeId.startsWith("insert:");
|
|
8554
|
+
if (!isEarlierInsert && !getInspectorRefFromElement(candidate)) continue;
|
|
8555
|
+
beforeSiblingEl = candidate;
|
|
8556
|
+
beforeSiblingNodeId = candidateNodeId;
|
|
8557
|
+
break;
|
|
8558
|
+
}
|
|
8505
8559
|
const insertCommand = {
|
|
8506
8560
|
type: "insert",
|
|
8507
8561
|
nodeId,
|
|
@@ -8527,6 +8581,15 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
|
|
|
8527
8581
|
inspectorRef: getInspectorRefFromElement(containerEl)
|
|
8528
8582
|
};
|
|
8529
8583
|
}
|
|
8584
|
+
let beforeSiblingIdentity = null;
|
|
8585
|
+
if (beforeSiblingEl && beforeSiblingNodeId) {
|
|
8586
|
+
beforeSiblingIdentity = {
|
|
8587
|
+
nodeId: beforeSiblingNodeId,
|
|
8588
|
+
nodeKey: getNodeKeyFromElement(beforeSiblingEl),
|
|
8589
|
+
selector: buildNodeSelector(beforeSiblingNodeId),
|
|
8590
|
+
inspectorRef: getInspectorRefFromElement(beforeSiblingEl)
|
|
8591
|
+
};
|
|
8592
|
+
}
|
|
8530
8593
|
const operationId = `${insertCommand.at}:${nodeId}`;
|
|
8531
8594
|
useDesignModeStore.getState().recordInsertChange({
|
|
8532
8595
|
operationId,
|
|
@@ -8535,9 +8598,13 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
|
|
|
8535
8598
|
inspectorRef,
|
|
8536
8599
|
displayName: component.displayName,
|
|
8537
8600
|
html: component.html,
|
|
8601
|
+
tsxCode: component.tsxCode ?? null,
|
|
8602
|
+
tsxImports: component.tsxImports ?? null,
|
|
8538
8603
|
containerId: intent.containerId,
|
|
8539
8604
|
containerNodeKey,
|
|
8540
|
-
index: intent.index
|
|
8605
|
+
index: intent.index,
|
|
8606
|
+
beforeSiblingInspectorRef: beforeSiblingIdentity?.inspectorRef ?? null,
|
|
8607
|
+
beforeSiblingNodeKey: beforeSiblingIdentity?.nodeKey ?? null
|
|
8541
8608
|
});
|
|
8542
8609
|
dispatchRuntimeEvent({
|
|
8543
8610
|
type: "element-inserted",
|
|
@@ -8546,8 +8613,11 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
|
|
|
8546
8613
|
nodeKey,
|
|
8547
8614
|
displayName: component.displayName,
|
|
8548
8615
|
html: component.html,
|
|
8616
|
+
tsxCode: component.tsxCode ?? null,
|
|
8617
|
+
tsxImports: component.tsxImports ?? null,
|
|
8549
8618
|
container: containerIdentity,
|
|
8550
|
-
index: intent.index
|
|
8619
|
+
index: intent.index,
|
|
8620
|
+
beforeSibling: beforeSiblingIdentity
|
|
8551
8621
|
});
|
|
8552
8622
|
}
|
|
8553
8623
|
setDropLine(null);
|
|
@@ -8598,8 +8668,12 @@ function HitArea({
|
|
|
8598
8668
|
selectedNodeId,
|
|
8599
8669
|
onResizeHandlePointerDown
|
|
8600
8670
|
}) {
|
|
8601
|
-
const
|
|
8602
|
-
|
|
8671
|
+
const isSelected = scanned.nodeId === selectedNodeId;
|
|
8672
|
+
const { setNodeRef, listeners, attributes, isDragging } = useDraggable({
|
|
8673
|
+
id: scanned.nodeId,
|
|
8674
|
+
disabled: !isSelected
|
|
8675
|
+
});
|
|
8676
|
+
useEffect11(() => {
|
|
8603
8677
|
setNodeRef(scanned.element);
|
|
8604
8678
|
return () => setNodeRef(null);
|
|
8605
8679
|
}, [setNodeRef, scanned.element]);
|
|
@@ -8611,7 +8685,7 @@ function HitArea({
|
|
|
8611
8685
|
el.style.removeProperty("opacity");
|
|
8612
8686
|
}
|
|
8613
8687
|
}, [isDragging, scanned.element]);
|
|
8614
|
-
|
|
8688
|
+
useEffect11(() => () => {
|
|
8615
8689
|
scanned.element.style.removeProperty("opacity");
|
|
8616
8690
|
scanned.element.style.removeProperty("transform");
|
|
8617
8691
|
scanned.element.style.removeProperty("transition");
|
|
@@ -8619,8 +8693,18 @@ function HitArea({
|
|
|
8619
8693
|
}, [scanned.element]);
|
|
8620
8694
|
const divRef = useRef10(null);
|
|
8621
8695
|
const [hoverResizeHandle, setHoverResizeHandle] = useState6(null);
|
|
8622
|
-
const
|
|
8623
|
-
|
|
8696
|
+
const justDraggedRef = useRef10(false);
|
|
8697
|
+
useEffect11(() => {
|
|
8698
|
+
if (isDragging) {
|
|
8699
|
+
justDraggedRef.current = true;
|
|
8700
|
+
return;
|
|
8701
|
+
}
|
|
8702
|
+
const id = window.setTimeout(() => {
|
|
8703
|
+
justDraggedRef.current = false;
|
|
8704
|
+
}, 0);
|
|
8705
|
+
return () => window.clearTimeout(id);
|
|
8706
|
+
}, [isDragging]);
|
|
8707
|
+
useEffect11(() => {
|
|
8624
8708
|
const div = divRef.current;
|
|
8625
8709
|
if (!div) return;
|
|
8626
8710
|
const onWheel = (e) => {
|
|
@@ -8636,7 +8720,7 @@ function HitArea({
|
|
|
8636
8720
|
return () => div.removeEventListener("wheel", onWheel);
|
|
8637
8721
|
}, []);
|
|
8638
8722
|
const { left, top, width, height } = scanned.rect;
|
|
8639
|
-
const cursor = isDragging ? "grabbing" : isSelected
|
|
8723
|
+
const cursor = isDragging ? "grabbing" : !isSelected ? "default" : hoverResizeHandle ? resizeCursorFromHandle(hoverResizeHandle) : "grab";
|
|
8640
8724
|
return /* @__PURE__ */ jsx4(
|
|
8641
8725
|
"div",
|
|
8642
8726
|
{
|
|
@@ -8667,6 +8751,35 @@ function HitArea({
|
|
|
8667
8751
|
...attributes,
|
|
8668
8752
|
...listeners,
|
|
8669
8753
|
onClick: (e) => {
|
|
8754
|
+
if (justDraggedRef.current) {
|
|
8755
|
+
e.preventDefault();
|
|
8756
|
+
e.stopPropagation();
|
|
8757
|
+
return;
|
|
8758
|
+
}
|
|
8759
|
+
const stack = document.elementsFromPoint(e.clientX, e.clientY);
|
|
8760
|
+
for (const candidate of stack) {
|
|
8761
|
+
if (!(candidate instanceof HTMLElement)) continue;
|
|
8762
|
+
if (candidate.hasAttribute("data-design-mode-ui")) continue;
|
|
8763
|
+
if (candidate === scanned.element) break;
|
|
8764
|
+
const candidateNodeId = candidate.getAttribute("data-dnd-node-id");
|
|
8765
|
+
if (candidateNodeId && candidateNodeId !== scanned.nodeId) {
|
|
8766
|
+
e.preventDefault();
|
|
8767
|
+
e.stopPropagation();
|
|
8768
|
+
candidate.dispatchEvent(
|
|
8769
|
+
new MouseEvent("mousedown", {
|
|
8770
|
+
bubbles: true,
|
|
8771
|
+
cancelable: true,
|
|
8772
|
+
clientX: e.clientX,
|
|
8773
|
+
clientY: e.clientY,
|
|
8774
|
+
metaKey: e.metaKey,
|
|
8775
|
+
ctrlKey: e.ctrlKey,
|
|
8776
|
+
shiftKey: e.shiftKey,
|
|
8777
|
+
altKey: e.altKey
|
|
8778
|
+
})
|
|
8779
|
+
);
|
|
8780
|
+
return;
|
|
8781
|
+
}
|
|
8782
|
+
}
|
|
8670
8783
|
e.preventDefault();
|
|
8671
8784
|
e.stopPropagation();
|
|
8672
8785
|
onActivate(scanned.nodeId);
|
|
@@ -8677,9 +8790,11 @@ function HitArea({
|
|
|
8677
8790
|
function DesignModeOverlay() {
|
|
8678
8791
|
const enabled = useDesignModeStore((s) => s.enabled);
|
|
8679
8792
|
const historyMode = useDesignModeStore((s) => s.historyMode);
|
|
8680
|
-
const setHovered = useDesignModeStore((s) => s.setHovered);
|
|
8681
8793
|
const selectElement = useDesignModeStore((s) => s.setSelected);
|
|
8682
|
-
const
|
|
8794
|
+
const inspectorSelectedNodeIds = useDesignModeStore(
|
|
8795
|
+
(s) => s.inspectorSelectedNodeIds
|
|
8796
|
+
);
|
|
8797
|
+
const arrangeSelectedNodeId = inspectorSelectedNodeIds.length === 1 ? inspectorSelectedNodeIds[0] : null;
|
|
8683
8798
|
const setHistoryAvailability = useDesignModeStore((s) => s.setHistoryAvailability);
|
|
8684
8799
|
const undoRequestId = useDesignModeStore((s) => s.undoRequestId);
|
|
8685
8800
|
const redoRequestId = useDesignModeStore((s) => s.redoRequestId);
|
|
@@ -8705,16 +8820,23 @@ function DesignModeOverlay() {
|
|
|
8705
8820
|
(el) => el.draggable !== false
|
|
8706
8821
|
);
|
|
8707
8822
|
}, [elements, nodeMap]);
|
|
8823
|
+
const arrangeHitAreaElement = useMemo6(() => {
|
|
8824
|
+
if (!arrangeSelectedNodeId) return null;
|
|
8825
|
+
if (externalDrag) return null;
|
|
8826
|
+
return draggableElements.find(
|
|
8827
|
+
(candidate) => candidate.nodeId === arrangeSelectedNodeId
|
|
8828
|
+
) ?? null;
|
|
8829
|
+
}, [arrangeSelectedNodeId, externalDrag, draggableElements]);
|
|
8708
8830
|
const refs = useOverlayRefs(undoRequestId, redoRequestId);
|
|
8709
8831
|
refs.elementsRef.current = elements;
|
|
8710
8832
|
refs.nodeMapRef.current = nodeMap;
|
|
8711
|
-
|
|
8833
|
+
useEffect11(() => {
|
|
8712
8834
|
const m = /* @__PURE__ */ new Map();
|
|
8713
8835
|
for (const el of draggableElements) m.set(el.nodeId, el);
|
|
8714
8836
|
refs.draggableNodeMapRef.current = m;
|
|
8715
8837
|
}, [draggableElements]);
|
|
8716
8838
|
const [grabFeedback, setGrabFeedback] = useState6(null);
|
|
8717
|
-
|
|
8839
|
+
useEffect11(() => {
|
|
8718
8840
|
if (!enabled) return;
|
|
8719
8841
|
const onPointerDown = (e) => {
|
|
8720
8842
|
if (!shouldShowGrabFeedback(
|
|
@@ -8728,7 +8850,7 @@ function DesignModeOverlay() {
|
|
|
8728
8850
|
document.addEventListener("pointerdown", onPointerDown, true);
|
|
8729
8851
|
return () => document.removeEventListener("pointerdown", onPointerDown, true);
|
|
8730
8852
|
}, [enabled]);
|
|
8731
|
-
|
|
8853
|
+
useEffect11(() => {
|
|
8732
8854
|
if (!grabFeedback) return;
|
|
8733
8855
|
const t = setTimeout(() => setGrabFeedback(null), 1400);
|
|
8734
8856
|
return () => clearTimeout(t);
|
|
@@ -8785,7 +8907,7 @@ function DesignModeOverlay() {
|
|
|
8785
8907
|
}
|
|
8786
8908
|
setHistoryAvailability(refs.historyRef.current.canUndo(), refs.historyRef.current.canRedo());
|
|
8787
8909
|
}, [historyMode, setHistoryAvailability]);
|
|
8788
|
-
|
|
8910
|
+
useEffect11(() => {
|
|
8789
8911
|
refs.historyRef.current.clear();
|
|
8790
8912
|
syncHistoryAvailability();
|
|
8791
8913
|
}, [enabled, syncHistoryAvailability]);
|
|
@@ -8799,7 +8921,7 @@ function DesignModeOverlay() {
|
|
|
8799
8921
|
);
|
|
8800
8922
|
const [insideRect, setInsideRect] = useState6(null);
|
|
8801
8923
|
const [dropLine, setDropLine] = useState6(null);
|
|
8802
|
-
|
|
8924
|
+
useEffect11(() => {
|
|
8803
8925
|
if (!enabled) return;
|
|
8804
8926
|
const fn = (e) => {
|
|
8805
8927
|
refs.mouseRef.current = { x: e.clientX, y: e.clientY };
|
|
@@ -8807,7 +8929,7 @@ function DesignModeOverlay() {
|
|
|
8807
8929
|
window.addEventListener("pointermove", fn, { capture: true, passive: true });
|
|
8808
8930
|
return () => window.removeEventListener("pointermove", fn, { capture: true });
|
|
8809
8931
|
}, [enabled]);
|
|
8810
|
-
|
|
8932
|
+
useEffect11(() => {
|
|
8811
8933
|
if (!enabled) return;
|
|
8812
8934
|
if (historyMode !== "local") return;
|
|
8813
8935
|
const onKeyDown = (e) => {
|
|
@@ -8836,7 +8958,7 @@ function DesignModeOverlay() {
|
|
|
8836
8958
|
setInsideRect,
|
|
8837
8959
|
setDropLine
|
|
8838
8960
|
});
|
|
8839
|
-
|
|
8961
|
+
useEffect11(() => {
|
|
8840
8962
|
if (!enabled || activeDrag) return;
|
|
8841
8963
|
if (undoRequestId === refs.processedUndoIdRef.current) return;
|
|
8842
8964
|
refs.processedUndoIdRef.current = undoRequestId;
|
|
@@ -8853,7 +8975,7 @@ function DesignModeOverlay() {
|
|
|
8853
8975
|
});
|
|
8854
8976
|
syncHistoryAvailability();
|
|
8855
8977
|
}, [undoRequestId, enabled, activeDrag, applyCommand, resume, selectElement, syncHistoryAvailability, undoLastChange]);
|
|
8856
|
-
|
|
8978
|
+
useEffect11(() => {
|
|
8857
8979
|
if (!enabled || activeDrag || historyMode !== "local") return;
|
|
8858
8980
|
if (redoRequestId === refs.processedRedoIdRef.current) return;
|
|
8859
8981
|
refs.processedRedoIdRef.current = redoRequestId;
|
|
@@ -8865,18 +8987,18 @@ function DesignModeOverlay() {
|
|
|
8865
8987
|
}
|
|
8866
8988
|
syncHistoryAvailability();
|
|
8867
8989
|
}, [redoRequestId, enabled, activeDrag, applyCommand, historyMode, resume, selectElement, syncHistoryAvailability, redoLastChange]);
|
|
8868
|
-
|
|
8990
|
+
useEffect11(() => {
|
|
8869
8991
|
syncHistoryAvailability();
|
|
8870
8992
|
}, [syncHistoryAvailability]);
|
|
8871
|
-
|
|
8993
|
+
useEffect11(() => {
|
|
8872
8994
|
dispatchRuntimeEvent({
|
|
8873
8995
|
type: "design-mode-changed",
|
|
8874
8996
|
mode: enabled ? "design" : "off"
|
|
8875
8997
|
});
|
|
8876
8998
|
}, [enabled]);
|
|
8877
|
-
|
|
8999
|
+
useEffect11(() => {
|
|
8878
9000
|
const aiOutput = exportChangesForAI();
|
|
8879
|
-
const updatedAt =
|
|
9001
|
+
const updatedAt = Date.now();
|
|
8880
9002
|
dispatchRuntimeEvent({
|
|
8881
9003
|
type: "arrange-session-changed",
|
|
8882
9004
|
session: buildArrangeSessionSnapshot({
|
|
@@ -8887,12 +9009,11 @@ function DesignModeOverlay() {
|
|
|
8887
9009
|
})
|
|
8888
9010
|
});
|
|
8889
9011
|
}, [enabled, exportChangesForAI, orderedChanges]);
|
|
8890
|
-
|
|
9012
|
+
useEffect11(() => {
|
|
8891
9013
|
if (!enabled) return;
|
|
8892
9014
|
document.body.classList.add("design-mode-active");
|
|
8893
9015
|
return () => document.body.classList.remove("design-mode-active");
|
|
8894
9016
|
}, [enabled]);
|
|
8895
|
-
useHoverDetection({ enabled, activeDrag, elementsRef: refs.elementsRef, setHovered });
|
|
8896
9017
|
useDesignModeAutoScroll({
|
|
8897
9018
|
active: !!activeDrag,
|
|
8898
9019
|
mouseRef: refs.mouseRef,
|
|
@@ -8931,19 +9052,21 @@ function DesignModeOverlay() {
|
|
|
8931
9052
|
elements,
|
|
8932
9053
|
draggingNodeId: activeDrag?.nodeId ?? null,
|
|
8933
9054
|
activeEl: refs.activeElRef.current,
|
|
9055
|
+
arrangeSelectedNodeId,
|
|
9056
|
+
externalDragActive: externalDrag !== null,
|
|
8934
9057
|
onResizeHandlePointerDown: handleResizeHandlePointerDown
|
|
8935
9058
|
}
|
|
8936
9059
|
),
|
|
8937
|
-
|
|
9060
|
+
arrangeHitAreaElement && /* @__PURE__ */ jsx4(
|
|
8938
9061
|
HitArea,
|
|
8939
9062
|
{
|
|
8940
|
-
scanned:
|
|
9063
|
+
scanned: arrangeHitAreaElement,
|
|
8941
9064
|
onActivate: selectElement,
|
|
8942
|
-
selectedNodeId:
|
|
9065
|
+
selectedNodeId: arrangeHitAreaElement.nodeId,
|
|
8943
9066
|
onResizeHandlePointerDown: handleResizeHandlePointerDown
|
|
8944
9067
|
},
|
|
8945
|
-
|
|
8946
|
-
)
|
|
9068
|
+
arrangeHitAreaElement.nodeId
|
|
9069
|
+
),
|
|
8947
9070
|
grabFeedback ? /* @__PURE__ */ jsx4(
|
|
8948
9071
|
"div",
|
|
8949
9072
|
{
|
|
@@ -9058,7 +9181,7 @@ function DndProvider({ children }) {
|
|
|
9058
9181
|
designModeState.resetArrangeSession();
|
|
9059
9182
|
designModeState.setEnabled(nextEnabled);
|
|
9060
9183
|
}, []);
|
|
9061
|
-
|
|
9184
|
+
useEffect12(() => {
|
|
9062
9185
|
const handleKeyDown = (e) => {
|
|
9063
9186
|
if (e.ctrlKey && e.shiftKey && e.key === "D") {
|
|
9064
9187
|
e.preventDefault();
|
|
@@ -9068,7 +9191,7 @@ function DndProvider({ children }) {
|
|
|
9068
9191
|
window.addEventListener("keydown", handleKeyDown);
|
|
9069
9192
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
9070
9193
|
}, [transitionDesignMode]);
|
|
9071
|
-
|
|
9194
|
+
useEffect12(() => {
|
|
9072
9195
|
const handleHostCommand = (event) => {
|
|
9073
9196
|
const detail = event.detail;
|
|
9074
9197
|
if (!detail || typeof detail !== "object") return;
|
|
@@ -9127,6 +9250,25 @@ function DndProvider({ children }) {
|
|
|
9127
9250
|
setInspectorTheme,
|
|
9128
9251
|
requestUndo
|
|
9129
9252
|
]);
|
|
9253
|
+
useEffect12(() => {
|
|
9254
|
+
const bridgeWindow = window;
|
|
9255
|
+
const bridge = {
|
|
9256
|
+
setInspectorSelection: (nodeIds) => {
|
|
9257
|
+
useDesignModeStore.getState().setInspectorSelection(nodeIds);
|
|
9258
|
+
}
|
|
9259
|
+
};
|
|
9260
|
+
bridgeWindow.__ARCHIE_DESIGN_MODE__ = bridge;
|
|
9261
|
+
const pending = bridgeWindow.__ARCHIE_DESIGN_MODE_PENDING__;
|
|
9262
|
+
if (Array.isArray(pending)) {
|
|
9263
|
+
bridge.setInspectorSelection(pending);
|
|
9264
|
+
delete bridgeWindow.__ARCHIE_DESIGN_MODE_PENDING__;
|
|
9265
|
+
}
|
|
9266
|
+
return () => {
|
|
9267
|
+
if (bridgeWindow.__ARCHIE_DESIGN_MODE__ === bridge) {
|
|
9268
|
+
delete bridgeWindow.__ARCHIE_DESIGN_MODE__;
|
|
9269
|
+
}
|
|
9270
|
+
};
|
|
9271
|
+
}, []);
|
|
9130
9272
|
const pointerSensor = useSensor(PointerSensor, { activationConstraint: { distance: 8 } });
|
|
9131
9273
|
const keyboardSensor = useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates });
|
|
9132
9274
|
const sensors = useSensors(pointerSensor, keyboardSensor);
|
|
@@ -9198,12 +9340,12 @@ function DndProvider({ children }) {
|
|
|
9198
9340
|
}
|
|
9199
9341
|
|
|
9200
9342
|
// src/client/useArchieDevToolsRuntime.ts
|
|
9201
|
-
import { useEffect as
|
|
9343
|
+
import { useEffect as useEffect13, useRef as useRef11 } from "react";
|
|
9202
9344
|
|
|
9203
9345
|
// src/client/archieLocalInspectorEnv.ts
|
|
9204
9346
|
function readArchieLocalInspectorFlag() {
|
|
9205
9347
|
try {
|
|
9206
|
-
return
|
|
9348
|
+
return false;
|
|
9207
9349
|
} catch {
|
|
9208
9350
|
return false;
|
|
9209
9351
|
}
|
|
@@ -9424,7 +9566,7 @@ function useArchieDevToolsRuntime({
|
|
|
9424
9566
|
const stableOptionsKey = JSON.stringify(inspectorOptions ?? null);
|
|
9425
9567
|
const inspectorOptionsRef = useRef11(inspectorOptions);
|
|
9426
9568
|
inspectorOptionsRef.current = inspectorOptions;
|
|
9427
|
-
|
|
9569
|
+
useEffect13(() => {
|
|
9428
9570
|
if (process.env.NODE_ENV !== "development") {
|
|
9429
9571
|
return;
|
|
9430
9572
|
}
|