@almadar/ui 4.50.5 → 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.
@@ -24957,10 +24957,18 @@ function useDataDnd(args) {
24957
24957
  const target = isRoot ? null : parentRoot;
24958
24958
  if (!target) {
24959
24959
  zonesRef.current.set(zoneId, meta);
24960
- 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
+ };
24961
24965
  }
24962
24966
  target.registerZone(zoneId, meta);
24963
- 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
+ };
24964
24972
  }, [parentRoot, isRoot, zoneId, meta]);
24965
24973
  const sensors = core$1.useSensors(
24966
24974
  core$1.useSensor(core$1.PointerSensor, { activationConstraint: { distance: 5 } }),
@@ -24968,10 +24976,18 @@ function useDataDnd(args) {
24968
24976
  );
24969
24977
  const collisionDetection = React93__namespace.default.useCallback((args2) => {
24970
24978
  const pointerCollisions = core$1.pointerWithin(args2);
24971
- 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
+ }
24972
24983
  const rectCollisions = core$1.rectIntersection(args2);
24973
- if (rectCollisions.length > 0) return rectCollisions;
24974
- 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;
24975
24991
  }, []);
24976
24992
  const findZoneByItem = React93__namespace.default.useCallback(
24977
24993
  (id) => {
@@ -24994,22 +25010,52 @@ function useDataDnd(args) {
24994
25010
  const handleDragEnd = React93__namespace.default.useCallback(
24995
25011
  (event) => {
24996
25012
  const { active, over } = event;
24997
- 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
+ }
24998
25024
  const sourceZone = findZoneByItem(active.id);
24999
25025
  const overData = over.data?.current;
25000
25026
  const targetGroup = overData?.dndGroup;
25001
- 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
+ }
25002
25036
  const targetZone = findZoneByGroup(targetGroup);
25003
- if (!targetZone) return;
25037
+ if (!targetZone) {
25038
+ dndLog.warn("dragEnd:abort:target-zone-not-registered", { targetGroup });
25039
+ return;
25040
+ }
25004
25041
  if (sourceZone.group !== targetZone.group) {
25005
25042
  if (targetZone.dropEvent) {
25006
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
+ });
25007
25051
  eventBus.emit(targetZone.dropEvent, {
25008
25052
  id: String(active.id),
25009
25053
  sourceGroup: sourceZone.group,
25010
25054
  targetGroup: targetZone.group,
25011
25055
  newIndex: newIndex2 === -1 ? targetZone.itemIds.length : newIndex2
25012
25056
  });
25057
+ } else {
25058
+ dndLog.warn("dragEnd:cross-container:no-dropEvent-on-target", { targetGroup: targetZone.group });
25013
25059
  }
25014
25060
  return;
25015
25061
  }
@@ -25021,11 +25067,19 @@ function useDataDnd(args) {
25021
25067
  setLocalOrder(reordered);
25022
25068
  }
25023
25069
  if (sourceZone.reorderEvent) {
25070
+ dndLog.info("dragEnd:reorder:emit", {
25071
+ event: sourceZone.reorderEvent,
25072
+ id: String(active.id),
25073
+ oldIndex,
25074
+ newIndex
25075
+ });
25024
25076
  eventBus.emit(sourceZone.reorderEvent, {
25025
25077
  id: String(active.id),
25026
25078
  oldIndex,
25027
25079
  newIndex
25028
25080
  });
25081
+ } else {
25082
+ dndLog.debug("dragEnd:reorder:no-reorderEvent", { sourceGroup: sourceZone.group });
25029
25083
  }
25030
25084
  },
25031
25085
  [orderedItems, ownGroup, findZoneByItem, findZoneByGroup, eventBus]
@@ -25066,15 +25120,20 @@ function useDataDnd(args) {
25066
25120
  [sortableData, enabled]
25067
25121
  );
25068
25122
  const DropZoneShell = ({ children }) => {
25123
+ const droppableId = `dnd-zone-${zoneId}`;
25069
25124
  const { setNodeRef, isOver } = core$1.useDroppable({
25070
- id: `dnd-zone-${zoneId}`,
25125
+ id: droppableId,
25071
25126
  data: sortableData
25072
25127
  });
25128
+ React93__namespace.default.useEffect(() => {
25129
+ dndLog.debug("dropzone:isOver:change", { droppableId, group: ownGroup, isOver });
25130
+ }, [droppableId, isOver]);
25073
25131
  return /* @__PURE__ */ jsxRuntime.jsx(
25074
25132
  Box,
25075
25133
  {
25076
25134
  ref: setNodeRef,
25077
25135
  "data-dnd-zone": ownGroup,
25136
+ "data-dnd-is-over": isOver ? "true" : "false",
25078
25137
  className: isOver ? "ring-2 ring-primary ring-offset-2 rounded-lg transition-all min-h-[3rem]" : "min-h-[3rem] rounded-lg transition-all",
25079
25138
  children
25080
25139
  }
@@ -25084,21 +25143,65 @@ function useDataDnd(args) {
25084
25143
  () => ({ registerZone, unregisterZone }),
25085
25144
  [registerZone, unregisterZone]
25086
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
+ }, []);
25087
25168
  const wrapContainer = React93__namespace.default.useCallback(
25088
25169
  (children) => {
25089
25170
  if (!enabled) return children;
25090
25171
  const strategy = layout === "grid" ? sortable.rectSortingStrategy : sortable.verticalListSortingStrategy;
25091
25172
  if (!isZone) {
25092
25173
  if (!isRoot) return children;
25093
- return /* @__PURE__ */ jsxRuntime.jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(core$1.DndContext, { sensors, collisionDetection, onDragEnd: handleDragEnd, children }) });
25174
+ return /* @__PURE__ */ jsxRuntime.jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(
25175
+ core$1.DndContext,
25176
+ {
25177
+ sensors,
25178
+ collisionDetection,
25179
+ onDragStart: handleDragStart,
25180
+ onDragOver: handleDragOver,
25181
+ onDragEnd: handleDragEnd,
25182
+ onDragCancel: handleDragCancel,
25183
+ children
25184
+ }
25185
+ ) });
25094
25186
  }
25095
25187
  const inner = /* @__PURE__ */ jsxRuntime.jsx(DropZoneShell, { children: /* @__PURE__ */ jsxRuntime.jsx(sortable.SortableContext, { items: itemIds, strategy, children }) });
25096
25188
  if (isRoot) {
25097
- return /* @__PURE__ */ jsxRuntime.jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(core$1.DndContext, { sensors, collisionDetection, onDragEnd: handleDragEnd, children: inner }) });
25189
+ return /* @__PURE__ */ jsxRuntime.jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(
25190
+ core$1.DndContext,
25191
+ {
25192
+ sensors,
25193
+ collisionDetection,
25194
+ onDragStart: handleDragStart,
25195
+ onDragOver: handleDragOver,
25196
+ onDragEnd: handleDragEnd,
25197
+ onDragCancel: handleDragCancel,
25198
+ children: inner
25199
+ }
25200
+ ) });
25098
25201
  }
25099
25202
  return inner;
25100
25203
  },
25101
- [enabled, isZone, layout, sensors, collisionDetection, handleDragEnd, itemIds, isRoot, rootContextValue]
25204
+ [enabled, isZone, layout, sensors, collisionDetection, handleDragStart, handleDragOver, handleDragEnd, handleDragCancel, itemIds, isRoot, rootContextValue]
25102
25205
  );
25103
25206
  return {
25104
25207
  enabled,
@@ -25108,12 +25211,13 @@ function useDataDnd(args) {
25108
25211
  orderedItems
25109
25212
  };
25110
25213
  }
25111
- var RootCtx;
25214
+ var dndLog, RootCtx;
25112
25215
  var init_useDataDnd = __esm({
25113
25216
  "components/molecules/useDataDnd.tsx"() {
25114
25217
  "use client";
25115
25218
  init_useEventBus();
25116
25219
  init_Box();
25220
+ dndLog = logger.createLogger("almadar:ui:dnd");
25117
25221
  RootCtx = React93__namespace.default.createContext(null);
25118
25222
  }
25119
25223
  });
package/dist/avl/index.js CHANGED
@@ -24911,10 +24911,18 @@ function useDataDnd(args) {
24911
24911
  const target = isRoot ? null : parentRoot;
24912
24912
  if (!target) {
24913
24913
  zonesRef.current.set(zoneId, meta);
24914
- 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
+ };
24915
24919
  }
24916
24920
  target.registerZone(zoneId, meta);
24917
- 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
+ };
24918
24926
  }, [parentRoot, isRoot, zoneId, meta]);
24919
24927
  const sensors = useSensors(
24920
24928
  useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),
@@ -24922,10 +24930,18 @@ function useDataDnd(args) {
24922
24930
  );
24923
24931
  const collisionDetection = React93__default.useCallback((args2) => {
24924
24932
  const pointerCollisions = pointerWithin(args2);
24925
- 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
+ }
24926
24937
  const rectCollisions = rectIntersection(args2);
24927
- if (rectCollisions.length > 0) return rectCollisions;
24928
- 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;
24929
24945
  }, []);
24930
24946
  const findZoneByItem = React93__default.useCallback(
24931
24947
  (id) => {
@@ -24948,22 +24964,52 @@ function useDataDnd(args) {
24948
24964
  const handleDragEnd = React93__default.useCallback(
24949
24965
  (event) => {
24950
24966
  const { active, over } = event;
24951
- 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
+ }
24952
24978
  const sourceZone = findZoneByItem(active.id);
24953
24979
  const overData = over.data?.current;
24954
24980
  const targetGroup = overData?.dndGroup;
24955
- 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
+ }
24956
24990
  const targetZone = findZoneByGroup(targetGroup);
24957
- if (!targetZone) return;
24991
+ if (!targetZone) {
24992
+ dndLog.warn("dragEnd:abort:target-zone-not-registered", { targetGroup });
24993
+ return;
24994
+ }
24958
24995
  if (sourceZone.group !== targetZone.group) {
24959
24996
  if (targetZone.dropEvent) {
24960
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
+ });
24961
25005
  eventBus.emit(targetZone.dropEvent, {
24962
25006
  id: String(active.id),
24963
25007
  sourceGroup: sourceZone.group,
24964
25008
  targetGroup: targetZone.group,
24965
25009
  newIndex: newIndex2 === -1 ? targetZone.itemIds.length : newIndex2
24966
25010
  });
25011
+ } else {
25012
+ dndLog.warn("dragEnd:cross-container:no-dropEvent-on-target", { targetGroup: targetZone.group });
24967
25013
  }
24968
25014
  return;
24969
25015
  }
@@ -24975,11 +25021,19 @@ function useDataDnd(args) {
24975
25021
  setLocalOrder(reordered);
24976
25022
  }
24977
25023
  if (sourceZone.reorderEvent) {
25024
+ dndLog.info("dragEnd:reorder:emit", {
25025
+ event: sourceZone.reorderEvent,
25026
+ id: String(active.id),
25027
+ oldIndex,
25028
+ newIndex
25029
+ });
24978
25030
  eventBus.emit(sourceZone.reorderEvent, {
24979
25031
  id: String(active.id),
24980
25032
  oldIndex,
24981
25033
  newIndex
24982
25034
  });
25035
+ } else {
25036
+ dndLog.debug("dragEnd:reorder:no-reorderEvent", { sourceGroup: sourceZone.group });
24983
25037
  }
24984
25038
  },
24985
25039
  [orderedItems, ownGroup, findZoneByItem, findZoneByGroup, eventBus]
@@ -25020,15 +25074,20 @@ function useDataDnd(args) {
25020
25074
  [sortableData, enabled]
25021
25075
  );
25022
25076
  const DropZoneShell = ({ children }) => {
25077
+ const droppableId = `dnd-zone-${zoneId}`;
25023
25078
  const { setNodeRef, isOver } = useDroppable({
25024
- id: `dnd-zone-${zoneId}`,
25079
+ id: droppableId,
25025
25080
  data: sortableData
25026
25081
  });
25082
+ React93__default.useEffect(() => {
25083
+ dndLog.debug("dropzone:isOver:change", { droppableId, group: ownGroup, isOver });
25084
+ }, [droppableId, isOver]);
25027
25085
  return /* @__PURE__ */ jsx(
25028
25086
  Box,
25029
25087
  {
25030
25088
  ref: setNodeRef,
25031
25089
  "data-dnd-zone": ownGroup,
25090
+ "data-dnd-is-over": isOver ? "true" : "false",
25032
25091
  className: isOver ? "ring-2 ring-primary ring-offset-2 rounded-lg transition-all min-h-[3rem]" : "min-h-[3rem] rounded-lg transition-all",
25033
25092
  children
25034
25093
  }
@@ -25038,21 +25097,65 @@ function useDataDnd(args) {
25038
25097
  () => ({ registerZone, unregisterZone }),
25039
25098
  [registerZone, unregisterZone]
25040
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
+ }, []);
25041
25122
  const wrapContainer = React93__default.useCallback(
25042
25123
  (children) => {
25043
25124
  if (!enabled) return children;
25044
25125
  const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
25045
25126
  if (!isZone) {
25046
25127
  if (!isRoot) return children;
25047
- return /* @__PURE__ */ jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsx(DndContext, { sensors, collisionDetection, onDragEnd: handleDragEnd, children }) });
25128
+ return /* @__PURE__ */ jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsx(
25129
+ DndContext,
25130
+ {
25131
+ sensors,
25132
+ collisionDetection,
25133
+ onDragStart: handleDragStart,
25134
+ onDragOver: handleDragOver,
25135
+ onDragEnd: handleDragEnd,
25136
+ onDragCancel: handleDragCancel,
25137
+ children
25138
+ }
25139
+ ) });
25048
25140
  }
25049
25141
  const inner = /* @__PURE__ */ jsx(DropZoneShell, { children: /* @__PURE__ */ jsx(SortableContext, { items: itemIds, strategy, children }) });
25050
25142
  if (isRoot) {
25051
- return /* @__PURE__ */ jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsx(DndContext, { sensors, collisionDetection, onDragEnd: handleDragEnd, children: inner }) });
25143
+ return /* @__PURE__ */ jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsx(
25144
+ DndContext,
25145
+ {
25146
+ sensors,
25147
+ collisionDetection,
25148
+ onDragStart: handleDragStart,
25149
+ onDragOver: handleDragOver,
25150
+ onDragEnd: handleDragEnd,
25151
+ onDragCancel: handleDragCancel,
25152
+ children: inner
25153
+ }
25154
+ ) });
25052
25155
  }
25053
25156
  return inner;
25054
25157
  },
25055
- [enabled, isZone, layout, sensors, collisionDetection, handleDragEnd, itemIds, isRoot, rootContextValue]
25158
+ [enabled, isZone, layout, sensors, collisionDetection, handleDragStart, handleDragOver, handleDragEnd, handleDragCancel, itemIds, isRoot, rootContextValue]
25056
25159
  );
25057
25160
  return {
25058
25161
  enabled,
@@ -25062,12 +25165,13 @@ function useDataDnd(args) {
25062
25165
  orderedItems
25063
25166
  };
25064
25167
  }
25065
- var RootCtx;
25168
+ var dndLog, RootCtx;
25066
25169
  var init_useDataDnd = __esm({
25067
25170
  "components/molecules/useDataDnd.tsx"() {
25068
25171
  "use client";
25069
25172
  init_useEventBus();
25070
25173
  init_Box();
25174
+ dndLog = createLogger("almadar:ui:dnd");
25071
25175
  RootCtx = React93__default.createContext(null);
25072
25176
  }
25073
25177
  });
@@ -20124,10 +20124,18 @@ function useDataDnd(args) {
20124
20124
  const target = isRoot ? null : parentRoot;
20125
20125
  if (!target) {
20126
20126
  zonesRef.current.set(zoneId, meta);
20127
- return () => zonesRef.current.delete(zoneId);
20127
+ dndLog.debug("zone:register:self", { zoneId, group: meta.group, itemCount: meta.itemIds.length, isRoot });
20128
+ return () => {
20129
+ zonesRef.current.delete(zoneId);
20130
+ dndLog.debug("zone:unregister:self", { zoneId, group: meta.group });
20131
+ };
20128
20132
  }
20129
20133
  target.registerZone(zoneId, meta);
20130
- return () => target.unregisterZone(zoneId);
20134
+ dndLog.debug("zone:register", { zoneId, group: meta.group, itemCount: meta.itemIds.length, dropEvent: meta.dropEvent, reorderEvent: meta.reorderEvent });
20135
+ return () => {
20136
+ target.unregisterZone(zoneId);
20137
+ dndLog.debug("zone:unregister", { zoneId, group: meta.group });
20138
+ };
20131
20139
  }, [parentRoot, isRoot, zoneId, meta]);
20132
20140
  const sensors = core$1.useSensors(
20133
20141
  core$1.useSensor(core$1.PointerSensor, { activationConstraint: { distance: 5 } }),
@@ -20135,10 +20143,18 @@ function useDataDnd(args) {
20135
20143
  );
20136
20144
  const collisionDetection = React75__namespace.default.useCallback((args2) => {
20137
20145
  const pointerCollisions = core$1.pointerWithin(args2);
20138
- if (pointerCollisions.length > 0) return pointerCollisions;
20146
+ if (pointerCollisions.length > 0) {
20147
+ dndLog.debug("collision:pointerWithin", { count: pointerCollisions.length, ids: pointerCollisions.map((c) => c.id) });
20148
+ return pointerCollisions;
20149
+ }
20139
20150
  const rectCollisions = core$1.rectIntersection(args2);
20140
- if (rectCollisions.length > 0) return rectCollisions;
20141
- return core$1.closestCorners(args2);
20151
+ if (rectCollisions.length > 0) {
20152
+ dndLog.debug("collision:rectIntersection", { count: rectCollisions.length, ids: rectCollisions.map((c) => c.id) });
20153
+ return rectCollisions;
20154
+ }
20155
+ const cornerCollisions = core$1.closestCorners(args2);
20156
+ dndLog.debug("collision:closestCorners", { count: cornerCollisions.length, ids: cornerCollisions.map((c) => c.id) });
20157
+ return cornerCollisions;
20142
20158
  }, []);
20143
20159
  const findZoneByItem = React75__namespace.default.useCallback(
20144
20160
  (id) => {
@@ -20161,22 +20177,52 @@ function useDataDnd(args) {
20161
20177
  const handleDragEnd = React75__namespace.default.useCallback(
20162
20178
  (event) => {
20163
20179
  const { active, over } = event;
20164
- if (!over) return;
20180
+ const allZones = Array.from(zonesRef.current.entries()).map(([id, m]) => ({ id, group: m.group, items: m.itemIds.length }));
20181
+ dndLog.debug("dragEnd:received", {
20182
+ activeId: active.id,
20183
+ overId: over?.id,
20184
+ overData: over?.data?.current,
20185
+ zones: allZones
20186
+ });
20187
+ if (!over) {
20188
+ dndLog.warn("dragEnd:abort:no-over", { activeId: active.id, reason: "no droppable under pointer at drop time \u2192 item snaps back" });
20189
+ return;
20190
+ }
20165
20191
  const sourceZone = findZoneByItem(active.id);
20166
20192
  const overData = over.data?.current;
20167
20193
  const targetGroup = overData?.dndGroup;
20168
- if (!sourceZone || !targetGroup) return;
20194
+ dndLog.debug("dragEnd:resolved", { sourceGroup: sourceZone?.group, targetGroup, overDataKeys: overData ? Object.keys(overData) : null });
20195
+ if (!sourceZone) {
20196
+ dndLog.warn("dragEnd:abort:no-source-zone", { activeId: active.id });
20197
+ return;
20198
+ }
20199
+ if (!targetGroup) {
20200
+ dndLog.warn("dragEnd:abort:no-target-group", { overId: over.id, overData });
20201
+ return;
20202
+ }
20169
20203
  const targetZone = findZoneByGroup(targetGroup);
20170
- if (!targetZone) return;
20204
+ if (!targetZone) {
20205
+ dndLog.warn("dragEnd:abort:target-zone-not-registered", { targetGroup });
20206
+ return;
20207
+ }
20171
20208
  if (sourceZone.group !== targetZone.group) {
20172
20209
  if (targetZone.dropEvent) {
20173
20210
  const newIndex2 = targetZone.itemIds.indexOf(over.id);
20211
+ dndLog.info("dragEnd:cross-container:emit", {
20212
+ event: targetZone.dropEvent,
20213
+ id: String(active.id),
20214
+ sourceGroup: sourceZone.group,
20215
+ targetGroup: targetZone.group,
20216
+ newIndex: newIndex2 === -1 ? targetZone.itemIds.length : newIndex2
20217
+ });
20174
20218
  eventBus.emit(targetZone.dropEvent, {
20175
20219
  id: String(active.id),
20176
20220
  sourceGroup: sourceZone.group,
20177
20221
  targetGroup: targetZone.group,
20178
20222
  newIndex: newIndex2 === -1 ? targetZone.itemIds.length : newIndex2
20179
20223
  });
20224
+ } else {
20225
+ dndLog.warn("dragEnd:cross-container:no-dropEvent-on-target", { targetGroup: targetZone.group });
20180
20226
  }
20181
20227
  return;
20182
20228
  }
@@ -20188,11 +20234,19 @@ function useDataDnd(args) {
20188
20234
  setLocalOrder(reordered);
20189
20235
  }
20190
20236
  if (sourceZone.reorderEvent) {
20237
+ dndLog.info("dragEnd:reorder:emit", {
20238
+ event: sourceZone.reorderEvent,
20239
+ id: String(active.id),
20240
+ oldIndex,
20241
+ newIndex
20242
+ });
20191
20243
  eventBus.emit(sourceZone.reorderEvent, {
20192
20244
  id: String(active.id),
20193
20245
  oldIndex,
20194
20246
  newIndex
20195
20247
  });
20248
+ } else {
20249
+ dndLog.debug("dragEnd:reorder:no-reorderEvent", { sourceGroup: sourceZone.group });
20196
20250
  }
20197
20251
  },
20198
20252
  [orderedItems, ownGroup, findZoneByItem, findZoneByGroup, eventBus]
@@ -20233,15 +20287,20 @@ function useDataDnd(args) {
20233
20287
  [sortableData, enabled]
20234
20288
  );
20235
20289
  const DropZoneShell = ({ children }) => {
20290
+ const droppableId = `dnd-zone-${zoneId}`;
20236
20291
  const { setNodeRef, isOver } = core$1.useDroppable({
20237
- id: `dnd-zone-${zoneId}`,
20292
+ id: droppableId,
20238
20293
  data: sortableData
20239
20294
  });
20295
+ React75__namespace.default.useEffect(() => {
20296
+ dndLog.debug("dropzone:isOver:change", { droppableId, group: ownGroup, isOver });
20297
+ }, [droppableId, isOver]);
20240
20298
  return /* @__PURE__ */ jsxRuntime.jsx(
20241
20299
  exports.Box,
20242
20300
  {
20243
20301
  ref: setNodeRef,
20244
20302
  "data-dnd-zone": ownGroup,
20303
+ "data-dnd-is-over": isOver ? "true" : "false",
20245
20304
  className: isOver ? "ring-2 ring-primary ring-offset-2 rounded-lg transition-all min-h-[3rem]" : "min-h-[3rem] rounded-lg transition-all",
20246
20305
  children
20247
20306
  }
@@ -20251,21 +20310,65 @@ function useDataDnd(args) {
20251
20310
  () => ({ registerZone, unregisterZone }),
20252
20311
  [registerZone, unregisterZone]
20253
20312
  );
20313
+ const handleDragStart = React75__namespace.default.useCallback((event) => {
20314
+ const sourceZone = findZoneByItem(event.active.id);
20315
+ dndLog.info("dragStart", {
20316
+ activeId: event.active.id,
20317
+ activeData: event.active.data?.current,
20318
+ sourceGroup: sourceZone?.group,
20319
+ zoneCount: zonesRef.current.size
20320
+ });
20321
+ }, [findZoneByItem]);
20322
+ const handleDragOver = React75__namespace.default.useCallback((event) => {
20323
+ dndLog.debug("dragOver", {
20324
+ activeId: event.active.id,
20325
+ overId: event.over?.id,
20326
+ overData: event.over?.data?.current
20327
+ });
20328
+ }, []);
20329
+ const handleDragCancel = React75__namespace.default.useCallback((event) => {
20330
+ dndLog.warn("dragCancel", {
20331
+ activeId: event.active.id,
20332
+ reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
20333
+ });
20334
+ }, []);
20254
20335
  const wrapContainer = React75__namespace.default.useCallback(
20255
20336
  (children) => {
20256
20337
  if (!enabled) return children;
20257
20338
  const strategy = layout === "grid" ? sortable.rectSortingStrategy : sortable.verticalListSortingStrategy;
20258
20339
  if (!isZone) {
20259
20340
  if (!isRoot) return children;
20260
- return /* @__PURE__ */ jsxRuntime.jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(core$1.DndContext, { sensors, collisionDetection, onDragEnd: handleDragEnd, children }) });
20341
+ return /* @__PURE__ */ jsxRuntime.jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(
20342
+ core$1.DndContext,
20343
+ {
20344
+ sensors,
20345
+ collisionDetection,
20346
+ onDragStart: handleDragStart,
20347
+ onDragOver: handleDragOver,
20348
+ onDragEnd: handleDragEnd,
20349
+ onDragCancel: handleDragCancel,
20350
+ children
20351
+ }
20352
+ ) });
20261
20353
  }
20262
20354
  const inner = /* @__PURE__ */ jsxRuntime.jsx(DropZoneShell, { children: /* @__PURE__ */ jsxRuntime.jsx(sortable.SortableContext, { items: itemIds, strategy, children }) });
20263
20355
  if (isRoot) {
20264
- return /* @__PURE__ */ jsxRuntime.jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(core$1.DndContext, { sensors, collisionDetection, onDragEnd: handleDragEnd, children: inner }) });
20356
+ return /* @__PURE__ */ jsxRuntime.jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(
20357
+ core$1.DndContext,
20358
+ {
20359
+ sensors,
20360
+ collisionDetection,
20361
+ onDragStart: handleDragStart,
20362
+ onDragOver: handleDragOver,
20363
+ onDragEnd: handleDragEnd,
20364
+ onDragCancel: handleDragCancel,
20365
+ children: inner
20366
+ }
20367
+ ) });
20265
20368
  }
20266
20369
  return inner;
20267
20370
  },
20268
- [enabled, isZone, layout, sensors, collisionDetection, handleDragEnd, itemIds, isRoot, rootContextValue]
20371
+ [enabled, isZone, layout, sensors, collisionDetection, handleDragStart, handleDragOver, handleDragEnd, handleDragCancel, itemIds, isRoot, rootContextValue]
20269
20372
  );
20270
20373
  return {
20271
20374
  enabled,
@@ -20275,12 +20378,13 @@ function useDataDnd(args) {
20275
20378
  orderedItems
20276
20379
  };
20277
20380
  }
20278
- var RootCtx;
20381
+ var dndLog, RootCtx;
20279
20382
  var init_useDataDnd = __esm({
20280
20383
  "components/molecules/useDataDnd.tsx"() {
20281
20384
  "use client";
20282
20385
  init_useEventBus();
20283
20386
  init_Box();
20387
+ dndLog = logger.createLogger("almadar:ui:dnd");
20284
20388
  RootCtx = React75__namespace.default.createContext(null);
20285
20389
  }
20286
20390
  });