@almadar/ui 4.50.4 → 4.50.6

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.
@@ -24928,12 +24928,17 @@ function useDataDnd(args) {
24928
24928
  React93__namespace.default.useEffect(() => {
24929
24929
  setLocalOrder(null);
24930
24930
  }, [items]);
24931
+ const itemIdsSignature = orderedItems.map((it, idx) => {
24932
+ const raw = it[dndItemIdField];
24933
+ return String(raw ?? `__idx_${idx}`);
24934
+ }).join("|");
24931
24935
  const itemIds = React93__namespace.default.useMemo(
24932
24936
  () => orderedItems.map((it, idx) => {
24933
24937
  const raw = it[dndItemIdField];
24934
24938
  return raw ?? `__idx_${idx}`;
24935
24939
  }),
24936
- [orderedItems, dndItemIdField]
24940
+ // eslint-disable-next-line react-hooks/exhaustive-deps
24941
+ [itemIdsSignature]
24937
24942
  );
24938
24943
  const zonesRef = React93__namespace.default.useRef(/* @__PURE__ */ new Map());
24939
24944
  const registerZone = React93__namespace.default.useCallback((zoneId2, meta2) => {
@@ -24942,10 +24947,6 @@ function useDataDnd(args) {
24942
24947
  const unregisterZone = React93__namespace.default.useCallback((zoneId2) => {
24943
24948
  zonesRef.current.delete(zoneId2);
24944
24949
  }, []);
24945
- const [overlayNode, setOverlayNode] = React93__namespace.default.useState(null);
24946
- const setOverlay = React93__namespace.default.useCallback((node) => {
24947
- setOverlayNode(node);
24948
- }, []);
24949
24950
  const zoneId = React93__namespace.default.useId();
24950
24951
  const ownGroup = dragGroup ?? accepts ?? zoneId;
24951
24952
  const meta = React93__namespace.default.useMemo(
@@ -24956,10 +24957,18 @@ function useDataDnd(args) {
24956
24957
  const target = isRoot ? null : parentRoot;
24957
24958
  if (!target) {
24958
24959
  zonesRef.current.set(zoneId, meta);
24959
- return () => zonesRef.current.delete(zoneId);
24960
+ dndLog.debug("zone:register:self", { zoneId, group: meta.group, itemCount: meta.itemIds.length, isRoot });
24961
+ return () => {
24962
+ zonesRef.current.delete(zoneId);
24963
+ dndLog.debug("zone:unregister:self", { zoneId, group: meta.group });
24964
+ };
24960
24965
  }
24961
24966
  target.registerZone(zoneId, meta);
24962
- return () => target.unregisterZone(zoneId);
24967
+ dndLog.debug("zone:register", { zoneId, group: meta.group, itemCount: meta.itemIds.length, dropEvent: meta.dropEvent, reorderEvent: meta.reorderEvent });
24968
+ return () => {
24969
+ target.unregisterZone(zoneId);
24970
+ dndLog.debug("zone:unregister", { zoneId, group: meta.group });
24971
+ };
24963
24972
  }, [parentRoot, isRoot, zoneId, meta]);
24964
24973
  const sensors = core$1.useSensors(
24965
24974
  core$1.useSensor(core$1.PointerSensor, { activationConstraint: { distance: 5 } }),
@@ -24967,10 +24976,18 @@ function useDataDnd(args) {
24967
24976
  );
24968
24977
  const collisionDetection = React93__namespace.default.useCallback((args2) => {
24969
24978
  const pointerCollisions = core$1.pointerWithin(args2);
24970
- if (pointerCollisions.length > 0) return pointerCollisions;
24979
+ if (pointerCollisions.length > 0) {
24980
+ dndLog.debug("collision:pointerWithin", { count: pointerCollisions.length, ids: pointerCollisions.map((c) => c.id) });
24981
+ return pointerCollisions;
24982
+ }
24971
24983
  const rectCollisions = core$1.rectIntersection(args2);
24972
- if (rectCollisions.length > 0) return rectCollisions;
24973
- return core$1.closestCorners(args2);
24984
+ if (rectCollisions.length > 0) {
24985
+ dndLog.debug("collision:rectIntersection", { count: rectCollisions.length, ids: rectCollisions.map((c) => c.id) });
24986
+ return rectCollisions;
24987
+ }
24988
+ const cornerCollisions = core$1.closestCorners(args2);
24989
+ dndLog.debug("collision:closestCorners", { count: cornerCollisions.length, ids: cornerCollisions.map((c) => c.id) });
24990
+ return cornerCollisions;
24974
24991
  }, []);
24975
24992
  const findZoneByItem = React93__namespace.default.useCallback(
24976
24993
  (id) => {
@@ -24993,22 +25010,52 @@ function useDataDnd(args) {
24993
25010
  const handleDragEnd = React93__namespace.default.useCallback(
24994
25011
  (event) => {
24995
25012
  const { active, over } = event;
24996
- if (!over) return;
25013
+ const allZones = Array.from(zonesRef.current.entries()).map(([id, m]) => ({ id, group: m.group, items: m.itemIds.length }));
25014
+ dndLog.debug("dragEnd:received", {
25015
+ activeId: active.id,
25016
+ overId: over?.id,
25017
+ overData: over?.data?.current,
25018
+ zones: allZones
25019
+ });
25020
+ if (!over) {
25021
+ dndLog.warn("dragEnd:abort:no-over", { activeId: active.id, reason: "no droppable under pointer at drop time \u2192 item snaps back" });
25022
+ return;
25023
+ }
24997
25024
  const sourceZone = findZoneByItem(active.id);
24998
25025
  const overData = over.data?.current;
24999
25026
  const targetGroup = overData?.dndGroup;
25000
- if (!sourceZone || !targetGroup) return;
25027
+ dndLog.debug("dragEnd:resolved", { sourceGroup: sourceZone?.group, targetGroup, overDataKeys: overData ? Object.keys(overData) : null });
25028
+ if (!sourceZone) {
25029
+ dndLog.warn("dragEnd:abort:no-source-zone", { activeId: active.id });
25030
+ return;
25031
+ }
25032
+ if (!targetGroup) {
25033
+ dndLog.warn("dragEnd:abort:no-target-group", { overId: over.id, overData });
25034
+ return;
25035
+ }
25001
25036
  const targetZone = findZoneByGroup(targetGroup);
25002
- if (!targetZone) return;
25037
+ if (!targetZone) {
25038
+ dndLog.warn("dragEnd:abort:target-zone-not-registered", { targetGroup });
25039
+ return;
25040
+ }
25003
25041
  if (sourceZone.group !== targetZone.group) {
25004
25042
  if (targetZone.dropEvent) {
25005
25043
  const newIndex2 = targetZone.itemIds.indexOf(over.id);
25044
+ dndLog.info("dragEnd:cross-container:emit", {
25045
+ event: targetZone.dropEvent,
25046
+ id: String(active.id),
25047
+ sourceGroup: sourceZone.group,
25048
+ targetGroup: targetZone.group,
25049
+ newIndex: newIndex2 === -1 ? targetZone.itemIds.length : newIndex2
25050
+ });
25006
25051
  eventBus.emit(targetZone.dropEvent, {
25007
25052
  id: String(active.id),
25008
25053
  sourceGroup: sourceZone.group,
25009
25054
  targetGroup: targetZone.group,
25010
25055
  newIndex: newIndex2 === -1 ? targetZone.itemIds.length : newIndex2
25011
25056
  });
25057
+ } else {
25058
+ dndLog.warn("dragEnd:cross-container:no-dropEvent-on-target", { targetGroup: targetZone.group });
25012
25059
  }
25013
25060
  return;
25014
25061
  }
@@ -25020,16 +25067,24 @@ function useDataDnd(args) {
25020
25067
  setLocalOrder(reordered);
25021
25068
  }
25022
25069
  if (sourceZone.reorderEvent) {
25070
+ dndLog.info("dragEnd:reorder:emit", {
25071
+ event: sourceZone.reorderEvent,
25072
+ id: String(active.id),
25073
+ oldIndex,
25074
+ newIndex
25075
+ });
25023
25076
  eventBus.emit(sourceZone.reorderEvent, {
25024
25077
  id: String(active.id),
25025
25078
  oldIndex,
25026
25079
  newIndex
25027
25080
  });
25081
+ } else {
25082
+ dndLog.debug("dragEnd:reorder:no-reorderEvent", { sourceGroup: sourceZone.group });
25028
25083
  }
25029
25084
  },
25030
25085
  [orderedItems, ownGroup, findZoneByItem, findZoneByGroup, eventBus]
25031
25086
  );
25032
- const overlaySink = isRoot ? setOverlay : parentRoot?.setOverlay;
25087
+ const sortableData = React93__namespace.default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
25033
25088
  const SortableItem = React93__namespace.default.useCallback(
25034
25089
  ({ id, children }) => {
25035
25090
  const {
@@ -25039,19 +25094,16 @@ function useDataDnd(args) {
25039
25094
  transform,
25040
25095
  transition,
25041
25096
  isDragging
25042
- } = sortable.useSortable({ id, data: { dndGroup: ownGroup } });
25043
- const childrenRef = React93__namespace.default.useRef(children);
25044
- childrenRef.current = children;
25045
- React93__namespace.default.useEffect(() => {
25046
- if (!isDragging || !overlaySink) return;
25047
- overlaySink(childrenRef.current);
25048
- return () => overlaySink(null);
25049
- }, [isDragging]);
25097
+ } = sortable.useSortable({ id, data: sortableData });
25050
25098
  const style = {
25051
25099
  transform: utilities.CSS.Transform.toString(transform),
25052
25100
  transition,
25053
25101
  opacity: isDragging ? 0.4 : 1,
25054
- cursor: enabled ? "grab" : void 0
25102
+ cursor: enabled ? "grab" : void 0,
25103
+ // Lift the dragged element above siblings so its visual movement
25104
+ // isn't hidden behind other cards / column boundaries.
25105
+ zIndex: isDragging ? 50 : void 0,
25106
+ position: isDragging ? "relative" : void 0
25055
25107
  };
25056
25108
  return /* @__PURE__ */ jsxRuntime.jsx(
25057
25109
  Box,
@@ -25065,73 +25117,91 @@ function useDataDnd(args) {
25065
25117
  }
25066
25118
  );
25067
25119
  },
25068
- [ownGroup, enabled, overlaySink]
25120
+ [sortableData, enabled]
25069
25121
  );
25070
25122
  const DropZoneShell = ({ children }) => {
25123
+ const droppableId = `dnd-zone-${zoneId}`;
25071
25124
  const { setNodeRef, isOver } = core$1.useDroppable({
25072
- id: `dnd-zone-${zoneId}`,
25073
- data: { dndGroup: ownGroup }
25125
+ id: droppableId,
25126
+ data: sortableData
25074
25127
  });
25128
+ React93__namespace.default.useEffect(() => {
25129
+ dndLog.debug("dropzone:isOver:change", { droppableId, group: ownGroup, isOver });
25130
+ }, [droppableId, isOver]);
25075
25131
  return /* @__PURE__ */ jsxRuntime.jsx(
25076
25132
  Box,
25077
25133
  {
25078
25134
  ref: setNodeRef,
25079
25135
  "data-dnd-zone": ownGroup,
25136
+ "data-dnd-is-over": isOver ? "true" : "false",
25080
25137
  className: isOver ? "ring-2 ring-primary ring-offset-2 rounded-lg transition-all min-h-[3rem]" : "min-h-[3rem] rounded-lg transition-all",
25081
25138
  children
25082
25139
  }
25083
25140
  );
25084
25141
  };
25085
25142
  const rootContextValue = React93__namespace.default.useMemo(
25086
- () => ({ registerZone, unregisterZone, setOverlay }),
25087
- [registerZone, unregisterZone, setOverlay]
25143
+ () => ({ registerZone, unregisterZone }),
25144
+ [registerZone, unregisterZone]
25088
25145
  );
25146
+ const handleDragStart = React93__namespace.default.useCallback((event) => {
25147
+ const sourceZone = findZoneByItem(event.active.id);
25148
+ dndLog.info("dragStart", {
25149
+ activeId: event.active.id,
25150
+ activeData: event.active.data?.current,
25151
+ sourceGroup: sourceZone?.group,
25152
+ zoneCount: zonesRef.current.size
25153
+ });
25154
+ }, [findZoneByItem]);
25155
+ const handleDragOver = React93__namespace.default.useCallback((event) => {
25156
+ dndLog.debug("dragOver", {
25157
+ activeId: event.active.id,
25158
+ overId: event.over?.id,
25159
+ overData: event.over?.data?.current
25160
+ });
25161
+ }, []);
25162
+ const handleDragCancel = React93__namespace.default.useCallback((event) => {
25163
+ dndLog.warn("dragCancel", {
25164
+ activeId: event.active.id,
25165
+ reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
25166
+ });
25167
+ }, []);
25089
25168
  const wrapContainer = React93__namespace.default.useCallback(
25090
25169
  (children) => {
25091
25170
  if (!enabled) return children;
25092
25171
  const strategy = layout === "grid" ? sortable.rectSortingStrategy : sortable.verticalListSortingStrategy;
25093
- const clearOverlay = () => setOverlay(null);
25094
25172
  if (!isZone) {
25095
25173
  if (!isRoot) return children;
25096
- return /* @__PURE__ */ jsxRuntime.jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsxRuntime.jsxs(
25174
+ return /* @__PURE__ */ jsxRuntime.jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(
25097
25175
  core$1.DndContext,
25098
25176
  {
25099
25177
  sensors,
25100
25178
  collisionDetection,
25101
- onDragEnd: (e) => {
25102
- handleDragEnd(e);
25103
- clearOverlay();
25104
- },
25105
- onDragCancel: clearOverlay,
25106
- children: [
25107
- children,
25108
- /* @__PURE__ */ jsxRuntime.jsx(core$1.DragOverlay, { children: overlayNode })
25109
- ]
25179
+ onDragStart: handleDragStart,
25180
+ onDragOver: handleDragOver,
25181
+ onDragEnd: handleDragEnd,
25182
+ onDragCancel: handleDragCancel,
25183
+ children
25110
25184
  }
25111
25185
  ) });
25112
25186
  }
25113
25187
  const inner = /* @__PURE__ */ jsxRuntime.jsx(DropZoneShell, { children: /* @__PURE__ */ jsxRuntime.jsx(sortable.SortableContext, { items: itemIds, strategy, children }) });
25114
25188
  if (isRoot) {
25115
- return /* @__PURE__ */ jsxRuntime.jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsxRuntime.jsxs(
25189
+ return /* @__PURE__ */ jsxRuntime.jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(
25116
25190
  core$1.DndContext,
25117
25191
  {
25118
25192
  sensors,
25119
25193
  collisionDetection,
25120
- onDragEnd: (e) => {
25121
- handleDragEnd(e);
25122
- clearOverlay();
25123
- },
25124
- onDragCancel: clearOverlay,
25125
- children: [
25126
- inner,
25127
- /* @__PURE__ */ jsxRuntime.jsx(core$1.DragOverlay, { children: overlayNode })
25128
- ]
25194
+ onDragStart: handleDragStart,
25195
+ onDragOver: handleDragOver,
25196
+ onDragEnd: handleDragEnd,
25197
+ onDragCancel: handleDragCancel,
25198
+ children: inner
25129
25199
  }
25130
25200
  ) });
25131
25201
  }
25132
25202
  return inner;
25133
25203
  },
25134
- [enabled, isZone, layout, sensors, collisionDetection, handleDragEnd, itemIds, isRoot, rootContextValue, overlayNode, setOverlay]
25204
+ [enabled, isZone, layout, sensors, collisionDetection, handleDragStart, handleDragOver, handleDragEnd, handleDragCancel, itemIds, isRoot, rootContextValue]
25135
25205
  );
25136
25206
  return {
25137
25207
  enabled,
@@ -25141,12 +25211,13 @@ function useDataDnd(args) {
25141
25211
  orderedItems
25142
25212
  };
25143
25213
  }
25144
- var RootCtx;
25214
+ var dndLog, RootCtx;
25145
25215
  var init_useDataDnd = __esm({
25146
25216
  "components/molecules/useDataDnd.tsx"() {
25147
25217
  "use client";
25148
25218
  init_useEventBus();
25149
25219
  init_Box();
25220
+ dndLog = logger.createLogger("almadar:ui:dnd");
25150
25221
  RootCtx = React93__namespace.default.createContext(null);
25151
25222
  }
25152
25223
  });
package/dist/avl/index.js CHANGED
@@ -34,7 +34,7 @@ import langToml from 'react-syntax-highlighter/dist/esm/languages/prism/toml.js'
34
34
  import langGo from 'react-syntax-highlighter/dist/esm/languages/prism/go.js';
35
35
  import langGraphql from 'react-syntax-highlighter/dist/esm/languages/prism/graphql.js';
36
36
  import { FieldTypeSchema, isInlineTrait, isEntityCall, schemaToIR, getPage, isCircuitEvent } from '@almadar/core';
37
- import { useSensors, useSensor, PointerSensor, KeyboardSensor, pointerWithin, rectIntersection, closestCorners, DndContext, DragOverlay, useDroppable } from '@dnd-kit/core';
37
+ import { useSensors, useSensor, PointerSensor, KeyboardSensor, pointerWithin, rectIntersection, closestCorners, DndContext, useDroppable } from '@dnd-kit/core';
38
38
  import { sortableKeyboardCoordinates, arrayMove, useSortable, SortableContext, rectSortingStrategy, verticalListSortingStrategy } from '@dnd-kit/sortable';
39
39
  import { CSS } from '@dnd-kit/utilities';
40
40
  import { useThree, useFrame, Canvas } from '@react-three/fiber';
@@ -24882,12 +24882,17 @@ function useDataDnd(args) {
24882
24882
  React93__default.useEffect(() => {
24883
24883
  setLocalOrder(null);
24884
24884
  }, [items]);
24885
+ const itemIdsSignature = orderedItems.map((it, idx) => {
24886
+ const raw = it[dndItemIdField];
24887
+ return String(raw ?? `__idx_${idx}`);
24888
+ }).join("|");
24885
24889
  const itemIds = React93__default.useMemo(
24886
24890
  () => orderedItems.map((it, idx) => {
24887
24891
  const raw = it[dndItemIdField];
24888
24892
  return raw ?? `__idx_${idx}`;
24889
24893
  }),
24890
- [orderedItems, dndItemIdField]
24894
+ // eslint-disable-next-line react-hooks/exhaustive-deps
24895
+ [itemIdsSignature]
24891
24896
  );
24892
24897
  const zonesRef = React93__default.useRef(/* @__PURE__ */ new Map());
24893
24898
  const registerZone = React93__default.useCallback((zoneId2, meta2) => {
@@ -24896,10 +24901,6 @@ function useDataDnd(args) {
24896
24901
  const unregisterZone = React93__default.useCallback((zoneId2) => {
24897
24902
  zonesRef.current.delete(zoneId2);
24898
24903
  }, []);
24899
- const [overlayNode, setOverlayNode] = React93__default.useState(null);
24900
- const setOverlay = React93__default.useCallback((node) => {
24901
- setOverlayNode(node);
24902
- }, []);
24903
24904
  const zoneId = React93__default.useId();
24904
24905
  const ownGroup = dragGroup ?? accepts ?? zoneId;
24905
24906
  const meta = React93__default.useMemo(
@@ -24910,10 +24911,18 @@ function useDataDnd(args) {
24910
24911
  const target = isRoot ? null : parentRoot;
24911
24912
  if (!target) {
24912
24913
  zonesRef.current.set(zoneId, meta);
24913
- return () => zonesRef.current.delete(zoneId);
24914
+ dndLog.debug("zone:register:self", { zoneId, group: meta.group, itemCount: meta.itemIds.length, isRoot });
24915
+ return () => {
24916
+ zonesRef.current.delete(zoneId);
24917
+ dndLog.debug("zone:unregister:self", { zoneId, group: meta.group });
24918
+ };
24914
24919
  }
24915
24920
  target.registerZone(zoneId, meta);
24916
- return () => target.unregisterZone(zoneId);
24921
+ dndLog.debug("zone:register", { zoneId, group: meta.group, itemCount: meta.itemIds.length, dropEvent: meta.dropEvent, reorderEvent: meta.reorderEvent });
24922
+ return () => {
24923
+ target.unregisterZone(zoneId);
24924
+ dndLog.debug("zone:unregister", { zoneId, group: meta.group });
24925
+ };
24917
24926
  }, [parentRoot, isRoot, zoneId, meta]);
24918
24927
  const sensors = useSensors(
24919
24928
  useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),
@@ -24921,10 +24930,18 @@ function useDataDnd(args) {
24921
24930
  );
24922
24931
  const collisionDetection = React93__default.useCallback((args2) => {
24923
24932
  const pointerCollisions = pointerWithin(args2);
24924
- if (pointerCollisions.length > 0) return pointerCollisions;
24933
+ if (pointerCollisions.length > 0) {
24934
+ dndLog.debug("collision:pointerWithin", { count: pointerCollisions.length, ids: pointerCollisions.map((c) => c.id) });
24935
+ return pointerCollisions;
24936
+ }
24925
24937
  const rectCollisions = rectIntersection(args2);
24926
- if (rectCollisions.length > 0) return rectCollisions;
24927
- return closestCorners(args2);
24938
+ if (rectCollisions.length > 0) {
24939
+ dndLog.debug("collision:rectIntersection", { count: rectCollisions.length, ids: rectCollisions.map((c) => c.id) });
24940
+ return rectCollisions;
24941
+ }
24942
+ const cornerCollisions = closestCorners(args2);
24943
+ dndLog.debug("collision:closestCorners", { count: cornerCollisions.length, ids: cornerCollisions.map((c) => c.id) });
24944
+ return cornerCollisions;
24928
24945
  }, []);
24929
24946
  const findZoneByItem = React93__default.useCallback(
24930
24947
  (id) => {
@@ -24947,22 +24964,52 @@ function useDataDnd(args) {
24947
24964
  const handleDragEnd = React93__default.useCallback(
24948
24965
  (event) => {
24949
24966
  const { active, over } = event;
24950
- if (!over) return;
24967
+ const allZones = Array.from(zonesRef.current.entries()).map(([id, m]) => ({ id, group: m.group, items: m.itemIds.length }));
24968
+ dndLog.debug("dragEnd:received", {
24969
+ activeId: active.id,
24970
+ overId: over?.id,
24971
+ overData: over?.data?.current,
24972
+ zones: allZones
24973
+ });
24974
+ if (!over) {
24975
+ dndLog.warn("dragEnd:abort:no-over", { activeId: active.id, reason: "no droppable under pointer at drop time \u2192 item snaps back" });
24976
+ return;
24977
+ }
24951
24978
  const sourceZone = findZoneByItem(active.id);
24952
24979
  const overData = over.data?.current;
24953
24980
  const targetGroup = overData?.dndGroup;
24954
- if (!sourceZone || !targetGroup) return;
24981
+ dndLog.debug("dragEnd:resolved", { sourceGroup: sourceZone?.group, targetGroup, overDataKeys: overData ? Object.keys(overData) : null });
24982
+ if (!sourceZone) {
24983
+ dndLog.warn("dragEnd:abort:no-source-zone", { activeId: active.id });
24984
+ return;
24985
+ }
24986
+ if (!targetGroup) {
24987
+ dndLog.warn("dragEnd:abort:no-target-group", { overId: over.id, overData });
24988
+ return;
24989
+ }
24955
24990
  const targetZone = findZoneByGroup(targetGroup);
24956
- if (!targetZone) return;
24991
+ if (!targetZone) {
24992
+ dndLog.warn("dragEnd:abort:target-zone-not-registered", { targetGroup });
24993
+ return;
24994
+ }
24957
24995
  if (sourceZone.group !== targetZone.group) {
24958
24996
  if (targetZone.dropEvent) {
24959
24997
  const newIndex2 = targetZone.itemIds.indexOf(over.id);
24998
+ dndLog.info("dragEnd:cross-container:emit", {
24999
+ event: targetZone.dropEvent,
25000
+ id: String(active.id),
25001
+ sourceGroup: sourceZone.group,
25002
+ targetGroup: targetZone.group,
25003
+ newIndex: newIndex2 === -1 ? targetZone.itemIds.length : newIndex2
25004
+ });
24960
25005
  eventBus.emit(targetZone.dropEvent, {
24961
25006
  id: String(active.id),
24962
25007
  sourceGroup: sourceZone.group,
24963
25008
  targetGroup: targetZone.group,
24964
25009
  newIndex: newIndex2 === -1 ? targetZone.itemIds.length : newIndex2
24965
25010
  });
25011
+ } else {
25012
+ dndLog.warn("dragEnd:cross-container:no-dropEvent-on-target", { targetGroup: targetZone.group });
24966
25013
  }
24967
25014
  return;
24968
25015
  }
@@ -24974,16 +25021,24 @@ function useDataDnd(args) {
24974
25021
  setLocalOrder(reordered);
24975
25022
  }
24976
25023
  if (sourceZone.reorderEvent) {
25024
+ dndLog.info("dragEnd:reorder:emit", {
25025
+ event: sourceZone.reorderEvent,
25026
+ id: String(active.id),
25027
+ oldIndex,
25028
+ newIndex
25029
+ });
24977
25030
  eventBus.emit(sourceZone.reorderEvent, {
24978
25031
  id: String(active.id),
24979
25032
  oldIndex,
24980
25033
  newIndex
24981
25034
  });
25035
+ } else {
25036
+ dndLog.debug("dragEnd:reorder:no-reorderEvent", { sourceGroup: sourceZone.group });
24982
25037
  }
24983
25038
  },
24984
25039
  [orderedItems, ownGroup, findZoneByItem, findZoneByGroup, eventBus]
24985
25040
  );
24986
- const overlaySink = isRoot ? setOverlay : parentRoot?.setOverlay;
25041
+ const sortableData = React93__default.useMemo(() => ({ dndGroup: ownGroup }), [ownGroup]);
24987
25042
  const SortableItem = React93__default.useCallback(
24988
25043
  ({ id, children }) => {
24989
25044
  const {
@@ -24993,19 +25048,16 @@ function useDataDnd(args) {
24993
25048
  transform,
24994
25049
  transition,
24995
25050
  isDragging
24996
- } = useSortable({ id, data: { dndGroup: ownGroup } });
24997
- const childrenRef = React93__default.useRef(children);
24998
- childrenRef.current = children;
24999
- React93__default.useEffect(() => {
25000
- if (!isDragging || !overlaySink) return;
25001
- overlaySink(childrenRef.current);
25002
- return () => overlaySink(null);
25003
- }, [isDragging]);
25051
+ } = useSortable({ id, data: sortableData });
25004
25052
  const style = {
25005
25053
  transform: CSS.Transform.toString(transform),
25006
25054
  transition,
25007
25055
  opacity: isDragging ? 0.4 : 1,
25008
- cursor: enabled ? "grab" : void 0
25056
+ cursor: enabled ? "grab" : void 0,
25057
+ // Lift the dragged element above siblings so its visual movement
25058
+ // isn't hidden behind other cards / column boundaries.
25059
+ zIndex: isDragging ? 50 : void 0,
25060
+ position: isDragging ? "relative" : void 0
25009
25061
  };
25010
25062
  return /* @__PURE__ */ jsx(
25011
25063
  Box,
@@ -25019,73 +25071,91 @@ function useDataDnd(args) {
25019
25071
  }
25020
25072
  );
25021
25073
  },
25022
- [ownGroup, enabled, overlaySink]
25074
+ [sortableData, enabled]
25023
25075
  );
25024
25076
  const DropZoneShell = ({ children }) => {
25077
+ const droppableId = `dnd-zone-${zoneId}`;
25025
25078
  const { setNodeRef, isOver } = useDroppable({
25026
- id: `dnd-zone-${zoneId}`,
25027
- data: { dndGroup: ownGroup }
25079
+ id: droppableId,
25080
+ data: sortableData
25028
25081
  });
25082
+ React93__default.useEffect(() => {
25083
+ dndLog.debug("dropzone:isOver:change", { droppableId, group: ownGroup, isOver });
25084
+ }, [droppableId, isOver]);
25029
25085
  return /* @__PURE__ */ jsx(
25030
25086
  Box,
25031
25087
  {
25032
25088
  ref: setNodeRef,
25033
25089
  "data-dnd-zone": ownGroup,
25090
+ "data-dnd-is-over": isOver ? "true" : "false",
25034
25091
  className: isOver ? "ring-2 ring-primary ring-offset-2 rounded-lg transition-all min-h-[3rem]" : "min-h-[3rem] rounded-lg transition-all",
25035
25092
  children
25036
25093
  }
25037
25094
  );
25038
25095
  };
25039
25096
  const rootContextValue = React93__default.useMemo(
25040
- () => ({ registerZone, unregisterZone, setOverlay }),
25041
- [registerZone, unregisterZone, setOverlay]
25097
+ () => ({ registerZone, unregisterZone }),
25098
+ [registerZone, unregisterZone]
25042
25099
  );
25100
+ const handleDragStart = React93__default.useCallback((event) => {
25101
+ const sourceZone = findZoneByItem(event.active.id);
25102
+ dndLog.info("dragStart", {
25103
+ activeId: event.active.id,
25104
+ activeData: event.active.data?.current,
25105
+ sourceGroup: sourceZone?.group,
25106
+ zoneCount: zonesRef.current.size
25107
+ });
25108
+ }, [findZoneByItem]);
25109
+ const handleDragOver = React93__default.useCallback((event) => {
25110
+ dndLog.debug("dragOver", {
25111
+ activeId: event.active.id,
25112
+ overId: event.over?.id,
25113
+ overData: event.over?.data?.current
25114
+ });
25115
+ }, []);
25116
+ const handleDragCancel = React93__default.useCallback((event) => {
25117
+ dndLog.warn("dragCancel", {
25118
+ activeId: event.active.id,
25119
+ reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
25120
+ });
25121
+ }, []);
25043
25122
  const wrapContainer = React93__default.useCallback(
25044
25123
  (children) => {
25045
25124
  if (!enabled) return children;
25046
25125
  const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
25047
- const clearOverlay = () => setOverlay(null);
25048
25126
  if (!isZone) {
25049
25127
  if (!isRoot) return children;
25050
- return /* @__PURE__ */ jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsxs(
25128
+ return /* @__PURE__ */ jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsx(
25051
25129
  DndContext,
25052
25130
  {
25053
25131
  sensors,
25054
25132
  collisionDetection,
25055
- onDragEnd: (e) => {
25056
- handleDragEnd(e);
25057
- clearOverlay();
25058
- },
25059
- onDragCancel: clearOverlay,
25060
- children: [
25061
- children,
25062
- /* @__PURE__ */ jsx(DragOverlay, { children: overlayNode })
25063
- ]
25133
+ onDragStart: handleDragStart,
25134
+ onDragOver: handleDragOver,
25135
+ onDragEnd: handleDragEnd,
25136
+ onDragCancel: handleDragCancel,
25137
+ children
25064
25138
  }
25065
25139
  ) });
25066
25140
  }
25067
25141
  const inner = /* @__PURE__ */ jsx(DropZoneShell, { children: /* @__PURE__ */ jsx(SortableContext, { items: itemIds, strategy, children }) });
25068
25142
  if (isRoot) {
25069
- return /* @__PURE__ */ jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsxs(
25143
+ return /* @__PURE__ */ jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsx(
25070
25144
  DndContext,
25071
25145
  {
25072
25146
  sensors,
25073
25147
  collisionDetection,
25074
- onDragEnd: (e) => {
25075
- handleDragEnd(e);
25076
- clearOverlay();
25077
- },
25078
- onDragCancel: clearOverlay,
25079
- children: [
25080
- inner,
25081
- /* @__PURE__ */ jsx(DragOverlay, { children: overlayNode })
25082
- ]
25148
+ onDragStart: handleDragStart,
25149
+ onDragOver: handleDragOver,
25150
+ onDragEnd: handleDragEnd,
25151
+ onDragCancel: handleDragCancel,
25152
+ children: inner
25083
25153
  }
25084
25154
  ) });
25085
25155
  }
25086
25156
  return inner;
25087
25157
  },
25088
- [enabled, isZone, layout, sensors, collisionDetection, handleDragEnd, itemIds, isRoot, rootContextValue, overlayNode, setOverlay]
25158
+ [enabled, isZone, layout, sensors, collisionDetection, handleDragStart, handleDragOver, handleDragEnd, handleDragCancel, itemIds, isRoot, rootContextValue]
25089
25159
  );
25090
25160
  return {
25091
25161
  enabled,
@@ -25095,12 +25165,13 @@ function useDataDnd(args) {
25095
25165
  orderedItems
25096
25166
  };
25097
25167
  }
25098
- var RootCtx;
25168
+ var dndLog, RootCtx;
25099
25169
  var init_useDataDnd = __esm({
25100
25170
  "components/molecules/useDataDnd.tsx"() {
25101
25171
  "use client";
25102
25172
  init_useEventBus();
25103
25173
  init_Box();
25174
+ dndLog = createLogger("almadar:ui:dnd");
25104
25175
  RootCtx = React93__default.createContext(null);
25105
25176
  }
25106
25177
  });