@headless-tree/core 0.0.0-20251215184014 → 0.0.0-20260107220200

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,13 @@
1
1
  # @headless-tree/core
2
2
 
3
- ## 0.0.0-20251215184014
3
+ ## 0.0.0-20260107220200
4
+
5
+ ### Patch Changes
6
+
7
+ - 39a8b44: Add skipUpdateTree parameter to `updateCachedChildrenIds` and `updateCachedData` in async tree loader
8
+ - ffd2619: Fixed an issue where `canDropForeignDragObject` was being called in `onDragOver` events without payload. `canDropForeignDragObject` should never be called in `onDragOver` events since there, browsers do not allow access to the data transfer payload. Now, `canDropForeignDragObject` is only called in onDrop events, and `canDragForeignDragObjectOver` is always called in `onDragOver` events.
9
+
10
+ ## 1.6.1
4
11
 
5
12
  ### Patch Changes
6
13
 
package/dist/index.d.mts CHANGED
@@ -329,9 +329,11 @@ type AsyncDataLoaderFeatureDef<T> = {
329
329
  * @param optimistic If true, the item will not trigger a state update on `loadingItemChildrens`, and
330
330
  * the tree will continue to display the old data until the new data has loaded. */
331
331
  invalidateChildrenIds: (optimistic?: boolean) => Promise<void>;
332
- /** Set to undefined to clear cache without triggering automatic refetch. Use @invalidateItemData to clear and triggering refetch. */
333
- updateCachedData: (data: T | undefined) => void;
334
- updateCachedChildrenIds: (childrenIds: string[]) => void;
332
+ /** Set to undefined to clear cache without triggering automatic refetch. Use @invalidateItemData to clear and triggering refetch.
333
+ * @param skipUpdateTree If true, the tree will not rebuild the tree structure cache afterwards by calling `tree.rebuildTree()`. */
334
+ updateCachedData: (data: T | undefined, skipUpdateTree?: boolean) => void;
335
+ /** @param skipUpdateTree If true, the tree will not rebuild the tree structure cache afterwards by calling `tree.rebuildTree()`. */
336
+ updateCachedChildrenIds: (childrenIds: string[], skipUpdateTree?: boolean) => void;
335
337
  hasLoadedData: () => boolean;
336
338
  isLoading: () => boolean;
337
339
  };
package/dist/index.d.ts CHANGED
@@ -329,9 +329,11 @@ type AsyncDataLoaderFeatureDef<T> = {
329
329
  * @param optimistic If true, the item will not trigger a state update on `loadingItemChildrens`, and
330
330
  * the tree will continue to display the old data until the new data has loaded. */
331
331
  invalidateChildrenIds: (optimistic?: boolean) => Promise<void>;
332
- /** Set to undefined to clear cache without triggering automatic refetch. Use @invalidateItemData to clear and triggering refetch. */
333
- updateCachedData: (data: T | undefined) => void;
334
- updateCachedChildrenIds: (childrenIds: string[]) => void;
332
+ /** Set to undefined to clear cache without triggering automatic refetch. Use @invalidateItemData to clear and triggering refetch.
333
+ * @param skipUpdateTree If true, the tree will not rebuild the tree structure cache afterwards by calling `tree.rebuildTree()`. */
334
+ updateCachedData: (data: T | undefined, skipUpdateTree?: boolean) => void;
335
+ /** @param skipUpdateTree If true, the tree will not rebuild the tree structure cache afterwards by calling `tree.rebuildTree()`. */
336
+ updateCachedChildrenIds: (childrenIds: string[], skipUpdateTree?: boolean) => void;
335
337
  hasLoadedData: () => boolean;
336
338
  isLoading: () => boolean;
337
339
  };
package/dist/index.js CHANGED
@@ -1274,15 +1274,17 @@ var asyncDataLoaderFeature = {
1274
1274
  }
1275
1275
  yield loadChildrenIds(tree, itemId);
1276
1276
  }),
1277
- updateCachedChildrenIds: ({ tree, itemId }, childrenIds) => {
1278
- const dataRef = tree.getDataRef();
1279
- dataRef.current.childrenIds[itemId] = childrenIds;
1280
- tree.rebuildTree();
1277
+ updateCachedChildrenIds: ({ tree, itemId }, childrenIds, skipUpdateTree) => {
1278
+ getDataRef(tree).current.childrenIds[itemId] = childrenIds;
1279
+ if (!skipUpdateTree) {
1280
+ tree.rebuildTree();
1281
+ }
1281
1282
  },
1282
- updateCachedData: ({ tree, itemId }, data) => {
1283
- const dataRef = tree.getDataRef();
1284
- dataRef.current.itemData[itemId] = data;
1285
- tree.rebuildTree();
1283
+ updateCachedData: ({ tree, itemId }, data, skipUpdateTree) => {
1284
+ getDataRef(tree).current.itemData[itemId] = data;
1285
+ if (!skipUpdateTree) {
1286
+ tree.rebuildTree();
1287
+ }
1286
1288
  },
1287
1289
  hasLoadedData: ({ tree, itemId }) => {
1288
1290
  const dataRef = tree.getDataRef();
@@ -1449,15 +1451,16 @@ var getReparentTarget = (item, reparentLevel, draggedItems) => {
1449
1451
  dragLineLevel: reparentLevel
1450
1452
  };
1451
1453
  };
1452
- var getDragTarget = (e, item, tree, canReorder = tree.getConfig().canReorder) => {
1454
+ var getDragTarget = (e, item, tree, hasDataTransferPayload, canReorder = tree.getConfig().canReorder) => {
1453
1455
  var _a;
1456
+ const dataTransfer = hasDataTransferPayload ? e.dataTransfer : null;
1454
1457
  const draggedItems = (_a = tree.getState().dnd) == null ? void 0 : _a.draggedItems;
1455
1458
  const itemMeta = item.getItemMeta();
1456
1459
  const parent = item.getParent();
1457
1460
  const itemTarget = { item };
1458
1461
  const parentTarget = parent ? { item: parent } : null;
1459
- const canBecomeSibling = parentTarget && canDrop(e.dataTransfer, parentTarget, tree);
1460
- const canMakeChild = canDrop(e.dataTransfer, itemTarget, tree);
1462
+ const canBecomeSibling = parentTarget && canDrop(dataTransfer, parentTarget, tree);
1463
+ const canMakeChild = canDrop(dataTransfer, itemTarget, tree);
1461
1464
  const placement = getTargetPlacement(e, item, tree, canMakeChild);
1462
1465
  if (!canReorder && parent && canBecomeSibling && placement.type !== 2 /* MakeChild */) {
1463
1466
  if (draggedItems == null ? void 0 : draggedItems.some((item2) => item2.isDescendentOf(parent.getId()))) {
@@ -1466,7 +1469,7 @@ var getDragTarget = (e, item, tree, canReorder = tree.getConfig().canReorder) =>
1466
1469
  return parentTarget;
1467
1470
  }
1468
1471
  if (!canReorder && parent && !canBecomeSibling) {
1469
- return getDragTarget(e, parent, tree, false);
1472
+ return getDragTarget(e, parent, tree, hasDataTransferPayload, false);
1470
1473
  }
1471
1474
  if (!parent) {
1472
1475
  return itemTarget;
@@ -1475,7 +1478,7 @@ var getDragTarget = (e, item, tree, canReorder = tree.getConfig().canReorder) =>
1475
1478
  return itemTarget;
1476
1479
  }
1477
1480
  if (!canBecomeSibling) {
1478
- return getDragTarget(e, parent, tree, false);
1481
+ return getDragTarget(e, parent, tree, hasDataTransferPayload, false);
1479
1482
  }
1480
1483
  if (placement.type === 3 /* Reparent */) {
1481
1484
  return getReparentTarget(item, placement.reparentLevel, draggedItems);
@@ -1657,12 +1660,12 @@ var dragAndDropFeature = {
1657
1660
  dataRef.current.lastDragCode = nextDragCode;
1658
1661
  dataRef.current.lastDragEnter = Date.now();
1659
1662
  handleAutoOpenFolder(dataRef, tree, item, placement);
1660
- const target = getDragTarget(e, item, tree);
1663
+ const target = getDragTarget(e, item, tree, false);
1661
1664
  if (!((_a = tree.getState().dnd) == null ? void 0 : _a.draggedItems) && (!e.dataTransfer || !((_c = (_b = tree.getConfig()).canDragForeignDragObjectOver) == null ? void 0 : _c.call(_b, e.dataTransfer, target)))) {
1662
1665
  dataRef.current.lastAllowDrop = false;
1663
1666
  return;
1664
1667
  }
1665
- if (!canDrop(e.dataTransfer, target, tree)) {
1668
+ if (!canDrop(null, target, tree)) {
1666
1669
  dataRef.current.lastAllowDrop = false;
1667
1670
  return;
1668
1671
  }
@@ -1692,7 +1695,7 @@ var dragAndDropFeature = {
1692
1695
  if (((_b = e.dataTransfer) == null ? void 0 : _b.dropEffect) === "none" || !draggedItems) {
1693
1696
  return;
1694
1697
  }
1695
- const target = getDragTarget(e, item, tree);
1698
+ const target = getDragTarget(e, item, tree, false);
1696
1699
  if (canDragForeignDragObjectOver && e.dataTransfer && !canDragForeignDragObjectOver(e.dataTransfer, target)) {
1697
1700
  return;
1698
1701
  }
@@ -1702,7 +1705,7 @@ var dragAndDropFeature = {
1702
1705
  var _a, _b, _c;
1703
1706
  e.stopPropagation();
1704
1707
  const dataRef = tree.getDataRef();
1705
- const target = getDragTarget(e, item, tree);
1708
+ const target = getDragTarget(e, item, tree, true);
1706
1709
  const draggedItems = (_a = tree.getState().dnd) == null ? void 0 : _a.draggedItems;
1707
1710
  const isValidDrop = canDrop(e.dataTransfer, target, tree);
1708
1711
  tree.applySubStateUpdate("dnd", {
package/dist/index.mjs CHANGED
@@ -1230,15 +1230,17 @@ var asyncDataLoaderFeature = {
1230
1230
  }
1231
1231
  yield loadChildrenIds(tree, itemId);
1232
1232
  }),
1233
- updateCachedChildrenIds: ({ tree, itemId }, childrenIds) => {
1234
- const dataRef = tree.getDataRef();
1235
- dataRef.current.childrenIds[itemId] = childrenIds;
1236
- tree.rebuildTree();
1233
+ updateCachedChildrenIds: ({ tree, itemId }, childrenIds, skipUpdateTree) => {
1234
+ getDataRef(tree).current.childrenIds[itemId] = childrenIds;
1235
+ if (!skipUpdateTree) {
1236
+ tree.rebuildTree();
1237
+ }
1237
1238
  },
1238
- updateCachedData: ({ tree, itemId }, data) => {
1239
- const dataRef = tree.getDataRef();
1240
- dataRef.current.itemData[itemId] = data;
1241
- tree.rebuildTree();
1239
+ updateCachedData: ({ tree, itemId }, data, skipUpdateTree) => {
1240
+ getDataRef(tree).current.itemData[itemId] = data;
1241
+ if (!skipUpdateTree) {
1242
+ tree.rebuildTree();
1243
+ }
1242
1244
  },
1243
1245
  hasLoadedData: ({ tree, itemId }) => {
1244
1246
  const dataRef = tree.getDataRef();
@@ -1405,15 +1407,16 @@ var getReparentTarget = (item, reparentLevel, draggedItems) => {
1405
1407
  dragLineLevel: reparentLevel
1406
1408
  };
1407
1409
  };
1408
- var getDragTarget = (e, item, tree, canReorder = tree.getConfig().canReorder) => {
1410
+ var getDragTarget = (e, item, tree, hasDataTransferPayload, canReorder = tree.getConfig().canReorder) => {
1409
1411
  var _a;
1412
+ const dataTransfer = hasDataTransferPayload ? e.dataTransfer : null;
1410
1413
  const draggedItems = (_a = tree.getState().dnd) == null ? void 0 : _a.draggedItems;
1411
1414
  const itemMeta = item.getItemMeta();
1412
1415
  const parent = item.getParent();
1413
1416
  const itemTarget = { item };
1414
1417
  const parentTarget = parent ? { item: parent } : null;
1415
- const canBecomeSibling = parentTarget && canDrop(e.dataTransfer, parentTarget, tree);
1416
- const canMakeChild = canDrop(e.dataTransfer, itemTarget, tree);
1418
+ const canBecomeSibling = parentTarget && canDrop(dataTransfer, parentTarget, tree);
1419
+ const canMakeChild = canDrop(dataTransfer, itemTarget, tree);
1417
1420
  const placement = getTargetPlacement(e, item, tree, canMakeChild);
1418
1421
  if (!canReorder && parent && canBecomeSibling && placement.type !== 2 /* MakeChild */) {
1419
1422
  if (draggedItems == null ? void 0 : draggedItems.some((item2) => item2.isDescendentOf(parent.getId()))) {
@@ -1422,7 +1425,7 @@ var getDragTarget = (e, item, tree, canReorder = tree.getConfig().canReorder) =>
1422
1425
  return parentTarget;
1423
1426
  }
1424
1427
  if (!canReorder && parent && !canBecomeSibling) {
1425
- return getDragTarget(e, parent, tree, false);
1428
+ return getDragTarget(e, parent, tree, hasDataTransferPayload, false);
1426
1429
  }
1427
1430
  if (!parent) {
1428
1431
  return itemTarget;
@@ -1431,7 +1434,7 @@ var getDragTarget = (e, item, tree, canReorder = tree.getConfig().canReorder) =>
1431
1434
  return itemTarget;
1432
1435
  }
1433
1436
  if (!canBecomeSibling) {
1434
- return getDragTarget(e, parent, tree, false);
1437
+ return getDragTarget(e, parent, tree, hasDataTransferPayload, false);
1435
1438
  }
1436
1439
  if (placement.type === 3 /* Reparent */) {
1437
1440
  return getReparentTarget(item, placement.reparentLevel, draggedItems);
@@ -1613,12 +1616,12 @@ var dragAndDropFeature = {
1613
1616
  dataRef.current.lastDragCode = nextDragCode;
1614
1617
  dataRef.current.lastDragEnter = Date.now();
1615
1618
  handleAutoOpenFolder(dataRef, tree, item, placement);
1616
- const target = getDragTarget(e, item, tree);
1619
+ const target = getDragTarget(e, item, tree, false);
1617
1620
  if (!((_a = tree.getState().dnd) == null ? void 0 : _a.draggedItems) && (!e.dataTransfer || !((_c = (_b = tree.getConfig()).canDragForeignDragObjectOver) == null ? void 0 : _c.call(_b, e.dataTransfer, target)))) {
1618
1621
  dataRef.current.lastAllowDrop = false;
1619
1622
  return;
1620
1623
  }
1621
- if (!canDrop(e.dataTransfer, target, tree)) {
1624
+ if (!canDrop(null, target, tree)) {
1622
1625
  dataRef.current.lastAllowDrop = false;
1623
1626
  return;
1624
1627
  }
@@ -1648,7 +1651,7 @@ var dragAndDropFeature = {
1648
1651
  if (((_b = e.dataTransfer) == null ? void 0 : _b.dropEffect) === "none" || !draggedItems) {
1649
1652
  return;
1650
1653
  }
1651
- const target = getDragTarget(e, item, tree);
1654
+ const target = getDragTarget(e, item, tree, false);
1652
1655
  if (canDragForeignDragObjectOver && e.dataTransfer && !canDragForeignDragObjectOver(e.dataTransfer, target)) {
1653
1656
  return;
1654
1657
  }
@@ -1658,7 +1661,7 @@ var dragAndDropFeature = {
1658
1661
  var _a, _b, _c;
1659
1662
  e.stopPropagation();
1660
1663
  const dataRef = tree.getDataRef();
1661
- const target = getDragTarget(e, item, tree);
1664
+ const target = getDragTarget(e, item, tree, true);
1662
1665
  const draggedItems = (_a = tree.getState().dnd) == null ? void 0 : _a.draggedItems;
1663
1666
  const isValidDrop = canDrop(e.dataTransfer, target, tree);
1664
1667
  tree.applySubStateUpdate("dnd", {
package/package.json CHANGED
@@ -13,7 +13,7 @@
13
13
  "checkbox",
14
14
  "hook"
15
15
  ],
16
- "version": "0.0.0-20251215184014",
16
+ "version": "0.0.0-20260107220200",
17
17
  "main": "dist/index.d.ts",
18
18
  "module": "dist/index.mjs",
19
19
  "types": "dist/index.d.mts",
@@ -180,15 +180,21 @@ export const asyncDataLoaderFeature: FeatureImplementation = {
180
180
  }
181
181
  await loadChildrenIds(tree, itemId);
182
182
  },
183
- updateCachedChildrenIds: ({ tree, itemId }, childrenIds) => {
184
- const dataRef = tree.getDataRef<AsyncDataLoaderDataRef>();
185
- dataRef.current.childrenIds[itemId] = childrenIds;
186
- tree.rebuildTree();
183
+ updateCachedChildrenIds: (
184
+ { tree, itemId },
185
+ childrenIds,
186
+ skipUpdateTree,
187
+ ) => {
188
+ getDataRef(tree).current.childrenIds[itemId] = childrenIds;
189
+ if (!skipUpdateTree) {
190
+ tree.rebuildTree();
191
+ }
187
192
  },
188
- updateCachedData: ({ tree, itemId }, data) => {
189
- const dataRef = tree.getDataRef<AsyncDataLoaderDataRef>();
190
- dataRef.current.itemData[itemId] = data;
191
- tree.rebuildTree();
193
+ updateCachedData: ({ tree, itemId }, data, skipUpdateTree) => {
194
+ getDataRef(tree).current.itemData[itemId] = data;
195
+ if (!skipUpdateTree) {
196
+ tree.rebuildTree();
197
+ }
192
198
  },
193
199
  hasLoadedData: ({ tree, itemId }) => {
194
200
  const dataRef = tree.getDataRef<AsyncDataLoaderDataRef>();
@@ -39,6 +39,7 @@ export type AsyncDataLoaderFeatureDef<T> = {
39
39
  waitForItemChildrenLoaded: (itemId: string) => Promise<void>;
40
40
  loadItemData: (itemId: string) => Promise<T>;
41
41
  loadChildrenIds: (itemId: string) => Promise<string[]>;
42
+
42
43
  /* idea: recursiveLoadItems: (itemId: string, cancelToken?: { current: boolean }, onLoad: (itemIds: string[]) => void) => Promise<T[]> */
43
44
  };
44
45
  itemInstance: SyncDataLoaderFeatureDef<T>["itemInstance"] & {
@@ -52,9 +53,16 @@ export type AsyncDataLoaderFeatureDef<T> = {
52
53
  * the tree will continue to display the old data until the new data has loaded. */
53
54
  invalidateChildrenIds: (optimistic?: boolean) => Promise<void>;
54
55
 
55
- /** Set to undefined to clear cache without triggering automatic refetch. Use @invalidateItemData to clear and triggering refetch. */
56
- updateCachedData: (data: T | undefined) => void;
57
- updateCachedChildrenIds: (childrenIds: string[]) => void;
56
+ /** Set to undefined to clear cache without triggering automatic refetch. Use @invalidateItemData to clear and triggering refetch.
57
+ * @param skipUpdateTree If true, the tree will not rebuild the tree structure cache afterwards by calling `tree.rebuildTree()`. */
58
+ updateCachedData: (data: T | undefined, skipUpdateTree?: boolean) => void;
59
+
60
+ /** @param skipUpdateTree If true, the tree will not rebuild the tree structure cache afterwards by calling `tree.rebuildTree()`. */
61
+ updateCachedChildrenIds: (
62
+ childrenIds: string[],
63
+ skipUpdateTree?: boolean,
64
+ ) => void;
65
+
58
66
  hasLoadedData: () => boolean;
59
67
  isLoading: () => boolean;
60
68
  };
@@ -328,8 +328,7 @@ describe("core-feature/drag-and-drop", () => {
328
328
  "onDropForeignDragObject",
329
329
  );
330
330
  const event = tree.createBottomDragEvent(2);
331
- tree.setElementBoundingBox("x212");
332
- tree.setElementBoundingBox("x213");
331
+ tree.setElementBoundingBox("x112");
333
332
  tree.do.dragOver("x112", event);
334
333
  tree.do.drop("x112", event);
335
334
  expect(onDropForeignDragObject).toHaveBeenCalledWith(
@@ -357,6 +356,38 @@ describe("core-feature/drag-and-drop", () => {
357
356
  tree.do.drop("x11", event);
358
357
  expect(onDropForeignDragObject).not.toHaveBeenCalled();
359
358
  });
359
+
360
+ it("calls canDragForeignDragObjectOver in drag over events, not canDropForeignDragObject", () => {
361
+ const canDropForeignDragObject = tree
362
+ .mockedHandler("canDropForeignDragObject")
363
+ .mockReturnValue(true);
364
+ const canDragForeignDragObjectOver = tree
365
+ .mockedHandler("canDragForeignDragObjectOver")
366
+ .mockReturnValue(true);
367
+ const event = TestTree.dragEvent();
368
+ tree.do.dragOver("x11", event);
369
+ expect(canDragForeignDragObjectOver).toHaveBeenCalledWith(
370
+ event.dataTransfer,
371
+ { item: tree.item("x11") },
372
+ );
373
+ expect(canDropForeignDragObject).not.toHaveBeenCalled();
374
+ });
375
+
376
+ it("calls canDropForeignDragObject in drop events, not canDragForeignDragObjectOver", () => {
377
+ const canDropForeignDragObject = tree
378
+ .mockedHandler("canDropForeignDragObject")
379
+ .mockReturnValue(true);
380
+ const canDragForeignDragObjectOver = tree
381
+ .mockedHandler("canDragForeignDragObjectOver")
382
+ .mockReturnValue(true);
383
+ const event = TestTree.dragEvent();
384
+ tree.do.drop("x11", event);
385
+ expect(canDropForeignDragObject).toHaveBeenCalledWith(
386
+ event.dataTransfer,
387
+ { item: tree.item("x11") },
388
+ );
389
+ expect(canDragForeignDragObjectOver).not.toHaveBeenCalled();
390
+ });
360
391
  });
361
392
 
362
393
  describe("with insertion handlers", () => {
@@ -236,7 +236,7 @@ export const dragAndDropFeature: FeatureImplementation = {
236
236
 
237
237
  handleAutoOpenFolder(dataRef, tree, item, placement);
238
238
 
239
- const target = getDragTarget(e, item, tree);
239
+ const target = getDragTarget(e, item, tree, false);
240
240
 
241
241
  if (
242
242
  !tree.getState().dnd?.draggedItems &&
@@ -249,7 +249,8 @@ export const dragAndDropFeature: FeatureImplementation = {
249
249
  return;
250
250
  }
251
251
 
252
- if (!canDrop(e.dataTransfer, target, tree)) {
252
+ // dataTransfer.payload is not accessible in onDragOver, so just skip entirely here. It'll be checked again in onDrop
253
+ if (!canDrop(null, target, tree)) {
253
254
  dataRef.current.lastAllowDrop = false;
254
255
  return;
255
256
  }
@@ -285,7 +286,7 @@ export const dragAndDropFeature: FeatureImplementation = {
285
286
  return;
286
287
  }
287
288
 
288
- const target = getDragTarget(e, item, tree);
289
+ const target = getDragTarget(e, item, tree, false);
289
290
  if (
290
291
  canDragForeignDragObjectOver &&
291
292
  e.dataTransfer &&
@@ -300,7 +301,7 @@ export const dragAndDropFeature: FeatureImplementation = {
300
301
  onDrop: async (e: DragEvent) => {
301
302
  e.stopPropagation();
302
303
  const dataRef = tree.getDataRef<DndDataRef>();
303
- const target = getDragTarget(e, item, tree);
304
+ const target = getDragTarget(e, item, tree, true);
304
305
  const draggedItems = tree.getState().dnd?.draggedItems;
305
306
  const isValidDrop = canDrop(e.dataTransfer, target, tree);
306
307
 
@@ -29,6 +29,8 @@ export type TargetPlacement =
29
29
  export const isOrderedDragTarget = <T>(dragTarget: DragTarget<T>) =>
30
30
  "childIndex" in dragTarget;
31
31
 
32
+ /** @param dataTransfer - If the data transfer object should not be considered, e.g. because the event is
33
+ * onDragOver where the browser does not allow reading the payload, pass null */
32
34
  export const canDrop = (
33
35
  dataTransfer: DataTransfer | null,
34
36
  target: DragTarget<any>,
@@ -197,21 +199,25 @@ export const getReparentTarget = <T>(
197
199
  };
198
200
  };
199
201
 
202
+ /** @param hasDataTransferPayload - If the data transfer object should not be considered, e.g. because the event is
203
+ * onDragOver where the browser does not allow reading the payload, pass false */
200
204
  export const getDragTarget = (
201
205
  e: any,
202
206
  item: ItemInstance<any>,
203
207
  tree: TreeInstance<any>,
208
+ hasDataTransferPayload: boolean,
204
209
  canReorder = tree.getConfig().canReorder,
205
210
  ): DragTarget<any> => {
211
+ const dataTransfer = hasDataTransferPayload ? e.dataTransfer : null;
206
212
  const draggedItems = tree.getState().dnd?.draggedItems;
207
213
  const itemMeta = item.getItemMeta();
208
214
  const parent = item.getParent();
209
215
  const itemTarget: DragTarget<any> = { item };
210
216
  const parentTarget: DragTarget<any> | null = parent ? { item: parent } : null;
211
217
  const canBecomeSibling =
212
- parentTarget && canDrop(e.dataTransfer, parentTarget, tree);
218
+ parentTarget && canDrop(dataTransfer, parentTarget, tree);
213
219
 
214
- const canMakeChild = canDrop(e.dataTransfer, itemTarget, tree);
220
+ const canMakeChild = canDrop(dataTransfer, itemTarget, tree);
215
221
  const placement = getTargetPlacement(e, item, tree, canMakeChild);
216
222
 
217
223
  if (
@@ -229,7 +235,7 @@ export const getDragTarget = (
229
235
 
230
236
  if (!canReorder && parent && !canBecomeSibling) {
231
237
  // TODO! this breaks in story DND/Can Drop. Maybe move this logic into a composable DragTargetStrategy[] ?
232
- return getDragTarget(e, parent, tree, false);
238
+ return getDragTarget(e, parent, tree, hasDataTransferPayload, false);
233
239
  }
234
240
 
235
241
  if (!parent) {
@@ -242,7 +248,7 @@ export const getDragTarget = (
242
248
  }
243
249
 
244
250
  if (!canBecomeSibling) {
245
- return getDragTarget(e, parent, tree, false);
251
+ return getDragTarget(e, parent, tree, hasDataTransferPayload, false);
246
252
  }
247
253
 
248
254
  if (placement.type === PlacementType.Reparent) {