@archie/devtools 0.0.20 → 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.
@@ -38,7 +38,7 @@ __export(client_exports, {
38
38
  module.exports = __toCommonJS(client_exports);
39
39
 
40
40
  // src/client/dnd/DndProvider.tsx
41
- var import_react19 = require("react");
41
+ var import_react18 = require("react");
42
42
 
43
43
  // node_modules/@dnd-kit/core/dist/core.esm.js
44
44
  var import_react3 = __toESM(require("react"));
@@ -4315,6 +4315,9 @@ function findMetaOwnerElement(el) {
4315
4315
  }
4316
4316
  function resolveHostElementFromFiberChain(el) {
4317
4317
  if (shouldIgnoreAsVirtualRuntime(el)) return null;
4318
+ if (el.hasAttribute("data-dnd-force-allow")) {
4319
+ return el;
4320
+ }
4318
4321
  const directMeta = getDirectEditorMeta(el);
4319
4322
  const ownerMeta = directMeta ?? getEditorMeta(el);
4320
4323
  if (isPassthroughMeta(ownerMeta)) {
@@ -4670,8 +4673,8 @@ function buildEmptyArrangeSessionState() {
4670
4673
  var useDesignModeStore = create((set, get) => ({
4671
4674
  // UI state
4672
4675
  enabled: false,
4673
- hoveredSelector: null,
4674
4676
  selectedSelector: null,
4677
+ inspectorSelectedNodeIds: [],
4675
4678
  historyMode: "local",
4676
4679
  inspectorTheme: DEFAULT_INSPECTOR_THEME,
4677
4680
  canUndo: false,
@@ -4687,16 +4690,23 @@ var useDesignModeStore = create((set, get) => ({
4687
4690
  // UI actions
4688
4691
  toggle: () => set((s) => ({ enabled: !s.enabled, ...buildEmptyArrangeSessionState() })),
4689
4692
  setEnabled: (enabled) => set({ enabled }),
4690
- setHovered: (selector) => set({ hoveredSelector: selector }),
4691
4693
  setSelected: (selector) => set({ selectedSelector: selector }),
4694
+ setInspectorSelection: (nodeIds) => {
4695
+ const next = nodeIds.filter((id) => typeof id === "string" && id.length > 0);
4696
+ const prev = get().inspectorSelectedNodeIds;
4697
+ if (prev.length === next.length && prev.every((id, i) => id === next[i])) {
4698
+ return;
4699
+ }
4700
+ set({ inspectorSelectedNodeIds: next });
4701
+ },
4692
4702
  setHistoryMode: (historyMode) => set({ historyMode }),
4693
4703
  setInspectorTheme: (theme) => set((s) => ({ inspectorTheme: mergeInspectorTheme({ ...s.inspectorTheme, ...theme }) })),
4694
4704
  setHistoryAvailability: (canUndo, canRedo) => set({ canUndo, canRedo }),
4695
4705
  requestUndo: () => set((s) => ({ undoRequestId: s.undoRequestId + 1 })),
4696
4706
  requestRedo: () => set((s) => ({ redoRequestId: s.redoRequestId + 1 })),
4697
4707
  resetAll: () => set({
4698
- hoveredSelector: null,
4699
4708
  selectedSelector: null,
4709
+ inspectorSelectedNodeIds: [],
4700
4710
  canUndo: false,
4701
4711
  canRedo: false
4702
4712
  }),
@@ -4814,9 +4824,13 @@ var useDesignModeStore = create((set, get) => ({
4814
4824
  inspectorRef,
4815
4825
  displayName,
4816
4826
  html,
4827
+ tsxCode,
4828
+ tsxImports,
4817
4829
  containerId,
4818
4830
  containerNodeKey,
4819
- index
4831
+ index,
4832
+ beforeSiblingInspectorRef,
4833
+ beforeSiblingNodeKey
4820
4834
  }) => {
4821
4835
  const now = Date.now();
4822
4836
  const normalizedOperationId = operationId ?? buildFallbackOperationId(now, nodeId);
@@ -4828,9 +4842,13 @@ var useDesignModeStore = create((set, get) => ({
4828
4842
  inspectorRef,
4829
4843
  displayName,
4830
4844
  html,
4845
+ tsxCode: tsxCode ?? null,
4846
+ tsxImports: tsxImports ?? null,
4831
4847
  containerId,
4832
4848
  containerNodeKey,
4833
4849
  index,
4850
+ beforeSiblingInspectorRef: beforeSiblingInspectorRef ?? null,
4851
+ beforeSiblingNodeKey: beforeSiblingNodeKey ?? null,
4834
4852
  at: now
4835
4853
  };
4836
4854
  set((s) => {
@@ -4908,7 +4926,7 @@ var useDesignModeStore = create((set, get) => ({
4908
4926
  }));
4909
4927
 
4910
4928
  // src/client/dnd/design-mode/DesignModeOverlay.tsx
4911
- var import_react17 = require("react");
4929
+ var import_react16 = require("react");
4912
4930
 
4913
4931
  // src/client/dnd/design-mode/useElementScanner.ts
4914
4932
  var import_react6 = require("react");
@@ -4927,15 +4945,17 @@ function buildNodeSelector(nodeId) {
4927
4945
  var LARGE_NODE_NEST_BLOCK_MIN_WIDTH = 520;
4928
4946
  var LARGE_NODE_NEST_BLOCK_MIN_HEIGHT = 260;
4929
4947
  var LARGE_NODE_NEST_BLOCK_MIN_AREA = 18e4;
4930
- function resolveGrabFeedbackTarget(target, scannedByNodeId) {
4931
- if (!(target instanceof Element)) return null;
4932
- if (target.closest("[data-design-mode-ui]")) return null;
4948
+ function shouldShowGrabFeedback(target, scannedByNodeId) {
4949
+ if (!(target instanceof Element)) return false;
4950
+ if (target.closest("[data-design-mode-ui]")) return false;
4951
+ if (!target.closest("#root")) return false;
4933
4952
  const host = target.closest(`[${DND_NODE_ID_ATTR}]`);
4934
- if (!host) return null;
4953
+ if (!host) {
4954
+ return true;
4955
+ }
4935
4956
  const nodeId = host.getAttribute(DND_NODE_ID_ATTR);
4936
4957
  const scanned = nodeId ? scannedByNodeId.get(nodeId) : null;
4937
- if (!scanned || scanned.draggable !== false) return null;
4938
- return scanned;
4958
+ return !scanned || scanned.draggable === false;
4939
4959
  }
4940
4960
  function isEligibleForDrag(sc) {
4941
4961
  if (sc.draggable === false) return false;
@@ -5435,14 +5455,14 @@ function handlePosition(dir) {
5435
5455
  };
5436
5456
  return positions[dir];
5437
5457
  }
5438
- function getOutlineStyle(rect, isSelected, isHovered, inspectorTheme) {
5458
+ function getOutlineStyle(rect, isSelected, inspectorTheme) {
5439
5459
  return {
5440
5460
  ...OUTLINE_BASE_STYLE,
5441
5461
  left: rect.left,
5442
5462
  top: rect.top,
5443
5463
  width: rect.width,
5444
5464
  height: rect.height,
5445
- border: isSelected ? `2px solid ${inspectorTheme.accent}` : isHovered ? `2px dashed ${inspectorTheme.hover}` : `1px dashed ${inspectorTheme.shared}`,
5465
+ border: isSelected ? `2px solid ${inspectorTheme.accent}` : `1px dashed ${inspectorTheme.shared}`,
5446
5466
  backgroundColor: isSelected ? inspectorTheme.accentSoft : "transparent"
5447
5467
  };
5448
5468
  }
@@ -5472,11 +5492,13 @@ function ElementHighlight({
5472
5492
  elements,
5473
5493
  draggingNodeId,
5474
5494
  activeEl,
5495
+ arrangeSelectedNodeId,
5496
+ externalDragActive,
5475
5497
  onResizeHandlePointerDown
5476
5498
  }) {
5477
- const hoveredSelector = useDesignModeStore((s) => s.hoveredSelector);
5478
- const selectedSelector = useDesignModeStore((s) => s.selectedSelector);
5479
5499
  const inspectorTheme = useDesignModeStore((s) => s.inspectorTheme);
5500
+ const internalDragInProgress = draggingNodeId !== null;
5501
+ const overlayVisible = arrangeSelectedNodeId !== null || internalDragInProgress;
5480
5502
  const containerRef = (0, import_react7.useRef)(null);
5481
5503
  const rafRef = (0, import_react7.useRef)(0);
5482
5504
  const syncPositions = (0, import_react7.useCallback)(() => {
@@ -5500,7 +5522,6 @@ function ElementHighlight({
5500
5522
  }
5501
5523
  }, [elements]);
5502
5524
  (0, import_react7.useEffect)(() => {
5503
- if (draggingNodeId) return;
5504
5525
  let running = true;
5505
5526
  const loop = () => {
5506
5527
  if (!running) return;
@@ -5512,8 +5533,9 @@ function ElementHighlight({
5512
5533
  running = false;
5513
5534
  cancelAnimationFrame(rafRef.current);
5514
5535
  };
5515
- }, [syncPositions, draggingNodeId]);
5516
- if (draggingNodeId) return null;
5536
+ }, [syncPositions]);
5537
+ if (!overlayVisible) return null;
5538
+ if (externalDragActive) return null;
5517
5539
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
5518
5540
  "div",
5519
5541
  {
@@ -5523,10 +5545,10 @@ function ElementHighlight({
5523
5545
  children: elements.map((el) => {
5524
5546
  if (el.nodeId === draggingNodeId) return null;
5525
5547
  if (activeEl && activeEl !== el.element && activeEl.contains(el.element)) return null;
5526
- const isHovered = el.nodeId === hoveredSelector;
5527
- const isSelected = el.nodeId === selectedSelector;
5548
+ const isSelected = el.nodeId === arrangeSelectedNodeId;
5549
+ if (!isSelected && !internalDragInProgress) return null;
5528
5550
  const rect = el.element.getBoundingClientRect();
5529
- const showLabel = isHovered || isSelected;
5551
+ const showLabel = isSelected;
5530
5552
  const labelTop = isSelected ? Math.max(0, rect.top - 20) : rect.top;
5531
5553
  const labelLeft = isSelected ? rect.left + 12 : rect.left;
5532
5554
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
@@ -5535,7 +5557,7 @@ function ElementHighlight({
5535
5557
  {
5536
5558
  "data-outline-for": el.nodeId,
5537
5559
  "data-design-mode-ui": true,
5538
- style: getOutlineStyle(rect, isSelected, isHovered, inspectorTheme),
5560
+ style: getOutlineStyle(rect, isSelected, inspectorTheme),
5539
5561
  children: isSelected && HANDLES.map((dir) => {
5540
5562
  const pos = handlePosition(dir);
5541
5563
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -5830,6 +5852,57 @@ function buildRectSlotRect(children, nodeMap, cRect, i, n, rows) {
5830
5852
  };
5831
5853
  }
5832
5854
 
5855
+ // src/client/dnd/design-mode/inserted-descendants.ts
5856
+ var NON_DRAGGABLE_DESCENDANT_TAGS = /* @__PURE__ */ new Set([
5857
+ // SVG internals — the whole <svg> is the unit; its parts must stay together.
5858
+ "svg",
5859
+ "path",
5860
+ "circle",
5861
+ "rect",
5862
+ "line",
5863
+ "polyline",
5864
+ "polygon",
5865
+ "g",
5866
+ "defs",
5867
+ "use",
5868
+ // <select>/<option>: options live inside their <select>, never standalone.
5869
+ "option",
5870
+ "optgroup",
5871
+ // Table internals: only meaningful in their <table> tree.
5872
+ "caption",
5873
+ "thead",
5874
+ "tbody",
5875
+ "tfoot",
5876
+ "tr",
5877
+ "th",
5878
+ "td",
5879
+ "col",
5880
+ "colgroup",
5881
+ // Self-closing inline atoms with no draggable surface.
5882
+ "br",
5883
+ "wbr",
5884
+ "hr",
5885
+ // Non-rendered metadata.
5886
+ "script",
5887
+ "style",
5888
+ "meta",
5889
+ "link",
5890
+ "title",
5891
+ "noscript",
5892
+ // Replaced media controls handled by their parent player.
5893
+ "source",
5894
+ "track"
5895
+ ]);
5896
+ function markInsertedDescendants(root) {
5897
+ const descendants = root.querySelectorAll("*");
5898
+ for (const node of descendants) {
5899
+ const tag = node.tagName.toLowerCase();
5900
+ if (NON_DRAGGABLE_DESCENDANT_TAGS.has(tag)) continue;
5901
+ node.setAttribute("data-dnd-force-allow", "");
5902
+ node.setAttribute("data-dnd-moved", "");
5903
+ }
5904
+ }
5905
+
5833
5906
  // src/client/dnd/design-mode/history.ts
5834
5907
  function applyInsertCommand(command, direction, resolveNodeElement) {
5835
5908
  if (direction === "undo") {
@@ -5852,6 +5925,7 @@ function applyInsertCommand(command, direction, resolveNodeElement) {
5852
5925
  (c) => c instanceof HTMLElement
5853
5926
  );
5854
5927
  container.insertBefore(newEl, kids[command.index] ?? null);
5928
+ markInsertedDescendants(newEl);
5855
5929
  return true;
5856
5930
  }
5857
5931
  var DEFAULT_LIMIT = 300;
@@ -6377,6 +6451,8 @@ function serializeArrangeChange(event, index) {
6377
6451
  containerId: event.kind === "insert" ? event.containerId : void 0,
6378
6452
  containerNodeKey: event.kind === "insert" ? event.containerNodeKey : void 0,
6379
6453
  insertIndex: event.kind === "insert" ? event.index : void 0,
6454
+ beforeSiblingInspectorRef: event.kind === "insert" ? event.beforeSiblingInspectorRef : void 0,
6455
+ beforeSiblingNodeKey: event.kind === "insert" ? event.beforeSiblingNodeKey : void 0,
6380
6456
  summary: summarizeEditorChangeEvent(event),
6381
6457
  at: event.at
6382
6458
  };
@@ -6674,50 +6750,8 @@ function useOverlayRefs(undoRequestId, redoRequestId) {
6674
6750
  }), []);
6675
6751
  }
6676
6752
 
6677
- // src/client/dnd/design-mode/useHoverDetection.ts
6678
- var import_react12 = require("react");
6679
- function useHoverDetection({
6680
- enabled,
6681
- activeDrag,
6682
- elementsRef,
6683
- setHovered
6684
- }) {
6685
- (0, import_react12.useEffect)(() => {
6686
- if (!enabled) {
6687
- setHovered(null);
6688
- return;
6689
- }
6690
- let lastNodeId = null;
6691
- const fn = (e) => {
6692
- if (activeDrag) return;
6693
- let best = null;
6694
- let bestArea = Infinity;
6695
- for (const sc of elementsRef.current) {
6696
- const r = sc.rect;
6697
- if (e.clientX >= r.left && e.clientX <= r.right && e.clientY >= r.top && e.clientY <= r.bottom) {
6698
- const a = r.width * r.height;
6699
- if (a < bestArea) {
6700
- bestArea = a;
6701
- best = sc;
6702
- }
6703
- }
6704
- }
6705
- const nodeId = best?.nodeId ?? null;
6706
- if (nodeId !== lastNodeId) {
6707
- lastNodeId = nodeId;
6708
- setHovered(nodeId);
6709
- }
6710
- };
6711
- document.addEventListener("mousemove", fn);
6712
- return () => {
6713
- document.removeEventListener("mousemove", fn);
6714
- setHovered(null);
6715
- };
6716
- }, [enabled, setHovered, activeDrag]);
6717
- }
6718
-
6719
6753
  // src/client/dnd/design-mode/useDragVisualLoop.ts
6720
- var import_react13 = require("react");
6754
+ var import_react12 = require("react");
6721
6755
 
6722
6756
  // src/client/dnd/design-mode/quadtree.ts
6723
6757
  function overlaps(a, b) {
@@ -7606,7 +7640,7 @@ function useDragVisualLoop({
7606
7640
  setInsideRect,
7607
7641
  setDropLine
7608
7642
  }) {
7609
- (0, import_react13.useEffect)(() => {
7643
+ (0, import_react12.useEffect)(() => {
7610
7644
  const engine = refs.engineRef.current;
7611
7645
  const snapshot = refs.snapshotRef.current;
7612
7646
  if (!activeDrag || !engine || !snapshot) return;
@@ -7836,7 +7870,7 @@ function useDragVisualLoop({
7836
7870
  }
7837
7871
 
7838
7872
  // src/client/dnd/design-mode/useDragLifecycle.ts
7839
- var import_react14 = require("react");
7873
+ var import_react13 = require("react");
7840
7874
  function buildRuntimeIdentityLocal(nodeId, resolveNodeElement, effectiveLaneSnapshot) {
7841
7875
  if (!nodeId) return null;
7842
7876
  const element = resolveNodeElement(nodeId);
@@ -8021,8 +8055,8 @@ function useDragLifecycle({
8021
8055
  setInsideRect,
8022
8056
  setDropLine
8023
8057
  }) {
8024
- const [activeDrag, setActiveDrag] = (0, import_react14.useState)(null);
8025
- const clearDragState = (0, import_react14.useCallback)(() => {
8058
+ const [activeDrag, setActiveDrag] = (0, import_react13.useState)(null);
8059
+ const clearDragState = (0, import_react13.useCallback)(() => {
8026
8060
  refs.animatorRef.current.clear();
8027
8061
  const activeEl = refs.activeElRef.current;
8028
8062
  refs.activeElRef.current = null;
@@ -8049,7 +8083,7 @@ function useDragLifecycle({
8049
8083
  setActiveDrag(null);
8050
8084
  resume();
8051
8085
  }, [clearCommitLaneCache, resume]);
8052
- const classifyCommandType = (0, import_react14.useCallback)((from, to, isNest) => {
8086
+ const classifyCommandType = (0, import_react13.useCallback)((from, to, isNest) => {
8053
8087
  if (isNest) return "nest";
8054
8088
  if (from.parentNodeId === to.parentNodeId) return "reorder";
8055
8089
  if (from.parentNodeId) {
@@ -8059,7 +8093,7 @@ function useDragLifecycle({
8059
8093
  }
8060
8094
  return "moveCrossContainer";
8061
8095
  }, [resolveNodeElement]);
8062
- const handleDragStart = (0, import_react14.useCallback)(({ active }) => {
8096
+ const handleDragStart = (0, import_react13.useCallback)(({ active }) => {
8063
8097
  if (refs.resizeSessionRef.current || Date.now() < refs.resizeDragBlockUntilRef.current) return;
8064
8098
  const activeId = active.id;
8065
8099
  const found = refs.draggableNodeMapRef.current.get(activeId) ?? refs.nodeMapRef.current.get(activeId);
@@ -8115,7 +8149,7 @@ function useDragLifecycle({
8115
8149
  element: anchorScanned.element
8116
8150
  });
8117
8151
  }, [clearCommitLaneCache, getCommitLaneSnapshot, getCurrentCommitPlacement, pause, selectElement]);
8118
- const handleDragEnd = (0, import_react14.useCallback)(({ active }) => {
8152
+ const handleDragEnd = (0, import_react13.useCallback)(({ active }) => {
8119
8153
  const activeEl = refs.activeElRef.current;
8120
8154
  const fallbackActiveId = active.id;
8121
8155
  const dragSession = refs.dragSessionAnchorRef.current;
@@ -8221,14 +8255,14 @@ function useDragLifecycle({
8221
8255
  clearDragState();
8222
8256
  syncHistoryAvailability();
8223
8257
  }, [applyCommand, classifyCommandType, clearDragState, getCurrentCommitPlacement, recordMoveChange, resolveNodeElement, selectElement, syncHistoryAvailability]);
8224
- const handleDragCancel = (0, import_react14.useCallback)(() => {
8258
+ const handleDragCancel = (0, import_react13.useCallback)(() => {
8225
8259
  clearDragState();
8226
8260
  }, [clearDragState]);
8227
8261
  return { activeDrag, handleDragStart, handleDragEnd, handleDragCancel };
8228
8262
  }
8229
8263
 
8230
8264
  // src/client/dnd/design-mode/useResizeSession.ts
8231
- var import_react15 = require("react");
8265
+ var import_react14 = require("react");
8232
8266
  var RESIZE_POINTER_TOLERANCE_PX = 2;
8233
8267
  var RESIZE_DRAG_BLOCK_MS = 180;
8234
8268
  var RESIZE_MIN = 24;
@@ -8239,7 +8273,7 @@ function useResizeSession({
8239
8273
  recordResizeChange,
8240
8274
  syncHistoryAvailability
8241
8275
  }) {
8242
- const handleResizeHandlePointerDown = (0, import_react15.useCallback)((e, nodeId, dir) => {
8276
+ const handleResizeHandlePointerDown = (0, import_react14.useCallback)((e, nodeId, dir) => {
8243
8277
  if (refs.resizeSessionRef.current) return;
8244
8278
  const selectedEl = refs.nodeMapRef.current.get(nodeId)?.element ?? document.querySelector(`[data-dnd-node-id="${nodeId}"]`);
8245
8279
  if (!selectedEl) return;
@@ -8285,7 +8319,7 @@ function useResizeSession({
8285
8319
  };
8286
8320
  pointerTarget?.setPointerCapture?.(e.pointerId);
8287
8321
  }, []);
8288
- const handleResizePointerMove = (0, import_react15.useCallback)((e) => {
8322
+ const handleResizePointerMove = (0, import_react14.useCallback)((e) => {
8289
8323
  const session = refs.resizeSessionRef.current;
8290
8324
  if (!session || e.pointerId !== session.pointerId) return;
8291
8325
  const dx = e.clientX - session.startX;
@@ -8331,7 +8365,7 @@ function useResizeSession({
8331
8365
  element.style.width = `${Math.round(Math.min(newW, window.innerWidth))}px`;
8332
8366
  element.style.height = `${Math.round(Math.min(newH, window.innerHeight))}px`;
8333
8367
  }, []);
8334
- const handleResizePointerUp = (0, import_react15.useCallback)((e) => {
8368
+ const handleResizePointerUp = (0, import_react14.useCallback)((e) => {
8335
8369
  const session = refs.resizeSessionRef.current;
8336
8370
  if (!session || e.pointerId !== session.pointerId) return;
8337
8371
  refs.resizeSessionRef.current = null;
@@ -8400,7 +8434,7 @@ function useResizeSession({
8400
8434
  });
8401
8435
  syncHistoryAvailability();
8402
8436
  }, [applyCommand, recordResizeChange, syncHistoryAvailability]);
8403
- (0, import_react15.useEffect)(() => {
8437
+ (0, import_react14.useEffect)(() => {
8404
8438
  if (!enabled) return;
8405
8439
  const handleResizePointerCancel = (e) => {
8406
8440
  const session = refs.resizeSessionRef.current;
@@ -8425,8 +8459,13 @@ function useResizeSession({
8425
8459
  }
8426
8460
 
8427
8461
  // src/client/dnd/design-mode/useExternalDragLoop.ts
8428
- var import_react16 = require("react");
8462
+ var import_react15 = require("react");
8429
8463
  var EXTERNAL_DRAG_ACTIVE_ID = "__external-drag-placeholder__";
8464
+ var insertNodeIdCounter = 0;
8465
+ function nextInsertNodeId() {
8466
+ insertNodeIdCounter += 1;
8467
+ return `insert:${Date.now()}:${insertNodeIdCounter}`;
8468
+ }
8430
8469
  function useExternalDragLoop({
8431
8470
  externalDrag,
8432
8471
  refs,
@@ -8434,9 +8473,9 @@ function useExternalDragLoop({
8434
8473
  resolveNodeElement,
8435
8474
  setDropLine
8436
8475
  }) {
8437
- const engineRef = (0, import_react16.useRef)(null);
8438
- const lastIntentRef = (0, import_react16.useRef)(null);
8439
- (0, import_react16.useEffect)(() => {
8476
+ const engineRef = (0, import_react15.useRef)(null);
8477
+ const lastIntentRef = (0, import_react15.useRef)(null);
8478
+ (0, import_react15.useEffect)(() => {
8440
8479
  if (!externalDrag) {
8441
8480
  engineRef.current = null;
8442
8481
  lastIntentRef.current = null;
@@ -8526,7 +8565,7 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
8526
8565
  setDropLine(null);
8527
8566
  return;
8528
8567
  }
8529
- const nodeId = `insert:${Date.now()}`;
8568
+ const nodeId = nextInsertNodeId();
8530
8569
  newElement.setAttribute(DND_NODE_ID_ATTR, nodeId);
8531
8570
  newElement.setAttribute("data-dnd-force-allow", "");
8532
8571
  newElement.setAttribute("data-dnd-moved", "");
@@ -8535,6 +8574,23 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
8535
8574
  );
8536
8575
  const beforeChild = children[intent.index] ?? null;
8537
8576
  containerEl.insertBefore(newElement, beforeChild);
8577
+ markInsertedDescendants(newElement);
8578
+ const postInsertChildren = Array.from(containerEl.children).filter(
8579
+ (child) => child instanceof HTMLElement
8580
+ );
8581
+ let beforeSiblingEl = null;
8582
+ let beforeSiblingNodeId = null;
8583
+ const startIdx = postInsertChildren.indexOf(newElement) + 1;
8584
+ for (let i = startIdx; i < postInsertChildren.length; i += 1) {
8585
+ const candidate = postInsertChildren[i];
8586
+ const candidateNodeId = candidate.getAttribute(DND_NODE_ID_ATTR);
8587
+ if (!candidateNodeId) continue;
8588
+ const isEarlierInsert = candidateNodeId.startsWith("insert:");
8589
+ if (!isEarlierInsert && !getInspectorRefFromElement(candidate)) continue;
8590
+ beforeSiblingEl = candidate;
8591
+ beforeSiblingNodeId = candidateNodeId;
8592
+ break;
8593
+ }
8538
8594
  const insertCommand = {
8539
8595
  type: "insert",
8540
8596
  nodeId,
@@ -8560,6 +8616,15 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
8560
8616
  inspectorRef: getInspectorRefFromElement(containerEl)
8561
8617
  };
8562
8618
  }
8619
+ let beforeSiblingIdentity = null;
8620
+ if (beforeSiblingEl && beforeSiblingNodeId) {
8621
+ beforeSiblingIdentity = {
8622
+ nodeId: beforeSiblingNodeId,
8623
+ nodeKey: getNodeKeyFromElement(beforeSiblingEl),
8624
+ selector: buildNodeSelector(beforeSiblingNodeId),
8625
+ inspectorRef: getInspectorRefFromElement(beforeSiblingEl)
8626
+ };
8627
+ }
8563
8628
  const operationId = `${insertCommand.at}:${nodeId}`;
8564
8629
  useDesignModeStore.getState().recordInsertChange({
8565
8630
  operationId,
@@ -8568,9 +8633,13 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
8568
8633
  inspectorRef,
8569
8634
  displayName: component.displayName,
8570
8635
  html: component.html,
8636
+ tsxCode: component.tsxCode ?? null,
8637
+ tsxImports: component.tsxImports ?? null,
8571
8638
  containerId: intent.containerId,
8572
8639
  containerNodeKey,
8573
- index: intent.index
8640
+ index: intent.index,
8641
+ beforeSiblingInspectorRef: beforeSiblingIdentity?.inspectorRef ?? null,
8642
+ beforeSiblingNodeKey: beforeSiblingIdentity?.nodeKey ?? null
8574
8643
  });
8575
8644
  dispatchRuntimeEvent({
8576
8645
  type: "element-inserted",
@@ -8579,8 +8648,11 @@ function commitExternalDrop(x, y, engine, component, refs, resolveNodeElement, s
8579
8648
  nodeKey,
8580
8649
  displayName: component.displayName,
8581
8650
  html: component.html,
8651
+ tsxCode: component.tsxCode ?? null,
8652
+ tsxImports: component.tsxImports ?? null,
8582
8653
  container: containerIdentity,
8583
- index: intent.index
8654
+ index: intent.index,
8655
+ beforeSibling: beforeSiblingIdentity
8584
8656
  });
8585
8657
  }
8586
8658
  setDropLine(null);
@@ -8631,12 +8703,16 @@ function HitArea({
8631
8703
  selectedNodeId,
8632
8704
  onResizeHandlePointerDown
8633
8705
  }) {
8634
- const { setNodeRef, listeners, attributes, isDragging } = useDraggable({ id: scanned.nodeId });
8635
- (0, import_react17.useEffect)(() => {
8706
+ const isSelected = scanned.nodeId === selectedNodeId;
8707
+ const { setNodeRef, listeners, attributes, isDragging } = useDraggable({
8708
+ id: scanned.nodeId,
8709
+ disabled: !isSelected
8710
+ });
8711
+ (0, import_react16.useEffect)(() => {
8636
8712
  setNodeRef(scanned.element);
8637
8713
  return () => setNodeRef(null);
8638
8714
  }, [setNodeRef, scanned.element]);
8639
- (0, import_react17.useLayoutEffect)(() => {
8715
+ (0, import_react16.useLayoutEffect)(() => {
8640
8716
  const el = scanned.element;
8641
8717
  if (isDragging) {
8642
8718
  el.style.opacity = "0";
@@ -8644,16 +8720,26 @@ function HitArea({
8644
8720
  el.style.removeProperty("opacity");
8645
8721
  }
8646
8722
  }, [isDragging, scanned.element]);
8647
- (0, import_react17.useEffect)(() => () => {
8723
+ (0, import_react16.useEffect)(() => () => {
8648
8724
  scanned.element.style.removeProperty("opacity");
8649
8725
  scanned.element.style.removeProperty("transform");
8650
8726
  scanned.element.style.removeProperty("transition");
8651
8727
  scanned.element.style.removeProperty("will-change");
8652
8728
  }, [scanned.element]);
8653
- const divRef = (0, import_react17.useRef)(null);
8654
- const [hoverResizeHandle, setHoverResizeHandle] = (0, import_react17.useState)(null);
8655
- const isSelected = scanned.nodeId === selectedNodeId;
8656
- (0, import_react17.useEffect)(() => {
8729
+ const divRef = (0, import_react16.useRef)(null);
8730
+ const [hoverResizeHandle, setHoverResizeHandle] = (0, import_react16.useState)(null);
8731
+ const justDraggedRef = (0, import_react16.useRef)(false);
8732
+ (0, import_react16.useEffect)(() => {
8733
+ if (isDragging) {
8734
+ justDraggedRef.current = true;
8735
+ return;
8736
+ }
8737
+ const id = window.setTimeout(() => {
8738
+ justDraggedRef.current = false;
8739
+ }, 0);
8740
+ return () => window.clearTimeout(id);
8741
+ }, [isDragging]);
8742
+ (0, import_react16.useEffect)(() => {
8657
8743
  const div = divRef.current;
8658
8744
  if (!div) return;
8659
8745
  const onWheel = (e) => {
@@ -8669,7 +8755,7 @@ function HitArea({
8669
8755
  return () => div.removeEventListener("wheel", onWheel);
8670
8756
  }, []);
8671
8757
  const { left, top, width, height } = scanned.rect;
8672
- const cursor = isDragging ? "grabbing" : isSelected && hoverResizeHandle ? resizeCursorFromHandle(hoverResizeHandle) : "grab";
8758
+ const cursor = isDragging ? "grabbing" : !isSelected ? "default" : hoverResizeHandle ? resizeCursorFromHandle(hoverResizeHandle) : "grab";
8673
8759
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8674
8760
  "div",
8675
8761
  {
@@ -8700,6 +8786,35 @@ function HitArea({
8700
8786
  ...attributes,
8701
8787
  ...listeners,
8702
8788
  onClick: (e) => {
8789
+ if (justDraggedRef.current) {
8790
+ e.preventDefault();
8791
+ e.stopPropagation();
8792
+ return;
8793
+ }
8794
+ const stack = document.elementsFromPoint(e.clientX, e.clientY);
8795
+ for (const candidate of stack) {
8796
+ if (!(candidate instanceof HTMLElement)) continue;
8797
+ if (candidate.hasAttribute("data-design-mode-ui")) continue;
8798
+ if (candidate === scanned.element) break;
8799
+ const candidateNodeId = candidate.getAttribute("data-dnd-node-id");
8800
+ if (candidateNodeId && candidateNodeId !== scanned.nodeId) {
8801
+ e.preventDefault();
8802
+ e.stopPropagation();
8803
+ candidate.dispatchEvent(
8804
+ new MouseEvent("mousedown", {
8805
+ bubbles: true,
8806
+ cancelable: true,
8807
+ clientX: e.clientX,
8808
+ clientY: e.clientY,
8809
+ metaKey: e.metaKey,
8810
+ ctrlKey: e.ctrlKey,
8811
+ shiftKey: e.shiftKey,
8812
+ altKey: e.altKey
8813
+ })
8814
+ );
8815
+ return;
8816
+ }
8817
+ }
8703
8818
  e.preventDefault();
8704
8819
  e.stopPropagation();
8705
8820
  onActivate(scanned.nodeId);
@@ -8710,9 +8825,11 @@ function HitArea({
8710
8825
  function DesignModeOverlay() {
8711
8826
  const enabled = useDesignModeStore((s) => s.enabled);
8712
8827
  const historyMode = useDesignModeStore((s) => s.historyMode);
8713
- const setHovered = useDesignModeStore((s) => s.setHovered);
8714
8828
  const selectElement = useDesignModeStore((s) => s.setSelected);
8715
- const selectedSelector = useDesignModeStore((s) => s.selectedSelector);
8829
+ const inspectorSelectedNodeIds = useDesignModeStore(
8830
+ (s) => s.inspectorSelectedNodeIds
8831
+ );
8832
+ const arrangeSelectedNodeId = inspectorSelectedNodeIds.length === 1 ? inspectorSelectedNodeIds[0] : null;
8716
8833
  const setHistoryAvailability = useDesignModeStore((s) => s.setHistoryAvailability);
8717
8834
  const undoRequestId = useDesignModeStore((s) => s.undoRequestId);
8718
8835
  const redoRequestId = useDesignModeStore((s) => s.redoRequestId);
@@ -8726,55 +8843,63 @@ function DesignModeOverlay() {
8726
8843
  const exportChangesForAI = useDesignModeStore((s) => s.exportChangesForAI);
8727
8844
  const externalDrag = useDesignModeStore((s) => s.externalDrag);
8728
8845
  const { elements, pause, resume } = useElementScanner(enabled);
8729
- const nodeMap = (0, import_react17.useMemo)(() => {
8846
+ const nodeMap = (0, import_react16.useMemo)(() => {
8730
8847
  const m = /* @__PURE__ */ new Map();
8731
8848
  for (const el of elements) m.set(el.nodeId, el);
8732
8849
  return m;
8733
8850
  }, [elements]);
8734
- const draggableElements = (0, import_react17.useMemo)(() => {
8851
+ const draggableElements = (0, import_react16.useMemo)(() => {
8735
8852
  if (elements.length === 0) return [];
8736
8853
  const projection = buildProjection(elements);
8737
8854
  return collectDraggableAnchors(elements, projection, nodeMap).filter(
8738
8855
  (el) => el.draggable !== false
8739
8856
  );
8740
8857
  }, [elements, nodeMap]);
8858
+ const arrangeHitAreaElement = (0, import_react16.useMemo)(() => {
8859
+ if (!arrangeSelectedNodeId) return null;
8860
+ if (externalDrag) return null;
8861
+ return draggableElements.find(
8862
+ (candidate) => candidate.nodeId === arrangeSelectedNodeId
8863
+ ) ?? null;
8864
+ }, [arrangeSelectedNodeId, externalDrag, draggableElements]);
8741
8865
  const refs = useOverlayRefs(undoRequestId, redoRequestId);
8742
8866
  refs.elementsRef.current = elements;
8743
8867
  refs.nodeMapRef.current = nodeMap;
8744
- (0, import_react17.useEffect)(() => {
8868
+ (0, import_react16.useEffect)(() => {
8745
8869
  const m = /* @__PURE__ */ new Map();
8746
8870
  for (const el of draggableElements) m.set(el.nodeId, el);
8747
8871
  refs.draggableNodeMapRef.current = m;
8748
8872
  }, [draggableElements]);
8749
- const [grabFeedback, setGrabFeedback] = (0, import_react17.useState)(null);
8750
- (0, import_react17.useEffect)(() => {
8873
+ const [grabFeedback, setGrabFeedback] = (0, import_react16.useState)(null);
8874
+ (0, import_react16.useEffect)(() => {
8751
8875
  if (!enabled) return;
8752
8876
  const onPointerDown = (e) => {
8753
- const scanned = resolveGrabFeedbackTarget(
8877
+ if (!shouldShowGrabFeedback(
8754
8878
  e.target,
8755
8879
  refs.nodeMapRef.current
8756
- );
8757
- if (!scanned) return;
8880
+ )) {
8881
+ return;
8882
+ }
8758
8883
  setGrabFeedback({ x: e.clientX, y: e.clientY, at: Date.now() });
8759
8884
  };
8760
8885
  document.addEventListener("pointerdown", onPointerDown, true);
8761
8886
  return () => document.removeEventListener("pointerdown", onPointerDown, true);
8762
8887
  }, [enabled]);
8763
- (0, import_react17.useEffect)(() => {
8888
+ (0, import_react16.useEffect)(() => {
8764
8889
  if (!grabFeedback) return;
8765
8890
  const t = setTimeout(() => setGrabFeedback(null), 1400);
8766
8891
  return () => clearTimeout(t);
8767
8892
  }, [grabFeedback]);
8768
- const resolveNodeElement = (0, import_react17.useCallback)((nodeId) => {
8893
+ const resolveNodeElement = (0, import_react16.useCallback)((nodeId) => {
8769
8894
  const known = refs.nodeMapRef.current.get(nodeId)?.element;
8770
8895
  if (known) return known;
8771
8896
  return document.querySelector(buildNodeSelector(nodeId));
8772
8897
  }, []);
8773
- const clearCommitLaneCache = (0, import_react17.useCallback)(() => {
8898
+ const clearCommitLaneCache = (0, import_react16.useCallback)(() => {
8774
8899
  refs.commitLaneCacheRef.current.clear();
8775
8900
  refs.sourceCommitLaneRef.current = null;
8776
8901
  }, []);
8777
- const getCommitLaneSnapshot = (0, import_react17.useCallback)((laneContainerId) => {
8902
+ const getCommitLaneSnapshot = (0, import_react16.useCallback)((laneContainerId) => {
8778
8903
  if (!laneContainerId) return null;
8779
8904
  if (refs.commitLaneCacheRef.current.has(laneContainerId)) {
8780
8905
  return refs.commitLaneCacheRef.current.get(laneContainerId) ?? null;
@@ -8783,11 +8908,11 @@ function DesignModeOverlay() {
8783
8908
  refs.commitLaneCacheRef.current.set(laneContainerId, snapshot);
8784
8909
  return snapshot;
8785
8910
  }, []);
8786
- const getCurrentCommitPlacement = (0, import_react17.useCallback)((anchorNodeId, laneContainerId) => {
8911
+ const getCurrentCommitPlacement = (0, import_react16.useCallback)((anchorNodeId, laneContainerId) => {
8787
8912
  const lane = getCommitLaneSnapshot(laneContainerId);
8788
8913
  return resolveCurrentCommitPlacement(lane, anchorNodeId);
8789
8914
  }, [getCommitLaneSnapshot]);
8790
- const applyCommand = (0, import_react17.useCallback)((command, direction) => {
8915
+ const applyCommand = (0, import_react16.useCallback)((command, direction) => {
8791
8916
  if (command.type === "resize") {
8792
8917
  const resCmd = command;
8793
8918
  const targetId = resCmd.targetNodeId ?? resCmd.nodeId;
@@ -8810,28 +8935,28 @@ function DesignModeOverlay() {
8810
8935
  clearCommitLaneCache();
8811
8936
  return true;
8812
8937
  }, [clearCommitLaneCache, resolveNodeElement]);
8813
- const syncHistoryAvailability = (0, import_react17.useCallback)(() => {
8938
+ const syncHistoryAvailability = (0, import_react16.useCallback)(() => {
8814
8939
  if (historyMode === "host") {
8815
8940
  setHistoryAvailability(false, false);
8816
8941
  return;
8817
8942
  }
8818
8943
  setHistoryAvailability(refs.historyRef.current.canUndo(), refs.historyRef.current.canRedo());
8819
8944
  }, [historyMode, setHistoryAvailability]);
8820
- (0, import_react17.useEffect)(() => {
8945
+ (0, import_react16.useEffect)(() => {
8821
8946
  refs.historyRef.current.clear();
8822
8947
  syncHistoryAvailability();
8823
8948
  }, [enabled, syncHistoryAvailability]);
8824
8949
  const sensors = useSensors(
8825
8950
  useSensor(PointerSensor, { activationConstraint: { distance: 8 } })
8826
8951
  );
8827
- const collisionDetection = (0, import_react17.useCallback)(
8952
+ const collisionDetection = (0, import_react16.useCallback)(
8828
8953
  (args) => createDesignModeCollisionDetection(refs.blockedContainerIdsRef.current)(args),
8829
8954
  []
8830
8955
  // eslint-disable-line react-hooks/exhaustive-deps -- refs are stable
8831
8956
  );
8832
- const [insideRect, setInsideRect] = (0, import_react17.useState)(null);
8833
- const [dropLine, setDropLine] = (0, import_react17.useState)(null);
8834
- (0, import_react17.useEffect)(() => {
8957
+ const [insideRect, setInsideRect] = (0, import_react16.useState)(null);
8958
+ const [dropLine, setDropLine] = (0, import_react16.useState)(null);
8959
+ (0, import_react16.useEffect)(() => {
8835
8960
  if (!enabled) return;
8836
8961
  const fn = (e) => {
8837
8962
  refs.mouseRef.current = { x: e.clientX, y: e.clientY };
@@ -8839,7 +8964,7 @@ function DesignModeOverlay() {
8839
8964
  window.addEventListener("pointermove", fn, { capture: true, passive: true });
8840
8965
  return () => window.removeEventListener("pointermove", fn, { capture: true });
8841
8966
  }, [enabled]);
8842
- (0, import_react17.useEffect)(() => {
8967
+ (0, import_react16.useEffect)(() => {
8843
8968
  if (!enabled) return;
8844
8969
  if (historyMode !== "local") return;
8845
8970
  const onKeyDown = (e) => {
@@ -8868,7 +8993,7 @@ function DesignModeOverlay() {
8868
8993
  setInsideRect,
8869
8994
  setDropLine
8870
8995
  });
8871
- (0, import_react17.useEffect)(() => {
8996
+ (0, import_react16.useEffect)(() => {
8872
8997
  if (!enabled || activeDrag) return;
8873
8998
  if (undoRequestId === refs.processedUndoIdRef.current) return;
8874
8999
  refs.processedUndoIdRef.current = undoRequestId;
@@ -8885,7 +9010,7 @@ function DesignModeOverlay() {
8885
9010
  });
8886
9011
  syncHistoryAvailability();
8887
9012
  }, [undoRequestId, enabled, activeDrag, applyCommand, resume, selectElement, syncHistoryAvailability, undoLastChange]);
8888
- (0, import_react17.useEffect)(() => {
9013
+ (0, import_react16.useEffect)(() => {
8889
9014
  if (!enabled || activeDrag || historyMode !== "local") return;
8890
9015
  if (redoRequestId === refs.processedRedoIdRef.current) return;
8891
9016
  refs.processedRedoIdRef.current = redoRequestId;
@@ -8897,18 +9022,18 @@ function DesignModeOverlay() {
8897
9022
  }
8898
9023
  syncHistoryAvailability();
8899
9024
  }, [redoRequestId, enabled, activeDrag, applyCommand, historyMode, resume, selectElement, syncHistoryAvailability, redoLastChange]);
8900
- (0, import_react17.useEffect)(() => {
9025
+ (0, import_react16.useEffect)(() => {
8901
9026
  syncHistoryAvailability();
8902
9027
  }, [syncHistoryAvailability]);
8903
- (0, import_react17.useEffect)(() => {
9028
+ (0, import_react16.useEffect)(() => {
8904
9029
  dispatchRuntimeEvent({
8905
9030
  type: "design-mode-changed",
8906
9031
  mode: enabled ? "design" : "off"
8907
9032
  });
8908
9033
  }, [enabled]);
8909
- (0, import_react17.useEffect)(() => {
9034
+ (0, import_react16.useEffect)(() => {
8910
9035
  const aiOutput = exportChangesForAI();
8911
- const updatedAt = orderedChanges.length > 0 ? orderedChanges[orderedChanges.length - 1]?.at ?? Date.now() : Date.now();
9036
+ const updatedAt = Date.now();
8912
9037
  dispatchRuntimeEvent({
8913
9038
  type: "arrange-session-changed",
8914
9039
  session: buildArrangeSessionSnapshot({
@@ -8919,12 +9044,11 @@ function DesignModeOverlay() {
8919
9044
  })
8920
9045
  });
8921
9046
  }, [enabled, exportChangesForAI, orderedChanges]);
8922
- (0, import_react17.useEffect)(() => {
9047
+ (0, import_react16.useEffect)(() => {
8923
9048
  if (!enabled) return;
8924
9049
  document.body.classList.add("design-mode-active");
8925
9050
  return () => document.body.classList.remove("design-mode-active");
8926
9051
  }, [enabled]);
8927
- useHoverDetection({ enabled, activeDrag, elementsRef: refs.elementsRef, setHovered });
8928
9052
  useDesignModeAutoScroll({
8929
9053
  active: !!activeDrag,
8930
9054
  mouseRef: refs.mouseRef,
@@ -8963,19 +9087,21 @@ function DesignModeOverlay() {
8963
9087
  elements,
8964
9088
  draggingNodeId: activeDrag?.nodeId ?? null,
8965
9089
  activeEl: refs.activeElRef.current,
9090
+ arrangeSelectedNodeId,
9091
+ externalDragActive: externalDrag !== null,
8966
9092
  onResizeHandlePointerDown: handleResizeHandlePointerDown
8967
9093
  }
8968
9094
  ),
8969
- draggableElements.map((el) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
9095
+ arrangeHitAreaElement && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8970
9096
  HitArea,
8971
9097
  {
8972
- scanned: el,
9098
+ scanned: arrangeHitAreaElement,
8973
9099
  onActivate: selectElement,
8974
- selectedNodeId: selectedSelector,
9100
+ selectedNodeId: arrangeHitAreaElement.nodeId,
8975
9101
  onResizeHandlePointerDown: handleResizeHandlePointerDown
8976
9102
  },
8977
- el.nodeId
8978
- )),
9103
+ arrangeHitAreaElement.nodeId
9104
+ ),
8979
9105
  grabFeedback ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8980
9106
  "div",
8981
9107
  {
@@ -9042,8 +9168,8 @@ function DesignModeOverlay() {
9042
9168
  }
9043
9169
 
9044
9170
  // src/client/dnd/design-mode/DesignModeErrorBoundary.tsx
9045
- var import_react18 = __toESM(require("react"));
9046
- var DesignModeErrorBoundary = class extends import_react18.default.Component {
9171
+ var import_react17 = __toESM(require("react"));
9172
+ var DesignModeErrorBoundary = class extends import_react17.default.Component {
9047
9173
  constructor(props) {
9048
9174
  super(props);
9049
9175
  this.state = { hasError: false };
@@ -9084,13 +9210,13 @@ function DndProvider({ children }) {
9084
9210
  const setHistoryMode = useDesignModeStore((s) => s.setHistoryMode);
9085
9211
  const setInspectorTheme = useDesignModeStore((s) => s.setInspectorTheme);
9086
9212
  const requestUndo = useDesignModeStore((s) => s.requestUndo);
9087
- const transitionDesignMode = (0, import_react19.useCallback)((nextEnabled) => {
9213
+ const transitionDesignMode = (0, import_react18.useCallback)((nextEnabled) => {
9088
9214
  const designModeState = useDesignModeStore.getState();
9089
9215
  if (designModeState.enabled === nextEnabled) return;
9090
9216
  designModeState.resetArrangeSession();
9091
9217
  designModeState.setEnabled(nextEnabled);
9092
9218
  }, []);
9093
- (0, import_react19.useEffect)(() => {
9219
+ (0, import_react18.useEffect)(() => {
9094
9220
  const handleKeyDown = (e) => {
9095
9221
  if (e.ctrlKey && e.shiftKey && e.key === "D") {
9096
9222
  e.preventDefault();
@@ -9100,7 +9226,7 @@ function DndProvider({ children }) {
9100
9226
  window.addEventListener("keydown", handleKeyDown);
9101
9227
  return () => window.removeEventListener("keydown", handleKeyDown);
9102
9228
  }, [transitionDesignMode]);
9103
- (0, import_react19.useEffect)(() => {
9229
+ (0, import_react18.useEffect)(() => {
9104
9230
  const handleHostCommand = (event) => {
9105
9231
  const detail = event.detail;
9106
9232
  if (!detail || typeof detail !== "object") return;
@@ -9159,10 +9285,29 @@ function DndProvider({ children }) {
9159
9285
  setInspectorTheme,
9160
9286
  requestUndo
9161
9287
  ]);
9288
+ (0, import_react18.useEffect)(() => {
9289
+ const bridgeWindow = window;
9290
+ const bridge = {
9291
+ setInspectorSelection: (nodeIds) => {
9292
+ useDesignModeStore.getState().setInspectorSelection(nodeIds);
9293
+ }
9294
+ };
9295
+ bridgeWindow.__ARCHIE_DESIGN_MODE__ = bridge;
9296
+ const pending = bridgeWindow.__ARCHIE_DESIGN_MODE_PENDING__;
9297
+ if (Array.isArray(pending)) {
9298
+ bridge.setInspectorSelection(pending);
9299
+ delete bridgeWindow.__ARCHIE_DESIGN_MODE_PENDING__;
9300
+ }
9301
+ return () => {
9302
+ if (bridgeWindow.__ARCHIE_DESIGN_MODE__ === bridge) {
9303
+ delete bridgeWindow.__ARCHIE_DESIGN_MODE__;
9304
+ }
9305
+ };
9306
+ }, []);
9162
9307
  const pointerSensor = useSensor(PointerSensor, { activationConstraint: { distance: 8 } });
9163
9308
  const keyboardSensor = useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates });
9164
9309
  const sensors = useSensors(pointerSensor, keyboardSensor);
9165
- const handleDragStart = (0, import_react19.useCallback)(
9310
+ const handleDragStart = (0, import_react18.useCallback)(
9166
9311
  (event) => {
9167
9312
  const { active } = event;
9168
9313
  const element = document.querySelector(`[data-canvas-node="${active.id}"]`);
@@ -9170,7 +9315,7 @@ function DndProvider({ children }) {
9170
9315
  },
9171
9316
  [setActive]
9172
9317
  );
9173
- const handleDragEnd = (0, import_react19.useCallback)(
9318
+ const handleDragEnd = (0, import_react18.useCallback)(
9174
9319
  (event) => {
9175
9320
  const { active, over } = event;
9176
9321
  const dragEndEvent = {
@@ -9186,7 +9331,7 @@ function DndProvider({ children }) {
9186
9331
  },
9187
9332
  [dragEndHandlers, setActive]
9188
9333
  );
9189
- const handleDesignModeCrash = (0, import_react19.useCallback)(() => {
9334
+ const handleDesignModeCrash = (0, import_react18.useCallback)(() => {
9190
9335
  const designModeState = useDesignModeStore.getState();
9191
9336
  designModeState.resetAll();
9192
9337
  designModeState.resetArrangeSession();
@@ -9230,13 +9375,12 @@ function DndProvider({ children }) {
9230
9375
  }
9231
9376
 
9232
9377
  // src/client/useArchieDevToolsRuntime.ts
9233
- var import_react21 = require("react");
9378
+ var import_react20 = require("react");
9234
9379
 
9235
9380
  // src/client/archieLocalInspectorEnv.ts
9236
- var import_meta = {};
9237
9381
  function readArchieLocalInspectorFlag() {
9238
9382
  try {
9239
- return import_meta.env?.VITE_ARCHIE_LOCAL_INSPECTOR === "true";
9383
+ return false;
9240
9384
  } catch {
9241
9385
  return false;
9242
9386
  }
@@ -9421,13 +9565,13 @@ function setupArchieRouteListener(router) {
9421
9565
  }
9422
9566
 
9423
9567
  // src/client/runtime/domMetaSanitizer.ts
9424
- var import_react20 = __toESM(require("react"));
9568
+ var import_react19 = __toESM(require("react"));
9425
9569
  var _installed = false;
9426
9570
  function installDomMetaSanitizer() {
9427
9571
  if (_installed) return;
9428
9572
  _installed = true;
9429
- const _origCE = import_react20.default.createElement.bind(import_react20.default);
9430
- import_react20.default.createElement = function patchedCreateElement(type, props, ...children) {
9573
+ const _origCE = import_react19.default.createElement.bind(import_react19.default);
9574
+ import_react19.default.createElement = function patchedCreateElement(type, props, ...children) {
9431
9575
  if (typeof type === "string" && props != null && "__editorMeta" in props) {
9432
9576
  const { __editorMeta: _stripped, ...rest } = props;
9433
9577
  return _origCE(type, rest, ...children);
@@ -9455,9 +9599,9 @@ function useArchieDevToolsRuntime({
9455
9599
  inspectorOptions
9456
9600
  }) {
9457
9601
  const stableOptionsKey = JSON.stringify(inspectorOptions ?? null);
9458
- const inspectorOptionsRef = (0, import_react21.useRef)(inspectorOptions);
9602
+ const inspectorOptionsRef = (0, import_react20.useRef)(inspectorOptions);
9459
9603
  inspectorOptionsRef.current = inspectorOptions;
9460
- (0, import_react21.useEffect)(() => {
9604
+ (0, import_react20.useEffect)(() => {
9461
9605
  if (process.env.NODE_ENV !== "development") {
9462
9606
  return;
9463
9607
  }