@headless-tree/core 0.0.0-20260107224057 → 0.0.0-20260108010329
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 +1 -1
- package/dist/index.d.mts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +52 -42
- package/dist/index.mjs +52 -42
- package/package.json +1 -1
- package/src/features/drag-and-drop/drag-and-drop.spec.ts +48 -0
- package/src/features/drag-and-drop/feature.ts +64 -59
- package/src/features/drag-and-drop/types.ts +7 -0
- package/src/features/prop-memoization/feature.ts +8 -0
- package/src/features/prop-memoization/types.ts +1 -0
package/CHANGELOG.md
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -68,6 +68,8 @@ type DragAndDropFeatureDef<T> = {
|
|
|
68
68
|
onCompleteForeignDrop?: (items: ItemInstance<T>[]) => void;
|
|
69
69
|
/** When dragging for this many ms on a closed folder, the folder will automatically open. Set to zero to disable. */
|
|
70
70
|
openOnDropDelay?: number;
|
|
71
|
+
/** If true, `item.getProps()` will not include drag event handlers. Use `item.getDragHandleProps()` on the handler element. */
|
|
72
|
+
seperateDragHandle?: boolean;
|
|
71
73
|
};
|
|
72
74
|
treeInstance: {
|
|
73
75
|
getDragTarget: () => DragTarget<T> | null;
|
|
@@ -84,6 +86,9 @@ type DragAndDropFeatureDef<T> = {
|
|
|
84
86
|
isDragTargetAbove: () => boolean;
|
|
85
87
|
isDragTargetBelow: () => boolean;
|
|
86
88
|
isDraggingOver: () => boolean;
|
|
89
|
+
/** Note that `item.getProps()` already passes in all drag event handlers by default. Set `seperateDragHandle` to true to
|
|
90
|
+
* disable the default behavior and use this on the handler element instead. */
|
|
91
|
+
getDragHandleProps: () => Record<string, any>;
|
|
87
92
|
};
|
|
88
93
|
hotkeys: never;
|
|
89
94
|
};
|
|
@@ -422,6 +427,7 @@ interface PropMemoizationDataRef {
|
|
|
422
427
|
memo?: {
|
|
423
428
|
tree?: Record<string, any>;
|
|
424
429
|
item?: Record<string, any>;
|
|
430
|
+
drag?: Record<string, any>;
|
|
425
431
|
search?: Record<string, any>;
|
|
426
432
|
rename?: Record<string, any>;
|
|
427
433
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -68,6 +68,8 @@ type DragAndDropFeatureDef<T> = {
|
|
|
68
68
|
onCompleteForeignDrop?: (items: ItemInstance<T>[]) => void;
|
|
69
69
|
/** When dragging for this many ms on a closed folder, the folder will automatically open. Set to zero to disable. */
|
|
70
70
|
openOnDropDelay?: number;
|
|
71
|
+
/** If true, `item.getProps()` will not include drag event handlers. Use `item.getDragHandleProps()` on the handler element. */
|
|
72
|
+
seperateDragHandle?: boolean;
|
|
71
73
|
};
|
|
72
74
|
treeInstance: {
|
|
73
75
|
getDragTarget: () => DragTarget<T> | null;
|
|
@@ -84,6 +86,9 @@ type DragAndDropFeatureDef<T> = {
|
|
|
84
86
|
isDragTargetAbove: () => boolean;
|
|
85
87
|
isDragTargetBelow: () => boolean;
|
|
86
88
|
isDraggingOver: () => boolean;
|
|
89
|
+
/** Note that `item.getProps()` already passes in all drag event handlers by default. Set `seperateDragHandle` to true to
|
|
90
|
+
* disable the default behavior and use this on the handler element instead. */
|
|
91
|
+
getDragHandleProps: () => Record<string, any>;
|
|
87
92
|
};
|
|
88
93
|
hotkeys: never;
|
|
89
94
|
};
|
|
@@ -422,6 +427,7 @@ interface PropMemoizationDataRef {
|
|
|
422
427
|
memo?: {
|
|
423
428
|
tree?: Record<string, any>;
|
|
424
429
|
item?: Record<string, any>;
|
|
430
|
+
drag?: Record<string, any>;
|
|
425
431
|
search?: Record<string, any>;
|
|
426
432
|
rename?: Record<string, any>;
|
|
427
433
|
};
|
package/dist/index.js
CHANGED
|
@@ -1620,36 +1620,8 @@ var dragAndDropFeature = {
|
|
|
1620
1620
|
}
|
|
1621
1621
|
},
|
|
1622
1622
|
itemInstance: {
|
|
1623
|
-
getProps: ({ tree, item, prev }) => __spreadProps(__spreadValues({}, prev == null ? void 0 : prev()), {
|
|
1624
|
-
draggable: true,
|
|
1623
|
+
getProps: ({ tree, item, prev }) => __spreadProps(__spreadValues(__spreadValues({}, prev == null ? void 0 : prev()), tree.getConfig().seperateDragHandle ? {} : item.getDragHandleProps()), {
|
|
1625
1624
|
onDragEnter: (e) => e.preventDefault(),
|
|
1626
|
-
onDragStart: (e) => {
|
|
1627
|
-
var _a, _b, _c, _d;
|
|
1628
|
-
const selectedItems = tree.getSelectedItems ? tree.getSelectedItems() : [tree.getFocusedItem()];
|
|
1629
|
-
const items = selectedItems.includes(item) ? selectedItems : [item];
|
|
1630
|
-
const config = tree.getConfig();
|
|
1631
|
-
if (!selectedItems.includes(item)) {
|
|
1632
|
-
(_a = tree.setSelectedItems) == null ? void 0 : _a.call(tree, [item.getItemMeta().itemId]);
|
|
1633
|
-
}
|
|
1634
|
-
if (!((_c = (_b = config.canDrag) == null ? void 0 : _b.call(config, items)) != null ? _c : true)) {
|
|
1635
|
-
e.preventDefault();
|
|
1636
|
-
return;
|
|
1637
|
-
}
|
|
1638
|
-
if (config.setDragImage) {
|
|
1639
|
-
const { imgElement, xOffset, yOffset } = config.setDragImage(items);
|
|
1640
|
-
(_d = e.dataTransfer) == null ? void 0 : _d.setDragImage(imgElement, xOffset != null ? xOffset : 0, yOffset != null ? yOffset : 0);
|
|
1641
|
-
}
|
|
1642
|
-
if (config.createForeignDragObject && e.dataTransfer) {
|
|
1643
|
-
const { format, data, dropEffect, effectAllowed } = config.createForeignDragObject(items);
|
|
1644
|
-
e.dataTransfer.setData(format, data);
|
|
1645
|
-
if (dropEffect) e.dataTransfer.dropEffect = dropEffect;
|
|
1646
|
-
if (effectAllowed) e.dataTransfer.effectAllowed = effectAllowed;
|
|
1647
|
-
}
|
|
1648
|
-
tree.applySubStateUpdate("dnd", {
|
|
1649
|
-
draggedItems: items,
|
|
1650
|
-
draggingOverItem: tree.getFocusedItem()
|
|
1651
|
-
});
|
|
1652
|
-
},
|
|
1653
1625
|
onDragOver: (e) => {
|
|
1654
1626
|
var _a, _b, _c;
|
|
1655
1627
|
e.stopPropagation();
|
|
@@ -1693,19 +1665,6 @@ var dragAndDropFeature = {
|
|
|
1693
1665
|
}));
|
|
1694
1666
|
}, 100);
|
|
1695
1667
|
},
|
|
1696
|
-
onDragEnd: (e) => {
|
|
1697
|
-
var _a, _b;
|
|
1698
|
-
const { onCompleteForeignDrop, canDragForeignDragObjectOver } = tree.getConfig();
|
|
1699
|
-
const draggedItems = (_a = tree.getState().dnd) == null ? void 0 : _a.draggedItems;
|
|
1700
|
-
if (((_b = e.dataTransfer) == null ? void 0 : _b.dropEffect) === "none" || !draggedItems) {
|
|
1701
|
-
return;
|
|
1702
|
-
}
|
|
1703
|
-
const target = getDragTarget(e, item, tree, false);
|
|
1704
|
-
if (canDragForeignDragObjectOver && e.dataTransfer && !canDragForeignDragObjectOver(e.dataTransfer, target)) {
|
|
1705
|
-
return;
|
|
1706
|
-
}
|
|
1707
|
-
onCompleteForeignDrop == null ? void 0 : onCompleteForeignDrop(draggedItems);
|
|
1708
|
-
},
|
|
1709
1668
|
onDrop: (e) => __async(null, null, function* () {
|
|
1710
1669
|
var _a, _b, _c;
|
|
1711
1670
|
e.stopPropagation();
|
|
@@ -1734,6 +1693,49 @@ var dragAndDropFeature = {
|
|
|
1734
1693
|
tree.updateDomFocus();
|
|
1735
1694
|
})
|
|
1736
1695
|
}),
|
|
1696
|
+
getDragHandleProps: ({ tree, item, prev }) => __spreadProps(__spreadValues({}, prev == null ? void 0 : prev()), {
|
|
1697
|
+
draggable: true,
|
|
1698
|
+
onDragStart: (e) => {
|
|
1699
|
+
var _a, _b, _c, _d;
|
|
1700
|
+
const selectedItems = tree.getSelectedItems ? tree.getSelectedItems() : [tree.getFocusedItem()];
|
|
1701
|
+
const items = selectedItems.includes(item) ? selectedItems : [item];
|
|
1702
|
+
const config = tree.getConfig();
|
|
1703
|
+
if (!selectedItems.includes(item)) {
|
|
1704
|
+
(_a = tree.setSelectedItems) == null ? void 0 : _a.call(tree, [item.getItemMeta().itemId]);
|
|
1705
|
+
}
|
|
1706
|
+
if (!((_c = (_b = config.canDrag) == null ? void 0 : _b.call(config, items)) != null ? _c : true)) {
|
|
1707
|
+
e.preventDefault();
|
|
1708
|
+
return;
|
|
1709
|
+
}
|
|
1710
|
+
if (config.setDragImage) {
|
|
1711
|
+
const { imgElement, xOffset, yOffset } = config.setDragImage(items);
|
|
1712
|
+
(_d = e.dataTransfer) == null ? void 0 : _d.setDragImage(imgElement, xOffset != null ? xOffset : 0, yOffset != null ? yOffset : 0);
|
|
1713
|
+
}
|
|
1714
|
+
if (config.createForeignDragObject && e.dataTransfer) {
|
|
1715
|
+
const { format, data, dropEffect, effectAllowed } = config.createForeignDragObject(items);
|
|
1716
|
+
e.dataTransfer.setData(format, data);
|
|
1717
|
+
if (dropEffect) e.dataTransfer.dropEffect = dropEffect;
|
|
1718
|
+
if (effectAllowed) e.dataTransfer.effectAllowed = effectAllowed;
|
|
1719
|
+
}
|
|
1720
|
+
tree.applySubStateUpdate("dnd", {
|
|
1721
|
+
draggedItems: items,
|
|
1722
|
+
draggingOverItem: tree.getFocusedItem()
|
|
1723
|
+
});
|
|
1724
|
+
},
|
|
1725
|
+
onDragEnd: (e) => {
|
|
1726
|
+
var _a, _b;
|
|
1727
|
+
const { onCompleteForeignDrop, canDragForeignDragObjectOver } = tree.getConfig();
|
|
1728
|
+
const draggedItems = (_a = tree.getState().dnd) == null ? void 0 : _a.draggedItems;
|
|
1729
|
+
if (((_b = e.dataTransfer) == null ? void 0 : _b.dropEffect) === "none" || !draggedItems) {
|
|
1730
|
+
return;
|
|
1731
|
+
}
|
|
1732
|
+
const target = getDragTarget(e, item, tree, false);
|
|
1733
|
+
if (canDragForeignDragObjectOver && e.dataTransfer && !canDragForeignDragObjectOver(e.dataTransfer, target)) {
|
|
1734
|
+
return;
|
|
1735
|
+
}
|
|
1736
|
+
onCompleteForeignDrop == null ? void 0 : onCompleteForeignDrop(draggedItems);
|
|
1737
|
+
}
|
|
1738
|
+
}),
|
|
1737
1739
|
isDragTarget: ({ tree, item }) => {
|
|
1738
1740
|
const target = tree.getDragTarget();
|
|
1739
1741
|
return target ? target.item.getId() === item.getId() : false;
|
|
@@ -2308,6 +2310,14 @@ var propMemoizationFeature = {
|
|
|
2308
2310
|
(_e = (_d = dataRef.current.memo).item) != null ? _e : _d.item = {};
|
|
2309
2311
|
return memoize(props, dataRef.current.memo.item);
|
|
2310
2312
|
},
|
|
2313
|
+
getDragHandleProps: ({ item, prev }) => {
|
|
2314
|
+
var _a, _b, _c, _d, _e;
|
|
2315
|
+
const dataRef = item.getDataRef();
|
|
2316
|
+
const props = (_a = prev == null ? void 0 : prev()) != null ? _a : {};
|
|
2317
|
+
(_c = (_b = dataRef.current).memo) != null ? _c : _b.memo = {};
|
|
2318
|
+
(_e = (_d = dataRef.current.memo).drag) != null ? _e : _d.drag = {};
|
|
2319
|
+
return memoize(props, dataRef.current.memo.drag);
|
|
2320
|
+
},
|
|
2311
2321
|
getRenameInputProps: ({ item, prev }) => {
|
|
2312
2322
|
var _a, _b, _c, _d, _e;
|
|
2313
2323
|
const dataRef = item.getDataRef();
|
package/dist/index.mjs
CHANGED
|
@@ -1576,36 +1576,8 @@ var dragAndDropFeature = {
|
|
|
1576
1576
|
}
|
|
1577
1577
|
},
|
|
1578
1578
|
itemInstance: {
|
|
1579
|
-
getProps: ({ tree, item, prev }) => __spreadProps(__spreadValues({}, prev == null ? void 0 : prev()), {
|
|
1580
|
-
draggable: true,
|
|
1579
|
+
getProps: ({ tree, item, prev }) => __spreadProps(__spreadValues(__spreadValues({}, prev == null ? void 0 : prev()), tree.getConfig().seperateDragHandle ? {} : item.getDragHandleProps()), {
|
|
1581
1580
|
onDragEnter: (e) => e.preventDefault(),
|
|
1582
|
-
onDragStart: (e) => {
|
|
1583
|
-
var _a, _b, _c, _d;
|
|
1584
|
-
const selectedItems = tree.getSelectedItems ? tree.getSelectedItems() : [tree.getFocusedItem()];
|
|
1585
|
-
const items = selectedItems.includes(item) ? selectedItems : [item];
|
|
1586
|
-
const config = tree.getConfig();
|
|
1587
|
-
if (!selectedItems.includes(item)) {
|
|
1588
|
-
(_a = tree.setSelectedItems) == null ? void 0 : _a.call(tree, [item.getItemMeta().itemId]);
|
|
1589
|
-
}
|
|
1590
|
-
if (!((_c = (_b = config.canDrag) == null ? void 0 : _b.call(config, items)) != null ? _c : true)) {
|
|
1591
|
-
e.preventDefault();
|
|
1592
|
-
return;
|
|
1593
|
-
}
|
|
1594
|
-
if (config.setDragImage) {
|
|
1595
|
-
const { imgElement, xOffset, yOffset } = config.setDragImage(items);
|
|
1596
|
-
(_d = e.dataTransfer) == null ? void 0 : _d.setDragImage(imgElement, xOffset != null ? xOffset : 0, yOffset != null ? yOffset : 0);
|
|
1597
|
-
}
|
|
1598
|
-
if (config.createForeignDragObject && e.dataTransfer) {
|
|
1599
|
-
const { format, data, dropEffect, effectAllowed } = config.createForeignDragObject(items);
|
|
1600
|
-
e.dataTransfer.setData(format, data);
|
|
1601
|
-
if (dropEffect) e.dataTransfer.dropEffect = dropEffect;
|
|
1602
|
-
if (effectAllowed) e.dataTransfer.effectAllowed = effectAllowed;
|
|
1603
|
-
}
|
|
1604
|
-
tree.applySubStateUpdate("dnd", {
|
|
1605
|
-
draggedItems: items,
|
|
1606
|
-
draggingOverItem: tree.getFocusedItem()
|
|
1607
|
-
});
|
|
1608
|
-
},
|
|
1609
1581
|
onDragOver: (e) => {
|
|
1610
1582
|
var _a, _b, _c;
|
|
1611
1583
|
e.stopPropagation();
|
|
@@ -1649,19 +1621,6 @@ var dragAndDropFeature = {
|
|
|
1649
1621
|
}));
|
|
1650
1622
|
}, 100);
|
|
1651
1623
|
},
|
|
1652
|
-
onDragEnd: (e) => {
|
|
1653
|
-
var _a, _b;
|
|
1654
|
-
const { onCompleteForeignDrop, canDragForeignDragObjectOver } = tree.getConfig();
|
|
1655
|
-
const draggedItems = (_a = tree.getState().dnd) == null ? void 0 : _a.draggedItems;
|
|
1656
|
-
if (((_b = e.dataTransfer) == null ? void 0 : _b.dropEffect) === "none" || !draggedItems) {
|
|
1657
|
-
return;
|
|
1658
|
-
}
|
|
1659
|
-
const target = getDragTarget(e, item, tree, false);
|
|
1660
|
-
if (canDragForeignDragObjectOver && e.dataTransfer && !canDragForeignDragObjectOver(e.dataTransfer, target)) {
|
|
1661
|
-
return;
|
|
1662
|
-
}
|
|
1663
|
-
onCompleteForeignDrop == null ? void 0 : onCompleteForeignDrop(draggedItems);
|
|
1664
|
-
},
|
|
1665
1624
|
onDrop: (e) => __async(null, null, function* () {
|
|
1666
1625
|
var _a, _b, _c;
|
|
1667
1626
|
e.stopPropagation();
|
|
@@ -1690,6 +1649,49 @@ var dragAndDropFeature = {
|
|
|
1690
1649
|
tree.updateDomFocus();
|
|
1691
1650
|
})
|
|
1692
1651
|
}),
|
|
1652
|
+
getDragHandleProps: ({ tree, item, prev }) => __spreadProps(__spreadValues({}, prev == null ? void 0 : prev()), {
|
|
1653
|
+
draggable: true,
|
|
1654
|
+
onDragStart: (e) => {
|
|
1655
|
+
var _a, _b, _c, _d;
|
|
1656
|
+
const selectedItems = tree.getSelectedItems ? tree.getSelectedItems() : [tree.getFocusedItem()];
|
|
1657
|
+
const items = selectedItems.includes(item) ? selectedItems : [item];
|
|
1658
|
+
const config = tree.getConfig();
|
|
1659
|
+
if (!selectedItems.includes(item)) {
|
|
1660
|
+
(_a = tree.setSelectedItems) == null ? void 0 : _a.call(tree, [item.getItemMeta().itemId]);
|
|
1661
|
+
}
|
|
1662
|
+
if (!((_c = (_b = config.canDrag) == null ? void 0 : _b.call(config, items)) != null ? _c : true)) {
|
|
1663
|
+
e.preventDefault();
|
|
1664
|
+
return;
|
|
1665
|
+
}
|
|
1666
|
+
if (config.setDragImage) {
|
|
1667
|
+
const { imgElement, xOffset, yOffset } = config.setDragImage(items);
|
|
1668
|
+
(_d = e.dataTransfer) == null ? void 0 : _d.setDragImage(imgElement, xOffset != null ? xOffset : 0, yOffset != null ? yOffset : 0);
|
|
1669
|
+
}
|
|
1670
|
+
if (config.createForeignDragObject && e.dataTransfer) {
|
|
1671
|
+
const { format, data, dropEffect, effectAllowed } = config.createForeignDragObject(items);
|
|
1672
|
+
e.dataTransfer.setData(format, data);
|
|
1673
|
+
if (dropEffect) e.dataTransfer.dropEffect = dropEffect;
|
|
1674
|
+
if (effectAllowed) e.dataTransfer.effectAllowed = effectAllowed;
|
|
1675
|
+
}
|
|
1676
|
+
tree.applySubStateUpdate("dnd", {
|
|
1677
|
+
draggedItems: items,
|
|
1678
|
+
draggingOverItem: tree.getFocusedItem()
|
|
1679
|
+
});
|
|
1680
|
+
},
|
|
1681
|
+
onDragEnd: (e) => {
|
|
1682
|
+
var _a, _b;
|
|
1683
|
+
const { onCompleteForeignDrop, canDragForeignDragObjectOver } = tree.getConfig();
|
|
1684
|
+
const draggedItems = (_a = tree.getState().dnd) == null ? void 0 : _a.draggedItems;
|
|
1685
|
+
if (((_b = e.dataTransfer) == null ? void 0 : _b.dropEffect) === "none" || !draggedItems) {
|
|
1686
|
+
return;
|
|
1687
|
+
}
|
|
1688
|
+
const target = getDragTarget(e, item, tree, false);
|
|
1689
|
+
if (canDragForeignDragObjectOver && e.dataTransfer && !canDragForeignDragObjectOver(e.dataTransfer, target)) {
|
|
1690
|
+
return;
|
|
1691
|
+
}
|
|
1692
|
+
onCompleteForeignDrop == null ? void 0 : onCompleteForeignDrop(draggedItems);
|
|
1693
|
+
}
|
|
1694
|
+
}),
|
|
1693
1695
|
isDragTarget: ({ tree, item }) => {
|
|
1694
1696
|
const target = tree.getDragTarget();
|
|
1695
1697
|
return target ? target.item.getId() === item.getId() : false;
|
|
@@ -2264,6 +2266,14 @@ var propMemoizationFeature = {
|
|
|
2264
2266
|
(_e = (_d = dataRef.current.memo).item) != null ? _e : _d.item = {};
|
|
2265
2267
|
return memoize(props, dataRef.current.memo.item);
|
|
2266
2268
|
},
|
|
2269
|
+
getDragHandleProps: ({ item, prev }) => {
|
|
2270
|
+
var _a, _b, _c, _d, _e;
|
|
2271
|
+
const dataRef = item.getDataRef();
|
|
2272
|
+
const props = (_a = prev == null ? void 0 : prev()) != null ? _a : {};
|
|
2273
|
+
(_c = (_b = dataRef.current).memo) != null ? _c : _b.memo = {};
|
|
2274
|
+
(_e = (_d = dataRef.current.memo).drag) != null ? _e : _d.drag = {};
|
|
2275
|
+
return memoize(props, dataRef.current.memo.drag);
|
|
2276
|
+
},
|
|
2267
2277
|
getRenameInputProps: ({ item, prev }) => {
|
|
2268
2278
|
var _a, _b, _c, _d, _e;
|
|
2269
2279
|
const dataRef = item.getDataRef();
|
package/package.json
CHANGED
|
@@ -729,6 +729,54 @@ describe("core-feature/drag-and-drop", () => {
|
|
|
729
729
|
});
|
|
730
730
|
});
|
|
731
731
|
|
|
732
|
+
describe("seperateDragHandle", () => {
|
|
733
|
+
it("includes all drag handlers in getProps() when seperateDragHandle is false", () => {
|
|
734
|
+
const props = tree.instance.getItemInstance("x111").getProps();
|
|
735
|
+
expect(props.draggable).toBe(true);
|
|
736
|
+
expect(props.onDragStart).toBeDefined();
|
|
737
|
+
expect(props.onDragEnd).toBeDefined();
|
|
738
|
+
expect(props.onDragEnter).toBeDefined();
|
|
739
|
+
expect(props.onDragOver).toBeDefined();
|
|
740
|
+
expect(props.onDragLeave).toBeDefined();
|
|
741
|
+
expect(props.onDrop).toBeDefined();
|
|
742
|
+
});
|
|
743
|
+
|
|
744
|
+
it("includes drag handle handlers in getDragHandleProps() when seperateDragHandle is false", () => {
|
|
745
|
+
const props = tree.instance
|
|
746
|
+
.getItemInstance("x111")
|
|
747
|
+
.getDragHandleProps();
|
|
748
|
+
expect(props.draggable).toBe(true);
|
|
749
|
+
expect(props.onDragStart).toBeDefined();
|
|
750
|
+
expect(props.onDragEnd).toBeDefined();
|
|
751
|
+
});
|
|
752
|
+
|
|
753
|
+
it("excludes drag handle handlers from getProps() but includes drop handlers when seperateDragHandle is true", async () => {
|
|
754
|
+
const testTree = await tree
|
|
755
|
+
.with({ seperateDragHandle: true })
|
|
756
|
+
.createTestCaseTree();
|
|
757
|
+
const props = testTree.instance.getItemInstance("x111").getProps();
|
|
758
|
+
expect(props.draggable).toBeUndefined();
|
|
759
|
+
expect(props.onDragStart).toBeUndefined();
|
|
760
|
+
expect(props.onDragEnd).toBeUndefined();
|
|
761
|
+
expect(props.onDragEnter).toBeDefined();
|
|
762
|
+
expect(props.onDragOver).toBeDefined();
|
|
763
|
+
expect(props.onDragLeave).toBeDefined();
|
|
764
|
+
expect(props.onDrop).toBeDefined();
|
|
765
|
+
});
|
|
766
|
+
|
|
767
|
+
it("includes drag handle handlers in getDragHandleProps() when seperateDragHandle is true", async () => {
|
|
768
|
+
const testTree = await tree
|
|
769
|
+
.with({ seperateDragHandle: true })
|
|
770
|
+
.createTestCaseTree();
|
|
771
|
+
const props = testTree.instance
|
|
772
|
+
.getItemInstance("x111")
|
|
773
|
+
.getDragHandleProps();
|
|
774
|
+
expect(props.draggable).toBe(true);
|
|
775
|
+
expect(props.onDragStart).toBeDefined();
|
|
776
|
+
expect(props.onDragEnd).toBeDefined();
|
|
777
|
+
});
|
|
778
|
+
});
|
|
779
|
+
|
|
732
780
|
describe("retains last drag state with dragcode", () => {
|
|
733
781
|
it("uses constant number of calls to canDrop", () => {
|
|
734
782
|
const canDrop = tree.mockedHandler("canDrop").mockReturnValue(true);
|
|
@@ -178,47 +178,10 @@ export const dragAndDropFeature: FeatureImplementation = {
|
|
|
178
178
|
itemInstance: {
|
|
179
179
|
getProps: ({ tree, item, prev }) => ({
|
|
180
180
|
...prev?.(),
|
|
181
|
-
|
|
182
|
-
draggable: true,
|
|
181
|
+
...(tree.getConfig().seperateDragHandle ? {} : item.getDragHandleProps()),
|
|
183
182
|
|
|
184
183
|
onDragEnter: (e: DragEvent) => e.preventDefault(),
|
|
185
184
|
|
|
186
|
-
onDragStart: (e: DragEvent) => {
|
|
187
|
-
const selectedItems = tree.getSelectedItems
|
|
188
|
-
? tree.getSelectedItems()
|
|
189
|
-
: [tree.getFocusedItem()];
|
|
190
|
-
const items = selectedItems.includes(item) ? selectedItems : [item];
|
|
191
|
-
const config = tree.getConfig();
|
|
192
|
-
|
|
193
|
-
if (!selectedItems.includes(item)) {
|
|
194
|
-
tree.setSelectedItems?.([item.getItemMeta().itemId]);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
if (!(config.canDrag?.(items) ?? true)) {
|
|
198
|
-
e.preventDefault();
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
if (config.setDragImage) {
|
|
203
|
-
const { imgElement, xOffset, yOffset } = config.setDragImage(items);
|
|
204
|
-
e.dataTransfer?.setDragImage(imgElement, xOffset ?? 0, yOffset ?? 0);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
if (config.createForeignDragObject && e.dataTransfer) {
|
|
208
|
-
const { format, data, dropEffect, effectAllowed } =
|
|
209
|
-
config.createForeignDragObject(items);
|
|
210
|
-
e.dataTransfer.setData(format, data);
|
|
211
|
-
|
|
212
|
-
if (dropEffect) e.dataTransfer.dropEffect = dropEffect;
|
|
213
|
-
if (effectAllowed) e.dataTransfer.effectAllowed = effectAllowed;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
tree.applySubStateUpdate("dnd", {
|
|
217
|
-
draggedItems: items,
|
|
218
|
-
draggingOverItem: tree.getFocusedItem(),
|
|
219
|
-
});
|
|
220
|
-
},
|
|
221
|
-
|
|
222
185
|
onDragOver: (e: DragEvent) => {
|
|
223
186
|
e.stopPropagation(); // don't bubble up to container dragover
|
|
224
187
|
const dataRef = tree.getDataRef<DndDataRef>();
|
|
@@ -277,27 +240,6 @@ export const dragAndDropFeature: FeatureImplementation = {
|
|
|
277
240
|
}, 100);
|
|
278
241
|
},
|
|
279
242
|
|
|
280
|
-
onDragEnd: (e: DragEvent) => {
|
|
281
|
-
const { onCompleteForeignDrop, canDragForeignDragObjectOver } =
|
|
282
|
-
tree.getConfig();
|
|
283
|
-
const draggedItems = tree.getState().dnd?.draggedItems;
|
|
284
|
-
|
|
285
|
-
if (e.dataTransfer?.dropEffect === "none" || !draggedItems) {
|
|
286
|
-
return;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
const target = getDragTarget(e, item, tree, false);
|
|
290
|
-
if (
|
|
291
|
-
canDragForeignDragObjectOver &&
|
|
292
|
-
e.dataTransfer &&
|
|
293
|
-
!canDragForeignDragObjectOver(e.dataTransfer, target)
|
|
294
|
-
) {
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
onCompleteForeignDrop?.(draggedItems);
|
|
299
|
-
},
|
|
300
|
-
|
|
301
243
|
onDrop: async (e: DragEvent) => {
|
|
302
244
|
e.stopPropagation();
|
|
303
245
|
const dataRef = tree.getDataRef<DndDataRef>();
|
|
@@ -332,6 +274,69 @@ export const dragAndDropFeature: FeatureImplementation = {
|
|
|
332
274
|
},
|
|
333
275
|
}),
|
|
334
276
|
|
|
277
|
+
getDragHandleProps: ({ tree, item, prev }) => ({
|
|
278
|
+
...prev?.(),
|
|
279
|
+
|
|
280
|
+
draggable: true,
|
|
281
|
+
|
|
282
|
+
onDragStart: (e: DragEvent) => {
|
|
283
|
+
const selectedItems = tree.getSelectedItems
|
|
284
|
+
? tree.getSelectedItems()
|
|
285
|
+
: [tree.getFocusedItem()];
|
|
286
|
+
const items = selectedItems.includes(item) ? selectedItems : [item];
|
|
287
|
+
const config = tree.getConfig();
|
|
288
|
+
|
|
289
|
+
if (!selectedItems.includes(item)) {
|
|
290
|
+
tree.setSelectedItems?.([item.getItemMeta().itemId]);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (!(config.canDrag?.(items) ?? true)) {
|
|
294
|
+
e.preventDefault();
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (config.setDragImage) {
|
|
299
|
+
const { imgElement, xOffset, yOffset } = config.setDragImage(items);
|
|
300
|
+
e.dataTransfer?.setDragImage(imgElement, xOffset ?? 0, yOffset ?? 0);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (config.createForeignDragObject && e.dataTransfer) {
|
|
304
|
+
const { format, data, dropEffect, effectAllowed } =
|
|
305
|
+
config.createForeignDragObject(items);
|
|
306
|
+
e.dataTransfer.setData(format, data);
|
|
307
|
+
|
|
308
|
+
if (dropEffect) e.dataTransfer.dropEffect = dropEffect;
|
|
309
|
+
if (effectAllowed) e.dataTransfer.effectAllowed = effectAllowed;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
tree.applySubStateUpdate("dnd", {
|
|
313
|
+
draggedItems: items,
|
|
314
|
+
draggingOverItem: tree.getFocusedItem(),
|
|
315
|
+
});
|
|
316
|
+
},
|
|
317
|
+
|
|
318
|
+
onDragEnd: (e: DragEvent) => {
|
|
319
|
+
const { onCompleteForeignDrop, canDragForeignDragObjectOver } =
|
|
320
|
+
tree.getConfig();
|
|
321
|
+
const draggedItems = tree.getState().dnd?.draggedItems;
|
|
322
|
+
|
|
323
|
+
if (e.dataTransfer?.dropEffect === "none" || !draggedItems) {
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const target = getDragTarget(e, item, tree, false);
|
|
328
|
+
if (
|
|
329
|
+
canDragForeignDragObjectOver &&
|
|
330
|
+
e.dataTransfer &&
|
|
331
|
+
!canDragForeignDragObjectOver(e.dataTransfer, target)
|
|
332
|
+
) {
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
onCompleteForeignDrop?.(draggedItems);
|
|
337
|
+
},
|
|
338
|
+
}),
|
|
339
|
+
|
|
335
340
|
isDragTarget: ({ tree, item }) => {
|
|
336
341
|
const target = tree.getDragTarget();
|
|
337
342
|
return target ? target.item.getId() === item.getId() : false;
|
|
@@ -97,6 +97,9 @@ export type DragAndDropFeatureDef<T> = {
|
|
|
97
97
|
|
|
98
98
|
/** When dragging for this many ms on a closed folder, the folder will automatically open. Set to zero to disable. */
|
|
99
99
|
openOnDropDelay?: number;
|
|
100
|
+
|
|
101
|
+
/** If true, `item.getProps()` will not include drag event handlers. Use `item.getDragHandleProps()` on the handler element. */
|
|
102
|
+
seperateDragHandle?: boolean;
|
|
100
103
|
};
|
|
101
104
|
treeInstance: {
|
|
102
105
|
getDragTarget: () => DragTarget<T> | null;
|
|
@@ -118,6 +121,10 @@ export type DragAndDropFeatureDef<T> = {
|
|
|
118
121
|
isDragTargetAbove: () => boolean;
|
|
119
122
|
isDragTargetBelow: () => boolean;
|
|
120
123
|
isDraggingOver: () => boolean;
|
|
124
|
+
|
|
125
|
+
/** Note that `item.getProps()` already passes in all drag event handlers by default. Set `seperateDragHandle` to true to
|
|
126
|
+
* disable the default behavior and use this on the handler element instead. */
|
|
127
|
+
getDragHandleProps: () => Record<string, any>;
|
|
121
128
|
};
|
|
122
129
|
hotkeys: never;
|
|
123
130
|
};
|
|
@@ -59,6 +59,14 @@ export const propMemoizationFeature: FeatureImplementation = {
|
|
|
59
59
|
return memoize(props, dataRef.current.memo.item);
|
|
60
60
|
},
|
|
61
61
|
|
|
62
|
+
getDragHandleProps: ({ item, prev }) => {
|
|
63
|
+
const dataRef = item.getDataRef<PropMemoizationDataRef>();
|
|
64
|
+
const props = prev?.() ?? {};
|
|
65
|
+
dataRef.current.memo ??= {};
|
|
66
|
+
dataRef.current.memo.drag ??= {};
|
|
67
|
+
return memoize(props, dataRef.current.memo.drag);
|
|
68
|
+
},
|
|
69
|
+
|
|
62
70
|
getRenameInputProps: ({ item, prev }) => {
|
|
63
71
|
const dataRef = item.getDataRef<PropMemoizationDataRef>();
|
|
64
72
|
const props = prev?.() ?? {};
|