@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.
@@ -20078,10 +20078,18 @@ function useDataDnd(args) {
20078
20078
  const target = isRoot ? null : parentRoot;
20079
20079
  if (!target) {
20080
20080
  zonesRef.current.set(zoneId, meta);
20081
- return () => zonesRef.current.delete(zoneId);
20081
+ dndLog.debug("zone:register:self", { zoneId, group: meta.group, itemCount: meta.itemIds.length, isRoot });
20082
+ return () => {
20083
+ zonesRef.current.delete(zoneId);
20084
+ dndLog.debug("zone:unregister:self", { zoneId, group: meta.group });
20085
+ };
20082
20086
  }
20083
20087
  target.registerZone(zoneId, meta);
20084
- return () => target.unregisterZone(zoneId);
20088
+ dndLog.debug("zone:register", { zoneId, group: meta.group, itemCount: meta.itemIds.length, dropEvent: meta.dropEvent, reorderEvent: meta.reorderEvent });
20089
+ return () => {
20090
+ target.unregisterZone(zoneId);
20091
+ dndLog.debug("zone:unregister", { zoneId, group: meta.group });
20092
+ };
20085
20093
  }, [parentRoot, isRoot, zoneId, meta]);
20086
20094
  const sensors = useSensors(
20087
20095
  useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),
@@ -20089,10 +20097,18 @@ function useDataDnd(args) {
20089
20097
  );
20090
20098
  const collisionDetection = React75__default.useCallback((args2) => {
20091
20099
  const pointerCollisions = pointerWithin(args2);
20092
- if (pointerCollisions.length > 0) return pointerCollisions;
20100
+ if (pointerCollisions.length > 0) {
20101
+ dndLog.debug("collision:pointerWithin", { count: pointerCollisions.length, ids: pointerCollisions.map((c) => c.id) });
20102
+ return pointerCollisions;
20103
+ }
20093
20104
  const rectCollisions = rectIntersection(args2);
20094
- if (rectCollisions.length > 0) return rectCollisions;
20095
- return closestCorners(args2);
20105
+ if (rectCollisions.length > 0) {
20106
+ dndLog.debug("collision:rectIntersection", { count: rectCollisions.length, ids: rectCollisions.map((c) => c.id) });
20107
+ return rectCollisions;
20108
+ }
20109
+ const cornerCollisions = closestCorners(args2);
20110
+ dndLog.debug("collision:closestCorners", { count: cornerCollisions.length, ids: cornerCollisions.map((c) => c.id) });
20111
+ return cornerCollisions;
20096
20112
  }, []);
20097
20113
  const findZoneByItem = React75__default.useCallback(
20098
20114
  (id) => {
@@ -20115,22 +20131,52 @@ function useDataDnd(args) {
20115
20131
  const handleDragEnd = React75__default.useCallback(
20116
20132
  (event) => {
20117
20133
  const { active, over } = event;
20118
- if (!over) return;
20134
+ const allZones = Array.from(zonesRef.current.entries()).map(([id, m]) => ({ id, group: m.group, items: m.itemIds.length }));
20135
+ dndLog.debug("dragEnd:received", {
20136
+ activeId: active.id,
20137
+ overId: over?.id,
20138
+ overData: over?.data?.current,
20139
+ zones: allZones
20140
+ });
20141
+ if (!over) {
20142
+ dndLog.warn("dragEnd:abort:no-over", { activeId: active.id, reason: "no droppable under pointer at drop time \u2192 item snaps back" });
20143
+ return;
20144
+ }
20119
20145
  const sourceZone = findZoneByItem(active.id);
20120
20146
  const overData = over.data?.current;
20121
20147
  const targetGroup = overData?.dndGroup;
20122
- if (!sourceZone || !targetGroup) return;
20148
+ dndLog.debug("dragEnd:resolved", { sourceGroup: sourceZone?.group, targetGroup, overDataKeys: overData ? Object.keys(overData) : null });
20149
+ if (!sourceZone) {
20150
+ dndLog.warn("dragEnd:abort:no-source-zone", { activeId: active.id });
20151
+ return;
20152
+ }
20153
+ if (!targetGroup) {
20154
+ dndLog.warn("dragEnd:abort:no-target-group", { overId: over.id, overData });
20155
+ return;
20156
+ }
20123
20157
  const targetZone = findZoneByGroup(targetGroup);
20124
- if (!targetZone) return;
20158
+ if (!targetZone) {
20159
+ dndLog.warn("dragEnd:abort:target-zone-not-registered", { targetGroup });
20160
+ return;
20161
+ }
20125
20162
  if (sourceZone.group !== targetZone.group) {
20126
20163
  if (targetZone.dropEvent) {
20127
20164
  const newIndex2 = targetZone.itemIds.indexOf(over.id);
20165
+ dndLog.info("dragEnd:cross-container:emit", {
20166
+ event: targetZone.dropEvent,
20167
+ id: String(active.id),
20168
+ sourceGroup: sourceZone.group,
20169
+ targetGroup: targetZone.group,
20170
+ newIndex: newIndex2 === -1 ? targetZone.itemIds.length : newIndex2
20171
+ });
20128
20172
  eventBus.emit(targetZone.dropEvent, {
20129
20173
  id: String(active.id),
20130
20174
  sourceGroup: sourceZone.group,
20131
20175
  targetGroup: targetZone.group,
20132
20176
  newIndex: newIndex2 === -1 ? targetZone.itemIds.length : newIndex2
20133
20177
  });
20178
+ } else {
20179
+ dndLog.warn("dragEnd:cross-container:no-dropEvent-on-target", { targetGroup: targetZone.group });
20134
20180
  }
20135
20181
  return;
20136
20182
  }
@@ -20142,11 +20188,19 @@ function useDataDnd(args) {
20142
20188
  setLocalOrder(reordered);
20143
20189
  }
20144
20190
  if (sourceZone.reorderEvent) {
20191
+ dndLog.info("dragEnd:reorder:emit", {
20192
+ event: sourceZone.reorderEvent,
20193
+ id: String(active.id),
20194
+ oldIndex,
20195
+ newIndex
20196
+ });
20145
20197
  eventBus.emit(sourceZone.reorderEvent, {
20146
20198
  id: String(active.id),
20147
20199
  oldIndex,
20148
20200
  newIndex
20149
20201
  });
20202
+ } else {
20203
+ dndLog.debug("dragEnd:reorder:no-reorderEvent", { sourceGroup: sourceZone.group });
20150
20204
  }
20151
20205
  },
20152
20206
  [orderedItems, ownGroup, findZoneByItem, findZoneByGroup, eventBus]
@@ -20187,15 +20241,20 @@ function useDataDnd(args) {
20187
20241
  [sortableData, enabled]
20188
20242
  );
20189
20243
  const DropZoneShell = ({ children }) => {
20244
+ const droppableId = `dnd-zone-${zoneId}`;
20190
20245
  const { setNodeRef, isOver } = useDroppable({
20191
- id: `dnd-zone-${zoneId}`,
20246
+ id: droppableId,
20192
20247
  data: sortableData
20193
20248
  });
20249
+ React75__default.useEffect(() => {
20250
+ dndLog.debug("dropzone:isOver:change", { droppableId, group: ownGroup, isOver });
20251
+ }, [droppableId, isOver]);
20194
20252
  return /* @__PURE__ */ jsx(
20195
20253
  Box,
20196
20254
  {
20197
20255
  ref: setNodeRef,
20198
20256
  "data-dnd-zone": ownGroup,
20257
+ "data-dnd-is-over": isOver ? "true" : "false",
20199
20258
  className: isOver ? "ring-2 ring-primary ring-offset-2 rounded-lg transition-all min-h-[3rem]" : "min-h-[3rem] rounded-lg transition-all",
20200
20259
  children
20201
20260
  }
@@ -20205,21 +20264,65 @@ function useDataDnd(args) {
20205
20264
  () => ({ registerZone, unregisterZone }),
20206
20265
  [registerZone, unregisterZone]
20207
20266
  );
20267
+ const handleDragStart = React75__default.useCallback((event) => {
20268
+ const sourceZone = findZoneByItem(event.active.id);
20269
+ dndLog.info("dragStart", {
20270
+ activeId: event.active.id,
20271
+ activeData: event.active.data?.current,
20272
+ sourceGroup: sourceZone?.group,
20273
+ zoneCount: zonesRef.current.size
20274
+ });
20275
+ }, [findZoneByItem]);
20276
+ const handleDragOver = React75__default.useCallback((event) => {
20277
+ dndLog.debug("dragOver", {
20278
+ activeId: event.active.id,
20279
+ overId: event.over?.id,
20280
+ overData: event.over?.data?.current
20281
+ });
20282
+ }, []);
20283
+ const handleDragCancel = React75__default.useCallback((event) => {
20284
+ dndLog.warn("dragCancel", {
20285
+ activeId: event.active.id,
20286
+ reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
20287
+ });
20288
+ }, []);
20208
20289
  const wrapContainer = React75__default.useCallback(
20209
20290
  (children) => {
20210
20291
  if (!enabled) return children;
20211
20292
  const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
20212
20293
  if (!isZone) {
20213
20294
  if (!isRoot) return children;
20214
- return /* @__PURE__ */ jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsx(DndContext, { sensors, collisionDetection, onDragEnd: handleDragEnd, children }) });
20295
+ return /* @__PURE__ */ jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsx(
20296
+ DndContext,
20297
+ {
20298
+ sensors,
20299
+ collisionDetection,
20300
+ onDragStart: handleDragStart,
20301
+ onDragOver: handleDragOver,
20302
+ onDragEnd: handleDragEnd,
20303
+ onDragCancel: handleDragCancel,
20304
+ children
20305
+ }
20306
+ ) });
20215
20307
  }
20216
20308
  const inner = /* @__PURE__ */ jsx(DropZoneShell, { children: /* @__PURE__ */ jsx(SortableContext, { items: itemIds, strategy, children }) });
20217
20309
  if (isRoot) {
20218
- return /* @__PURE__ */ jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsx(DndContext, { sensors, collisionDetection, onDragEnd: handleDragEnd, children: inner }) });
20310
+ return /* @__PURE__ */ jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsx(
20311
+ DndContext,
20312
+ {
20313
+ sensors,
20314
+ collisionDetection,
20315
+ onDragStart: handleDragStart,
20316
+ onDragOver: handleDragOver,
20317
+ onDragEnd: handleDragEnd,
20318
+ onDragCancel: handleDragCancel,
20319
+ children: inner
20320
+ }
20321
+ ) });
20219
20322
  }
20220
20323
  return inner;
20221
20324
  },
20222
- [enabled, isZone, layout, sensors, collisionDetection, handleDragEnd, itemIds, isRoot, rootContextValue]
20325
+ [enabled, isZone, layout, sensors, collisionDetection, handleDragStart, handleDragOver, handleDragEnd, handleDragCancel, itemIds, isRoot, rootContextValue]
20223
20326
  );
20224
20327
  return {
20225
20328
  enabled,
@@ -20229,12 +20332,13 @@ function useDataDnd(args) {
20229
20332
  orderedItems
20230
20333
  };
20231
20334
  }
20232
- var RootCtx;
20335
+ var dndLog, RootCtx;
20233
20336
  var init_useDataDnd = __esm({
20234
20337
  "components/molecules/useDataDnd.tsx"() {
20235
20338
  "use client";
20236
20339
  init_useEventBus();
20237
20340
  init_Box();
20341
+ dndLog = createLogger("almadar:ui:dnd");
20238
20342
  RootCtx = React75__default.createContext(null);
20239
20343
  }
20240
20344
  });
@@ -21369,10 +21369,18 @@ function useDataDnd(args) {
21369
21369
  const target = isRoot ? null : parentRoot;
21370
21370
  if (!target) {
21371
21371
  zonesRef.current.set(zoneId, meta);
21372
- return () => zonesRef.current.delete(zoneId);
21372
+ dndLog.debug("zone:register:self", { zoneId, group: meta.group, itemCount: meta.itemIds.length, isRoot });
21373
+ return () => {
21374
+ zonesRef.current.delete(zoneId);
21375
+ dndLog.debug("zone:unregister:self", { zoneId, group: meta.group });
21376
+ };
21373
21377
  }
21374
21378
  target.registerZone(zoneId, meta);
21375
- return () => target.unregisterZone(zoneId);
21379
+ dndLog.debug("zone:register", { zoneId, group: meta.group, itemCount: meta.itemIds.length, dropEvent: meta.dropEvent, reorderEvent: meta.reorderEvent });
21380
+ return () => {
21381
+ target.unregisterZone(zoneId);
21382
+ dndLog.debug("zone:unregister", { zoneId, group: meta.group });
21383
+ };
21376
21384
  }, [parentRoot, isRoot, zoneId, meta]);
21377
21385
  const sensors = core$1.useSensors(
21378
21386
  core$1.useSensor(core$1.PointerSensor, { activationConstraint: { distance: 5 } }),
@@ -21380,10 +21388,18 @@ function useDataDnd(args) {
21380
21388
  );
21381
21389
  const collisionDetection = React81__namespace.default.useCallback((args2) => {
21382
21390
  const pointerCollisions = core$1.pointerWithin(args2);
21383
- if (pointerCollisions.length > 0) return pointerCollisions;
21391
+ if (pointerCollisions.length > 0) {
21392
+ dndLog.debug("collision:pointerWithin", { count: pointerCollisions.length, ids: pointerCollisions.map((c) => c.id) });
21393
+ return pointerCollisions;
21394
+ }
21384
21395
  const rectCollisions = core$1.rectIntersection(args2);
21385
- if (rectCollisions.length > 0) return rectCollisions;
21386
- return core$1.closestCorners(args2);
21396
+ if (rectCollisions.length > 0) {
21397
+ dndLog.debug("collision:rectIntersection", { count: rectCollisions.length, ids: rectCollisions.map((c) => c.id) });
21398
+ return rectCollisions;
21399
+ }
21400
+ const cornerCollisions = core$1.closestCorners(args2);
21401
+ dndLog.debug("collision:closestCorners", { count: cornerCollisions.length, ids: cornerCollisions.map((c) => c.id) });
21402
+ return cornerCollisions;
21387
21403
  }, []);
21388
21404
  const findZoneByItem = React81__namespace.default.useCallback(
21389
21405
  (id) => {
@@ -21406,22 +21422,52 @@ function useDataDnd(args) {
21406
21422
  const handleDragEnd = React81__namespace.default.useCallback(
21407
21423
  (event) => {
21408
21424
  const { active, over } = event;
21409
- if (!over) return;
21425
+ const allZones = Array.from(zonesRef.current.entries()).map(([id, m]) => ({ id, group: m.group, items: m.itemIds.length }));
21426
+ dndLog.debug("dragEnd:received", {
21427
+ activeId: active.id,
21428
+ overId: over?.id,
21429
+ overData: over?.data?.current,
21430
+ zones: allZones
21431
+ });
21432
+ if (!over) {
21433
+ dndLog.warn("dragEnd:abort:no-over", { activeId: active.id, reason: "no droppable under pointer at drop time \u2192 item snaps back" });
21434
+ return;
21435
+ }
21410
21436
  const sourceZone = findZoneByItem(active.id);
21411
21437
  const overData = over.data?.current;
21412
21438
  const targetGroup = overData?.dndGroup;
21413
- if (!sourceZone || !targetGroup) return;
21439
+ dndLog.debug("dragEnd:resolved", { sourceGroup: sourceZone?.group, targetGroup, overDataKeys: overData ? Object.keys(overData) : null });
21440
+ if (!sourceZone) {
21441
+ dndLog.warn("dragEnd:abort:no-source-zone", { activeId: active.id });
21442
+ return;
21443
+ }
21444
+ if (!targetGroup) {
21445
+ dndLog.warn("dragEnd:abort:no-target-group", { overId: over.id, overData });
21446
+ return;
21447
+ }
21414
21448
  const targetZone = findZoneByGroup(targetGroup);
21415
- if (!targetZone) return;
21449
+ if (!targetZone) {
21450
+ dndLog.warn("dragEnd:abort:target-zone-not-registered", { targetGroup });
21451
+ return;
21452
+ }
21416
21453
  if (sourceZone.group !== targetZone.group) {
21417
21454
  if (targetZone.dropEvent) {
21418
21455
  const newIndex2 = targetZone.itemIds.indexOf(over.id);
21456
+ dndLog.info("dragEnd:cross-container:emit", {
21457
+ event: targetZone.dropEvent,
21458
+ id: String(active.id),
21459
+ sourceGroup: sourceZone.group,
21460
+ targetGroup: targetZone.group,
21461
+ newIndex: newIndex2 === -1 ? targetZone.itemIds.length : newIndex2
21462
+ });
21419
21463
  eventBus.emit(targetZone.dropEvent, {
21420
21464
  id: String(active.id),
21421
21465
  sourceGroup: sourceZone.group,
21422
21466
  targetGroup: targetZone.group,
21423
21467
  newIndex: newIndex2 === -1 ? targetZone.itemIds.length : newIndex2
21424
21468
  });
21469
+ } else {
21470
+ dndLog.warn("dragEnd:cross-container:no-dropEvent-on-target", { targetGroup: targetZone.group });
21425
21471
  }
21426
21472
  return;
21427
21473
  }
@@ -21433,11 +21479,19 @@ function useDataDnd(args) {
21433
21479
  setLocalOrder(reordered);
21434
21480
  }
21435
21481
  if (sourceZone.reorderEvent) {
21482
+ dndLog.info("dragEnd:reorder:emit", {
21483
+ event: sourceZone.reorderEvent,
21484
+ id: String(active.id),
21485
+ oldIndex,
21486
+ newIndex
21487
+ });
21436
21488
  eventBus.emit(sourceZone.reorderEvent, {
21437
21489
  id: String(active.id),
21438
21490
  oldIndex,
21439
21491
  newIndex
21440
21492
  });
21493
+ } else {
21494
+ dndLog.debug("dragEnd:reorder:no-reorderEvent", { sourceGroup: sourceZone.group });
21441
21495
  }
21442
21496
  },
21443
21497
  [orderedItems, ownGroup, findZoneByItem, findZoneByGroup, eventBus]
@@ -21478,15 +21532,20 @@ function useDataDnd(args) {
21478
21532
  [sortableData, enabled]
21479
21533
  );
21480
21534
  const DropZoneShell = ({ children }) => {
21535
+ const droppableId = `dnd-zone-${zoneId}`;
21481
21536
  const { setNodeRef, isOver } = core$1.useDroppable({
21482
- id: `dnd-zone-${zoneId}`,
21537
+ id: droppableId,
21483
21538
  data: sortableData
21484
21539
  });
21540
+ React81__namespace.default.useEffect(() => {
21541
+ dndLog.debug("dropzone:isOver:change", { droppableId, group: ownGroup, isOver });
21542
+ }, [droppableId, isOver]);
21485
21543
  return /* @__PURE__ */ jsxRuntime.jsx(
21486
21544
  Box,
21487
21545
  {
21488
21546
  ref: setNodeRef,
21489
21547
  "data-dnd-zone": ownGroup,
21548
+ "data-dnd-is-over": isOver ? "true" : "false",
21490
21549
  className: isOver ? "ring-2 ring-primary ring-offset-2 rounded-lg transition-all min-h-[3rem]" : "min-h-[3rem] rounded-lg transition-all",
21491
21550
  children
21492
21551
  }
@@ -21496,21 +21555,65 @@ function useDataDnd(args) {
21496
21555
  () => ({ registerZone, unregisterZone }),
21497
21556
  [registerZone, unregisterZone]
21498
21557
  );
21558
+ const handleDragStart = React81__namespace.default.useCallback((event) => {
21559
+ const sourceZone = findZoneByItem(event.active.id);
21560
+ dndLog.info("dragStart", {
21561
+ activeId: event.active.id,
21562
+ activeData: event.active.data?.current,
21563
+ sourceGroup: sourceZone?.group,
21564
+ zoneCount: zonesRef.current.size
21565
+ });
21566
+ }, [findZoneByItem]);
21567
+ const handleDragOver = React81__namespace.default.useCallback((event) => {
21568
+ dndLog.debug("dragOver", {
21569
+ activeId: event.active.id,
21570
+ overId: event.over?.id,
21571
+ overData: event.over?.data?.current
21572
+ });
21573
+ }, []);
21574
+ const handleDragCancel = React81__namespace.default.useCallback((event) => {
21575
+ dndLog.warn("dragCancel", {
21576
+ activeId: event.active.id,
21577
+ reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
21578
+ });
21579
+ }, []);
21499
21580
  const wrapContainer = React81__namespace.default.useCallback(
21500
21581
  (children) => {
21501
21582
  if (!enabled) return children;
21502
21583
  const strategy = layout === "grid" ? sortable.rectSortingStrategy : sortable.verticalListSortingStrategy;
21503
21584
  if (!isZone) {
21504
21585
  if (!isRoot) return children;
21505
- return /* @__PURE__ */ jsxRuntime.jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(core$1.DndContext, { sensors, collisionDetection, onDragEnd: handleDragEnd, children }) });
21586
+ return /* @__PURE__ */ jsxRuntime.jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(
21587
+ core$1.DndContext,
21588
+ {
21589
+ sensors,
21590
+ collisionDetection,
21591
+ onDragStart: handleDragStart,
21592
+ onDragOver: handleDragOver,
21593
+ onDragEnd: handleDragEnd,
21594
+ onDragCancel: handleDragCancel,
21595
+ children
21596
+ }
21597
+ ) });
21506
21598
  }
21507
21599
  const inner = /* @__PURE__ */ jsxRuntime.jsx(DropZoneShell, { children: /* @__PURE__ */ jsxRuntime.jsx(sortable.SortableContext, { items: itemIds, strategy, children }) });
21508
21600
  if (isRoot) {
21509
- return /* @__PURE__ */ jsxRuntime.jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(core$1.DndContext, { sensors, collisionDetection, onDragEnd: handleDragEnd, children: inner }) });
21601
+ return /* @__PURE__ */ jsxRuntime.jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(
21602
+ core$1.DndContext,
21603
+ {
21604
+ sensors,
21605
+ collisionDetection,
21606
+ onDragStart: handleDragStart,
21607
+ onDragOver: handleDragOver,
21608
+ onDragEnd: handleDragEnd,
21609
+ onDragCancel: handleDragCancel,
21610
+ children: inner
21611
+ }
21612
+ ) });
21510
21613
  }
21511
21614
  return inner;
21512
21615
  },
21513
- [enabled, isZone, layout, sensors, collisionDetection, handleDragEnd, itemIds, isRoot, rootContextValue]
21616
+ [enabled, isZone, layout, sensors, collisionDetection, handleDragStart, handleDragOver, handleDragEnd, handleDragCancel, itemIds, isRoot, rootContextValue]
21514
21617
  );
21515
21618
  return {
21516
21619
  enabled,
@@ -21520,12 +21623,13 @@ function useDataDnd(args) {
21520
21623
  orderedItems
21521
21624
  };
21522
21625
  }
21523
- var RootCtx;
21626
+ var dndLog, RootCtx;
21524
21627
  var init_useDataDnd = __esm({
21525
21628
  "components/molecules/useDataDnd.tsx"() {
21526
21629
  "use client";
21527
21630
  init_useEventBus();
21528
21631
  init_Box();
21632
+ dndLog = logger.createLogger("almadar:ui:dnd");
21529
21633
  RootCtx = React81__namespace.default.createContext(null);
21530
21634
  }
21531
21635
  });
@@ -21323,10 +21323,18 @@ function useDataDnd(args) {
21323
21323
  const target = isRoot ? null : parentRoot;
21324
21324
  if (!target) {
21325
21325
  zonesRef.current.set(zoneId, meta);
21326
- return () => zonesRef.current.delete(zoneId);
21326
+ dndLog.debug("zone:register:self", { zoneId, group: meta.group, itemCount: meta.itemIds.length, isRoot });
21327
+ return () => {
21328
+ zonesRef.current.delete(zoneId);
21329
+ dndLog.debug("zone:unregister:self", { zoneId, group: meta.group });
21330
+ };
21327
21331
  }
21328
21332
  target.registerZone(zoneId, meta);
21329
- return () => target.unregisterZone(zoneId);
21333
+ dndLog.debug("zone:register", { zoneId, group: meta.group, itemCount: meta.itemIds.length, dropEvent: meta.dropEvent, reorderEvent: meta.reorderEvent });
21334
+ return () => {
21335
+ target.unregisterZone(zoneId);
21336
+ dndLog.debug("zone:unregister", { zoneId, group: meta.group });
21337
+ };
21330
21338
  }, [parentRoot, isRoot, zoneId, meta]);
21331
21339
  const sensors = useSensors(
21332
21340
  useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),
@@ -21334,10 +21342,18 @@ function useDataDnd(args) {
21334
21342
  );
21335
21343
  const collisionDetection = React81__default.useCallback((args2) => {
21336
21344
  const pointerCollisions = pointerWithin(args2);
21337
- if (pointerCollisions.length > 0) return pointerCollisions;
21345
+ if (pointerCollisions.length > 0) {
21346
+ dndLog.debug("collision:pointerWithin", { count: pointerCollisions.length, ids: pointerCollisions.map((c) => c.id) });
21347
+ return pointerCollisions;
21348
+ }
21338
21349
  const rectCollisions = rectIntersection(args2);
21339
- if (rectCollisions.length > 0) return rectCollisions;
21340
- return closestCorners(args2);
21350
+ if (rectCollisions.length > 0) {
21351
+ dndLog.debug("collision:rectIntersection", { count: rectCollisions.length, ids: rectCollisions.map((c) => c.id) });
21352
+ return rectCollisions;
21353
+ }
21354
+ const cornerCollisions = closestCorners(args2);
21355
+ dndLog.debug("collision:closestCorners", { count: cornerCollisions.length, ids: cornerCollisions.map((c) => c.id) });
21356
+ return cornerCollisions;
21341
21357
  }, []);
21342
21358
  const findZoneByItem = React81__default.useCallback(
21343
21359
  (id) => {
@@ -21360,22 +21376,52 @@ function useDataDnd(args) {
21360
21376
  const handleDragEnd = React81__default.useCallback(
21361
21377
  (event) => {
21362
21378
  const { active, over } = event;
21363
- if (!over) return;
21379
+ const allZones = Array.from(zonesRef.current.entries()).map(([id, m]) => ({ id, group: m.group, items: m.itemIds.length }));
21380
+ dndLog.debug("dragEnd:received", {
21381
+ activeId: active.id,
21382
+ overId: over?.id,
21383
+ overData: over?.data?.current,
21384
+ zones: allZones
21385
+ });
21386
+ if (!over) {
21387
+ dndLog.warn("dragEnd:abort:no-over", { activeId: active.id, reason: "no droppable under pointer at drop time \u2192 item snaps back" });
21388
+ return;
21389
+ }
21364
21390
  const sourceZone = findZoneByItem(active.id);
21365
21391
  const overData = over.data?.current;
21366
21392
  const targetGroup = overData?.dndGroup;
21367
- if (!sourceZone || !targetGroup) return;
21393
+ dndLog.debug("dragEnd:resolved", { sourceGroup: sourceZone?.group, targetGroup, overDataKeys: overData ? Object.keys(overData) : null });
21394
+ if (!sourceZone) {
21395
+ dndLog.warn("dragEnd:abort:no-source-zone", { activeId: active.id });
21396
+ return;
21397
+ }
21398
+ if (!targetGroup) {
21399
+ dndLog.warn("dragEnd:abort:no-target-group", { overId: over.id, overData });
21400
+ return;
21401
+ }
21368
21402
  const targetZone = findZoneByGroup(targetGroup);
21369
- if (!targetZone) return;
21403
+ if (!targetZone) {
21404
+ dndLog.warn("dragEnd:abort:target-zone-not-registered", { targetGroup });
21405
+ return;
21406
+ }
21370
21407
  if (sourceZone.group !== targetZone.group) {
21371
21408
  if (targetZone.dropEvent) {
21372
21409
  const newIndex2 = targetZone.itemIds.indexOf(over.id);
21410
+ dndLog.info("dragEnd:cross-container:emit", {
21411
+ event: targetZone.dropEvent,
21412
+ id: String(active.id),
21413
+ sourceGroup: sourceZone.group,
21414
+ targetGroup: targetZone.group,
21415
+ newIndex: newIndex2 === -1 ? targetZone.itemIds.length : newIndex2
21416
+ });
21373
21417
  eventBus.emit(targetZone.dropEvent, {
21374
21418
  id: String(active.id),
21375
21419
  sourceGroup: sourceZone.group,
21376
21420
  targetGroup: targetZone.group,
21377
21421
  newIndex: newIndex2 === -1 ? targetZone.itemIds.length : newIndex2
21378
21422
  });
21423
+ } else {
21424
+ dndLog.warn("dragEnd:cross-container:no-dropEvent-on-target", { targetGroup: targetZone.group });
21379
21425
  }
21380
21426
  return;
21381
21427
  }
@@ -21387,11 +21433,19 @@ function useDataDnd(args) {
21387
21433
  setLocalOrder(reordered);
21388
21434
  }
21389
21435
  if (sourceZone.reorderEvent) {
21436
+ dndLog.info("dragEnd:reorder:emit", {
21437
+ event: sourceZone.reorderEvent,
21438
+ id: String(active.id),
21439
+ oldIndex,
21440
+ newIndex
21441
+ });
21390
21442
  eventBus.emit(sourceZone.reorderEvent, {
21391
21443
  id: String(active.id),
21392
21444
  oldIndex,
21393
21445
  newIndex
21394
21446
  });
21447
+ } else {
21448
+ dndLog.debug("dragEnd:reorder:no-reorderEvent", { sourceGroup: sourceZone.group });
21395
21449
  }
21396
21450
  },
21397
21451
  [orderedItems, ownGroup, findZoneByItem, findZoneByGroup, eventBus]
@@ -21432,15 +21486,20 @@ function useDataDnd(args) {
21432
21486
  [sortableData, enabled]
21433
21487
  );
21434
21488
  const DropZoneShell = ({ children }) => {
21489
+ const droppableId = `dnd-zone-${zoneId}`;
21435
21490
  const { setNodeRef, isOver } = useDroppable({
21436
- id: `dnd-zone-${zoneId}`,
21491
+ id: droppableId,
21437
21492
  data: sortableData
21438
21493
  });
21494
+ React81__default.useEffect(() => {
21495
+ dndLog.debug("dropzone:isOver:change", { droppableId, group: ownGroup, isOver });
21496
+ }, [droppableId, isOver]);
21439
21497
  return /* @__PURE__ */ jsx(
21440
21498
  Box,
21441
21499
  {
21442
21500
  ref: setNodeRef,
21443
21501
  "data-dnd-zone": ownGroup,
21502
+ "data-dnd-is-over": isOver ? "true" : "false",
21444
21503
  className: isOver ? "ring-2 ring-primary ring-offset-2 rounded-lg transition-all min-h-[3rem]" : "min-h-[3rem] rounded-lg transition-all",
21445
21504
  children
21446
21505
  }
@@ -21450,21 +21509,65 @@ function useDataDnd(args) {
21450
21509
  () => ({ registerZone, unregisterZone }),
21451
21510
  [registerZone, unregisterZone]
21452
21511
  );
21512
+ const handleDragStart = React81__default.useCallback((event) => {
21513
+ const sourceZone = findZoneByItem(event.active.id);
21514
+ dndLog.info("dragStart", {
21515
+ activeId: event.active.id,
21516
+ activeData: event.active.data?.current,
21517
+ sourceGroup: sourceZone?.group,
21518
+ zoneCount: zonesRef.current.size
21519
+ });
21520
+ }, [findZoneByItem]);
21521
+ const handleDragOver = React81__default.useCallback((event) => {
21522
+ dndLog.debug("dragOver", {
21523
+ activeId: event.active.id,
21524
+ overId: event.over?.id,
21525
+ overData: event.over?.data?.current
21526
+ });
21527
+ }, []);
21528
+ const handleDragCancel = React81__default.useCallback((event) => {
21529
+ dndLog.warn("dragCancel", {
21530
+ activeId: event.active.id,
21531
+ reason: "dnd-kit cancelled the drag (escape key, pointer interrupted, or external)"
21532
+ });
21533
+ }, []);
21453
21534
  const wrapContainer = React81__default.useCallback(
21454
21535
  (children) => {
21455
21536
  if (!enabled) return children;
21456
21537
  const strategy = layout === "grid" ? rectSortingStrategy : verticalListSortingStrategy;
21457
21538
  if (!isZone) {
21458
21539
  if (!isRoot) return children;
21459
- return /* @__PURE__ */ jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsx(DndContext, { sensors, collisionDetection, onDragEnd: handleDragEnd, children }) });
21540
+ return /* @__PURE__ */ jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsx(
21541
+ DndContext,
21542
+ {
21543
+ sensors,
21544
+ collisionDetection,
21545
+ onDragStart: handleDragStart,
21546
+ onDragOver: handleDragOver,
21547
+ onDragEnd: handleDragEnd,
21548
+ onDragCancel: handleDragCancel,
21549
+ children
21550
+ }
21551
+ ) });
21460
21552
  }
21461
21553
  const inner = /* @__PURE__ */ jsx(DropZoneShell, { children: /* @__PURE__ */ jsx(SortableContext, { items: itemIds, strategy, children }) });
21462
21554
  if (isRoot) {
21463
- return /* @__PURE__ */ jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsx(DndContext, { sensors, collisionDetection, onDragEnd: handleDragEnd, children: inner }) });
21555
+ return /* @__PURE__ */ jsx(RootCtx.Provider, { value: rootContextValue, children: /* @__PURE__ */ jsx(
21556
+ DndContext,
21557
+ {
21558
+ sensors,
21559
+ collisionDetection,
21560
+ onDragStart: handleDragStart,
21561
+ onDragOver: handleDragOver,
21562
+ onDragEnd: handleDragEnd,
21563
+ onDragCancel: handleDragCancel,
21564
+ children: inner
21565
+ }
21566
+ ) });
21464
21567
  }
21465
21568
  return inner;
21466
21569
  },
21467
- [enabled, isZone, layout, sensors, collisionDetection, handleDragEnd, itemIds, isRoot, rootContextValue]
21570
+ [enabled, isZone, layout, sensors, collisionDetection, handleDragStart, handleDragOver, handleDragEnd, handleDragCancel, itemIds, isRoot, rootContextValue]
21468
21571
  );
21469
21572
  return {
21470
21573
  enabled,
@@ -21474,12 +21577,13 @@ function useDataDnd(args) {
21474
21577
  orderedItems
21475
21578
  };
21476
21579
  }
21477
- var RootCtx;
21580
+ var dndLog, RootCtx;
21478
21581
  var init_useDataDnd = __esm({
21479
21582
  "components/molecules/useDataDnd.tsx"() {
21480
21583
  "use client";
21481
21584
  init_useEventBus();
21482
21585
  init_Box();
21586
+ dndLog = createLogger("almadar:ui:dnd");
21483
21587
  RootCtx = React81__default.createContext(null);
21484
21588
  }
21485
21589
  });