@headless-tree/core 0.0.0-20250731075124 → 0.0.0-20250807215101

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,6 @@
1
1
  # @headless-tree/core
2
2
 
3
- ## 0.0.0-20250731075124
3
+ ## 0.0.0-20250807215101
4
4
 
5
5
  ### Minor Changes
6
6
 
@@ -14,6 +14,8 @@
14
14
  - b41e1d2: fixed a bug where ending drag without successful drop doesn't properly reset drag line (#132)
15
15
  - b413f74: Fix `aria-posinset` and `aria-level` to be 1-based indexing
16
16
  - a250b3b: Fix a bug where expand from the initial keyboard focus fails when rootItemId is an empty string
17
+ - 62867e8: Introduced a short delay before hiding the drag line when leaving a drag target, which helps to reduce flickering of the dragline when moving between items
18
+ - c4579eb: Update keyboard drag and drop to include the focused item in the dragged items
17
19
  - 662e2a8: Improved customizability of checkboxes feature (still alpha state), allowing you to customize `propagateCheckedState` and `canCheckFolders` independently
18
20
  - 662e2a8: Changed to new buildtool in core packages (now using tsup) to hopefully fix some ESM/CJS integrations
19
21
 
package/dist/index.d.mts CHANGED
@@ -1,6 +1,7 @@
1
1
  interface DndDataRef {
2
2
  lastDragCode?: string;
3
3
  lastAllowDrop?: boolean;
4
+ lastDragEnter?: number;
4
5
  windowDragEndListener?: () => void;
5
6
  }
6
7
  interface DndState<T> {
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  interface DndDataRef {
2
2
  lastDragCode?: string;
3
3
  lastAllowDrop?: boolean;
4
+ lastDragEnter?: number;
4
5
  windowDragEndListener?: () => void;
5
6
  }
6
7
  interface DndState<T> {
package/dist/index.js CHANGED
@@ -1516,6 +1516,7 @@ var dragAndDropFeature = {
1516
1516
  return;
1517
1517
  }
1518
1518
  dataRef.current.lastDragCode = nextDragCode;
1519
+ dataRef.current.lastDragEnter = Date.now();
1519
1520
  const target = getDragTarget(e, item, tree);
1520
1521
  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)))) {
1521
1522
  dataRef.current.lastAllowDrop = false;
@@ -1533,12 +1534,16 @@ var dragAndDropFeature = {
1533
1534
  e.preventDefault();
1534
1535
  },
1535
1536
  onDragLeave: () => {
1536
- const dataRef = tree.getDataRef();
1537
- dataRef.current.lastDragCode = "no-drag";
1538
- tree.applySubStateUpdate("dnd", (state) => __spreadProps(__spreadValues({}, state), {
1539
- draggingOverItem: void 0,
1540
- dragTarget: void 0
1541
- }));
1537
+ setTimeout(() => {
1538
+ var _a;
1539
+ const dataRef = tree.getDataRef();
1540
+ if (((_a = dataRef.current.lastDragEnter) != null ? _a : 0) + 100 >= Date.now()) return;
1541
+ dataRef.current.lastDragCode = "no-drag";
1542
+ tree.applySubStateUpdate("dnd", (state) => __spreadProps(__spreadValues({}, state), {
1543
+ draggingOverItem: void 0,
1544
+ dragTarget: void 0
1545
+ }));
1546
+ }, 100);
1542
1547
  },
1543
1548
  onDragEnd: (e) => {
1544
1549
  var _a, _b;
@@ -1735,7 +1740,11 @@ var keyboardDragAndDropFeature = {
1735
1740
  preventDefault: true,
1736
1741
  isEnabled: (tree) => !tree.getState().dnd,
1737
1742
  handler: (_, tree) => {
1738
- tree.startKeyboardDrag(tree.getSelectedItems());
1743
+ const selectedItems = tree.getSelectedItems();
1744
+ const focusedItem = tree.getFocusedItem();
1745
+ tree.startKeyboardDrag(
1746
+ selectedItems.includes(focusedItem) ? selectedItems : selectedItems.concat(focusedItem)
1747
+ );
1739
1748
  }
1740
1749
  },
1741
1750
  dragUp: {
package/dist/index.mjs CHANGED
@@ -1472,6 +1472,7 @@ var dragAndDropFeature = {
1472
1472
  return;
1473
1473
  }
1474
1474
  dataRef.current.lastDragCode = nextDragCode;
1475
+ dataRef.current.lastDragEnter = Date.now();
1475
1476
  const target = getDragTarget(e, item, tree);
1476
1477
  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)))) {
1477
1478
  dataRef.current.lastAllowDrop = false;
@@ -1489,12 +1490,16 @@ var dragAndDropFeature = {
1489
1490
  e.preventDefault();
1490
1491
  },
1491
1492
  onDragLeave: () => {
1492
- const dataRef = tree.getDataRef();
1493
- dataRef.current.lastDragCode = "no-drag";
1494
- tree.applySubStateUpdate("dnd", (state) => __spreadProps(__spreadValues({}, state), {
1495
- draggingOverItem: void 0,
1496
- dragTarget: void 0
1497
- }));
1493
+ setTimeout(() => {
1494
+ var _a;
1495
+ const dataRef = tree.getDataRef();
1496
+ if (((_a = dataRef.current.lastDragEnter) != null ? _a : 0) + 100 >= Date.now()) return;
1497
+ dataRef.current.lastDragCode = "no-drag";
1498
+ tree.applySubStateUpdate("dnd", (state) => __spreadProps(__spreadValues({}, state), {
1499
+ draggingOverItem: void 0,
1500
+ dragTarget: void 0
1501
+ }));
1502
+ }, 100);
1498
1503
  },
1499
1504
  onDragEnd: (e) => {
1500
1505
  var _a, _b;
@@ -1691,7 +1696,11 @@ var keyboardDragAndDropFeature = {
1691
1696
  preventDefault: true,
1692
1697
  isEnabled: (tree) => !tree.getState().dnd,
1693
1698
  handler: (_, tree) => {
1694
- tree.startKeyboardDrag(tree.getSelectedItems());
1699
+ const selectedItems = tree.getSelectedItems();
1700
+ const focusedItem = tree.getFocusedItem();
1701
+ tree.startKeyboardDrag(
1702
+ selectedItems.includes(focusedItem) ? selectedItems : selectedItems.concat(focusedItem)
1703
+ );
1695
1704
  }
1696
1705
  },
1697
1706
  dragUp: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@headless-tree/core",
3
- "version": "0.0.0-20250731075124",
3
+ "version": "0.0.0-20250807215101",
4
4
  "main": "dist/index.d.ts",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.mts",
@@ -193,6 +193,7 @@ export const dragAndDropFeature: FeatureImplementation = {
193
193
  return;
194
194
  }
195
195
  dataRef.current.lastDragCode = nextDragCode;
196
+ dataRef.current.lastDragEnter = Date.now();
196
197
 
197
198
  const target = getDragTarget(e, item, tree);
198
199
 
@@ -222,13 +223,16 @@ export const dragAndDropFeature: FeatureImplementation = {
222
223
  },
223
224
 
224
225
  onDragLeave: () => {
225
- const dataRef = tree.getDataRef<DndDataRef>();
226
- dataRef.current.lastDragCode = "no-drag";
227
- tree.applySubStateUpdate("dnd", (state) => ({
228
- ...state,
229
- draggingOverItem: undefined,
230
- dragTarget: undefined,
231
- }));
226
+ setTimeout(() => {
227
+ const dataRef = tree.getDataRef<DndDataRef>();
228
+ if ((dataRef.current.lastDragEnter ?? 0) + 100 >= Date.now()) return;
229
+ dataRef.current.lastDragCode = "no-drag";
230
+ tree.applySubStateUpdate("dnd", (state) => ({
231
+ ...state,
232
+ draggingOverItem: undefined,
233
+ dragTarget: undefined,
234
+ }));
235
+ }, 100);
232
236
  },
233
237
 
234
238
  onDragEnd: (e: DragEvent) => {
@@ -3,6 +3,7 @@ import { ItemInstance, SetStateFn } from "../../types/core";
3
3
  export interface DndDataRef {
4
4
  lastDragCode?: string;
5
5
  lastAllowDrop?: boolean;
6
+ lastDragEnter?: number;
6
7
  windowDragEndListener?: () => void;
7
8
  }
8
9
 
@@ -191,7 +191,14 @@ export const keyboardDragAndDropFeature: FeatureImplementation = {
191
191
  preventDefault: true,
192
192
  isEnabled: (tree) => !tree.getState().dnd,
193
193
  handler: (_, tree) => {
194
- tree.startKeyboardDrag(tree.getSelectedItems());
194
+ const selectedItems = tree.getSelectedItems();
195
+ const focusedItem = tree.getFocusedItem();
196
+
197
+ tree.startKeyboardDrag(
198
+ selectedItems.includes(focusedItem)
199
+ ? selectedItems
200
+ : selectedItems.concat(focusedItem),
201
+ );
195
202
  },
196
203
  },
197
204
  dragUp: {
@@ -49,6 +49,37 @@ describe("core-feature/keyboard-drag-and-drop", () => {
49
49
  tree.expect.substate("assistiveDndState", AssistiveDndState.Started);
50
50
  });
51
51
 
52
+ it("starts dragging only focused item", () => {
53
+ tree.item("x3").setFocused();
54
+ tree.do.hotkey("startDrag");
55
+ tree.expect.substate("dnd", {
56
+ draggedItems: [tree.item("x3")],
57
+ dragTarget: {
58
+ childIndex: 3,
59
+ dragLineIndex: 19,
60
+ dragLineLevel: 0,
61
+ insertionIndex: 2,
62
+ item: tree.item("x"),
63
+ },
64
+ });
65
+ });
66
+
67
+ it("starts dragging both selected and focused item", () => {
68
+ tree.do.selectMultiple("x111", "x112");
69
+ tree.item("x3").setFocused();
70
+ tree.do.hotkey("startDrag");
71
+ tree.expect.substate("dnd", {
72
+ draggedItems: [tree.item("x111"), tree.item("x112"), tree.item("x3")],
73
+ dragTarget: {
74
+ childIndex: 3,
75
+ dragLineIndex: 19,
76
+ dragLineLevel: 0,
77
+ insertionIndex: 2,
78
+ item: tree.item("x"),
79
+ },
80
+ });
81
+ });
82
+
52
83
  it("moves down 1", () => {
53
84
  tree.do.selectMultiple("x111", "x112");
54
85
  tree.do.hotkey("startDrag");
@@ -355,13 +386,13 @@ describe("core-feature/keyboard-drag-and-drop", () => {
355
386
 
356
387
  it("doesnt go below end of tree", () => {
357
388
  const lastState = {
358
- draggedItems: [tree.item("x111")],
389
+ draggedItems: [tree.item("x111"), tree.item("x3")],
359
390
  dragTarget: {
360
391
  item: tree.item("x"),
361
392
  childIndex: 4,
362
393
  dragLineIndex: 20,
363
394
  dragLineLevel: 0,
364
- insertionIndex: 4,
395
+ insertionIndex: 3,
365
396
  },
366
397
  };
367
398
 
@@ -378,7 +409,7 @@ describe("core-feature/keyboard-drag-and-drop", () => {
378
409
 
379
410
  it("doesnt go above top of tree", () => {
380
411
  const firstState = {
381
- draggedItems: [tree.item("x111")],
412
+ draggedItems: [tree.item("x111"), tree.item("x1")],
382
413
  dragTarget: {
383
414
  item: tree.item("x"),
384
415
  childIndex: 0,